1 /* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800
2 Copyright (C) 2005-2022 Free Software Foundation, Inc.
3 Contributed by Arnold Metselaar <arnold_m@operamail.com>
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 #include "safe-ctype.h"
26 #include "dwarf2dbg.h"
27 #include "dw2gencfi.h"
29 /* Exported constants. */
30 const char comment_chars
[] = ";\0";
31 const char line_comment_chars
[] = "#;\0";
32 const char line_separator_chars
[] = "\0";
33 const char EXP_CHARS
[] = "eE\0";
34 const char FLT_CHARS
[] = "RrDdFfSsHh\0";
36 /* For machine specific options. */
37 const char * md_shortopts
= ""; /* None yet. */
41 OPTION_MARCH
= OPTION_MD_BASE
,
55 OPTION_FP_SINGLE_FORMAT
,
56 OPTION_FP_DOUBLE_FORMAT
,
57 OPTION_COMPAT_LL_PREFIX
,
58 OPTION_COMPAT_COLONLESS
,
62 #define INS_Z80 (1 << 0)
63 #define INS_R800 (1 << 1)
64 #define INS_GBZ80 (1 << 2)
65 #define INS_Z180 (1 << 3)
66 #define INS_EZ80 (1 << 4)
67 #define INS_Z80N (1 << 5)
68 #define INS_MARCH_MASK 0xffff
70 #define INS_IDX_HALF (1 << 16)
71 #define INS_IN_F_C (1 << 17)
72 #define INS_OUT_C_0 (1 << 18)
73 #define INS_SLI (1 << 19)
74 #define INS_ROT_II_LD (1 << 20) /* instructions like SLA (ii+d),r; which is: LD r,(ii+d); SLA r; LD (ii+d),r */
75 #define INS_TUNE_MASK 0xffff0000
77 #define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80 | INS_Z80N)
80 #define INS_UNDOC (INS_IDX_HALF | INS_IN_F_C)
81 #define INS_UNPORT (INS_OUT_C_0 | INS_SLI | INS_ROT_II_LD)
83 struct option md_longopts
[] =
85 { "march", required_argument
, NULL
, OPTION_MARCH
},
86 { "z80", no_argument
, NULL
, OPTION_MACH_Z80
},
87 { "r800", no_argument
, NULL
, OPTION_MACH_R800
},
88 { "z180", no_argument
, NULL
, OPTION_MACH_Z180
},
89 { "ez80", no_argument
, NULL
, OPTION_MACH_EZ80_Z80
},
90 { "ez80-adl", no_argument
, NULL
, OPTION_MACH_EZ80_ADL
},
91 { "fp-s", required_argument
, NULL
, OPTION_FP_SINGLE_FORMAT
},
92 { "fp-d", required_argument
, NULL
, OPTION_FP_DOUBLE_FORMAT
},
93 { "strict", no_argument
, NULL
, OPTION_MACH_FUD
},
94 { "full", no_argument
, NULL
, OPTION_MACH_IUP
},
95 { "with-inst", required_argument
, NULL
, OPTION_MACH_INST
},
96 { "Wnins", required_argument
, NULL
, OPTION_MACH_INST
},
97 { "without-inst", required_argument
, NULL
, OPTION_MACH_NO_INST
},
98 { "local-prefix", required_argument
, NULL
, OPTION_COMPAT_LL_PREFIX
},
99 { "colonless", no_argument
, NULL
, OPTION_COMPAT_COLONLESS
},
100 { "sdcc", no_argument
, NULL
, OPTION_COMPAT_SDCC
},
101 { "Fins", required_argument
, NULL
, OPTION_MACH_NO_INST
},
102 { "ignore-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_IUD
},
103 { "Wnud", no_argument
, NULL
, OPTION_MACH_IUD
},
104 { "warn-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_WUD
},
105 { "Wud", no_argument
, NULL
, OPTION_MACH_WUD
},
106 { "forbid-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_FUD
},
107 { "Fud", no_argument
, NULL
, OPTION_MACH_FUD
},
108 { "ignore-unportable-instructions", no_argument
, NULL
, OPTION_MACH_IUP
},
109 { "Wnup", no_argument
, NULL
, OPTION_MACH_IUP
},
110 { "warn-unportable-instructions", no_argument
, NULL
, OPTION_MACH_WUP
},
111 { "Wup", no_argument
, NULL
, OPTION_MACH_WUP
},
112 { "forbid-unportable-instructions", no_argument
, NULL
, OPTION_MACH_FUP
},
113 { "Fup", no_argument
, NULL
, OPTION_MACH_FUP
},
115 { NULL
, no_argument
, NULL
, 0 }
118 size_t md_longopts_size
= sizeof (md_longopts
);
120 extern int coff_flags
;
121 /* Instruction classes that silently assembled. */
122 static int ins_ok
= INS_Z80
| INS_UNDOC
;
123 /* Instruction classes that generate errors. */
124 static int ins_err
= ~(INS_Z80
| INS_UNDOC
);
125 /* eZ80 CPU mode (ADL or Z80) */
126 static int cpu_mode
= 0; /* 0 - Z80, 1 - ADL */
127 /* accept SDCC specific instruction encoding */
128 static int sdcc_compat
= 0;
129 /* accept colonless labels */
130 static int colonless_labels
= 0;
131 /* local label prefix (NULL - default) */
132 static const char *local_label_prefix
= NULL
;
133 /* floating point support */
134 typedef const char *(*str_to_float_t
)(char *litP
, int *sizeP
);
135 static str_to_float_t str_to_float
;
136 static str_to_float_t str_to_double
;
138 /* mode of current instruction */
139 #define INST_MODE_S 0 /* short data mode */
140 #define INST_MODE_IS 0 /* short instruction mode */
141 #define INST_MODE_L 2 /* long data mode */
142 #define INST_MODE_IL 1 /* long instruction mode */
143 #define INST_MODE_FORCED 4 /* CPU mode changed by instruction suffix*/
144 static char inst_mode
;
155 static const struct match_info
158 {"z80", INS_Z80
, 0, 0, "Zilog Z80" },
159 {"ez80", INS_EZ80
, 0, 0, "Zilog eZ80" },
160 {"gbz80", INS_GBZ80
, INS_UNDOC
|INS_UNPORT
, 0, "GameBoy Z80" },
161 {"r800", INS_R800
, INS_UNPORT
, 0, "Ascii R800" },
162 {"z180", INS_Z180
, INS_UNDOC
|INS_UNPORT
, 0, "Zilog Z180" },
163 {"z80n", INS_Z80N
, 0, 0, "Z80 Next" }
166 static const struct match_info
169 {"full", INS_UNDOC
|INS_UNPORT
, 0, 0, "assemble all known instructions" },
170 {"adl", 0, 0, 1, "eZ80 ADL mode by default" },
171 {"xyhl", INS_IDX_HALF
, 0, 0, "instructions with halves of index registers" },
172 {"infc", INS_IN_F_C
, 0, 0, "instruction IN F,(C)" },
173 {"outc0", INS_OUT_C_0
, 0, 0, "instruction OUT (C),0" },
174 {"sli", INS_SLI
, 0, 0, "instruction known as SLI, SLL, or SL1" },
175 {"xdcb", INS_ROT_II_LD
, 0, 0, "instructions like RL (IX+d),R (DD/FD CB dd oo)" }
179 static int signed_overflow (signed long value
, unsigned bitsize
);
180 static int unsigned_overflow (unsigned long value
, unsigned bitsize
);
181 static int is_overflow (long value
, unsigned bitsize
);
184 setup_march (const char *name
, int *ok
, int *err
, int *mode
)
187 size_t len
= strcspn (name
, "+-");
188 for (i
= 0; i
< ARRAY_SIZE (match_cpu_table
); ++i
)
189 if (!strncasecmp (name
, match_cpu_table
[i
].name
, len
)
190 && strlen (match_cpu_table
[i
].name
) == len
)
192 *ok
= match_cpu_table
[i
].ins_ok
;
193 *err
= match_cpu_table
[i
].ins_err
;
194 *mode
= match_cpu_table
[i
].cpu_mode
;
198 if (i
>= ARRAY_SIZE (match_cpu_table
))
199 as_fatal (_("Invalid CPU is specified: %s"), name
);
203 name
= &name
[len
+ 1];
204 len
= strcspn (name
, "+-");
205 for (i
= 0; i
< ARRAY_SIZE (match_ext_table
); ++i
)
206 if (!strncasecmp (name
, match_ext_table
[i
].name
, len
)
207 && strlen (match_ext_table
[i
].name
) == len
)
211 *ok
|= match_ext_table
[i
].ins_ok
;
212 *err
&= ~match_ext_table
[i
].ins_ok
;
213 *mode
|= match_ext_table
[i
].cpu_mode
;
217 *ok
&= ~match_ext_table
[i
].ins_ok
;
218 *err
|= match_ext_table
[i
].ins_ok
;
219 *mode
&= ~match_ext_table
[i
].cpu_mode
;
223 if (i
>= ARRAY_SIZE (match_ext_table
))
224 as_fatal (_("Invalid EXTENSION is specified: %s"), name
);
229 setup_instruction (const char *inst
, int *add
, int *sub
)
232 if (!strcmp (inst
, "idx-reg-halves"))
234 else if (!strcmp (inst
, "sli"))
236 else if (!strcmp (inst
, "op-ii-ld"))
238 else if (!strcmp (inst
, "in-f-c"))
240 else if (!strcmp (inst
, "out-c-0"))
250 str_to_zeda32 (char *litP
, int *sizeP
);
252 str_to_float48 (char *litP
, int *sizeP
);
254 str_to_ieee754_h (char *litP
, int *sizeP
);
256 str_to_ieee754_s (char *litP
, int *sizeP
);
258 str_to_ieee754_d (char *litP
, int *sizeP
);
260 static str_to_float_t
261 get_str_to_float (const char *arg
)
263 if (strcasecmp (arg
, "zeda32") == 0)
264 return str_to_zeda32
;
266 if (strcasecmp (arg
, "math48") == 0)
267 return str_to_float48
;
269 if (strcasecmp (arg
, "half") != 0)
270 return str_to_ieee754_h
;
272 if (strcasecmp (arg
, "single") != 0)
273 return str_to_ieee754_s
;
275 if (strcasecmp (arg
, "double") != 0)
276 return str_to_ieee754_d
;
278 if (strcasecmp (arg
, "ieee754") == 0)
279 as_fatal (_("invalid floating point numbers type `%s'"), arg
);
284 setup_instruction_list (const char *list
, int *add
, int *sub
)
291 for (b
= list
; *b
!= '\0';)
298 if (sz
== 0 || sz
>= (int)sizeof (buf
))
300 as_bad (_("invalid INST in command line: %s"), b
);
305 if (setup_instruction (buf
, add
, sub
))
309 as_bad (_("invalid INST in command line: %s"), buf
);
320 md_parse_option (int c
, const char* arg
)
327 setup_march (arg
, & ins_ok
, & ins_err
, & cpu_mode
);
329 case OPTION_MACH_Z80
:
330 setup_march ("z80", & ins_ok
, & ins_err
, & cpu_mode
);
332 case OPTION_MACH_R800
:
333 setup_march ("r800", & ins_ok
, & ins_err
, & cpu_mode
);
335 case OPTION_MACH_Z180
:
336 setup_march ("z180", & ins_ok
, & ins_err
, & cpu_mode
);
338 case OPTION_MACH_EZ80_Z80
:
339 setup_march ("ez80", & ins_ok
, & ins_err
, & cpu_mode
);
341 case OPTION_MACH_EZ80_ADL
:
342 setup_march ("ez80+adl", & ins_ok
, & ins_err
, & cpu_mode
);
344 case OPTION_FP_SINGLE_FORMAT
:
345 str_to_float
= get_str_to_float (arg
);
347 case OPTION_FP_DOUBLE_FORMAT
:
348 str_to_double
= get_str_to_float (arg
);
350 case OPTION_MACH_INST
:
351 if ((ins_ok
& INS_GBZ80
) == 0)
352 return setup_instruction_list (arg
, & ins_ok
, & ins_err
);
354 case OPTION_MACH_NO_INST
:
355 if ((ins_ok
& INS_GBZ80
) == 0)
356 return setup_instruction_list (arg
, & ins_err
, & ins_ok
);
358 case OPTION_MACH_WUD
:
359 case OPTION_MACH_IUD
:
360 if ((ins_ok
& INS_GBZ80
) == 0)
363 ins_err
&= ~INS_UNDOC
;
366 case OPTION_MACH_WUP
:
367 case OPTION_MACH_IUP
:
368 if ((ins_ok
& INS_GBZ80
) == 0)
370 ins_ok
|= INS_UNDOC
| INS_UNPORT
;
371 ins_err
&= ~(INS_UNDOC
| INS_UNPORT
);
374 case OPTION_MACH_FUD
:
375 if ((ins_ok
& (INS_R800
| INS_GBZ80
)) == 0)
377 ins_ok
&= (INS_UNDOC
| INS_UNPORT
);
378 ins_err
|= INS_UNDOC
| INS_UNPORT
;
381 case OPTION_MACH_FUP
:
382 ins_ok
&= ~INS_UNPORT
;
383 ins_err
|= INS_UNPORT
;
385 case OPTION_COMPAT_LL_PREFIX
:
386 local_label_prefix
= (arg
&& *arg
) ? arg
: NULL
;
388 case OPTION_COMPAT_SDCC
:
391 case OPTION_COMPAT_COLONLESS
:
392 colonless_labels
= 1;
400 md_show_usage (FILE * f
)
404 CPU model options:\n\
405 -march=CPU[+EXT...][-EXT...]\n\
406 \t\t\t generate code for CPU, where CPU is one of:\n"));
407 for (i
= 0; i
< ARRAY_SIZE(match_cpu_table
); ++i
)
408 fprintf (f
, " %-8s\t\t %s\n", match_cpu_table
[i
].name
, match_cpu_table
[i
].comment
);
409 fprintf (f
, _("And EXT is combination (+EXT - add, -EXT - remove) of:\n"));
410 for (i
= 0; i
< ARRAY_SIZE(match_ext_table
); ++i
)
411 fprintf (f
, " %-8s\t\t %s\n", match_ext_table
[i
].name
, match_ext_table
[i
].comment
);
413 Compatibility options:\n\
414 -local-prefix=TEXT\t treat labels prefixed by TEXT as local\n\
415 -colonless\t\t permit colonless labels\n\
416 -sdcc\t\t\t accept SDCC specific instruction syntax\n\
417 -fp-s=FORMAT\t\t set single precision FP numbers format\n\
418 -fp-d=FORMAT\t\t set double precision FP numbers format\n\
419 Where FORMAT one of:\n\
420 ieee754\t\t IEEE754 compatible (depends on directive)\n\
421 half\t\t\t IEEE754 half precision (16 bit)\n\
422 single\t\t IEEE754 single precision (32 bit)\n\
423 double\t\t IEEE754 double precision (64 bit)\n\
424 zeda32\t\t Zeda z80float library 32 bit format\n\
425 math48\t\t 48 bit format from Math48 library\n\
427 Default: -march=z80+xyhl+infc\n"));
430 static symbolS
* zero
;
438 #define R_STACKABLE (0x80)
439 #define R_ARITH (0x40)
442 #define R_INDEX (R_IX | R_IY)
451 #define REG_F (6 | 8)
456 #define REG_AF (3 | R_STACKABLE)
457 #define REG_BC (0 | R_STACKABLE | R_ARITH)
458 #define REG_DE (1 | R_STACKABLE | R_ARITH)
459 #define REG_HL (2 | R_STACKABLE | R_ARITH)
460 #define REG_IX (REG_HL | R_IX)
461 #define REG_IY (REG_HL | R_IY)
462 #define REG_SP (3 | R_ARITH)
464 static const struct reg_entry regtable
[] =
466 {"a", REG_A
, INS_ALL
},
467 {"af", REG_AF
, INS_ALL
},
468 {"b", REG_B
, INS_ALL
},
469 {"bc", REG_BC
, INS_ALL
},
470 {"c", REG_C
, INS_ALL
},
471 {"d", REG_D
, INS_ALL
},
472 {"de", REG_DE
, INS_ALL
},
473 {"e", REG_E
, INS_ALL
},
474 {"f", REG_F
, INS_IN_F_C
| INS_Z80N
| INS_R800
},
475 {"h", REG_H
, INS_ALL
},
476 {"hl", REG_HL
, INS_ALL
},
477 {"i", REG_I
, INS_NOT_GBZ80
},
478 {"ix", REG_IX
, INS_NOT_GBZ80
},
479 {"ixh", REG_H
| R_IX
, INS_IDX_HALF
| INS_EZ80
| INS_R800
| INS_Z80N
},
480 {"ixl", REG_L
| R_IX
, INS_IDX_HALF
| INS_EZ80
| INS_R800
| INS_Z80N
},
481 {"iy", REG_IY
, INS_NOT_GBZ80
},
482 {"iyh", REG_H
| R_IY
, INS_IDX_HALF
| INS_EZ80
| INS_R800
| INS_Z80N
},
483 {"iyl", REG_L
| R_IY
, INS_IDX_HALF
| INS_EZ80
| INS_R800
| INS_Z80N
},
484 {"l", REG_L
, INS_ALL
},
485 {"mb", REG_MB
, INS_EZ80
},
486 {"r", REG_R
, INS_NOT_GBZ80
},
487 {"sp", REG_SP
, INS_ALL
},
490 #define BUFLEN 8 /* Large enough for any keyword. */
495 expressionS nul
, reg
;
497 unsigned int i
, j
, k
;
500 memset (®
, 0, sizeof (reg
));
501 memset (&nul
, 0, sizeof (nul
));
503 if (ins_ok
& INS_EZ80
) /* if select EZ80 cpu then */
504 listing_lhs_width
= 6; /* use 6 bytes per line in the listing */
506 reg
.X_op
= O_register
;
508 reg
.X_add_symbol
= reg
.X_op_symbol
= 0;
509 for ( i
= 0 ; i
< ARRAY_SIZE ( regtable
) ; ++i
)
511 if (regtable
[i
].isa
&& !(regtable
[i
].isa
& ins_ok
))
513 reg
.X_add_number
= regtable
[i
].number
;
514 k
= strlen ( regtable
[i
].name
);
518 for ( j
= ( 1<<k
) ; j
; --j
)
520 for ( k
= 0 ; regtable
[i
].name
[k
] ; ++k
)
522 buf
[k
] = ( j
& ( 1<<k
) ) ? TOUPPER (regtable
[i
].name
[k
]) : regtable
[i
].name
[k
];
524 symbolS
* psym
= symbol_find_or_make (buf
);
525 S_SET_SEGMENT (psym
, reg_section
);
526 symbol_set_value_expression (psym
, ®
);
530 p
= input_line_pointer
;
531 input_line_pointer
= (char *) "0";
534 input_line_pointer
= p
;
535 zero
= make_expr_symbol (& nul
);
536 /* We do not use relaxation (yet). */
545 switch (ins_ok
& INS_MARCH_MASK
)
548 mach_type
= bfd_mach_z80
;
551 mach_type
= bfd_mach_r800
;
554 mach_type
= bfd_mach_z180
;
557 mach_type
= bfd_mach_gbz80
;
560 mach_type
= cpu_mode
? bfd_mach_ez80_adl
: bfd_mach_ez80_z80
;
563 mach_type
= bfd_mach_z80n
;
568 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach_type
);
571 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
573 z80_elf_final_processing (void)
574 {/* nothing to do, all is done by BFD itself */
577 elf_elfheader (stdoutput)->e_flags = elf_flags;
583 skip_space (const char *s
)
585 while (*s
== ' ' || *s
== '\t')
590 /* A non-zero return-value causes a continue in the
591 function read_a_source_file () in ../read.c. */
593 z80_start_line_hook (void)
598 /* Convert one character constants. */
599 for (p
= input_line_pointer
; *p
&& *p
!= '\n'; ++p
)
604 if (p
[1] != 0 && p
[1] != '\'' && p
[2] == '\'')
606 snprintf (buf
, 4, "%3d", (unsigned char)p
[1]);
614 for (quote
= *p
++; quote
!= *p
&& '\n' != *p
; ++p
)
618 as_bad (_("-- unterminated string"));
619 ignore_rest_of_line ();
623 case '#': /* force to use next expression as immediate value in SDCC */
626 if (ISSPACE(p
[1]) && *skip_space (p
+ 1) == '(')
627 { /* ld a,# (expr)... -> ld a,0+(expr)... */
631 else /* ld a,#(expr)... -> ld a,+(expr); ld a,#expr -> ld a, expr */
632 *p
= (p
[1] == '(') ? '+' : ' ';
636 /* Check for <label>[:] =|([.](EQU|DEFL)) <value>. */
637 if (is_name_beginner (*input_line_pointer
))
640 char c
, *rest
, *line_start
;
643 line_start
= input_line_pointer
;
646 c
= get_symbol_name (&name
);
647 rest
= input_line_pointer
+ 1;
648 if (c
== ':' && *rest
== ':')
650 /* remove second colon if SDCC compatibility enabled */
655 rest
= (char*)skip_space (rest
);
657 len
= (rest
[1] == '=') ? 2 : 1;
662 if (strncasecmp (rest
, "EQU", 3) == 0)
664 else if (strncasecmp (rest
, "DEFL", 4) == 0)
669 if (len
&& (len
<= 2 || !ISALPHA (rest
[len
])))
671 /* Handle assignment here. */
672 if (line_start
[-1] == '\n')
674 bump_line_counters ();
677 input_line_pointer
= rest
+ len
- 1;
678 /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
681 case 1: /* label = expr */
682 case 4: /* label DEFL expr */
685 case 2: /* label == expr */
686 case 3: /* label EQU expr */
694 /* Restore line and pointer. */
695 (void) restore_line_pointer (c
);
696 input_line_pointer
= line_start
;
703 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
709 md_atof (int type
, char *litP
, int *sizeP
)
718 return str_to_float (litP
, sizeP
);
725 return str_to_double (litP
, sizeP
);
728 return ieee_md_atof (type
, litP
, sizeP
, false);
732 md_section_align (segT seg ATTRIBUTE_UNUSED
, valueT size
)
738 md_pcrel_from (fixS
* fixp
)
740 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
743 typedef const char * (asfunc
)(char, char, const char*);
745 typedef struct _table_t
748 unsigned char prefix
;
749 unsigned char opcode
;
751 unsigned inss
; /*0 - all CPU types or list of supported INS_* */
754 /* Compares the key for structs that start with a char * to the key. */
756 key_cmp (const void * a
, const void * b
)
758 const char *str_a
, *str_b
;
760 str_a
= *((const char**)a
);
761 str_b
= *((const char**)b
);
762 return strcmp (str_a
, str_b
);
766 const char *key
= buf
;
768 /* Prevent an error on a line from also generating
769 a "junk at end of line" error message. */
770 static char err_flag
;
773 error (const char * message
)
778 as_bad ("%s", message
);
785 error (_("illegal operand"));
789 wrong_mach (int ins_type
)
791 if (ins_type
& ins_err
)
794 as_warn (_("undocumented instruction"));
798 check_mach (int ins_type
)
800 if ((ins_type
& ins_ok
) == 0)
801 wrong_mach (ins_type
);
804 /* Check whether an expression is indirect. */
806 is_indir (const char *s
)
812 /* Indirection is indicated with parentheses. */
815 for (p
= s
, depth
= 0; *p
&& *p
!= ','; ++p
)
821 for (quote
= *p
++; quote
!= *p
&& *p
!= '\n'; ++p
)
822 if (*p
== '\\' && p
[1])
832 p
= skip_space (p
+ 1);
838 error (_("mismatched parentheses"));
844 error (_("mismatched parentheses"));
849 /* Check whether a symbol involves a register. */
851 contains_register (symbolS
*sym
)
855 expressionS
* ex
= symbol_get_value_expression (sym
);
864 if (ex
->X_op_symbol
&& contains_register (ex
->X_op_symbol
))
869 if (ex
->X_add_symbol
&& contains_register (ex
->X_add_symbol
))
881 /* Parse general expression, not looking for indexed addressing. */
883 parse_exp_not_indexed (const char *s
, expressionS
*op
)
889 memset (op
, 0, sizeof (*op
));
891 if (sdcc_compat
&& (*p
== '<' || *p
== '>'))
895 case '<': /* LSB request */
898 case '>': /* MSB request */
899 make_shift
= cpu_mode
? 16 : 8;
906 if (make_shift
== -1)
907 indir
= is_indir (p
);
911 if (indir
&& (ins_ok
& INS_GBZ80
))
912 { /* check for instructions like ld a,(hl+), ld (hl-),a */
913 p
= skip_space (p
+1);
914 if (!strncasecmp (p
, "hl", 2))
917 if (*skip_space(p
+1) == ')' && (*p
== '+' || *p
== '-'))
920 op
->X_add_symbol
= NULL
;
921 op
->X_add_number
= (*p
== '+') ? REG_HL
: -REG_HL
;
922 input_line_pointer
= (char*)skip_space(p
+ 1) + 1;
923 return input_line_pointer
;
927 input_line_pointer
= (char*) s
;
932 error (_("missing operand"));
935 error (_("bad expression syntax"));
943 /* replace [op] by [op >> shift] */
945 op
->X_add_symbol
= make_expr_symbol (op
);
946 op
->X_add_number
= 0;
947 op
->X_op
= O_right_shift
;
948 memset (&data
, 0, sizeof (data
));
949 data
.X_op
= O_constant
;
950 data
.X_add_number
= make_shift
;
951 op
->X_op_symbol
= make_expr_symbol (&data
);
953 return input_line_pointer
;
957 unify_indexed (expressionS
*op
)
959 if (O_register
!= symbol_get_value_expression (op
->X_add_symbol
)->X_op
)
962 int rnum
= symbol_get_value_expression (op
->X_add_symbol
)->X_add_number
;
963 if ( ((REG_IX
!= rnum
) && (REG_IY
!= rnum
)) || contains_register (op
->X_op_symbol
))
969 /* Convert subtraction to addition of negative value. */
970 if (O_subtract
== op
->X_op
)
973 memset (&minus
, 0, sizeof (minus
));
974 minus
.X_op
= O_uminus
;
975 minus
.X_add_symbol
= op
->X_op_symbol
;
976 op
->X_op_symbol
= make_expr_symbol (&minus
);
980 /* Clear X_add_number of the expression. */
981 if (op
->X_add_number
!= 0)
984 memset (&add
, 0, sizeof (add
));
986 add
.X_add_number
= op
->X_add_number
;
987 add
.X_add_symbol
= op
->X_op_symbol
;
988 op
->X_add_symbol
= make_expr_symbol (&add
);
991 op
->X_add_symbol
= op
->X_op_symbol
;
993 op
->X_add_number
= rnum
;
998 /* Parse expression, change operator to O_md1 for indexed addressing. */
1000 parse_exp (const char *s
, expressionS
*op
)
1002 const char* res
= parse_exp_not_indexed (s
, op
);
1007 if (unify_indexed (op
) && op
->X_md
)
1011 if (op
->X_md
&& ((REG_IX
== op
->X_add_number
) || (REG_IY
== op
->X_add_number
)))
1013 op
->X_add_symbol
= zero
;
1018 /* parse SDCC syntax where index register offset placed before parentheses */
1019 if (sdcc_compat
&& is_indir (res
))
1023 res
= parse_exp (res
, op
);
1024 if (op
->X_op
!= O_md1
|| op
->X_add_symbol
!= zero
)
1027 op
->X_add_symbol
= make_expr_symbol (&off
);
1036 /* Condition codes, including some synonyms provided by HiTech zas. */
1037 static const struct reg_entry cc_tab
[] =
1039 { "age", 6 << 3, INS_ALL
},
1040 { "alt", 7 << 3, INS_ALL
},
1041 { "c", 3 << 3, INS_ALL
},
1042 { "di", 4 << 3, INS_ALL
},
1043 { "ei", 5 << 3, INS_ALL
},
1044 { "lge", 2 << 3, INS_ALL
},
1045 { "llt", 3 << 3, INS_ALL
},
1046 { "m", 7 << 3, INS_ALL
},
1047 { "nc", 2 << 3, INS_ALL
},
1048 { "nz", 0 << 3, INS_ALL
},
1049 { "p", 6 << 3, INS_ALL
},
1050 { "pe", 5 << 3, INS_ALL
},
1051 { "po", 4 << 3, INS_ALL
},
1052 { "z", 1 << 3, INS_ALL
},
1055 /* Parse condition code. */
1057 parse_cc (const char *s
, char * op
)
1061 struct reg_entry
* cc_p
;
1063 for (i
= 0; i
< BUFLEN
; ++i
)
1065 if (!ISALPHA (s
[i
])) /* Condition codes consist of letters only. */
1067 buf
[i
] = TOLOWER (s
[i
]);
1071 && ((s
[i
] == 0) || (s
[i
] == ',')))
1074 cc_p
= bsearch (&key
, cc_tab
, ARRAY_SIZE (cc_tab
),
1075 sizeof (cc_tab
[0]), key_cmp
);
1092 emit_insn (char prefix
, char opcode
, const char * args
)
1107 void z80_cons_fix_new (fragS
*frag_p
, int offset
, int nbytes
, expressionS
*exp
)
1109 bfd_reloc_code_real_type r
[4] =
1117 if (nbytes
< 1 || nbytes
> 4)
1119 as_bad (_("unsupported BFD relocation size %u"), nbytes
);
1123 fix_new_exp (frag_p
, offset
, nbytes
, exp
, 0, r
[nbytes
-1]);
1128 emit_data_val (expressionS
* val
, int size
)
1131 bfd_reloc_code_real_type r_type
;
1133 p
= frag_more (size
);
1134 if (val
->X_op
== O_constant
)
1137 if (is_overflow (val
->X_add_number
, size
*8))
1138 as_warn ( _("%d-bit overflow (%+ld)"), size
*8, val
->X_add_number
);
1139 for (i
= 0; i
< size
; ++i
)
1140 p
[i
] = (char)(val
->X_add_number
>> (i
*8));
1146 case 1: r_type
= BFD_RELOC_8
; break;
1147 case 2: r_type
= BFD_RELOC_16
; break;
1148 case 3: r_type
= BFD_RELOC_24
; break;
1149 case 4: r_type
= BFD_RELOC_32
; break;
1150 case 8: r_type
= BFD_RELOC_64
; break;
1152 as_fatal (_("invalid data size %d"), size
);
1155 if ( (val
->X_op
== O_register
)
1156 || (val
->X_op
== O_md1
)
1157 || contains_register (val
->X_add_symbol
)
1158 || contains_register (val
->X_op_symbol
))
1161 if (size
<= 2 && val
->X_op_symbol
)
1163 bool simplify
= true;
1164 int shift
= symbol_get_value_expression (val
->X_op_symbol
)->X_add_number
;
1165 if (val
->X_op
== O_bit_and
&& shift
== (1 << (size
*8))-1)
1167 else if (val
->X_op
!= O_right_shift
)
1174 case 0: r_type
= BFD_RELOC_Z80_BYTE0
; break;
1175 case 8: r_type
= BFD_RELOC_Z80_BYTE1
; break;
1176 case 16: r_type
= BFD_RELOC_Z80_BYTE2
; break;
1177 case 24: r_type
= BFD_RELOC_Z80_BYTE3
; break;
1178 default: simplify
= false;
1181 else /* if (size == 2) */
1185 case 0: r_type
= BFD_RELOC_Z80_WORD0
; break;
1186 case 16: r_type
= BFD_RELOC_Z80_WORD1
; break;
1188 case 24: /* add two byte fixups */
1189 val
->X_op
= O_symbol
;
1190 val
->X_op_symbol
= NULL
;
1191 val
->X_add_number
= 0;
1194 fix_new_exp (frag_now
, p
++ - frag_now
->fr_literal
, 1, val
, false,
1195 BFD_RELOC_Z80_BYTE1
);
1196 /* prepare to next byte */
1197 r_type
= BFD_RELOC_Z80_BYTE2
;
1200 r_type
= BFD_RELOC_Z80_BYTE3
; /* high byte will be 0 */
1204 default: simplify
= false;
1210 val
->X_op
= O_symbol
;
1211 val
->X_op_symbol
= NULL
;
1212 val
->X_add_number
= 0;
1216 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, size
, val
, false, r_type
);
1220 emit_byte (expressionS
* val
, bfd_reloc_code_real_type r_type
)
1224 if (r_type
== BFD_RELOC_8
)
1226 emit_data_val (val
, 1);
1230 *p
= val
->X_add_number
;
1231 if (contains_register (val
->X_add_symbol
) || contains_register (val
->X_op_symbol
))
1235 else if ((r_type
== BFD_RELOC_8_PCREL
) && (val
->X_op
== O_constant
))
1237 as_bad (_("cannot make a relative jump to an absolute location"));
1239 else if (val
->X_op
== O_constant
)
1241 if ((val
->X_add_number
< -128) || (val
->X_add_number
>= 128))
1243 if (r_type
== BFD_RELOC_Z80_DISP8
)
1244 as_bad (_("index overflow (%+ld)"), val
->X_add_number
);
1246 as_bad (_("offset overflow (%+ld)"), val
->X_add_number
);
1251 /* For symbols only, constants are stored at begin of function. */
1252 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 1, val
,
1253 r_type
== BFD_RELOC_8_PCREL
, r_type
);
1258 emit_word (expressionS
* val
)
1260 emit_data_val (val
, (inst_mode
& INST_MODE_IL
) ? 3 : 2);
1264 emit_mx (char prefix
, char opcode
, int shift
, expressionS
* arg
)
1265 /* The operand m may be r, (hl), (ix+d), (iy+d),
1266 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1271 rnum
= arg
->X_add_number
;
1287 if ((prefix
== 0) && (rnum
& R_INDEX
))
1289 prefix
= (rnum
& R_IX
) ? 0xDD : 0xFD;
1290 if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
1291 check_mach (INS_IDX_HALF
);
1300 q
= frag_more (prefix
? 2 : 1);
1303 * q
++ = opcode
+ (rnum
<< shift
);
1306 if (ins_ok
& INS_GBZ80
)
1312 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1313 *q
= (prefix
) ? prefix
: (opcode
+ (6 << shift
));
1315 expressionS offset
= *arg
;
1316 offset
.X_op
= O_symbol
;
1317 offset
.X_add_number
= 0;
1318 emit_byte (&offset
, BFD_RELOC_Z80_DISP8
);
1323 *q
= opcode
+(6<<shift
);
1331 /* The operand m may be r, (hl), (ix+d), (iy+d),
1332 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1334 emit_m (char prefix
, char opcode
, const char *args
)
1339 p
= parse_exp (args
, &arg_m
);
1344 emit_mx (prefix
, opcode
, 0, &arg_m
);
1352 /* The operand m may be as above or one of the undocumented
1353 combinations (ix+d),r and (iy+d),r (if unportable instructions
1357 emit_mr (char prefix
, char opcode
, const char *args
)
1359 expressionS arg_m
, arg_r
;
1362 p
= parse_exp (args
, & arg_m
);
1369 p
= parse_exp (p
+ 1, & arg_r
);
1371 if ((arg_r
.X_md
== 0)
1372 && (arg_r
.X_op
== O_register
)
1373 && (arg_r
.X_add_number
< 8))
1374 opcode
+= arg_r
.X_add_number
- 6; /* Emit_mx () will add 6. */
1380 if (!(ins_ok
& INS_Z80N
))
1381 check_mach (INS_ROT_II_LD
);
1385 emit_mx (prefix
, opcode
, 0, & arg_m
);
1394 emit_sx (char prefix
, char opcode
, expressionS
* arg_p
)
1398 switch (arg_p
->X_op
)
1402 emit_mx (prefix
, opcode
, 0, arg_p
);
1409 q
= frag_more (prefix
? 2 : 1);
1413 emit_byte (arg_p
, BFD_RELOC_8
);
1418 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1420 emit_s (char prefix
, char opcode
, const char *args
)
1425 p
= parse_exp (args
, & arg_s
);
1426 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
1427 { /* possible instruction in generic format op A,x */
1428 if (!(ins_ok
& INS_EZ80
) && !sdcc_compat
)
1431 p
= parse_exp (p
, & arg_s
);
1433 emit_sx (prefix
, opcode
, & arg_s
);
1438 emit_sub (char prefix
, char opcode
, const char *args
)
1443 if (!(ins_ok
& INS_GBZ80
))
1444 return emit_s (prefix
, opcode
, args
);
1445 p
= parse_exp (args
, & arg_s
);
1448 error (_("bad instruction syntax"));
1452 if (arg_s
.X_md
!= 0 || arg_s
.X_op
!= O_register
|| arg_s
.X_add_number
!= REG_A
)
1455 p
= parse_exp (p
, & arg_s
);
1457 emit_sx (prefix
, opcode
, & arg_s
);
1462 emit_swap (char prefix
, char opcode
, const char *args
)
1468 if (!(ins_ok
& INS_Z80N
))
1469 return emit_mr (prefix
, opcode
, args
);
1471 /* check for alias swap a for swapnib of Z80N */
1472 p
= parse_exp (args
, ®
);
1473 if (reg
.X_md
!= 0 || reg
.X_op
!= O_register
|| reg
.X_add_number
!= REG_A
)
1483 emit_call (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1486 const char *p
; char *q
;
1488 p
= parse_exp_not_indexed (args
, &addr
);
1500 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1502 emit_incdec (char prefix
, char opcode
, const char * args
)
1504 expressionS operand
;
1506 const char *p
; char *q
;
1508 p
= parse_exp (args
, &operand
);
1509 rnum
= operand
.X_add_number
;
1510 if ((! operand
.X_md
)
1511 && (operand
.X_op
== O_register
)
1514 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1516 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1517 *q
= prefix
+ ((rnum
& 3) << 4);
1521 if ((operand
.X_op
== O_md1
) || (operand
.X_op
== O_register
))
1522 emit_mx (0, opcode
, 3, & operand
);
1530 emit_jr (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1536 p
= parse_exp_not_indexed (args
, &addr
);
1543 addr
.X_add_number
--; /* pcrel computes after offset code */
1544 emit_byte (&addr
, BFD_RELOC_8_PCREL
);
1550 emit_jp (char prefix
, char opcode
, const char * args
)
1557 p
= parse_exp_not_indexed (args
, & addr
);
1560 rnum
= addr
.X_add_number
;
1561 if ((O_register
== addr
.X_op
) && (REG_HL
== (rnum
& ~R_INDEX
)))
1563 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1565 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1568 else if (addr
.X_op
== O_register
&& rnum
== REG_C
&& (ins_ok
& INS_Z80N
))
1587 emit_im (char prefix
, char opcode
, const char * args
)
1593 p
= parse_exp (args
, & mode
);
1594 if (mode
.X_md
|| (mode
.X_op
!= O_constant
))
1597 switch (mode
.X_add_number
)
1601 ++mode
.X_add_number
;
1606 *q
= opcode
+ 8*mode
.X_add_number
;
1615 emit_pop (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1621 p
= parse_exp (args
, & regp
);
1623 && (regp
.X_op
== O_register
)
1624 && (regp
.X_add_number
& R_STACKABLE
))
1628 rnum
= regp
.X_add_number
;
1632 *q
++ = (rnum
&R_IX
)?0xDD:0xFD;
1636 *q
= opcode
+ ((rnum
& 3) << 4);
1645 emit_push (char prefix
, char opcode
, const char * args
)
1651 p
= parse_exp (args
, & arg
);
1652 if (arg
.X_op
== O_register
)
1653 return emit_pop (prefix
, opcode
, args
);
1655 if (arg
.X_md
|| arg
.X_op
== O_md1
|| !(ins_ok
& INS_Z80N
))
1663 fix_new_exp (frag_now
, q
- frag_now
->fr_literal
, 2, &arg
, false,
1664 BFD_RELOC_Z80_16_BE
);
1670 emit_retcc (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1675 p
= parse_cc (args
, &cc
);
1681 return p
? p
: args
;
1685 emit_adc (char prefix
, char opcode
, const char * args
)
1692 p
= parse_exp (args
, &term
);
1695 error (_("bad instruction syntax"));
1699 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1702 switch (term
.X_add_number
)
1705 p
= emit_s (0, prefix
, p
);
1708 p
= parse_exp (p
, &term
);
1709 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1711 rnum
= term
.X_add_number
;
1712 if (R_ARITH
== (rnum
& (R_ARITH
| R_INDEX
)))
1716 *q
= opcode
+ ((rnum
& 3) << 4);
1728 emit_add (char prefix
, char opcode
, const char * args
)
1735 p
= parse_exp (args
, &term
);
1738 error (_("bad instruction syntax"));
1742 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1745 switch (term
.X_add_number
)
1748 p
= emit_s (0, prefix
, p
);
1751 p
= parse_exp (p
, &term
);
1752 if (!(ins_ok
& INS_GBZ80
) || term
.X_md
|| term
.X_op
== O_register
)
1756 emit_byte (&term
, BFD_RELOC_Z80_DISP8
);
1760 if (!(ins_ok
& INS_Z80N
))
1769 lhs
= term
.X_add_number
;
1770 p
= parse_exp (p
, &term
);
1771 rhs
= term
.X_add_number
;
1772 if (term
.X_md
!= 0 || term
.X_op
== O_md1
)
1774 else if ((term
.X_op
== O_register
) && (rhs
& R_ARITH
) && (rhs
== lhs
|| (rhs
& ~R_INDEX
) != REG_HL
))
1778 q
= frag_more ((lhs
& R_INDEX
) ? 2 : 1);
1780 *q
++ = (lhs
& R_IX
) ? 0xDD : 0xFD;
1781 *q
= opcode
+ ((rhs
& 3) << 4);
1785 else if (!(lhs
& R_INDEX
) && (ins_ok
& INS_Z80N
))
1787 if (term
.X_op
== O_register
&& rhs
== REG_A
)
1788 { /* ADD BC/DE/HL,A */
1791 *q
= 0x33 - (lhs
& 3);
1794 else if (term
.X_op
!= O_register
&& term
.X_op
!= O_md1
)
1795 { /* ADD BC/DE/HL,nn */
1798 *q
= 0x36 - (lhs
& 3);
1811 emit_bit (char prefix
, char opcode
, const char * args
)
1817 p
= parse_exp (args
, &b
);
1819 error (_("bad instruction syntax"));
1821 bn
= b
.X_add_number
;
1823 && (b
.X_op
== O_constant
)
1828 /* Bit : no optional third operand. */
1829 p
= emit_m (prefix
, opcode
+ (bn
<< 3), p
);
1831 /* Set, res : resulting byte can be copied to register. */
1832 p
= emit_mr (prefix
, opcode
+ (bn
<< 3), p
);
1839 /* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
1841 emit_bshft (char prefix
, char opcode
, const char * args
)
1847 p
= parse_exp (args
, & r1
);
1849 error (_("bad instruction syntax"));
1850 p
= parse_exp (p
, & r2
);
1851 if (r1
.X_md
|| r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_DE
||
1852 r2
.X_md
|| r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_B
)
1861 emit_jpcc (char prefix
, char opcode
, const char * args
)
1866 p
= parse_cc (args
, & cc
);
1867 if (p
&& *p
++ == ',')
1868 p
= emit_call (0, opcode
+ cc
, p
);
1870 p
= (prefix
== (char)0xC3)
1871 ? emit_jp (0xE9, prefix
, args
)
1872 : emit_call (0, prefix
, args
);
1877 emit_jrcc (char prefix
, char opcode
, const char * args
)
1882 p
= parse_cc (args
, &cc
);
1883 if (p
&& *p
++ == ',')
1886 error (_("condition code invalid for jr"));
1888 p
= emit_jr (0, opcode
+ cc
, p
);
1891 p
= emit_jr (0, prefix
, args
);
1897 emit_ex (char prefix_in ATTRIBUTE_UNUSED
,
1898 char opcode_in ATTRIBUTE_UNUSED
, const char * args
)
1902 char prefix
, opcode
;
1904 p
= parse_exp_not_indexed (args
, &op
);
1908 error (_("bad instruction syntax"));
1912 prefix
= opcode
= 0;
1913 if (op
.X_op
== O_register
)
1914 switch (op
.X_add_number
| (op
.X_md
? 0x8000 : 0))
1917 if (TOLOWER (*p
++) == 'a' && TOLOWER (*p
++) == 'f')
1919 /* The scrubber changes '\'' to '`' in this context. */
1926 if (TOLOWER (*p
++) == 'h' && TOLOWER (*p
++) == 'l')
1930 p
= parse_exp (p
, & op
);
1931 if (op
.X_op
== O_register
1933 && (op
.X_add_number
& ~R_INDEX
) == REG_HL
)
1936 if (R_INDEX
& op
.X_add_number
)
1937 prefix
= (R_IX
& op
.X_add_number
) ? 0xDD : 0xFD;
1942 emit_insn (prefix
, opcode
, p
);
1950 emit_in (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1953 expressionS reg
, port
;
1957 p
= parse_exp (args
, ®
);
1958 if (reg
.X_md
&& reg
.X_op
== O_register
&& reg
.X_add_number
== REG_C
)
1959 { /* permit instruction in (c) as alias for in f,(c) */
1962 reg
.X_add_number
= REG_F
;
1968 error (_("bad instruction syntax"));
1971 p
= parse_exp (p
, &port
);
1974 && reg
.X_op
== O_register
1975 && (reg
.X_add_number
<= 7 || reg
.X_add_number
== REG_F
)
1978 if (port
.X_op
!= O_md1
&& port
.X_op
!= O_register
)
1980 if (REG_A
== reg
.X_add_number
)
1984 emit_byte (&port
, BFD_RELOC_8
);
1991 if (port
.X_add_number
== REG_C
|| port
.X_add_number
== REG_BC
)
1993 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
1995 else if (reg
.X_add_number
== REG_F
&& !(ins_ok
& (INS_R800
|INS_Z80N
)))
1996 check_mach (INS_IN_F_C
);
1999 *q
= 0x40|((reg
.X_add_number
&7)<<3);
2011 emit_in0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2014 expressionS reg
, port
;
2018 p
= parse_exp (args
, ®
);
2021 error (_("bad instruction syntax"));
2025 p
= parse_exp (p
, &port
);
2027 && reg
.X_op
== O_register
2028 && reg
.X_add_number
<= 7
2030 && port
.X_op
!= O_md1
2031 && port
.X_op
!= O_register
)
2035 *q
= 0x00|(reg
.X_add_number
<< 3);
2036 emit_byte (&port
, BFD_RELOC_8
);
2044 emit_out (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2047 expressionS reg
, port
;
2051 p
= parse_exp (args
, & port
);
2054 error (_("bad instruction syntax"));
2057 p
= parse_exp (p
, ®
);
2059 { ill_op (); return p
; }
2060 /* Allow "out (c), 0" as unportable instruction. */
2061 if (reg
.X_op
== O_constant
&& reg
.X_add_number
== 0)
2063 if (!(ins_ok
& INS_Z80N
))
2064 check_mach (INS_OUT_C_0
);
2065 reg
.X_op
= O_register
;
2066 reg
.X_add_number
= 6;
2069 || reg
.X_op
!= O_register
2070 || reg
.X_add_number
> 7)
2073 if (port
.X_op
!= O_register
&& port
.X_op
!= O_md1
)
2075 if (REG_A
== reg
.X_add_number
)
2079 emit_byte (&port
, BFD_RELOC_8
);
2086 if (REG_C
== port
.X_add_number
|| port
.X_add_number
== REG_BC
)
2088 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
2092 *q
= 0x41 | (reg
.X_add_number
<< 3);
2101 emit_out0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2104 expressionS reg
, port
;
2108 p
= parse_exp (args
, & port
);
2111 error (_("bad instruction syntax"));
2114 p
= parse_exp (p
, ®
);
2116 && port
.X_op
!= O_register
2117 && port
.X_op
!= O_md1
2119 && reg
.X_op
== O_register
2120 && reg
.X_add_number
<= 7)
2124 *q
= 0x01 | (reg
.X_add_number
<< 3);
2125 emit_byte (&port
, BFD_RELOC_8
);
2133 emit_rst (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2139 p
= parse_exp_not_indexed (args
, &addr
);
2140 if (addr
.X_op
!= O_constant
)
2142 error ("rst needs constant address");
2146 if (addr
.X_add_number
& ~(7 << 3))
2151 *q
= opcode
+ (addr
.X_add_number
& (7 << 3));
2156 /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
2158 emit_ld_m_n (expressionS
*dst
, expressionS
*src
)
2162 expressionS dst_offset
;
2164 switch (dst
->X_add_number
)
2166 case REG_HL
: prefix
= 0x00; break;
2167 case REG_IX
: prefix
= 0xDD; break;
2168 case REG_IY
: prefix
= 0xFD; break;
2174 q
= frag_more (prefix
? 2 : 1);
2181 dst_offset
.X_op
= O_symbol
;
2182 dst_offset
.X_add_number
= 0;
2183 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2185 emit_byte (src
, BFD_RELOC_8
);
2188 /* For 8-bit load register to memory instructions: LD (<expression>),r. */
2190 emit_ld_m_r (expressionS
*dst
, expressionS
*src
)
2194 expressionS dst_offset
;
2199 if (ins_ok
& INS_GBZ80
)
2200 { /* LD (HL+),A or LD (HL-),A */
2201 if (src
->X_op
!= O_register
|| src
->X_add_number
!= REG_A
)
2203 *frag_more (1) = (dst
->X_add_number
== REG_HL
) ? 0x22 : 0x32;
2207 prefix
= (dst
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2210 switch (dst
->X_add_number
)
2212 case REG_BC
: /* LD (BC),A */
2213 case REG_DE
: /* LD (DE),A */
2214 if (src
->X_add_number
== REG_A
)
2217 *q
= 0x02 | ((dst
->X_add_number
& 3) << 4);
2223 case REG_HL
: /* LD (HL),r or LD (ii+d),r */
2224 if (src
->X_add_number
<= 7)
2226 q
= frag_more (prefix
? 2 : 1);
2229 *q
= 0x70 | src
->X_add_number
;
2233 dst_offset
.X_op
= O_symbol
;
2234 dst_offset
.X_add_number
= 0;
2235 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2243 default: /* LD (nn),A */
2244 if (src
->X_add_number
== REG_A
)
2247 *q
= (ins_ok
& INS_GBZ80
) ? 0xEA : 0x32;
2256 /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
2258 emit_ld_m_rr (expressionS
*dst
, expressionS
*src
)
2263 expressionS dst_offset
;
2267 case O_md1
: /* eZ80 instructions LD (ii+d),rr */
2268 case O_register
: /* eZ80 instructions LD (HL),rr */
2269 if (!(ins_ok
& INS_EZ80
)) /* 16-bit indirect load group is supported by eZ80 only */
2271 switch (dst
->X_add_number
)
2273 case REG_IX
: prefix
= 0xDD; break;
2274 case REG_IY
: prefix
= 0xFD; break;
2275 case REG_HL
: prefix
= 0xED; break;
2279 switch (src
->X_add_number
)
2281 case REG_BC
: opcode
= 0x0F; break;
2282 case REG_DE
: opcode
= 0x1F; break;
2283 case REG_HL
: opcode
= 0x2F; break;
2284 case REG_IX
: opcode
= (prefix
!= 0xFD) ? 0x3F : 0x3E; break;
2285 case REG_IY
: opcode
= (prefix
!= 0xFD) ? 0x3E : 0x3F; break;
2289 q
= frag_more (prefix
? 2 : 1);
2292 if (prefix
== 0xFD || prefix
== 0xDD)
2295 dst_offset
.X_op
= O_symbol
;
2296 dst_offset
.X_add_number
= 0;
2297 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2300 default: /* LD (nn),rr */
2301 if (ins_ok
& INS_GBZ80
)
2303 /* GBZ80 supports only LD (nn),SP */
2304 if (src
->X_add_number
== REG_SP
)
2314 switch (src
->X_add_number
)
2316 case REG_BC
: prefix
= 0xED; opcode
= 0x43; break;
2317 case REG_DE
: prefix
= 0xED; opcode
= 0x53; break;
2318 case REG_HL
: prefix
= 0x00; opcode
= 0x22; break;
2319 case REG_IX
: prefix
= 0xDD; opcode
= 0x22; break;
2320 case REG_IY
: prefix
= 0xFD; opcode
= 0x22; break;
2321 case REG_SP
: prefix
= 0xED; opcode
= 0x73; break;
2326 q
= frag_more (prefix
? 2 : 1);
2335 emit_ld_r_m (expressionS
*dst
, expressionS
*src
)
2336 { /* for 8-bit memory load to register: LD r,(xxx) */
2340 expressionS src_offset
;
2342 if (dst
->X_add_number
== REG_A
&& src
->X_op
== O_register
)
2343 { /* LD A,(BC) or LD A,(DE) */
2344 switch (src
->X_add_number
)
2346 case REG_BC
: opcode
= 0x0A; break;
2347 case REG_DE
: opcode
= 0x1A; break;
2361 if (ins_ok
& INS_GBZ80
)
2362 { /* LD A,(HL+) or LD A,(HL-) */
2363 if (dst
->X_op
== O_register
&& dst
->X_add_number
== REG_A
)
2364 *frag_more (1) = (src
->X_add_number
== REG_HL
) ? 0x2A : 0x3A;
2371 if (dst
->X_add_number
> 7)
2373 opcode
= 0x46; /* LD B,(HL) */
2374 switch (src
->X_add_number
)
2376 case REG_HL
: prefix
= 0x00; break;
2377 case REG_IX
: prefix
= 0xDD; break;
2378 case REG_IY
: prefix
= 0xFD; break;
2382 q
= frag_more (prefix
? 2 : 1);
2385 *q
= opcode
| ((dst
->X_add_number
& 7) << 3);
2389 src_offset
.X_op
= O_symbol
;
2390 src_offset
.X_add_number
= 0;
2391 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2394 default: /* LD A,(nn) */
2395 if (dst
->X_add_number
== REG_A
)
2398 *q
= (ins_ok
& INS_GBZ80
) ? 0xFA : 0x3A;
2407 emit_ld_r_n (expressionS
*dst
, expressionS
*src
)
2408 { /* for 8-bit immediate value load to register: LD r,n */
2412 switch (dst
->X_add_number
)
2434 q
= frag_more (prefix
? 2 : 1);
2437 if (ins_ok
& INS_GBZ80
)
2439 else if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2440 check_mach (INS_IDX_HALF
);
2443 *q
= 0x06 | ((dst
->X_add_number
& 7) << 3);
2444 emit_byte (src
, BFD_RELOC_8
);
2448 emit_ld_r_r (expressionS
*dst
, expressionS
*src
)
2449 { /* mostly 8-bit load register from register instructions: LD r,r */
2450 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2456 switch (dst
->X_add_number
)
2459 switch (src
->X_add_number
)
2461 case REG_HL
: prefix
= 0x00; break;
2462 case REG_IX
: prefix
= 0xDD; break;
2463 case REG_IY
: prefix
= 0xFD; break;
2470 if (!(ins_ok
& INS_EZ80
))
2472 if (src
->X_add_number
!= REG_I
)
2475 error (_("ADL mode instruction"));
2481 if (src
->X_add_number
== REG_HL
)
2483 if (!(ins_ok
& INS_EZ80
))
2486 error (_("ADL mode instruction"));
2490 else if (src
->X_add_number
== REG_A
)
2499 if (!(ins_ok
& INS_EZ80
) || (src
->X_add_number
!= REG_A
))
2502 error (_("ADL mode instruction"));
2507 if (src
->X_add_number
== REG_A
) /* LD R,A */
2516 if (src
->X_add_number
== REG_I
) /* LD A,I */
2522 else if (src
->X_add_number
== REG_R
) /* LD A,R */
2528 else if (src
->X_add_number
== REG_MB
) /* LD A,MB */
2530 if (!(ins_ok
& INS_EZ80
))
2535 error (_("ADL mode instruction"));
2566 switch (src
->X_add_number
)
2577 ill_op (); /* LD iiH/L,H/L are not permitted */
2581 if (prefix
== 0xFD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2582 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2588 if (prefix
== 0xDD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2589 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2596 opcode
= 0x40 + ((dst
->X_add_number
& 7) << 3) + (src
->X_add_number
& 7);
2598 if ((ins_ok
& INS_GBZ80
) && prefix
!= 0)
2600 if (ii_halves
&& !(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2601 check_mach (INS_IDX_HALF
);
2602 if (prefix
== 0 && (ins_ok
& INS_EZ80
))
2606 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2607 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2608 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2609 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2610 as_warn (_("unsupported instruction, assembled as NOP"));
2616 q
= frag_more (prefix
? 2 : 1);
2623 emit_ld_rr_m (expressionS
*dst
, expressionS
*src
)
2624 { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2628 expressionS src_offset
;
2630 /* GBZ80 has no support for 16-bit load from memory instructions */
2631 if (ins_ok
& INS_GBZ80
)
2637 case O_md1
: /* LD rr,(ii+d) */
2638 prefix
= (src
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2640 case O_register
: /* LD rr,(HL) */
2641 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2642 if (!(ins_ok
& INS_EZ80
))
2644 switch (dst
->X_add_number
)
2646 case REG_BC
: opcode
= 0x07; break;
2647 case REG_DE
: opcode
= 0x17; break;
2648 case REG_HL
: opcode
= 0x27; break;
2649 case REG_IX
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x37 : 0x31; break;
2650 case REG_IY
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x31 : 0x37; break;
2660 src_offset
.X_op
= O_symbol
;
2661 src_offset
.X_add_number
= 0;
2662 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2665 default: /* LD rr,(nn) */
2666 switch (dst
->X_add_number
)
2668 case REG_BC
: prefix
= 0xED; opcode
= 0x4B; break;
2669 case REG_DE
: prefix
= 0xED; opcode
= 0x5B; break;
2670 case REG_HL
: prefix
= 0x00; opcode
= 0x2A; break;
2671 case REG_SP
: prefix
= 0xED; opcode
= 0x7B; break;
2672 case REG_IX
: prefix
= 0xDD; opcode
= 0x2A; break;
2673 case REG_IY
: prefix
= 0xFD; opcode
= 0x2A; break;
2677 q
= frag_more (prefix
? 2 : 1);
2687 emit_ld_rr_nn (expressionS
*dst
, expressionS
*src
)
2688 { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2691 int opcode
= 0x21; /* LD HL,nn */
2692 switch (dst
->X_add_number
)
2705 opcode
= 0x01 + ((dst
->X_add_number
& 3) << 4);
2711 if (prefix
&& (ins_ok
& INS_GBZ80
))
2713 q
= frag_more (prefix
? 2 : 1);
2721 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
2724 expressionS dst
, src
;
2727 p
= parse_exp (args
, & dst
);
2729 error (_("bad instruction syntax"));
2730 p
= parse_exp (p
, & src
);
2734 if (src
.X_op
== O_register
)
2736 if (src
.X_add_number
<= 7)
2737 emit_ld_m_r (& dst
, & src
); /* LD (xxx),r */
2739 emit_ld_m_rr (& dst
, & src
); /* LD (xxx),rr */
2742 emit_ld_m_n (& dst
, & src
); /* LD (hl),n or LD (ix/y+r),n */
2744 else if (dst
.X_op
== O_register
)
2748 if (dst
.X_add_number
<= 7)
2749 emit_ld_r_m (& dst
, & src
);
2751 emit_ld_rr_m (& dst
, & src
);
2753 else if (src
.X_op
== O_register
)
2754 emit_ld_r_r (& dst
, & src
);
2755 else if ((dst
.X_add_number
& ~R_INDEX
) <= 7)
2756 emit_ld_r_n (& dst
, & src
);
2758 emit_ld_rr_nn (& dst
, & src
);
2767 emit_lddldi (char prefix
, char opcode
, const char * args
)
2769 expressionS dst
, src
;
2773 if (!(ins_ok
& INS_GBZ80
))
2774 return emit_insn (prefix
, opcode
, args
);
2776 p
= parse_exp (args
, & dst
);
2778 error (_("bad instruction syntax"));
2779 p
= parse_exp (p
, & src
);
2781 if (dst
.X_op
!= O_register
|| src
.X_op
!= O_register
)
2784 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2785 opcode
= (opcode
& 0x08) * 2 + 0x22;
2788 && dst
.X_add_number
== REG_HL
2790 && src
.X_add_number
== REG_A
)
2791 opcode
|= 0x00; /* LDx (HL),A */
2792 else if (dst
.X_md
== 0
2793 && dst
.X_add_number
== REG_A
2795 && src
.X_add_number
== REG_HL
)
2796 opcode
|= 0x08; /* LDx A,(HL) */
2806 emit_ldh (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2809 expressionS dst
, src
;
2813 p
= parse_exp (args
, & dst
);
2816 error (_("bad instruction syntax"));
2820 p
= parse_exp (p
, & src
);
2822 && dst
.X_op
== O_register
2823 && dst
.X_add_number
== REG_A
2825 && src
.X_op
!= O_md1
)
2827 if (src
.X_op
!= O_register
)
2831 emit_byte (& src
, BFD_RELOC_8
);
2833 else if (src
.X_add_number
== REG_C
)
2834 *frag_more (1) = 0xF2;
2838 else if (dst
.X_md
!= 0
2839 && dst
.X_op
!= O_md1
2841 && src
.X_op
== O_register
2842 && src
.X_add_number
== REG_A
)
2844 if (dst
.X_op
== O_register
)
2846 if (dst
.X_add_number
== REG_C
)
2858 emit_byte (& dst
, BFD_RELOC_8
);
2868 emit_ldhl (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2870 expressionS dst
, src
;
2873 p
= parse_exp (args
, & dst
);
2876 error (_("bad instruction syntax"));
2880 p
= parse_exp (p
, & src
);
2881 if (dst
.X_md
|| dst
.X_op
!= O_register
|| dst
.X_add_number
!= REG_SP
2882 || src
.X_md
|| src
.X_op
== O_register
|| src
.X_op
== O_md1
)
2886 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2891 parse_lea_pea_args (const char * args
, expressionS
*op
)
2894 p
= parse_exp (args
, op
);
2895 if (sdcc_compat
&& *p
== ',' && op
->X_op
== O_register
)
2898 p
= parse_exp (p
+ 1, &off
);
2900 op
->X_add_symbol
= make_expr_symbol (&off
);
2906 emit_lea (char prefix
, char opcode
, const char * args
)
2908 expressionS dst
, src
;
2913 p
= parse_exp (args
, & dst
);
2914 if (dst
.X_md
!= 0 || dst
.X_op
!= O_register
)
2917 rnum
= dst
.X_add_number
;
2923 opcode
= 0x02 | ((rnum
& 0x03) << 4);
2926 opcode
= 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2929 opcode
= 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2936 error (_("bad instruction syntax"));
2938 p
= parse_lea_pea_args (p
, & src
);
2939 if (src
.X_md
!= 0 || src
.X_op
!= O_add
/*&& src.X_op != O_register*/)
2942 rnum
= src
.X_add_number
;
2947 case O_register
: /* permit instructions like LEA rr,IX without displacement specified */
2948 src
.X_add_symbol
= zero
;
2957 opcode
= (opcode
== (char)0x33) ? 0x55 : (opcode
|0x00);
2960 opcode
= (opcode
== (char)0x32) ? 0x54 : (opcode
|0x01);
2967 src
.X_op
= O_symbol
;
2968 src
.X_add_number
= 0;
2969 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2975 emit_mlt (char prefix
, char opcode
, const char * args
)
2981 p
= parse_exp (args
, & arg
);
2982 if (arg
.X_md
!= 0 || arg
.X_op
!= O_register
|| !(arg
.X_add_number
& R_ARITH
))
2986 if (ins_ok
& INS_Z80N
)
2988 if (arg
.X_add_number
!= REG_DE
)
2996 *q
= opcode
| ((arg
.X_add_number
& 3) << 4);
3002 /* MUL D,E (Z80N only) */
3004 emit_mul (char prefix
, char opcode
, const char * args
)
3010 p
= parse_exp (args
, & r1
);
3012 error (_("bad instruction syntax"));
3013 p
= parse_exp (p
, & r2
);
3015 if (r1
.X_md
!= 0 || r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_D
||
3016 r2
.X_md
!= 0 || r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_E
)
3027 emit_nextreg (char prefix
, char opcode ATTRIBUTE_UNUSED
, const char * args
)
3033 p
= parse_exp (args
, & rr
);
3035 error (_("bad instruction syntax"));
3036 p
= parse_exp (p
, & nn
);
3037 if (rr
.X_md
!= 0 || rr
.X_op
== O_register
|| rr
.X_op
== O_md1
||
3038 nn
.X_md
!= 0 || nn
.X_op
== O_md1
)
3042 emit_byte (&rr
, BFD_RELOC_8
);
3043 if (nn
.X_op
== O_register
&& nn
.X_add_number
== REG_A
)
3045 else if (nn
.X_op
!= O_register
)
3048 emit_byte (&nn
, BFD_RELOC_8
);
3056 emit_pea (char prefix
, char opcode
, const char * args
)
3062 p
= parse_lea_pea_args (args
, & arg
);
3064 || (/*arg.X_op != O_register &&*/ arg
.X_op
!= O_add
)
3065 || !(arg
.X_add_number
& R_INDEX
))
3067 /* PEA ii without displacement is mostly typo,
3068 because there is PUSH instruction which is shorter and faster */
3069 /*if (arg.X_op == O_register)
3070 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3074 *q
= opcode
+ (arg
.X_add_number
== REG_IY
? 1 : 0);
3076 arg
.X_op
= O_symbol
;
3077 arg
.X_add_number
= 0;
3078 emit_byte (& arg
, BFD_RELOC_Z80_DISP8
);
3084 emit_reti (char prefix
, char opcode
, const char * args
)
3086 if (ins_ok
& INS_GBZ80
)
3087 return emit_insn (0x00, 0xD9, args
);
3089 return emit_insn (prefix
, opcode
, args
);
3093 emit_tst (char prefix
, char opcode
, const char *args
)
3100 p
= parse_exp (args
, & arg_s
);
3101 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
3103 if (!(ins_ok
& INS_EZ80
))
3106 p
= parse_exp (p
, & arg_s
);
3109 rnum
= arg_s
.X_add_number
;
3116 rnum
= arg_s
.X_add_number
;
3117 if (arg_s
.X_md
!= 0)
3126 *q
= opcode
| (rnum
<< 3);
3132 if (ins_ok
& INS_Z80N
)
3142 emit_byte (& arg_s
, BFD_RELOC_8
);
3148 emit_insn_n (char prefix
, char opcode
, const char *args
)
3154 p
= parse_exp (args
, & arg
);
3155 if (arg
.X_md
|| arg
.X_op
== O_register
|| arg
.X_op
== O_md1
)
3161 emit_byte (& arg
, BFD_RELOC_8
);
3167 emit_data (int size ATTRIBUTE_UNUSED
)
3174 if (is_it_end_of_statement ())
3176 demand_empty_rest_of_line ();
3179 p
= skip_space (input_line_pointer
);
3183 if (*p
== '\"' || *p
== '\'')
3185 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
3187 u
= frag_more (cnt
);
3190 as_warn (_("unterminated string"));
3192 p
= skip_space (p
+1);
3196 p
= parse_exp (p
, &exp
);
3197 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3203 as_warn (_("parentheses ignored"));
3204 emit_byte (&exp
, BFD_RELOC_8
);
3208 while (*p
++ == ',') ;
3209 input_line_pointer
= (char *)(p
-1);
3218 if (is_it_end_of_statement ())
3220 demand_empty_rest_of_line ();
3223 p
= skip_space (input_line_pointer
);
3227 p
= parse_exp (p
, &exp
);
3228 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3234 as_warn (_("parentheses ignored"));
3235 emit_data_val (&exp
, size
);
3237 } while (*p
++ == ',') ;
3238 input_line_pointer
= (char *)(p
-1);
3241 /* next functions were commented out because it is difficult to mix
3242 both ADL and Z80 mode instructions within one COFF file:
3243 objdump cannot recognize point of mode switching.
3246 set_cpu_mode (int mode
)
3248 if (ins_ok
& INS_EZ80
)
3251 error (_("CPU mode is unsupported by target"));
3255 assume (int arg ATTRIBUTE_UNUSED
)
3261 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3262 c
= get_symbol_name (& name
);
3263 if (strncasecmp (name
, "ADL", 4) != 0)
3269 restore_line_pointer (c
);
3270 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3271 if (*input_line_pointer
++ != '=')
3273 error (_("assignment expected"));
3276 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3277 n
= get_single_number ();
3283 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3287 p
= skip_space (args
);
3288 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
3294 reg
= TOLOWER (*p
++);
3301 check_mach (INS_R800
);
3302 if (!*skip_space (p
))
3306 *q
= opcode
+ ((reg
- 'b') << 3);
3318 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3322 p
= skip_space (args
);
3323 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
3330 p
= parse_exp (p
, & reg
);
3332 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
3333 switch (reg
.X_add_number
)
3337 check_mach (INS_R800
);
3340 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
3350 assemble_suffix (const char **suffix
)
3353 const char sf
[8][4] =
3373 for (i
= 0; (i
< 3) && (ISALPHA (*p
)); i
++)
3374 sbuf
[i
] = TOLOWER (*p
++);
3375 if (*p
&& !ISSPACE (*p
))
3380 t
= bsearch (sbuf
, sf
, ARRAY_SIZE (sf
), sizeof (sf
[0]), (int(*)(const void*, const void*)) strcmp
);
3387 i
= cpu_mode
? 0x5B : 0x52;
3390 i
= cpu_mode
? 0x49 : 0x40;
3393 i
= cpu_mode
? 0x5B : 0x49;
3402 i
= cpu_mode
? 0x52 : 0x40;
3411 *frag_more (1) = (char)i
;
3414 case 0x40: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IS
; break;
3415 case 0x49: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IS
; break;
3416 case 0x52: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IL
; break;
3417 case 0x5B: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IL
; break;
3425 #if defined(OBJ_ELF)
3426 return obj_elf_section (arg
);
3427 #elif defined(OBJ_COFF)
3428 return obj_coff_section (arg
);
3430 #error Unknown object format
3440 as_fatal (_("Invalid directive"));
3443 ins_ok
&= INS_MARCH_MASK
;
3445 if (old_ins
!= ins_ok
)
3450 ignore (int arg ATTRIBUTE_UNUSED
)
3452 ignore_rest_of_line ();
3460 as_fatal (_("Invalid directive"));
3461 for (p
= input_line_pointer
; *p
&& *p
!= '(' && *p
!= '\n'; p
++)
3468 ignore_rest_of_line ();
3474 /* Handle the .bss pseudo-op. */
3477 s_bss (int ignore ATTRIBUTE_UNUSED
)
3479 subseg_set (bss_section
, 0);
3480 demand_empty_rest_of_line ();
3483 /* Port specific pseudo ops. */
3484 const pseudo_typeS md_pseudo_table
[] =
3486 { ".area", area
, 0},
3487 { ".assume", assume
, 0},
3488 { ".ez80", set_inss
, INS_EZ80
},
3489 { ".gbz80", set_inss
, INS_GBZ80
},
3490 { ".module", ignore
, 0},
3491 { ".optsdcc", ignore
, 0},
3492 { ".r800", set_inss
, INS_R800
},
3493 { ".set", s_set
, 0},
3494 { ".z180", set_inss
, INS_Z180
},
3495 { ".hd64", set_inss
, INS_Z180
},
3496 { ".z80", set_inss
, INS_Z80
},
3497 { ".z80n", set_inss
, INS_Z80N
},
3499 { "db" , emit_data
, 1},
3500 { "d24", z80_cons
, 3},
3501 { "d32", z80_cons
, 4},
3502 { "def24", z80_cons
, 3},
3503 { "def32", z80_cons
, 4},
3504 { "defb", emit_data
, 1},
3505 { "defm", emit_data
, 1},
3506 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
3507 { "defw", z80_cons
, 2},
3508 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
3509 { "dw", z80_cons
, 2},
3510 { "psect", psect
, 0}, /* TODO: Translate attributes. */
3511 { "set", 0, 0}, /* Real instruction on z80. */
3512 { "xdef", s_globl
, 0}, /* Synonym for .GLOBAL */
3513 { "xref", s_ignore
, 0}, /* Synonym for .EXTERN */
3517 static table_t instab
[] =
3519 { "adc", 0x88, 0x4A, emit_adc
, INS_ALL
},
3520 { "add", 0x80, 0x09, emit_add
, INS_ALL
},
3521 { "and", 0x00, 0xA0, emit_s
, INS_ALL
},
3522 { "bit", 0xCB, 0x40, emit_bit
, INS_ALL
},
3523 { "brlc", 0xED, 0x2C, emit_bshft
,INS_Z80N
},
3524 { "bsla", 0xED, 0x28, emit_bshft
,INS_Z80N
},
3525 { "bsra", 0xED, 0x29, emit_bshft
,INS_Z80N
},
3526 { "bsrf", 0xED, 0x2B, emit_bshft
,INS_Z80N
},
3527 { "bsrl", 0xED, 0x2A, emit_bshft
,INS_Z80N
},
3528 { "call", 0xCD, 0xC4, emit_jpcc
, INS_ALL
},
3529 { "ccf", 0x00, 0x3F, emit_insn
, INS_ALL
},
3530 { "cp", 0x00, 0xB8, emit_s
, INS_ALL
},
3531 { "cpd", 0xED, 0xA9, emit_insn
, INS_NOT_GBZ80
},
3532 { "cpdr", 0xED, 0xB9, emit_insn
, INS_NOT_GBZ80
},
3533 { "cpi", 0xED, 0xA1, emit_insn
, INS_NOT_GBZ80
},
3534 { "cpir", 0xED, 0xB1, emit_insn
, INS_NOT_GBZ80
},
3535 { "cpl", 0x00, 0x2F, emit_insn
, INS_ALL
},
3536 { "daa", 0x00, 0x27, emit_insn
, INS_ALL
},
3537 { "dec", 0x0B, 0x05, emit_incdec
,INS_ALL
},
3538 { "di", 0x00, 0xF3, emit_insn
, INS_ALL
},
3539 { "djnz", 0x00, 0x10, emit_jr
, INS_NOT_GBZ80
},
3540 { "ei", 0x00, 0xFB, emit_insn
, INS_ALL
},
3541 { "ex", 0x00, 0x00, emit_ex
, INS_NOT_GBZ80
},
3542 { "exx", 0x00, 0xD9, emit_insn
, INS_NOT_GBZ80
},
3543 { "halt", 0x00, 0x76, emit_insn
, INS_ALL
},
3544 { "im", 0xED, 0x46, emit_im
, INS_NOT_GBZ80
},
3545 { "in", 0x00, 0x00, emit_in
, INS_NOT_GBZ80
},
3546 { "in0", 0xED, 0x00, emit_in0
, INS_Z180
|INS_EZ80
},
3547 { "inc", 0x03, 0x04, emit_incdec
,INS_ALL
},
3548 { "ind", 0xED, 0xAA, emit_insn
, INS_NOT_GBZ80
},
3549 { "ind2", 0xED, 0x8C, emit_insn
, INS_EZ80
},
3550 { "ind2r",0xED, 0x9C, emit_insn
, INS_EZ80
},
3551 { "indm", 0xED, 0x8A, emit_insn
, INS_EZ80
},
3552 { "indmr",0xED, 0x9A, emit_insn
, INS_EZ80
},
3553 { "indr", 0xED, 0xBA, emit_insn
, INS_NOT_GBZ80
},
3554 { "indrx",0xED, 0xCA, emit_insn
, INS_EZ80
},
3555 { "ini", 0xED, 0xA2, emit_insn
, INS_NOT_GBZ80
},
3556 { "ini2", 0xED, 0x84, emit_insn
, INS_EZ80
},
3557 { "ini2r",0xED, 0x94, emit_insn
, INS_EZ80
},
3558 { "inim", 0xED, 0x82, emit_insn
, INS_EZ80
},
3559 { "inimr",0xED, 0x92, emit_insn
, INS_EZ80
},
3560 { "inir", 0xED, 0xB2, emit_insn
, INS_NOT_GBZ80
},
3561 { "inirx",0xED, 0xC2, emit_insn
, INS_EZ80
},
3562 { "jp", 0xC3, 0xC2, emit_jpcc
, INS_ALL
},
3563 { "jr", 0x18, 0x20, emit_jrcc
, INS_ALL
},
3564 { "ld", 0x00, 0x00, emit_ld
, INS_ALL
},
3565 { "ldd", 0xED, 0xA8, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3566 { "lddr", 0xED, 0xB8, emit_insn
, INS_NOT_GBZ80
},
3567 { "lddrx",0xED, 0xBC, emit_insn
, INS_Z80N
},
3568 { "lddx", 0xED, 0xAC, emit_insn
, INS_Z80N
},
3569 { "ldh", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3570 { "ldhl", 0x00, 0xF8, emit_ldhl
, INS_GBZ80
},
3571 { "ldi", 0xED, 0xA0, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3572 { "ldir", 0xED, 0xB0, emit_insn
, INS_NOT_GBZ80
},
3573 { "ldirx",0xED, 0xB4, emit_insn
, INS_Z80N
},
3574 { "ldix", 0xED, 0xA4, emit_insn
, INS_Z80N
},
3575 { "ldpirx",0xED,0xB7, emit_insn
, INS_Z80N
},
3576 { "ldws", 0xED, 0xA5, emit_insn
, INS_Z80N
},
3577 { "lea", 0xED, 0x02, emit_lea
, INS_EZ80
},
3578 { "mirror",0xED,0x24, emit_insn
, INS_Z80N
},
3579 { "mlt", 0xED, 0x4C, emit_mlt
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3580 { "mul", 0xED, 0x30, emit_mul
, INS_Z80N
},
3581 { "mulub",0xED, 0xC5, emit_mulub
,INS_R800
},
3582 { "muluw",0xED, 0xC3, emit_muluw
,INS_R800
},
3583 { "neg", 0xED, 0x44, emit_insn
, INS_NOT_GBZ80
},
3584 { "nextreg",0xED,0x91,emit_nextreg
,INS_Z80N
},
3585 { "nop", 0x00, 0x00, emit_insn
, INS_ALL
},
3586 { "or", 0x00, 0xB0, emit_s
, INS_ALL
},
3587 { "otd2r",0xED, 0xBC, emit_insn
, INS_EZ80
},
3588 { "otdm", 0xED, 0x8B, emit_insn
, INS_Z180
|INS_EZ80
},
3589 { "otdmr",0xED, 0x9B, emit_insn
, INS_Z180
|INS_EZ80
},
3590 { "otdr", 0xED, 0xBB, emit_insn
, INS_NOT_GBZ80
},
3591 { "otdrx",0xED, 0xCB, emit_insn
, INS_EZ80
},
3592 { "oti2r",0xED, 0xB4, emit_insn
, INS_EZ80
},
3593 { "otim", 0xED, 0x83, emit_insn
, INS_Z180
|INS_EZ80
},
3594 { "otimr",0xED, 0x93, emit_insn
, INS_Z180
|INS_EZ80
},
3595 { "otir", 0xED, 0xB3, emit_insn
, INS_NOT_GBZ80
},
3596 { "otirx",0xED, 0xC3, emit_insn
, INS_EZ80
},
3597 { "out", 0x00, 0x00, emit_out
, INS_NOT_GBZ80
},
3598 { "out0", 0xED, 0x01, emit_out0
, INS_Z180
|INS_EZ80
},
3599 { "outd", 0xED, 0xAB, emit_insn
, INS_NOT_GBZ80
},
3600 { "outd2",0xED, 0xAC, emit_insn
, INS_EZ80
},
3601 { "outi", 0xED, 0xA3, emit_insn
, INS_NOT_GBZ80
},
3602 { "outi2",0xED, 0xA4, emit_insn
, INS_EZ80
},
3603 { "outinb",0xED,0x90, emit_insn
, INS_Z80N
},
3604 { "pea", 0xED, 0x65, emit_pea
, INS_EZ80
},
3605 { "pixelad",0xED,0x94,emit_insn
, INS_Z80N
},
3606 { "pixeldn",0xED,0x93,emit_insn
, INS_Z80N
},
3607 { "pop", 0x00, 0xC1, emit_pop
, INS_ALL
},
3608 { "push", 0x00, 0xC5, emit_push
, INS_ALL
},
3609 { "res", 0xCB, 0x80, emit_bit
, INS_ALL
},
3610 { "ret", 0xC9, 0xC0, emit_retcc
,INS_ALL
},
3611 { "reti", 0xED, 0x4D, emit_reti
, INS_ALL
}, /*GBZ80 has its own opcode for it*/
3612 { "retn", 0xED, 0x45, emit_insn
, INS_NOT_GBZ80
},
3613 { "rl", 0xCB, 0x10, emit_mr
, INS_ALL
},
3614 { "rla", 0x00, 0x17, emit_insn
, INS_ALL
},
3615 { "rlc", 0xCB, 0x00, emit_mr
, INS_ALL
},
3616 { "rlca", 0x00, 0x07, emit_insn
, INS_ALL
},
3617 { "rld", 0xED, 0x6F, emit_insn
, INS_NOT_GBZ80
},
3618 { "rr", 0xCB, 0x18, emit_mr
, INS_ALL
},
3619 { "rra", 0x00, 0x1F, emit_insn
, INS_ALL
},
3620 { "rrc", 0xCB, 0x08, emit_mr
, INS_ALL
},
3621 { "rrca", 0x00, 0x0F, emit_insn
, INS_ALL
},
3622 { "rrd", 0xED, 0x67, emit_insn
, INS_NOT_GBZ80
},
3623 { "rsmix",0xED, 0x7E, emit_insn
, INS_EZ80
},
3624 { "rst", 0x00, 0xC7, emit_rst
, INS_ALL
},
3625 { "sbc", 0x98, 0x42, emit_adc
, INS_ALL
},
3626 { "scf", 0x00, 0x37, emit_insn
, INS_ALL
},
3627 { "set", 0xCB, 0xC0, emit_bit
, INS_ALL
},
3628 { "setae",0xED, 0x95, emit_insn
, INS_Z80N
},
3629 { "sl1", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3630 { "sla", 0xCB, 0x20, emit_mr
, INS_ALL
},
3631 { "sli", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3632 { "sll", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3633 { "slp", 0xED, 0x76, emit_insn
, INS_Z180
|INS_EZ80
},
3634 { "sra", 0xCB, 0x28, emit_mr
, INS_ALL
},
3635 { "srl", 0xCB, 0x38, emit_mr
, INS_ALL
},
3636 { "stmix",0xED, 0x7D, emit_insn
, INS_EZ80
},
3637 { "stop", 0x00, 0x10, emit_insn
, INS_GBZ80
},
3638 { "sub", 0x00, 0x90, emit_sub
, INS_ALL
},
3639 { "swap", 0xCB, 0x30, emit_swap
, INS_GBZ80
|INS_Z80N
},
3640 { "swapnib",0xED,0x23,emit_insn
, INS_Z80N
},
3641 { "test", 0xED, 0x27, emit_insn_n
, INS_Z80N
},
3642 { "tst", 0xED, 0x04, emit_tst
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3643 { "tstio",0xED, 0x74, emit_insn_n
,INS_Z180
|INS_EZ80
},
3644 { "xor", 0x00, 0xA8, emit_s
, INS_ALL
},
3648 md_assemble (char *str
)
3656 inst_mode
= cpu_mode
? (INST_MODE_L
| INST_MODE_IL
) : (INST_MODE_S
| INST_MODE_IS
);
3657 old_ptr
= input_line_pointer
;
3658 p
= skip_space (str
);
3659 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
) || ISDIGIT (*p
));)
3660 buf
[i
++] = TOLOWER (*p
++);
3664 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
3666 as_bad (_("Unknown instruction '%s'"), buf
);
3670 dwarf2_emit_insn (0);
3671 if ((*p
) && (!ISSPACE (*p
)))
3673 if (*p
!= '.' || !(ins_ok
& INS_EZ80
) || !assemble_suffix (&p
))
3675 as_bad (_("syntax error"));
3683 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
3684 sizeof (instab
[0]), key_cmp
);
3685 if (!insp
|| (insp
->inss
&& !(insp
->inss
& ins_ok
)))
3688 as_bad (_("Unknown instruction `%s'"), buf
);
3692 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
3694 if ((!err_flag
) && *p
)
3695 as_bad (_("junk at end of line, "
3696 "first unrecognized character is `%c'"), *p
);
3700 input_line_pointer
= old_ptr
;
3704 signed_overflow (signed long value
, unsigned bitsize
)
3706 signed long max
= (signed long) ((1UL << (bitsize
- 1)) - 1);
3707 return value
< -max
- 1 || value
> max
;
3711 unsigned_overflow (unsigned long value
, unsigned bitsize
)
3713 return value
>> (bitsize
- 1) >> 1 != 0;
3717 is_overflow (long value
, unsigned bitsize
)
3720 return signed_overflow (value
, bitsize
);
3721 return unsigned_overflow ((unsigned long)value
, bitsize
);
3725 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg
)
3728 char *p_lit
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3730 if (fixP
->fx_addsy
== NULL
)
3732 else if (fixP
->fx_pcrel
)
3734 segT s
= S_GET_SEGMENT (fixP
->fx_addsy
);
3735 if (s
== seg
|| s
== absolute_section
)
3737 val
+= S_GET_VALUE (fixP
->fx_addsy
);
3742 switch (fixP
->fx_r_type
)
3744 case BFD_RELOC_8_PCREL
:
3745 case BFD_RELOC_Z80_DISP8
:
3750 case BFD_RELOC_Z80_16_BE
:
3751 fixP
->fx_no_overflow
= 0;
3754 fixP
->fx_no_overflow
= 1;
3758 switch (fixP
->fx_r_type
)
3760 case BFD_RELOC_8_PCREL
:
3761 case BFD_RELOC_Z80_DISP8
:
3762 if (fixP
->fx_done
&& signed_overflow (val
, 8))
3763 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3764 _("8-bit signed offset out of range (%+ld)"), val
);
3768 case BFD_RELOC_Z80_BYTE0
:
3772 case BFD_RELOC_Z80_BYTE1
:
3773 *p_lit
++ = (val
>> 8);
3776 case BFD_RELOC_Z80_BYTE2
:
3777 *p_lit
++ = (val
>> 16);
3780 case BFD_RELOC_Z80_BYTE3
:
3781 *p_lit
++ = (val
>> 24);
3785 if (fixP
->fx_done
&& is_overflow(val
, 8))
3786 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3787 _("8-bit overflow (%+ld)"), val
);
3791 case BFD_RELOC_Z80_WORD1
:
3792 *p_lit
++ = (val
>> 16);
3793 *p_lit
++ = (val
>> 24);
3796 case BFD_RELOC_Z80_WORD0
:
3798 *p_lit
++ = (val
>> 8);
3802 if (fixP
->fx_done
&& is_overflow(val
, 16))
3803 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3804 _("16-bit overflow (%+ld)"), val
);
3806 *p_lit
++ = (val
>> 8);
3809 case BFD_RELOC_24
: /* Def24 may produce this. */
3810 if (fixP
->fx_done
&& is_overflow(val
, 24))
3811 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3812 _("24-bit overflow (%+ld)"), val
);
3814 *p_lit
++ = (val
>> 8);
3815 *p_lit
++ = (val
>> 16);
3818 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
3819 if (fixP
->fx_done
&& is_overflow(val
, 32))
3820 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3821 _("32-bit overflow (%+ld)"), val
);
3823 *p_lit
++ = (val
>> 8);
3824 *p_lit
++ = (val
>> 16);
3825 *p_lit
++ = (val
>> 24);
3828 case BFD_RELOC_Z80_16_BE
: /* Z80N PUSH nn instruction produce this. */
3829 *p_lit
++ = val
>> 8;
3834 printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP
->fx_r_type
);
3839 /* GAS will call this to generate a reloc. GAS will pass the
3840 resulting reloc to `bfd_install_relocation'. This currently works
3841 poorly, as `bfd_install_relocation' often does the wrong thing, and
3842 instances of `tc_gen_reloc' have been written to work around the
3843 problems, which in turns makes it difficult to fix
3844 `bfd_install_relocation'. */
3846 /* If while processing a fixup, a reloc really
3847 needs to be created then it is done here. */
3850 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
3854 if (fixp
->fx_subsy
!= NULL
)
3856 as_bad_subtract (fixp
);
3860 reloc
= XNEW (arelent
);
3861 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3862 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3863 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3864 reloc
->addend
= fixp
->fx_offset
;
3865 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3866 if (reloc
->howto
== NULL
)
3868 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3869 _("reloc %d not supported by object file format"),
3870 (int) fixp
->fx_r_type
);
3874 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
3875 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3876 reloc
->address
= fixp
->fx_offset
;
3882 z80_tc_labels_without_colon (void)
3884 return colonless_labels
;
3888 z80_tc_label_is_local (const char *name
)
3892 if (local_label_prefix
== NULL
)
3894 for (p
= local_label_prefix
, n
= name
; *p
&& *n
&& *n
== *p
; p
++, n
++)
3899 /* Parse floating point number from string and compute mantissa and
3900 exponent. Mantissa is normalized.
3902 #define EXP_MIN -0x10000
3903 #define EXP_MAX 0x10000
3905 str_to_broken_float (bool *signP
, bfd_uint64_t
*mantissaP
, int *expP
)
3909 bfd_uint64_t mantissa
= 0;
3913 p
= (char*)skip_space (input_line_pointer
);
3916 if (sign
|| *p
== '+')
3918 if (strncasecmp (p
, "NaN", 3) == 0)
3922 input_line_pointer
= p
+ 3;
3925 if (strncasecmp (p
, "inf", 3) == 0)
3927 *mantissaP
= 1ull << 63;
3929 input_line_pointer
= p
+ 3;
3932 for (; ISDIGIT (*p
); ++p
)
3940 mantissa
= mantissa
* 10 + (*p
- '0');
3942 /* skip non-significant digits */
3943 for (; ISDIGIT (*p
); ++p
)
3949 if (!exponent
) /* If no precision overflow. */
3951 for (; ISDIGIT (*p
); ++p
, --exponent
)
3959 mantissa
= mantissa
* 10 + (*p
- '0');
3962 for (; ISDIGIT (*p
); ++p
)
3965 if (*p
== 'e' || *p
== 'E')
3971 if (es
|| *p
== '+')
3973 for (; ISDIGIT (*p
); ++p
)
3976 t
= t
* 10 + (*p
- '0');
3978 exponent
+= (es
) ? -t
: t
;
3980 if (ISALNUM (*p
) || *p
== '.')
3982 input_line_pointer
= p
;
3985 *mantissaP
= 1ull << 63;
3987 return 1; /* result is 0 */
3990 for (; mantissa
<= ~0ull/10; --exponent
)
3992 /* Now we have sign, mantissa, and signed decimal exponent
3993 need to recompute to binary exponent. */
3994 for (i
= 64; exponent
> 0; --exponent
)
3996 /* be sure that no integer overflow */
3997 while (mantissa
> ~0ull/10)
4004 for (; exponent
< 0; ++exponent
)
4006 while (!(mantissa
>> 63))
4014 for (; !(mantissa
>> 63); --i
)
4016 *mantissaP
= mantissa
;
4022 str_to_zeda32(char *litP
, int *sizeP
)
4024 bfd_uint64_t mantissa
;
4030 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
4031 return _("invalid syntax");
4032 /* I do not know why decrement is needed */
4034 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
4038 /* make 24 bit mantissa */
4040 /* check for overflow */
4047 if (exponent
< -127)
4052 else if (exponent
> 127)
4055 mantissa
= sign
? 0xc00000 : 0x400000;
4057 else if (mantissa
== 0)
4060 mantissa
= 0x200000;
4063 mantissa
&= (1ull << 23) - 1;
4064 for (i
= 0; i
< 24; i
+= 8)
4065 *litP
++ = (char)(mantissa
>> i
);
4066 *litP
= (char)(0x80 + exponent
);
4071 Math48 by Anders Hejlsberg support.
4072 Mantissa is 39 bits wide, exponent 8 bit wide.
4075 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4076 bit 7-0: exponent+128 (0 - value is null)
4077 MIN: 2.938735877e-39
4078 MAX: 1.701411835e+38
4081 str_to_float48(char *litP
, int *sizeP
)
4083 bfd_uint64_t mantissa
;
4089 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
4090 return _("invalid syntax");
4091 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4095 /* make 40 bit mantissa */
4097 /* check for overflow */
4103 if (exponent
< -127)
4105 memset (litP
, 0, 6);
4109 return _("overflow");
4111 mantissa
&= (1ull << 39) - 1;
4112 *litP
++ = (char)(0x80 + exponent
);
4113 for (i
= 0; i
< 40; i
+= 8)
4114 *litP
++ = (char)(mantissa
>> i
);
4119 str_to_ieee754_h(char *litP
, int *sizeP
)
4121 return ieee_md_atof ('h', litP
, sizeP
, false);
4125 str_to_ieee754_s(char *litP
, int *sizeP
)
4127 return ieee_md_atof ('s', litP
, sizeP
, false);
4131 str_to_ieee754_d(char *litP
, int *sizeP
)
4133 return ieee_md_atof ('d', litP
, sizeP
, false);
4136 #ifdef TARGET_USE_CFIPOP
4137 /* Initialize the DWARF-2 unwind information for this procedure. */
4139 z80_tc_frame_initial_instructions (void)
4141 static int sp_regno
= -1;
4144 sp_regno
= z80_tc_regname_to_dw2regnum ("sp");
4146 cfi_add_CFA_def_cfa (sp_regno
, 0);
4150 z80_tc_regname_to_dw2regnum (const char *regname
)
4152 static const char *regs
[] =
4153 { /* same registers as for GDB */
4154 "af", "bc", "de", "hl",
4155 "sp", "pc", "ix", "iy",
4156 "af_", "bc_", "de_", "hl_",
4161 for (i
= 0; i
< ARRAY_SIZE(regs
); ++i
)
4162 if (!strcasecmp (regs
[i
], regname
))
4169 /* Implement DWARF2_ADDR_SIZE. */
4171 z80_dwarf2_addr_size (const bfd
*abfd
)
4173 switch (bfd_get_mach (abfd
))
4175 case bfd_mach_ez80_adl
: