1 /* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800
2 Copyright (C) 2005-2020 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"
28 /* Exported constants. */
29 const char comment_chars
[] = ";\0";
30 const char line_comment_chars
[] = "#;\0";
31 const char line_separator_chars
[] = "\0";
32 const char EXP_CHARS
[] = "eE\0";
33 const char FLT_CHARS
[] = "RrDdFfSsHh\0";
35 /* For machine specific options. */
36 const char * md_shortopts
= ""; /* None yet. */
40 OPTION_MACH_Z80
= OPTION_MD_BASE
,
54 OPTION_FP_SINGLE_FORMAT
,
55 OPTION_FP_DOUBLE_FORMAT
,
56 OPTION_COMPAT_LL_PREFIX
,
57 OPTION_COMPAT_COLONLESS
,
61 #define INS_Z80 (1 << 0)
62 #define INS_R800 (1 << 1)
63 #define INS_GBZ80 (1 << 2)
64 #define INS_Z180 (1 << 3)
65 #define INS_EZ80 (1 << 4)
66 #define INS_MARCH_MASK 0xffff
68 #define INS_IDX_HALF (1 << 16)
69 #define INS_IN_F_C (1 << 17)
70 #define INS_OUT_C_0 (1 << 18)
71 #define INS_SLI (1 << 19)
72 #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 */
73 #define INS_TUNE_MASK 0xffff0000
75 #define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80)
78 #define INS_UNDOC (INS_IDX_HALF | INS_IN_F_C)
79 #define INS_UNPORT (INS_OUT_C_0 | INS_SLI | INS_ROT_II_LD)
81 struct option md_longopts
[] =
83 { "z80", no_argument
, NULL
, OPTION_MACH_Z80
},
84 { "r800", no_argument
, NULL
, OPTION_MACH_R800
},
85 { "z180", no_argument
, NULL
, OPTION_MACH_Z180
},
86 { "ez80", no_argument
, NULL
, OPTION_MACH_EZ80_Z80
},
87 { "ez80-adl", no_argument
, NULL
, OPTION_MACH_EZ80_ADL
},
88 { "fp-s", required_argument
, NULL
, OPTION_FP_SINGLE_FORMAT
},
89 { "fp-d", required_argument
, NULL
, OPTION_FP_DOUBLE_FORMAT
},
90 { "strict", no_argument
, NULL
, OPTION_MACH_FUD
},
91 { "full", no_argument
, NULL
, OPTION_MACH_IUP
},
92 { "with-inst", required_argument
, NULL
, OPTION_MACH_INST
},
93 { "Wnins", required_argument
, NULL
, OPTION_MACH_INST
},
94 { "without-inst", required_argument
, NULL
, OPTION_MACH_NO_INST
},
95 { "local-prefix", required_argument
, NULL
, OPTION_COMPAT_LL_PREFIX
},
96 { "colonless", no_argument
, NULL
, OPTION_COMPAT_COLONLESS
},
97 { "sdcc", no_argument
, NULL
, OPTION_COMPAT_SDCC
},
98 { "Fins", required_argument
, NULL
, OPTION_MACH_NO_INST
},
99 { "ignore-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_IUD
},
100 { "Wnud", no_argument
, NULL
, OPTION_MACH_IUD
},
101 { "warn-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_WUD
},
102 { "Wud", no_argument
, NULL
, OPTION_MACH_WUD
},
103 { "forbid-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_FUD
},
104 { "Fud", no_argument
, NULL
, OPTION_MACH_FUD
},
105 { "ignore-unportable-instructions", no_argument
, NULL
, OPTION_MACH_IUP
},
106 { "Wnup", no_argument
, NULL
, OPTION_MACH_IUP
},
107 { "warn-unportable-instructions", no_argument
, NULL
, OPTION_MACH_WUP
},
108 { "Wup", no_argument
, NULL
, OPTION_MACH_WUP
},
109 { "forbid-unportable-instructions", no_argument
, NULL
, OPTION_MACH_FUP
},
110 { "Fup", no_argument
, NULL
, OPTION_MACH_FUP
},
112 { NULL
, no_argument
, NULL
, 0 }
115 size_t md_longopts_size
= sizeof (md_longopts
);
117 extern int coff_flags
;
118 /* Instruction classes that silently assembled. */
119 static int ins_ok
= INS_Z80
| INS_UNDOC
;
120 /* Instruction classes that generate errors. */
121 static int ins_err
= ~(INS_Z80
| INS_UNDOC
);
122 /* eZ80 CPU mode (ADL or Z80) */
123 static int cpu_mode
= 0; /* 0 - Z80, 1 - ADL */
124 /* accept SDCC specific instruction encoding */
125 static int sdcc_compat
= 0;
126 /* accept colonless labels */
127 static int colonless_labels
= 0;
128 /* local label prefix (NULL - default) */
129 static const char *local_label_prefix
= NULL
;
130 /* floating point support */
131 typedef const char *(*str_to_float_t
)(char *litP
, int *sizeP
);
132 static str_to_float_t str_to_float
;
133 static str_to_float_t str_to_double
;
135 /* mode of current instruction */
136 #define INST_MODE_S 0 /* short data mode */
137 #define INST_MODE_IS 0 /* short instruction mode */
138 #define INST_MODE_L 2 /* long data mode */
139 #define INST_MODE_IL 1 /* long instruction mode */
140 #define INST_MODE_FORCED 4 /* CPU mode changed by instruction suffix*/
141 static char inst_mode
;
144 setup_instruction (const char *inst
, int *add
, int *sub
)
147 if (!strcmp (inst
, "idx-reg-halves"))
149 else if (!strcmp (inst
, "sli"))
151 else if (!strcmp (inst
, "op-ii-ld"))
153 else if (!strcmp (inst
, "in-f-c"))
155 else if (!strcmp (inst
, "out-c-0"))
165 str_to_zeda32 (char *litP
, int *sizeP
);
167 str_to_float48 (char *litP
, int *sizeP
);
169 str_to_ieee754_h (char *litP
, int *sizeP
);
171 str_to_ieee754_s (char *litP
, int *sizeP
);
173 str_to_ieee754_d (char *litP
, int *sizeP
);
175 static str_to_float_t
176 get_str_to_float (const char *arg
)
178 if (strcasecmp (arg
, "zeda32") == 0)
179 return str_to_zeda32
;
181 if (strcasecmp (arg
, "math48") == 0)
182 return str_to_float48
;
184 if (strcasecmp (arg
, "half") != 0)
185 return str_to_ieee754_h
;
187 if (strcasecmp (arg
, "single") != 0)
188 return str_to_ieee754_s
;
190 if (strcasecmp (arg
, "double") != 0)
191 return str_to_ieee754_d
;
193 if (strcasecmp (arg
, "ieee754") == 0)
194 as_fatal (_("invalid floating point numbers type `%s'"), arg
);
199 setup_instruction_list (const char *list
, int *add
, int *sub
)
206 for (b
= list
; *b
!= '\0';)
213 if (sz
== 0 || sz
>= (int)sizeof (buf
))
215 as_bad (_("invalid INST in command line: %s"), b
);
220 if (setup_instruction (buf
, add
, sub
))
224 as_bad (_("invalid INST in command line: %s"), buf
);
235 md_parse_option (int c
, const char* arg
)
241 case OPTION_MACH_Z80
:
242 ins_ok
= (ins_ok
& INS_TUNE_MASK
) | INS_Z80
;
243 ins_err
= (ins_err
& INS_MARCH_MASK
) | (~INS_Z80
& INS_MARCH_MASK
);
245 case OPTION_MACH_R800
:
246 ins_ok
= INS_R800
| INS_IDX_HALF
;
247 ins_err
= INS_UNPORT
;
249 case OPTION_MACH_Z180
:
251 ins_err
= INS_UNDOC
| INS_UNPORT
;
253 case OPTION_MACH_EZ80_Z80
:
255 ins_err
= (INS_UNDOC
| INS_UNPORT
) & ~INS_IDX_HALF
;
258 case OPTION_MACH_EZ80_ADL
:
260 ins_err
= (INS_UNDOC
| INS_UNPORT
) & ~INS_IDX_HALF
;
263 case OPTION_MACH_GBZ80
:
265 ins_err
= INS_UNDOC
| INS_UNPORT
;
267 case OPTION_FP_SINGLE_FORMAT
:
268 str_to_float
= get_str_to_float (arg
);
270 case OPTION_FP_DOUBLE_FORMAT
:
271 str_to_double
= get_str_to_float (arg
);
273 case OPTION_MACH_INST
:
274 if ((ins_ok
& INS_GBZ80
) == 0)
275 return setup_instruction_list (arg
, & ins_ok
, & ins_err
);
277 case OPTION_MACH_NO_INST
:
278 if ((ins_ok
& INS_GBZ80
) == 0)
279 return setup_instruction_list (arg
, & ins_err
, & ins_ok
);
281 case OPTION_MACH_WUD
:
282 case OPTION_MACH_IUD
:
283 if ((ins_ok
& INS_GBZ80
) == 0)
286 ins_err
&= ~INS_UNDOC
;
289 case OPTION_MACH_WUP
:
290 case OPTION_MACH_IUP
:
291 if ((ins_ok
& INS_GBZ80
) == 0)
293 ins_ok
|= INS_UNDOC
| INS_UNPORT
;
294 ins_err
&= ~(INS_UNDOC
| INS_UNPORT
);
297 case OPTION_MACH_FUD
:
298 if ((ins_ok
& (INS_R800
| INS_GBZ80
)) == 0)
300 ins_ok
&= (INS_UNDOC
| INS_UNPORT
);
301 ins_err
|= INS_UNDOC
| INS_UNPORT
;
304 case OPTION_MACH_FUP
:
305 ins_ok
&= ~INS_UNPORT
;
306 ins_err
|= INS_UNPORT
;
308 case OPTION_COMPAT_LL_PREFIX
:
309 local_label_prefix
= (arg
&& *arg
) ? arg
: NULL
;
311 case OPTION_COMPAT_SDCC
:
313 local_label_prefix
= "_";
315 case OPTION_COMPAT_COLONLESS
:
316 colonless_labels
= 1;
324 md_show_usage (FILE * f
)
327 CPU model options:\n\
328 -z80\t\t\t assemble for Z80\n\
329 -r800\t\t\t assemble for R800\n\
330 -z180\t\t\t assemble for Z180\n\
331 -ez80\t\t\t assemble for eZ80 in Z80 mode by default\n\
332 -ez80-adl\t\t assemble for eZ80 in ADL mode by default\n\
334 Compatibility options:\n\
335 -local-prefix=TEXT\t treat labels prefixed by TEXT as local\n\
336 -colonless\t\t permit colonless labels\n\
337 -sdcc\t\t\t accept SDCC specific instruction syntax\n\
338 -fp-s=FORMAT\t\t set single precission FP numbers format\n\
339 -fp-d=FORMAT\t\t set double precission FP numbers format\n\
340 Where FORMAT one of:\n\
341 ieee754\t\t IEEE754 compatible\n\
342 half\t\t\t IEEE754 half precision (16 bit)\n\
343 single\t\t IEEE754 single precision (32 bit)\n\
344 double\t\t IEEE754 double precision (64 bit)\n\
345 zeda32\t\t Zeda z80float library 32 bit format\n\
346 math48\t\t 48 bit format from Math48 library\n\
348 Support for known undocumented instructions:\n\
349 -strict\t\t assemble only documented instructions\n\
350 -full\t\t\t assemble all undocumented instructions\n\
351 -with-inst=INST[,...]\n\
352 -Wnins INST[,...]\t assemble specified instruction(s)\n\
353 -without-inst=INST[,...]\n\
354 -Fins INST[,...]\t do not assemble specified instruction(s)\n\
355 Where INST is one of:\n\
356 idx-reg-halves\t instructions with halves of index registers\n\
357 sli\t\t\t instruction SLI/SLL\n\
358 op-ii-ld\t\t instructions like SLA (II+dd),R (opcodes DD/FD CB dd xx)\n\
359 in-f-c\t\t instruction IN F,(C)\n\
360 out-c-0\t\t instruction OUT (C),0\n\
363 -ignore-undocumented-instructions\n\
364 -Wnud\t\t\t silently assemble undocumented Z80-instructions that work on R800\n\
365 -ignore-unportable-instructions\n\
366 -Wnup\t\t\t silently assemble all undocumented Z80-instructions\n\
367 -warn-undocumented-instructions\n\
368 -Wud\t\t\t issue warnings for undocumented Z80-instructions that work on R800\n\
369 -warn-unportable-instructions\n\
370 -Wup\t\t\t issue warnings for other undocumented Z80-instructions\n\
371 -forbid-undocumented-instructions\n\
372 -Fud\t\t\t treat all undocumented Z80-instructions as errors\n\
373 -forbid-unportable-instructions\n\
374 -Fup\t\t\t treat undocumented Z80-instructions that do not work on R800 as errors\n\
376 Default: -z80 -ignore-undocumented-instructions -warn-unportable-instructions.\n");
379 static symbolS
* zero
;
386 #define R_STACKABLE (0x80)
387 #define R_ARITH (0x40)
390 #define R_INDEX (R_IX | R_IY)
399 #define REG_F (6 | 8)
404 #define REG_AF (3 | R_STACKABLE)
405 #define REG_BC (0 | R_STACKABLE | R_ARITH)
406 #define REG_DE (1 | R_STACKABLE | R_ARITH)
407 #define REG_HL (2 | R_STACKABLE | R_ARITH)
408 #define REG_IX (REG_HL | R_IX)
409 #define REG_IY (REG_HL | R_IY)
410 #define REG_SP (3 | R_ARITH)
412 static const struct reg_entry regtable
[] =
427 {"ixh",REG_H
| R_IX
},
428 {"ixl",REG_L
| R_IX
},
430 {"iyh",REG_H
| R_IY
},
431 {"iyl",REG_L
| R_IY
},
438 #define BUFLEN 8 /* Large enough for any keyword. */
443 expressionS nul
, reg
;
445 unsigned int i
, j
, k
;
448 if (ins_ok
& INS_EZ80
) /* if select EZ80 cpu then */
449 listing_lhs_width
= 6; /* use 6 bytes per line in the listing */
451 reg
.X_op
= O_register
;
453 reg
.X_add_symbol
= reg
.X_op_symbol
= 0;
454 for ( i
= 0 ; i
< ARRAY_SIZE ( regtable
) ; ++i
)
456 reg
.X_add_number
= regtable
[i
].number
;
457 k
= strlen ( regtable
[i
].name
);
461 for ( j
= ( 1<<k
) ; j
; --j
)
463 for ( k
= 0 ; regtable
[i
].name
[k
] ; ++k
)
465 buf
[k
] = ( j
& ( 1<<k
) ) ? TOUPPER (regtable
[i
].name
[k
]) : regtable
[i
].name
[k
];
467 symbolS
* psym
= symbol_find_or_make (buf
);
468 S_SET_SEGMENT (psym
, reg_section
);
469 symbol_set_value_expression (psym
, ®
);
473 p
= input_line_pointer
;
474 input_line_pointer
= (char *) "0";
477 input_line_pointer
= p
;
478 zero
= make_expr_symbol (& nul
);
479 /* We do not use relaxation (yet). */
488 switch (ins_ok
& INS_MARCH_MASK
)
491 if (ins_ok
& INS_UNPORT
)
492 mach_type
= bfd_mach_z80full
;
493 else if (ins_ok
& INS_UNDOC
)
494 mach_type
= bfd_mach_z80
;
496 mach_type
= bfd_mach_z80strict
;
499 mach_type
= bfd_mach_r800
;
502 mach_type
= bfd_mach_z180
;
505 mach_type
= bfd_mach_gbz80
;
508 mach_type
= cpu_mode
? bfd_mach_ez80_adl
: bfd_mach_ez80_z80
;
514 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach_type
);
517 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
519 z80_elf_final_processing (void)
522 switch (ins_ok
& INS_MARCH_MASK
)
525 elf_flags
= EF_Z80_MACH_Z80
;
528 elf_flags
= EF_Z80_MACH_R800
;
531 elf_flags
= EF_Z80_MACH_Z180
;
534 elf_flags
= EF_Z80_MACH_GBZ80
;
537 elf_flags
= cpu_mode
? EF_Z80_MACH_EZ80_ADL
: EF_Z80_MACH_EZ80_Z80
;
543 elf_elfheader (stdoutput
)->e_flags
= elf_flags
;
548 skip_space (const char *s
)
550 while (*s
== ' ' || *s
== '\t')
555 /* A non-zero return-value causes a continue in the
556 function read_a_source_file () in ../read.c. */
558 z80_start_line_hook (void)
563 /* Convert one character constants. */
564 for (p
= input_line_pointer
; *p
&& *p
!= '\n'; ++p
)
569 if (p
[1] != 0 && p
[1] != '\'' && p
[2] == '\'')
571 snprintf (buf
, 4, "%3d", (unsigned char)p
[1]);
579 for (quote
= *p
++; quote
!= *p
&& '\n' != *p
; ++p
)
583 as_bad (_("-- unterminated string"));
584 ignore_rest_of_line ();
590 *p
= (*skip_space (p
+ 1) == '(') ? '+' : ' ';
594 /* Check for <label>[:] [.](EQU|DEFL) <value>. */
595 if (is_name_beginner (*input_line_pointer
))
598 char c
, *rest
, *line_start
;
601 line_start
= input_line_pointer
;
605 c
= get_symbol_name (&name
);
606 rest
= input_line_pointer
+ 1;
608 if (ISSPACE (c
) && colonless_labels
)
612 bump_line_counters ();
617 if (c
== ':' && sdcc_compat
&& rest
[-2] != '$')
618 dollar_label_clear ();
621 /* remove second colon if SDCC compatibility enabled */
626 rest
= (char*)skip_space (rest
);
629 if (strncasecmp (rest
, "EQU", 3) == 0)
631 else if (strncasecmp (rest
, "DEFL", 4) == 0)
635 if (len
&& (!ISALPHA (rest
[len
])))
637 /* Handle assignment here. */
638 if (line_start
[-1] == '\n')
640 bump_line_counters ();
643 input_line_pointer
= rest
+ len
- 1;
644 /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
645 equals (name
, len
== 4);
650 /* Restore line and pointer. */
651 (void) restore_line_pointer (c
);
652 input_line_pointer
= line_start
;
659 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
665 md_atof (int type
, char *litP
, int *sizeP
)
674 return str_to_float (litP
, sizeP
);
681 return str_to_double (litP
, sizeP
);
684 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
688 md_section_align (segT seg ATTRIBUTE_UNUSED
, valueT size
)
694 md_pcrel_from (fixS
* fixp
)
696 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
699 typedef const char * (asfunc
)(char, char, const char*);
701 typedef struct _table_t
704 unsigned char prefix
;
705 unsigned char opcode
;
707 unsigned inss
; /*0 - all CPU types or list of supported INS_* */
710 /* Compares the key for structs that start with a char * to the key. */
712 key_cmp (const void * a
, const void * b
)
714 const char *str_a
, *str_b
;
716 str_a
= *((const char**)a
);
717 str_b
= *((const char**)b
);
718 return strcmp (str_a
, str_b
);
722 const char *key
= buf
;
724 /* Prevent an error on a line from also generating
725 a "junk at end of line" error message. */
726 static char err_flag
;
729 error (const char * message
)
734 as_bad ("%s", message
);
741 error (_("illegal operand"));
745 wrong_mach (int ins_type
)
747 if (ins_type
& ins_err
)
750 as_warn (_("undocumented instruction"));
754 check_mach (int ins_type
)
756 if ((ins_type
& ins_ok
) == 0)
757 wrong_mach (ins_type
);
760 /* Check whether an expression is indirect. */
762 is_indir (const char *s
)
768 /* Indirection is indicated with parentheses. */
771 for (p
= s
, depth
= 0; *p
&& *p
!= ','; ++p
)
777 for (quote
= *p
++; quote
!= *p
&& *p
!= '\n'; ++p
)
778 if (*p
== '\\' && p
[1])
788 p
= skip_space (p
+ 1);
794 error (_("mismatched parentheses"));
800 error (_("mismatched parentheses"));
805 /* Check whether a symbol involves a register. */
807 contains_register (symbolS
*sym
)
811 expressionS
* ex
= symbol_get_value_expression(sym
);
813 return (O_register
== ex
->X_op
)
814 || (ex
->X_add_symbol
&& contains_register(ex
->X_add_symbol
))
815 || (ex
->X_op_symbol
&& contains_register(ex
->X_op_symbol
));
821 /* Parse general expression, not looking for indexed addressing. */
823 parse_exp_not_indexed (const char *s
, expressionS
*op
)
830 if (sdcc_compat
&& (*p
== '<' || *p
== '>'))
834 case '<': /* LSB request */
837 case '>': /* MSB request */
838 make_shift
= cpu_mode
? 16 : 8;
845 op
->X_md
= indir
= is_indir (p
);
846 input_line_pointer
= (char*) s
;
851 error (_("missing operand"));
854 error (_("bad expression syntax"));
862 /* replace [op] by [op >> shift] */
864 op
->X_add_symbol
= make_expr_symbol (op
);
865 op
->X_add_number
= 0;
866 op
->X_op
= O_right_shift
;
867 memset (&data
, 0, sizeof (data
));
868 data
.X_op
= O_constant
;
869 data
.X_add_number
= make_shift
;
870 op
->X_op_symbol
= make_expr_symbol (&data
);
872 return input_line_pointer
;
876 unify_indexed (expressionS
*op
)
878 if (O_register
!= symbol_get_value_expression (op
->X_add_symbol
)->X_op
)
881 int rnum
= symbol_get_value_expression (op
->X_add_symbol
)->X_add_number
;
882 if ( ((REG_IX
!= rnum
) && (REG_IY
!= rnum
)) || contains_register (op
->X_op_symbol
))
888 /* Convert subtraction to addition of negative value. */
889 if (O_subtract
== op
->X_op
)
892 minus
.X_op
= O_uminus
;
893 minus
.X_add_number
= 0;
894 minus
.X_add_symbol
= op
->X_op_symbol
;
895 minus
.X_op_symbol
= 0;
896 op
->X_op_symbol
= make_expr_symbol (&minus
);
900 /* Clear X_add_number of the expression. */
901 if (op
->X_add_number
!= 0)
904 memset (&add
, 0, sizeof (add
));
906 add
.X_add_number
= op
->X_add_number
;
907 add
.X_add_symbol
= op
->X_op_symbol
;
909 op
->X_add_symbol
= make_expr_symbol (&add
);
912 op
->X_add_symbol
= op
->X_op_symbol
;
914 op
->X_add_number
= rnum
;
919 /* Parse expression, change operator to O_md1 for indexed addressing. */
921 parse_exp (const char *s
, expressionS
*op
)
923 const char* res
= parse_exp_not_indexed (s
, op
);
928 if (unify_indexed (op
) && op
->X_md
)
932 if (op
->X_md
&& ((REG_IX
== op
->X_add_number
) || (REG_IY
== op
->X_add_number
)))
934 op
->X_add_symbol
= zero
;
939 /* parse SDCC syntax where index register offset placed before parentheses */
940 if (sdcc_compat
&& is_indir (res
))
944 res
= parse_exp (res
, op
);
945 if (op
->X_op
!= O_md1
|| op
->X_add_symbol
!= zero
)
948 op
->X_add_symbol
= make_expr_symbol (&off
);
957 /* Condition codes, including some synonyms provided by HiTech zas. */
958 static const struct reg_entry cc_tab
[] =
976 /* Parse condition code. */
978 parse_cc (const char *s
, char * op
)
982 struct reg_entry
* cc_p
;
984 for (i
= 0; i
< BUFLEN
; ++i
)
986 if (!ISALPHA (s
[i
])) /* Condition codes consist of letters only. */
988 buf
[i
] = TOLOWER (s
[i
]);
992 && ((s
[i
] == 0) || (s
[i
] == ',')))
995 cc_p
= bsearch (&key
, cc_tab
, ARRAY_SIZE (cc_tab
),
996 sizeof (cc_tab
[0]), key_cmp
);
1013 emit_insn (char prefix
, char opcode
, const char * args
)
1028 void z80_cons_fix_new (fragS
*frag_p
, int offset
, int nbytes
, expressionS
*exp
)
1030 bfd_reloc_code_real_type r
[4] =
1038 if (nbytes
< 1 || nbytes
> 4)
1040 as_bad (_("unsupported BFD relocation size %u"), nbytes
);
1044 fix_new_exp (frag_p
, offset
, nbytes
, exp
, 0, r
[nbytes
-1]);
1049 emit_data_val (expressionS
* val
, int size
)
1052 bfd_reloc_code_real_type r_type
;
1054 p
= frag_more (size
);
1055 if (val
->X_op
== O_constant
)
1058 for (i
= 0; i
< size
; ++i
)
1059 p
[i
] = (char)(val
->X_add_number
>> (i
*8));
1065 case 1: r_type
= BFD_RELOC_8
; break;
1066 case 2: r_type
= BFD_RELOC_16
; break;
1067 case 3: r_type
= BFD_RELOC_24
; break;
1068 case 4: r_type
= BFD_RELOC_32
; break;
1069 case 8: r_type
= BFD_RELOC_64
; break;
1071 as_fatal (_("invalid data size %d"), size
);
1074 if ( (val
->X_op
== O_register
)
1075 || (val
->X_op
== O_md1
)
1076 || contains_register (val
->X_add_symbol
)
1077 || contains_register (val
->X_op_symbol
))
1080 if (size
<= 2 && val
->X_op_symbol
)
1082 bfd_boolean simplify
= TRUE
;
1083 int shift
= symbol_get_value_expression (val
->X_op_symbol
)->X_add_number
;
1084 if (val
->X_op
== O_bit_and
&& shift
== (1 << (size
*8))-1)
1086 else if (val
->X_op
!= O_right_shift
)
1093 case 0: r_type
= BFD_RELOC_Z80_BYTE0
; break;
1094 case 8: r_type
= BFD_RELOC_Z80_BYTE1
; break;
1095 case 16: r_type
= BFD_RELOC_Z80_BYTE2
; break;
1096 case 24: r_type
= BFD_RELOC_Z80_BYTE3
; break;
1097 default: simplify
= FALSE
;
1100 else /* if (size == 2) */
1104 case 0: r_type
= BFD_RELOC_Z80_WORD0
; break;
1105 case 16: r_type
= BFD_RELOC_Z80_WORD1
; break;
1106 default: simplify
= FALSE
;
1112 val
->X_op
= O_symbol
;
1113 val
->X_op_symbol
= NULL
;
1114 val
->X_add_number
= 0;
1118 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, size
, val
, FALSE
, r_type
);
1122 emit_byte (expressionS
* val
, bfd_reloc_code_real_type r_type
)
1127 if (r_type
== BFD_RELOC_8
)
1129 emit_data_val (val
, 1);
1133 *p
= val
->X_add_number
;
1134 if ( contains_register (val
->X_add_symbol
) || contains_register (val
->X_op_symbol
) )
1138 else if ((r_type
== BFD_RELOC_8_PCREL
) && (val
->X_op
== O_constant
))
1140 as_bad (_("cannot make a relative jump to an absolute location"));
1142 else if (val
->X_op
== O_constant
)
1145 hi
= (BFD_RELOC_8
== r_type
) ? 255 : 127;
1147 if ((val
->X_add_number
< lo
) || (val
->X_add_number
> hi
))
1149 if (r_type
== BFD_RELOC_Z80_DISP8
)
1150 as_bad (_("offset too large"));
1152 as_warn (_("overflow"));
1157 /* For symbols only, constants are stored at begin of function */
1158 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 1, val
,
1159 (r_type
== BFD_RELOC_8_PCREL
) ? TRUE
: FALSE
, r_type
);
1164 emit_word (expressionS
* val
)
1166 emit_data_val (val
, (inst_mode
& INST_MODE_IL
) ? 3 : 2);
1170 emit_mx (char prefix
, char opcode
, int shift
, expressionS
* arg
)
1171 /* The operand m may be r, (hl), (ix+d), (iy+d),
1172 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1177 rnum
= arg
->X_add_number
;
1193 if ((prefix
== 0) && (rnum
& R_INDEX
))
1195 prefix
= (rnum
& R_IX
) ? 0xDD : 0xFD;
1196 if (!(ins_ok
& INS_EZ80
))
1197 check_mach (INS_IDX_HALF
);
1206 q
= frag_more (prefix
? 2 : 1);
1209 * q
++ = opcode
+ (rnum
<< shift
);
1212 if (ins_ok
& INS_GBZ80
)
1218 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1219 *q
= (prefix
) ? prefix
: (opcode
+ (6 << shift
));
1221 expressionS offset
= *arg
;
1222 offset
.X_op
= O_symbol
;
1223 offset
.X_add_number
= 0;
1224 emit_byte (&offset
, BFD_RELOC_Z80_DISP8
);
1229 *q
= opcode
+(6<<shift
);
1237 /* The operand m may be r, (hl), (ix+d), (iy+d),
1238 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1240 emit_m (char prefix
, char opcode
, const char *args
)
1245 p
= parse_exp (args
, &arg_m
);
1250 emit_mx (prefix
, opcode
, 0, &arg_m
);
1258 /* The operand m may be as above or one of the undocumented
1259 combinations (ix+d),r and (iy+d),r (if unportable instructions
1263 emit_mr (char prefix
, char opcode
, const char *args
)
1265 expressionS arg_m
, arg_r
;
1268 p
= parse_exp (args
, & arg_m
);
1275 p
= parse_exp (p
+ 1, & arg_r
);
1277 if ((arg_r
.X_md
== 0)
1278 && (arg_r
.X_op
== O_register
)
1279 && (arg_r
.X_add_number
< 8))
1280 opcode
+= arg_r
.X_add_number
- 6; /* Emit_mx () will add 6. */
1286 check_mach (INS_ROT_II_LD
);
1290 emit_mx (prefix
, opcode
, 0, & arg_m
);
1299 emit_sx (char prefix
, char opcode
, expressionS
* arg_p
)
1303 switch (arg_p
->X_op
)
1307 emit_mx (prefix
, opcode
, 0, arg_p
);
1314 q
= frag_more (prefix
? 2 : 1);
1318 emit_byte (arg_p
, BFD_RELOC_8
);
1323 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1325 emit_s (char prefix
, char opcode
, const char *args
)
1330 p
= parse_exp (args
, & arg_s
);
1331 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
1332 { /* possible instruction in generic format op A,x */
1333 if (!(ins_ok
& INS_EZ80
) && !sdcc_compat
)
1336 p
= parse_exp (p
, & arg_s
);
1338 emit_sx (prefix
, opcode
, & arg_s
);
1343 emit_call (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1346 const char *p
; char *q
;
1348 p
= parse_exp_not_indexed (args
, &addr
);
1360 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1362 emit_incdec (char prefix
, char opcode
, const char * args
)
1364 expressionS operand
;
1366 const char *p
; char *q
;
1368 p
= parse_exp (args
, &operand
);
1369 rnum
= operand
.X_add_number
;
1370 if ((! operand
.X_md
)
1371 && (operand
.X_op
== O_register
)
1374 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1376 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1377 *q
= prefix
+ ((rnum
& 3) << 4);
1381 if ((operand
.X_op
== O_md1
) || (operand
.X_op
== O_register
))
1382 emit_mx (0, opcode
, 3, & operand
);
1390 emit_jr (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1396 p
= parse_exp_not_indexed (args
, &addr
);
1403 addr
.X_add_number
--; /* pcrel computes after offset code */
1404 emit_byte (&addr
, BFD_RELOC_8_PCREL
);
1410 emit_jp (char prefix
, char opcode
, const char * args
)
1417 p
= parse_exp_not_indexed (args
, & addr
);
1420 rnum
= addr
.X_add_number
;
1421 if ((O_register
== addr
.X_op
) && (REG_HL
== (rnum
& ~R_INDEX
)))
1423 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1425 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1441 emit_im (char prefix
, char opcode
, const char * args
)
1447 p
= parse_exp (args
, & mode
);
1448 if (mode
.X_md
|| (mode
.X_op
!= O_constant
))
1451 switch (mode
.X_add_number
)
1455 ++mode
.X_add_number
;
1460 *q
= opcode
+ 8*mode
.X_add_number
;
1469 emit_pop (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1475 p
= parse_exp (args
, & regp
);
1477 && (regp
.X_op
== O_register
)
1478 && (regp
.X_add_number
& R_STACKABLE
))
1482 rnum
= regp
.X_add_number
;
1486 *q
++ = (rnum
&R_IX
)?0xDD:0xFD;
1490 *q
= opcode
+ ((rnum
& 3) << 4);
1499 emit_retcc (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1504 p
= parse_cc (args
, &cc
);
1510 return p
? p
: args
;
1514 emit_adc (char prefix
, char opcode
, const char * args
)
1521 p
= parse_exp (args
, &term
);
1524 error (_("bad instruction syntax"));
1528 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1531 switch (term
.X_add_number
)
1534 p
= emit_s (0, prefix
, p
);
1537 p
= parse_exp (p
, &term
);
1538 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1540 rnum
= term
.X_add_number
;
1541 if (R_ARITH
== (rnum
& (R_ARITH
| R_INDEX
)))
1545 *q
= opcode
+ ((rnum
& 3) << 4);
1557 emit_add (char prefix
, char opcode
, const char * args
)
1564 p
= parse_exp (args
, &term
);
1567 error (_("bad instruction syntax"));
1571 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1574 switch (term
.X_add_number
& ~R_INDEX
)
1577 p
= emit_s (0, prefix
, p
);
1580 lhs
= term
.X_add_number
;
1581 p
= parse_exp (p
, &term
);
1582 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1584 rhs
= term
.X_add_number
;
1586 && ((rhs
== lhs
) || ((rhs
& ~R_INDEX
) != REG_HL
)))
1588 q
= frag_more ((lhs
& R_INDEX
) ? 2 : 1);
1590 *q
++ = (lhs
& R_IX
) ? 0xDD : 0xFD;
1591 *q
= opcode
+ ((rhs
& 3) << 4);
1603 emit_bit (char prefix
, char opcode
, const char * args
)
1609 p
= parse_exp (args
, &b
);
1611 error (_("bad instruction syntax"));
1613 bn
= b
.X_add_number
;
1615 && (b
.X_op
== O_constant
)
1620 /* Bit : no optional third operand. */
1621 p
= emit_m (prefix
, opcode
+ (bn
<< 3), p
);
1623 /* Set, res : resulting byte can be copied to register. */
1624 p
= emit_mr (prefix
, opcode
+ (bn
<< 3), p
);
1632 emit_jpcc (char prefix
, char opcode
, const char * args
)
1637 p
= parse_cc (args
, & cc
);
1638 if (p
&& *p
++ == ',')
1639 p
= emit_call (0, opcode
+ cc
, p
);
1641 p
= (prefix
== (char)0xC3)
1642 ? emit_jp (0xE9, prefix
, args
)
1643 : emit_call (0, prefix
, args
);
1648 emit_jrcc (char prefix
, char opcode
, const char * args
)
1653 p
= parse_cc (args
, &cc
);
1654 if (p
&& *p
++ == ',')
1657 error (_("condition code invalid for jr"));
1659 p
= emit_jr (0, opcode
+ cc
, p
);
1662 p
= emit_jr (0, prefix
, args
);
1668 emit_ex (char prefix_in ATTRIBUTE_UNUSED
,
1669 char opcode_in ATTRIBUTE_UNUSED
, const char * args
)
1673 char prefix
, opcode
;
1675 p
= parse_exp_not_indexed (args
, &op
);
1679 error (_("bad instruction syntax"));
1683 prefix
= opcode
= 0;
1684 if (op
.X_op
== O_register
)
1685 switch (op
.X_add_number
| (op
.X_md
? 0x8000 : 0))
1688 if (TOLOWER (*p
++) == 'a' && TOLOWER (*p
++) == 'f')
1690 /* The scrubber changes '\'' to '`' in this context. */
1697 if (TOLOWER (*p
++) == 'h' && TOLOWER (*p
++) == 'l')
1701 p
= parse_exp (p
, & op
);
1702 if (op
.X_op
== O_register
1704 && (op
.X_add_number
& ~R_INDEX
) == REG_HL
)
1707 if (R_INDEX
& op
.X_add_number
)
1708 prefix
= (R_IX
& op
.X_add_number
) ? 0xDD : 0xFD;
1713 emit_insn (prefix
, opcode
, p
);
1721 emit_in (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1724 expressionS reg
, port
;
1728 p
= parse_exp (args
, ®
);
1731 error (_("bad instruction syntax"));
1735 p
= parse_exp (p
, &port
);
1737 && reg
.X_op
== O_register
1738 && (reg
.X_add_number
<= 7 || reg
.X_add_number
== REG_F
)
1741 if (port
.X_op
!= O_md1
&& port
.X_op
!= O_register
)
1743 if (REG_A
== reg
.X_add_number
)
1747 emit_byte (&port
, BFD_RELOC_8
);
1754 if (port
.X_add_number
== REG_C
|| port
.X_add_number
== REG_BC
)
1756 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
1758 else if (reg
.X_add_number
== REG_F
&& !(ins_ok
& INS_R800
))
1759 check_mach (INS_IN_F_C
);
1762 *q
= 0x40|((reg
.X_add_number
&7)<<3);
1774 emit_in0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1777 expressionS reg
, port
;
1781 p
= parse_exp (args
, ®
);
1784 error (_("bad instruction syntax"));
1788 p
= parse_exp (p
, &port
);
1790 && reg
.X_op
== O_register
1791 && reg
.X_add_number
<= 7
1793 && port
.X_op
!= O_md1
1794 && port
.X_op
!= O_register
)
1798 *q
= 0x00|(reg
.X_add_number
<< 3);
1799 emit_byte (&port
, BFD_RELOC_8
);
1807 emit_out (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1810 expressionS reg
, port
;
1814 p
= parse_exp (args
, & port
);
1817 error (_("bad instruction syntax"));
1820 p
= parse_exp (p
, ®
);
1822 { ill_op (); return p
; }
1823 /* Allow "out (c), 0" as unportable instruction. */
1824 if (reg
.X_op
== O_constant
&& reg
.X_add_number
== 0)
1826 check_mach (INS_OUT_C_0
);
1827 reg
.X_op
= O_register
;
1828 reg
.X_add_number
= 6;
1831 || reg
.X_op
!= O_register
1832 || reg
.X_add_number
> 7)
1835 if (port
.X_op
!= O_register
&& port
.X_op
!= O_md1
)
1837 if (REG_A
== reg
.X_add_number
)
1841 emit_byte (&port
, BFD_RELOC_8
);
1848 if (REG_C
== port
.X_add_number
|| port
.X_add_number
== REG_BC
)
1850 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
1854 *q
= 0x41 | (reg
.X_add_number
<< 3);
1863 emit_out0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1866 expressionS reg
, port
;
1870 p
= parse_exp (args
, & port
);
1873 error (_("bad instruction syntax"));
1876 p
= parse_exp (p
, ®
);
1878 && port
.X_op
!= O_register
1879 && port
.X_op
!= O_md1
1881 && reg
.X_op
== O_register
1882 && reg
.X_add_number
<= 7)
1886 *q
= 0x01 | (reg
.X_add_number
<< 3);
1887 emit_byte (&port
, BFD_RELOC_8
);
1895 emit_rst (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1901 p
= parse_exp_not_indexed (args
, &addr
);
1902 if (addr
.X_op
!= O_constant
)
1904 error ("rst needs constant address");
1908 if (addr
.X_add_number
& ~(7 << 3))
1913 *q
= opcode
+ (addr
.X_add_number
& (7 << 3));
1918 /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
1920 emit_ld_m_n (expressionS
*dst
, expressionS
*src
)
1924 expressionS dst_offset
;
1926 switch (dst
->X_add_number
)
1928 case REG_HL
: prefix
= 0x00; break;
1929 case REG_IX
: prefix
= 0xDD; break;
1930 case REG_IY
: prefix
= 0xFD; break;
1936 q
= frag_more (prefix
? 2 : 1);
1943 dst_offset
.X_op
= O_symbol
;
1944 dst_offset
.X_add_number
= 0;
1945 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
1947 emit_byte (src
, BFD_RELOC_8
);
1950 /* For 8-bit load register to memory instructions: LD (<expression>),r. */
1952 emit_ld_m_r (expressionS
*dst
, expressionS
*src
)
1956 expressionS dst_offset
;
1961 prefix
= (dst
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
1964 switch (dst
->X_add_number
)
1966 case REG_BC
: /* LD (BC),A */
1967 case REG_DE
: /* LD (DE),A */
1968 if (src
->X_add_number
== REG_A
)
1971 *q
= 0x02 | ((dst
->X_add_number
& 3) << 4);
1977 case REG_HL
: /* LD (HL),r or LD (ii+d),r */
1978 if (src
->X_add_number
<= 7)
1980 q
= frag_more (prefix
? 2 : 1);
1983 *q
= 0x70 | src
->X_add_number
;
1987 dst_offset
.X_op
= O_symbol
;
1988 dst_offset
.X_add_number
= 0;
1989 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
1997 default: /* LD (nn),A */
1998 if (src
->X_add_number
== REG_A
)
2010 /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
2012 emit_ld_m_rr (expressionS
*dst
, expressionS
*src
)
2017 expressionS dst_offset
;
2021 case O_md1
: /* eZ80 instructions LD (ii+d),rr */
2022 case O_register
: /* eZ80 instructions LD (HL),rr */
2023 if (!(ins_ok
& INS_EZ80
)) /* 16-bit indirect load group is supported by eZ80 only */
2025 switch (dst
->X_add_number
)
2027 case REG_IX
: prefix
= 0xDD; break;
2028 case REG_IY
: prefix
= 0xFD; break;
2029 case REG_HL
: prefix
= 0xED; break;
2033 switch (src
->X_add_number
)
2035 case REG_BC
: opcode
= 0x0F; break;
2036 case REG_DE
: opcode
= 0x1F; break;
2037 case REG_HL
: opcode
= 0x2F; break;
2038 case REG_IX
: opcode
= (prefix
!= 0xFD) ? 0x3F : 0x3E; break;
2039 case REG_IY
: opcode
= (prefix
!= 0xFD) ? 0x3E : 0x3F; break;
2043 q
= frag_more (prefix
? 2 : 1);
2046 if (prefix
== 0xFD || prefix
== 0xDD)
2049 dst_offset
.X_op
= O_symbol
;
2050 dst_offset
.X_add_number
= 0;
2051 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2054 default: /* LD (nn),rr */
2055 if (ins_ok
& INS_GBZ80
)
2057 /* GBZ80 supports only LD (nn),SP */
2058 if (src
->X_add_number
== REG_SP
)
2068 switch (src
->X_add_number
)
2070 case REG_BC
: prefix
= 0xED; opcode
= 0x43; break;
2071 case REG_DE
: prefix
= 0xED; opcode
= 0x53; break;
2072 case REG_HL
: prefix
= 0x00; opcode
= 0x22; break;
2073 case REG_IX
: prefix
= 0xDD; opcode
= 0x22; break;
2074 case REG_IY
: prefix
= 0xFD; opcode
= 0x22; break;
2075 case REG_SP
: prefix
= 0xED; opcode
= 0x73; break;
2080 q
= frag_more (prefix
? 2 : 1);
2089 emit_ld_r_m (expressionS
*dst
, expressionS
*src
)
2090 { /* for 8-bit memory load to register: LD r,(xxx) */
2094 expressionS src_offset
;
2096 if (dst
->X_add_number
== REG_A
&& src
->X_op
== O_register
)
2097 { /* LD A,(BC) or LD A,(DE) */
2098 switch (src
->X_add_number
)
2100 case REG_BC
: opcode
= 0x0A; break;
2101 case REG_DE
: opcode
= 0x1A; break;
2116 if (dst
->X_add_number
> 7)
2118 opcode
= 0x46; /* LD B,(HL) */
2119 switch (src
->X_add_number
)
2121 case REG_HL
: prefix
= 0x00; break;
2122 case REG_IX
: prefix
= 0xDD; break;
2123 case REG_IY
: prefix
= 0xFD; break;
2127 q
= frag_more (prefix
? 2 : 1);
2130 *q
= opcode
| ((dst
->X_add_number
& 7) << 3);
2134 src_offset
.X_op
= O_symbol
;
2135 src_offset
.X_add_number
= 0;
2136 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2139 default: /* LD A,(nn) */
2140 if (dst
->X_add_number
== REG_A
)
2150 emit_ld_r_n (expressionS
*dst
, expressionS
*src
)
2151 { /* for 8-bit immediate value load to register: LD r,n */
2155 switch (dst
->X_add_number
)
2178 q
= frag_more (prefix
? 2 : 1);
2181 if (ins_ok
& INS_GBZ80
)
2183 else if (!(ins_ok
& INS_EZ80
))
2184 check_mach (INS_IDX_HALF
);
2187 *q
= 0x06 | ((dst
->X_add_number
& 7) << 3);
2188 emit_byte (src
, BFD_RELOC_8
);
2192 emit_ld_r_r (expressionS
*dst
, expressionS
*src
)
2193 { /* mostly 8-bit load register from register instructions: LD r,r */
2194 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2200 switch (dst
->X_add_number
)
2203 switch (src
->X_add_number
)
2205 case REG_HL
: prefix
= 0x00; break;
2206 case REG_IX
: prefix
= 0xDD; break;
2207 case REG_IY
: prefix
= 0xFD; break;
2211 if (ins_ok
& INS_GBZ80
)
2216 if (!(ins_ok
& INS_EZ80
))
2218 if (src
->X_add_number
!= REG_I
)
2221 error (_("ADL mode instruction"));
2227 if (src
->X_add_number
== REG_HL
)
2229 if (!(ins_ok
& INS_EZ80
))
2232 error (_("ADL mode instruction"));
2236 else if (src
->X_add_number
== REG_A
)
2245 if (!(ins_ok
& INS_EZ80
) || (src
->X_add_number
!= REG_A
))
2248 error (_("ADL mode instruction"));
2253 if (src
->X_add_number
== REG_A
) /* LD R,A */
2262 if (src
->X_add_number
== REG_I
) /* LD A,I */
2268 else if (src
->X_add_number
== REG_R
) /* LD A,R */
2274 else if (src
->X_add_number
== REG_MB
) /* LD A,MB */
2276 if (!(ins_ok
& INS_EZ80
))
2281 error (_("ADL mode instruction"));
2312 switch (src
->X_add_number
)
2323 ill_op (); /* LD iiH/L,H/L are not permitted */
2327 if (prefix
== 0xFD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2328 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2334 if (prefix
== 0xDD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2335 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2342 opcode
= 0x40 + ((dst
->X_add_number
& 7) << 3) + (src
->X_add_number
& 7);
2344 if ((ins_ok
& INS_GBZ80
) && prefix
!= 0)
2346 if (ii_halves
&& !(ins_ok
& INS_EZ80
))
2347 check_mach (INS_IDX_HALF
);
2348 if (prefix
== 0 && (ins_ok
& INS_EZ80
))
2352 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2353 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2354 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2355 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2356 as_warn (_("unsupported instruction, assembled as NOP"));
2362 q
= frag_more (prefix
? 2 : 1);
2369 emit_ld_rr_m (expressionS
*dst
, expressionS
*src
)
2370 { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2374 expressionS src_offset
;
2376 /* GBZ80 has no support for 16-bit load from memory instructions */
2377 if (ins_ok
& INS_GBZ80
)
2383 case O_md1
: /* LD rr,(ii+d) */
2384 prefix
= (src
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2386 case O_register
: /* LD rr,(HL) */
2387 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2388 if (!(ins_ok
& INS_EZ80
))
2390 switch (dst
->X_add_number
)
2392 case REG_BC
: opcode
= 0x07; break;
2393 case REG_DE
: opcode
= 0x17; break;
2394 case REG_HL
: opcode
= 0x27; break;
2395 case REG_IX
: opcode
= (!prefix
|| prefix
== 0xDD) ? 0x37 : 0x31; break;
2396 case REG_IY
: opcode
= prefix
? ((prefix
== 0xDD) ? 0x31 : 0x37) : 0x36; break;
2406 src_offset
.X_op
= O_symbol
;
2407 src_offset
.X_add_number
= 0;
2408 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2411 default: /* LD rr,(nn) */
2412 switch (dst
->X_add_number
)
2414 case REG_BC
: prefix
= 0xED; opcode
= 0x4B; break;
2415 case REG_DE
: prefix
= 0xED; opcode
= 0x5B; break;
2416 case REG_HL
: prefix
= 0x00; opcode
= 0x2A; break;
2417 case REG_SP
: prefix
= 0xED; opcode
= 0x7B; break;
2418 case REG_IX
: prefix
= 0xDD; opcode
= 0x2A; break;
2419 case REG_IY
: prefix
= 0xFD; opcode
= 0x2A; break;
2423 q
= frag_more (prefix
? 2 : 1);
2433 emit_ld_rr_nn (expressionS
*dst
, expressionS
*src
)
2434 { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2437 int opcode
= 0x21; /* LD HL,nn */
2438 switch (dst
->X_add_number
)
2451 opcode
= 0x01 + ((dst
->X_add_number
& 3) << 4);
2457 if (prefix
&& (ins_ok
& INS_GBZ80
))
2459 q
= frag_more (prefix
? 2 : 1);
2467 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
2470 expressionS dst
, src
;
2473 p
= parse_exp (args
, & dst
);
2475 error (_("bad instruction syntax"));
2476 p
= parse_exp (p
, & src
);
2480 if (src
.X_op
== O_register
)
2482 if (src
.X_add_number
<= 7)
2483 emit_ld_m_r (& dst
, & src
); /* LD (xxx),r */
2485 emit_ld_m_rr (& dst
, & src
); /* LD (xxx),rr */
2488 emit_ld_m_n (& dst
, & src
); /* LD (hl),n or LD (ix/y+r),n */
2490 else if (dst
.X_op
== O_register
)
2494 if (dst
.X_add_number
<= 7)
2495 emit_ld_r_m (& dst
, & src
);
2497 emit_ld_rr_m (& dst
, & src
);
2499 else if (src
.X_op
== O_register
)
2500 emit_ld_r_r (& dst
, & src
);
2501 else if ((dst
.X_add_number
& ~R_INDEX
) <= 7)
2502 emit_ld_r_n (& dst
, & src
);
2504 emit_ld_rr_nn (& dst
, & src
);
2513 emit_lddldi (char prefix
, char opcode
, const char * args
)
2515 expressionS dst
, src
;
2519 if (!(ins_ok
& INS_GBZ80
))
2520 return emit_insn (prefix
, opcode
, args
);
2522 p
= parse_exp (args
, & dst
);
2524 error (_("bad instruction syntax"));
2525 p
= parse_exp (args
, & src
);
2527 if (dst
.X_op
!= O_register
|| src
.X_op
!= O_register
)
2530 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2531 opcode
= (opcode
& 0x08) * 2 + 0x22;
2534 && dst
.X_add_number
== REG_HL
2536 && src
.X_add_number
== REG_A
)
2537 opcode
|= 0x00; /* LDx (HL),A */
2538 else if (dst
.X_md
== 0
2539 && dst
.X_add_number
== REG_A
2541 && src
.X_add_number
== REG_HL
)
2542 opcode
|= 0x08; /* LDx A,(HL) */
2552 emit_ldh (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2555 expressionS dst
, src
;
2559 p
= parse_exp (args
, & dst
);
2562 error (_("bad instruction syntax"));
2566 p
= parse_exp (p
, & src
);
2568 && dst
.X_op
== O_register
2569 && dst
.X_add_number
== REG_A
2571 && src
.X_op
!= O_md1
2572 && src
.X_op
!= O_register
)
2576 emit_byte (& src
, BFD_RELOC_8
);
2578 else if (dst
.X_md
!= 0
2579 && dst
.X_op
!= O_md1
2581 && src
.X_op
== O_register
2582 && src
.X_add_number
== REG_A
)
2584 if (dst
.X_op
== O_register
)
2586 if (dst
.X_add_number
== REG_C
)
2598 emit_byte (& dst
, BFD_RELOC_8
);
2608 parse_lea_pea_args (const char * args
, expressionS
*op
)
2611 p
= parse_exp (args
, op
);
2612 if (sdcc_compat
&& *p
== ',' && op
->X_op
== O_register
)
2615 p
= parse_exp (p
+ 1, &off
);
2617 op
->X_add_symbol
= make_expr_symbol (&off
);
2623 emit_lea (char prefix
, char opcode
, const char * args
)
2625 expressionS dst
, src
;
2630 p
= parse_exp (args
, & dst
);
2631 if (dst
.X_md
!= 0 || dst
.X_op
!= O_register
)
2634 rnum
= dst
.X_add_number
;
2640 opcode
= 0x02 | ((rnum
& 0x03) << 4);
2643 opcode
= 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2646 opcode
= 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2653 error (_("bad instruction syntax"));
2655 p
= parse_lea_pea_args (p
, & src
);
2656 if (src
.X_md
!= 0 || src
.X_op
!= O_add
/*&& src.X_op != O_register*/)
2659 rnum
= src
.X_add_number
;
2664 case O_register
: /* permit instructions like LEA rr,IX without displacement specified */
2665 src
.X_add_symbol
= zero
;
2674 opcode
= (opcode
== (char)0x33) ? 0x55 : (opcode
|0x00);
2677 opcode
= (opcode
== (char)0x32) ? 0x54 : (opcode
|0x01);
2684 src
.X_op
= O_symbol
;
2685 src
.X_add_number
= 0;
2686 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2692 emit_mlt (char prefix
, char opcode
, const char * args
)
2698 p
= parse_exp (args
, & arg
);
2699 if (arg
.X_md
!= 0 || arg
.X_op
!= O_register
|| !(arg
.X_add_number
& R_ARITH
))
2704 *q
= opcode
| ((arg
.X_add_number
& 3) << 4);
2710 emit_pea (char prefix
, char opcode
, const char * args
)
2716 p
= parse_lea_pea_args (args
, & arg
);
2718 || (/*arg.X_op != O_register &&*/ arg
.X_op
!= O_add
)
2719 || !(arg
.X_add_number
& R_INDEX
))
2721 /* PEA ii without displacement is mostly typo,
2722 because there is PUSH instruction which is shorter and faster */
2723 /*if (arg.X_op == O_register)
2724 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
2728 *q
= opcode
+ (arg
.X_add_number
== REG_IY
? 1 : 0);
2730 arg
.X_op
= O_symbol
;
2731 arg
.X_add_number
= 0;
2732 emit_byte (& arg
, BFD_RELOC_Z80_DISP8
);
2738 emit_reti (char prefix
, char opcode
, const char * args
)
2740 if (ins_ok
& INS_GBZ80
)
2741 return emit_insn (0x00, 0xD9, args
);
2743 return emit_insn (prefix
, opcode
, args
);
2747 emit_tst (char prefix
, char opcode
, const char *args
)
2754 p
= parse_exp (args
, & arg_s
);
2755 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
2757 if (!(ins_ok
& INS_EZ80
))
2760 p
= parse_exp (p
, & arg_s
);
2763 rnum
= arg_s
.X_add_number
;
2770 rnum
= arg_s
.X_add_number
;
2771 if (arg_s
.X_md
!= 0)
2780 *q
= opcode
| (rnum
<< 3);
2788 emit_byte (& arg_s
, BFD_RELOC_8
);
2794 emit_tstio (char prefix
, char opcode
, const char *args
)
2800 p
= parse_exp (args
, & arg
);
2801 if (arg
.X_md
|| arg
.X_op
== O_register
|| arg
.X_op
== O_md1
)
2807 emit_byte (& arg
, BFD_RELOC_8
);
2813 emit_data (int size ATTRIBUTE_UNUSED
)
2820 if (is_it_end_of_statement ())
2822 demand_empty_rest_of_line ();
2825 p
= skip_space (input_line_pointer
);
2829 if (*p
== '\"' || *p
== '\'')
2831 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
2833 u
= frag_more (cnt
);
2836 as_warn (_("unterminated string"));
2838 p
= skip_space (p
+1);
2842 p
= parse_exp (p
, &exp
);
2843 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
2849 as_warn (_("parentheses ignored"));
2850 emit_byte (&exp
, BFD_RELOC_8
);
2854 while (*p
++ == ',') ;
2855 input_line_pointer
= (char *)(p
-1);
2864 if (is_it_end_of_statement ())
2866 demand_empty_rest_of_line ();
2869 p
= skip_space (input_line_pointer
);
2873 p
= parse_exp (p
, &exp
);
2874 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
2880 as_warn (_("parentheses ignored"));
2881 emit_data_val (&exp
, size
);
2883 } while (*p
++ == ',') ;
2884 input_line_pointer
= (char *)(p
-1);
2887 /* next functions were commented out because it is difficult to mix
2888 both ADL and Z80 mode instructions within one COFF file:
2889 objdump cannot recognize point of mode switching.
2892 set_cpu_mode (int mode
)
2894 if (ins_ok
& INS_EZ80
)
2897 error (_("CPU mode is unsupported by target"));
2901 assume (int arg ATTRIBUTE_UNUSED
)
2907 input_line_pointer
= (char*)skip_space (input_line_pointer
);
2908 c
= get_symbol_name (& name
);
2909 if (strncasecmp (name
, "ADL", 4) != 0)
2915 restore_line_pointer (c
);
2916 input_line_pointer
= (char*)skip_space (input_line_pointer
);
2917 if (*input_line_pointer
++ != '=')
2919 error (_("assignment expected"));
2922 input_line_pointer
= (char*)skip_space (input_line_pointer
);
2923 n
= get_single_number ();
2929 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2933 p
= skip_space (args
);
2934 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
2940 reg
= TOLOWER (*p
++);
2947 check_mach (INS_R800
);
2948 if (!*skip_space (p
))
2952 *q
= opcode
+ ((reg
- 'b') << 3);
2964 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2968 p
= skip_space (args
);
2969 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
2976 p
= parse_exp (p
, & reg
);
2978 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
2979 switch (reg
.X_add_number
)
2983 check_mach (INS_R800
);
2986 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
2996 assemble_suffix (const char **suffix
)
2999 const char sf
[8][4] =
3019 for (i
= 0; (i
< 3) && (ISALPHA (*p
)); i
++)
3020 sbuf
[i
] = TOLOWER (*p
++);
3021 if (*p
&& !ISSPACE (*p
))
3026 t
= bsearch (sbuf
, sf
, ARRAY_SIZE (sf
), sizeof (sf
[0]), (int(*)(const void*, const void*)) strcmp
);
3033 i
= cpu_mode
? 0x5B : 0x52;
3036 i
= cpu_mode
? 0x49 : 0x40;
3039 i
= cpu_mode
? 0x5B : 0x49;
3048 i
= cpu_mode
? 0x52 : 0x40;
3057 *frag_more (1) = (char)i
;
3060 case 0x40: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IS
; break;
3061 case 0x49: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IS
; break;
3062 case 0x52: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IL
; break;
3063 case 0x5B: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IL
; break;
3071 #if defined(OBJ_ELF)
3072 return obj_elf_section (arg
);
3073 #elif defined(OBJ_COFF)
3074 return obj_coff_section (arg
);
3076 #error Unknown object format
3086 as_fatal (_("Invalid directive"));
3089 ins_ok
&= INS_MARCH_MASK
;
3091 if (old_ins
!= ins_ok
)
3096 ignore (int arg ATTRIBUTE_UNUSED
)
3098 ignore_rest_of_line ();
3106 as_fatal (_("Invalid directive"));
3107 for (p
= input_line_pointer
; *p
&& *p
!= '(' && *p
!= '\n'; p
++)
3114 ignore_rest_of_line ();
3120 /* Port specific pseudo ops. */
3121 const pseudo_typeS md_pseudo_table
[] =
3123 { ".area", area
, 0},
3124 { ".assume", assume
, 0},
3125 { ".ez80", set_inss
, INS_EZ80
},
3126 { ".gbz80", set_inss
, INS_GBZ80
},
3127 { ".module", ignore
, 0},
3128 { ".optsdcc", ignore
, 0},
3129 { ".r800", set_inss
, INS_R800
},
3130 { ".set", s_set
, 0},
3131 { ".z180", set_inss
, INS_Z180
},
3132 { ".z80", set_inss
, INS_Z80
},
3133 { "db" , emit_data
, 1},
3134 { "d24", z80_cons
, 3},
3135 { "d32", z80_cons
, 4},
3136 { "def24", z80_cons
, 3},
3137 { "def32", z80_cons
, 4},
3138 { "defb", emit_data
, 1},
3139 { "defm", emit_data
, 1},
3140 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
3141 { "defw", z80_cons
, 2},
3142 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
3143 { "dw", z80_cons
, 2},
3144 { "psect", psect
, 0}, /* TODO: Translate attributes. */
3145 { "set", 0, 0}, /* Real instruction on z80. */
3149 static table_t instab
[] =
3151 { "adc", 0x88, 0x4A, emit_adc
, INS_ALL
},
3152 { "add", 0x80, 0x09, emit_add
, INS_ALL
},
3153 { "and", 0x00, 0xA0, emit_s
, INS_ALL
},
3154 { "bit", 0xCB, 0x40, emit_bit
, INS_ALL
},
3155 { "call", 0xCD, 0xC4, emit_jpcc
, INS_ALL
},
3156 { "ccf", 0x00, 0x3F, emit_insn
, INS_ALL
},
3157 { "cp", 0x00, 0xB8, emit_s
, INS_ALL
},
3158 { "cpd", 0xED, 0xA9, emit_insn
, INS_NOT_GBZ80
},
3159 { "cpdr", 0xED, 0xB9, emit_insn
, INS_NOT_GBZ80
},
3160 { "cpi", 0xED, 0xA1, emit_insn
, INS_NOT_GBZ80
},
3161 { "cpir", 0xED, 0xB1, emit_insn
, INS_NOT_GBZ80
},
3162 { "cpl", 0x00, 0x2F, emit_insn
, INS_ALL
},
3163 { "daa", 0x00, 0x27, emit_insn
, INS_ALL
},
3164 { "dec", 0x0B, 0x05, emit_incdec
,INS_ALL
},
3165 { "di", 0x00, 0xF3, emit_insn
, INS_ALL
},
3166 { "djnz", 0x00, 0x10, emit_jr
, INS_NOT_GBZ80
},
3167 { "ei", 0x00, 0xFB, emit_insn
, INS_ALL
},
3168 { "ex", 0x00, 0x00, emit_ex
, INS_NOT_GBZ80
},
3169 { "exx", 0x00, 0xD9, emit_insn
, INS_NOT_GBZ80
},
3170 { "halt", 0x00, 0x76, emit_insn
, INS_ALL
},
3171 { "im", 0xED, 0x46, emit_im
, INS_NOT_GBZ80
},
3172 { "in", 0x00, 0x00, emit_in
, INS_NOT_GBZ80
},
3173 { "in0", 0xED, 0x00, emit_in0
, INS_Z180
|INS_EZ80
},
3174 { "inc", 0x03, 0x04, emit_incdec
,INS_ALL
},
3175 { "ind", 0xED, 0xAA, emit_insn
, INS_NOT_GBZ80
},
3176 { "ind2", 0xED, 0x8C, emit_insn
, INS_EZ80
},
3177 { "ind2r",0xED, 0x9C, emit_insn
, INS_EZ80
},
3178 { "indm", 0xED, 0x8A, emit_insn
, INS_EZ80
},
3179 { "indmr",0xED, 0x9A, emit_insn
, INS_EZ80
},
3180 { "indr", 0xED, 0xBA, emit_insn
, INS_NOT_GBZ80
},
3181 { "indrx",0xED, 0xCA, emit_insn
, INS_EZ80
},
3182 { "ini", 0xED, 0xA2, emit_insn
, INS_NOT_GBZ80
},
3183 { "ini2", 0xED, 0x84, emit_insn
, INS_EZ80
},
3184 { "ini2r",0xED, 0x94, emit_insn
, INS_EZ80
},
3185 { "inim", 0xED, 0x82, emit_insn
, INS_EZ80
},
3186 { "inimr",0xED, 0x92, emit_insn
, INS_EZ80
},
3187 { "inir", 0xED, 0xB2, emit_insn
, INS_NOT_GBZ80
},
3188 { "inirx",0xED, 0xC2, emit_insn
, INS_EZ80
},
3189 { "jp", 0xC3, 0xC2, emit_jpcc
, INS_ALL
},
3190 { "jr", 0x18, 0x20, emit_jrcc
, INS_ALL
},
3191 { "ld", 0x00, 0x00, emit_ld
, INS_ALL
},
3192 { "ldd", 0xED, 0xA8, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3193 { "lddr", 0xED, 0xB8, emit_insn
, INS_NOT_GBZ80
},
3194 { "ldh", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3195 { "ldhl", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3196 { "ldi", 0xED, 0xA0, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3197 { "ldir", 0xED, 0xB0, emit_insn
, INS_NOT_GBZ80
},
3198 { "lea", 0xED, 0x02, emit_lea
, INS_EZ80
},
3199 { "mlt", 0xED, 0x4C, emit_mlt
, INS_Z180
|INS_EZ80
},
3200 { "mulub",0xED, 0xC5, emit_mulub
,INS_R800
},
3201 { "muluw",0xED, 0xC3, emit_muluw
,INS_R800
},
3202 { "neg", 0xed, 0x44, emit_insn
, INS_NOT_GBZ80
},
3203 { "nop", 0x00, 0x00, emit_insn
, INS_ALL
},
3204 { "or", 0x00, 0xB0, emit_s
, INS_ALL
},
3205 { "otd2r",0xED, 0xBC, emit_insn
, INS_EZ80
},
3206 { "otdm", 0xED, 0x8B, emit_insn
, INS_Z180
|INS_EZ80
},
3207 { "otdmr",0xED, 0x9B, emit_insn
, INS_Z180
|INS_EZ80
},
3208 { "otdr", 0xED, 0xBB, emit_insn
, INS_NOT_GBZ80
},
3209 { "otdrx",0xED, 0xCB, emit_insn
, INS_EZ80
},
3210 { "oti2r",0xED, 0xB4, emit_insn
, INS_EZ80
},
3211 { "otim", 0xED, 0x83, emit_insn
, INS_Z180
|INS_EZ80
},
3212 { "otimr",0xED, 0x93, emit_insn
, INS_Z180
|INS_EZ80
},
3213 { "otir", 0xED, 0xB3, emit_insn
, INS_NOT_GBZ80
},
3214 { "otirx",0xED, 0xC3, emit_insn
, INS_EZ80
},
3215 { "out", 0x00, 0x00, emit_out
, INS_NOT_GBZ80
},
3216 { "out0", 0xED, 0x01, emit_out0
, INS_Z180
|INS_EZ80
},
3217 { "outd", 0xED, 0xAB, emit_insn
, INS_NOT_GBZ80
},
3218 { "outd2",0xED, 0xAC, emit_insn
, INS_EZ80
},
3219 { "outi", 0xED, 0xA3, emit_insn
, INS_NOT_GBZ80
},
3220 { "outi2",0xED, 0xA4, emit_insn
, INS_EZ80
},
3221 { "pea", 0xED, 0x65, emit_pea
, INS_EZ80
},
3222 { "pop", 0x00, 0xC1, emit_pop
, INS_ALL
},
3223 { "push", 0x00, 0xC5, emit_pop
, INS_ALL
},
3224 { "res", 0xCB, 0x80, emit_bit
, INS_ALL
},
3225 { "ret", 0xC9, 0xC0, emit_retcc
,INS_ALL
},
3226 { "reti", 0xED, 0x4D, emit_reti
, INS_ALL
}, /*GBZ80 has its own opcode for it*/
3227 { "retn", 0xED, 0x45, emit_insn
, INS_NOT_GBZ80
},
3228 { "rl", 0xCB, 0x10, emit_mr
, INS_ALL
},
3229 { "rla", 0x00, 0x17, emit_insn
, INS_ALL
},
3230 { "rlc", 0xCB, 0x00, emit_mr
, INS_ALL
},
3231 { "rlca", 0x00, 0x07, emit_insn
, INS_ALL
},
3232 { "rld", 0xED, 0x6F, emit_insn
, INS_NOT_GBZ80
},
3233 { "rr", 0xCB, 0x18, emit_mr
, INS_ALL
},
3234 { "rra", 0x00, 0x1F, emit_insn
, INS_ALL
},
3235 { "rrc", 0xCB, 0x08, emit_mr
, INS_ALL
},
3236 { "rrca", 0x00, 0x0F, emit_insn
, INS_ALL
},
3237 { "rrd", 0xED, 0x67, emit_insn
, INS_NOT_GBZ80
},
3238 { "rsmix",0xED, 0x7E, emit_insn
, INS_EZ80
},
3239 { "rst", 0x00, 0xC7, emit_rst
, INS_ALL
},
3240 { "sbc", 0x98, 0x42, emit_adc
, INS_ALL
},
3241 { "scf", 0x00, 0x37, emit_insn
, INS_ALL
},
3242 { "set", 0xCB, 0xC0, emit_bit
, INS_ALL
},
3243 { "sla", 0xCB, 0x20, emit_mr
, INS_ALL
},
3244 { "sli", 0xCB, 0x30, emit_mr
, INS_SLI
},
3245 { "sll", 0xCB, 0x30, emit_mr
, INS_SLI
},
3246 { "slp", 0xED, 0x76, emit_insn
, INS_Z180
|INS_EZ80
},
3247 { "sra", 0xCB, 0x28, emit_mr
, INS_ALL
},
3248 { "srl", 0xCB, 0x38, emit_mr
, INS_ALL
},
3249 { "stmix",0xED, 0x7D, emit_insn
, INS_EZ80
},
3250 { "stop", 0x00, 0x10, emit_insn
, INS_GBZ80
},
3251 { "sub", 0x00, 0x90, emit_s
, INS_ALL
},
3252 { "swap", 0xCB, 0x30, emit_mr
, INS_GBZ80
},
3253 { "tst", 0xED, 0x04, emit_tst
, INS_Z180
|INS_EZ80
},
3254 { "tstio",0xED, 0x74, emit_tstio
,INS_Z180
|INS_EZ80
},
3255 { "xor", 0x00, 0xA8, emit_s
, INS_ALL
},
3259 md_assemble (char *str
)
3267 inst_mode
= cpu_mode
? (INST_MODE_L
| INST_MODE_IL
) : (INST_MODE_S
| INST_MODE_IS
);
3268 old_ptr
= input_line_pointer
;
3269 p
= skip_space (str
);
3270 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
) || ISDIGIT (*p
));)
3271 buf
[i
++] = TOLOWER (*p
++);
3275 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
3277 as_bad (_("Unknown instruction '%s'"), buf
);
3281 dwarf2_emit_insn (0);
3282 if ((*p
) && (!ISSPACE (*p
)))
3284 if (*p
!= '.' || !(ins_ok
& INS_EZ80
) || !assemble_suffix (&p
))
3286 as_bad (_("syntax error"));
3294 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
3295 sizeof (instab
[0]), key_cmp
);
3296 if (!insp
|| (insp
->inss
&& !(insp
->inss
& ins_ok
)))
3298 as_bad (_("Unknown instruction '%s'"), buf
);
3303 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
3305 if ((!err_flag
) && *p
)
3306 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
3311 input_line_pointer
= old_ptr
;
3315 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
3317 long val
= * (long *) valP
;
3318 char *p_lit
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3320 switch (fixP
->fx_r_type
)
3322 case BFD_RELOC_8_PCREL
:
3325 fixP
->fx_no_overflow
= 1;
3330 fixP
->fx_no_overflow
= (-128 <= val
&& val
< 128);
3331 if (!fixP
->fx_no_overflow
)
3332 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3333 _("relative jump out of range"));
3339 case BFD_RELOC_Z80_DISP8
:
3342 fixP
->fx_no_overflow
= 1;
3347 fixP
->fx_no_overflow
= (-128 <= val
&& val
< 128);
3348 if (!fixP
->fx_no_overflow
)
3349 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3350 _("index offset out of range"));
3356 case BFD_RELOC_Z80_BYTE0
:
3358 fixP
->fx_no_overflow
= 1;
3359 if (fixP
->fx_addsy
== NULL
)
3363 case BFD_RELOC_Z80_BYTE1
:
3364 *p_lit
++ = (val
>> 8);
3365 fixP
->fx_no_overflow
= 1;
3366 if (fixP
->fx_addsy
== NULL
)
3370 case BFD_RELOC_Z80_BYTE2
:
3371 *p_lit
++ = (val
>> 16);
3372 fixP
->fx_no_overflow
= 1;
3373 if (fixP
->fx_addsy
== NULL
)
3377 case BFD_RELOC_Z80_BYTE3
:
3378 *p_lit
++ = (val
>> 24);
3379 fixP
->fx_no_overflow
= 1;
3380 if (fixP
->fx_addsy
== NULL
)
3385 if (val
> 255 || val
< -128)
3386 as_warn_where (fixP
->fx_file
, fixP
->fx_line
, _("overflow"));
3388 fixP
->fx_no_overflow
= 1;
3389 if (fixP
->fx_addsy
== NULL
)
3393 case BFD_RELOC_Z80_WORD1
:
3394 *p_lit
++ = (val
>> 16);
3395 *p_lit
++ = (val
>> 24);
3396 fixP
->fx_no_overflow
= 1;
3397 if (fixP
->fx_addsy
== NULL
)
3401 case BFD_RELOC_Z80_WORD0
:
3404 *p_lit
++ = (val
>> 8);
3405 fixP
->fx_no_overflow
= 1;
3406 if (fixP
->fx_addsy
== NULL
)
3410 case BFD_RELOC_24
: /* Def24 may produce this. */
3412 *p_lit
++ = (val
>> 8);
3413 *p_lit
++ = (val
>> 16);
3414 fixP
->fx_no_overflow
= 1;
3415 if (fixP
->fx_addsy
== NULL
)
3419 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
3421 *p_lit
++ = (val
>> 8);
3422 *p_lit
++ = (val
>> 16);
3423 *p_lit
++ = (val
>> 24);
3424 if (fixP
->fx_addsy
== NULL
)
3429 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP
->fx_r_type
);
3434 /* GAS will call this to generate a reloc. GAS will pass the
3435 resulting reloc to `bfd_install_relocation'. This currently works
3436 poorly, as `bfd_install_relocation' often does the wrong thing, and
3437 instances of `tc_gen_reloc' have been written to work around the
3438 problems, which in turns makes it difficult to fix
3439 `bfd_install_relocation'. */
3441 /* If while processing a fixup, a reloc really
3442 needs to be created then it is done here. */
3445 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
3449 if (! bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
))
3451 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3452 _("reloc %d not supported by object file format"),
3453 (int) fixp
->fx_r_type
);
3457 reloc
= XNEW (arelent
);
3458 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3459 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3460 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3461 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3462 reloc
->addend
= fixp
->fx_offset
;
3468 z80_tc_label_is_local (const char *name
)
3472 if (local_label_prefix
== NULL
)
3474 for (p
= local_label_prefix
, n
= name
; *p
&& *n
&& *n
== *p
; p
++, n
++)
3479 /* Parse floating point number from string and compute mantissa and
3480 exponent. Mantissa is normalized.
3482 #define EXP_MIN -0x10000
3483 #define EXP_MAX 0x10000
3485 str_to_broken_float (bfd_boolean
*signP
, bfd_uint64_t
*mantissaP
, int *expP
)
3489 bfd_uint64_t mantissa
= 0;
3493 p
= (char*)skip_space (input_line_pointer
);
3496 if (sign
|| *p
== '+')
3498 if (strncasecmp (p
, "NaN", 3) == 0)
3502 input_line_pointer
= p
+ 3;
3505 if (strncasecmp (p
, "inf", 3) == 0)
3507 *mantissaP
= 1ull << 63;
3509 input_line_pointer
= p
+ 3;
3512 for (; ISDIGIT (*p
); ++p
)
3520 mantissa
= mantissa
* 10 + (*p
- '0');
3522 /* skip non-significant digits */
3523 for (; ISDIGIT (*p
); ++p
)
3529 if (!exponent
) /* If no precission overflow. */
3531 for (; ISDIGIT (*p
); ++p
, --exponent
)
3539 mantissa
= mantissa
* 10 + (*p
- '0');
3542 for (; ISDIGIT (*p
); ++p
)
3545 if (*p
== 'e' || *p
== 'E')
3551 if (es
|| *p
== '+')
3553 for (; ISDIGIT (*p
); ++p
)
3556 t
= t
* 10 + (*p
- '0');
3558 exponent
+= (es
) ? -t
: t
;
3560 if (ISALNUM (*p
) || *p
== '.')
3562 input_line_pointer
= p
;
3565 *mantissaP
= 1ull << 63;
3567 return 1; /* result is 0 */
3570 for (; mantissa
<= ~0ull/10; --exponent
)
3572 /* Now we have sign, mantissa, and signed decimal exponent
3573 need to recompute to binary exponent. */
3574 for (i
= 64; exponent
> 0; --exponent
)
3576 /* be sure that no integer overflow */
3577 while (mantissa
> ~0ull/10)
3584 for (; exponent
< 0; ++exponent
)
3586 while (!(mantissa
>> 63))
3594 for (; !(mantissa
>> 63); --i
)
3596 *mantissaP
= mantissa
;
3602 str_to_zeda32(char *litP
, int *sizeP
)
3604 bfd_uint64_t mantissa
;
3610 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
3611 return _("invalid syntax");
3612 /* I do not know why decrement is needed */
3614 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
3618 /* make 24 bit mantissa */
3620 /* check for overflow */
3627 if (exponent
< -127)
3632 else if (exponent
> 127)
3635 mantissa
= sign
? 0xc00000 : 0x400000;
3637 else if (mantissa
== 0)
3640 mantissa
= 0x200000;
3643 mantissa
&= (1ull << 23) - 1;
3644 for (i
= 0; i
< 24; i
+= 8)
3645 *litP
++ = (char)(mantissa
>> i
);
3646 *litP
= (char)(0x80 + exponent
);
3651 Math48 by Anders Hejlsberg support.
3652 Mantissa is 39 bits wide, exponent 8 bit wide.
3655 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
3656 bit 7-0: exponent+128 (0 - value is null)
3657 MIN: 2.938735877e-39
3658 MAX: 1.701411835e+38
3661 str_to_float48(char *litP
, int *sizeP
)
3663 bfd_uint64_t mantissa
;
3669 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
3670 return _("invalid syntax");
3671 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
3675 /* make 40 bit mantissa */
3677 /* check for overflow */
3683 if (exponent
< -127)
3685 memset (litP
, 0, 6);
3689 return _("overflow");
3691 mantissa
&= (1ull << 39) - 1;
3692 *litP
++ = (char)(0x80 + exponent
);
3693 for (i
= 0; i
< 40; i
+= 8)
3694 *litP
++ = (char)(mantissa
>> i
);
3699 str_to_ieee754_h(char *litP
, int *sizeP
)
3701 return ieee_md_atof ('h', litP
, sizeP
, FALSE
);
3705 str_to_ieee754_s(char *litP
, int *sizeP
)
3707 return ieee_md_atof ('s', litP
, sizeP
, FALSE
);
3711 str_to_ieee754_d(char *litP
, int *sizeP
)
3713 return ieee_md_atof ('d', litP
, sizeP
, FALSE
);