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"
27 /* Exported constants. */
28 const char comment_chars
[] = ";\0";
29 const char line_comment_chars
[] = "#;\0";
30 const char line_separator_chars
[] = "\0";
31 const char EXP_CHARS
[] = "eE\0";
32 const char FLT_CHARS
[] = "RrFf\0";
34 /* For machine specific options. */
35 const char * md_shortopts
= ""; /* None yet. */
39 OPTION_MACH_Z80
= OPTION_MD_BASE
,
55 OPTION_COMPAT_LL_PREFIX
,
56 OPTION_COMPAT_COLONLESS
,
60 #define INS_Z80 (1 << 0)
61 #define INS_R800 (1 << 1)
62 #define INS_GBZ80 (1 << 2)
63 #define INS_Z180 (1 << 3)
64 #define INS_EZ80 (1 << 4)
65 #define INS_MARCH_MASK 0xffff
67 #define INS_IDX_HALF (1 << 16)
68 #define INS_IN_F_C (1 << 17)
69 #define INS_OUT_C_0 (1 << 18)
70 #define INS_SLI (1 << 19)
71 #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 */
72 #define INS_TUNE_MASK 0xffff0000
74 #define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80)
77 #define INS_UNDOC (INS_IDX_HALF | INS_IN_F_C)
78 #define INS_UNPORT (INS_OUT_C_0 | INS_SLI | INS_ROT_II_LD)
80 struct option md_longopts
[] =
82 { "z80", no_argument
, NULL
, OPTION_MACH_Z80
},
83 { "r800", no_argument
, NULL
, OPTION_MACH_R800
},
84 { "z180", no_argument
, NULL
, OPTION_MACH_Z180
},
85 { "ez80", no_argument
, NULL
, OPTION_MACH_EZ80_Z80
},
86 { "ez80-adl", no_argument
, NULL
, OPTION_MACH_EZ80_ADL
},
87 { "float", required_argument
, NULL
, OPTION_FLOAT_FORMAT
},
88 { "double", required_argument
, NULL
, OPTION_DOUBLE_FORMAT
},
89 { "strict", no_argument
, NULL
, OPTION_MACH_FUD
},
90 { "full", no_argument
, NULL
, OPTION_MACH_IUP
},
91 { "with-inst", required_argument
, NULL
, OPTION_MACH_INST
},
92 { "Wnins", required_argument
, NULL
, OPTION_MACH_INST
},
93 { "without-inst", required_argument
, NULL
, OPTION_MACH_NO_INST
},
94 { "local-prefix", required_argument
, NULL
, OPTION_COMPAT_LL_PREFIX
},
95 { "colonless", no_argument
, NULL
, OPTION_COMPAT_COLONLESS
},
96 { "sdcc", no_argument
, NULL
, OPTION_COMPAT_SDCC
},
97 { "Fins", required_argument
, NULL
, OPTION_MACH_NO_INST
},
98 { "ignore-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_IUD
},
99 { "Wnud", no_argument
, NULL
, OPTION_MACH_IUD
},
100 { "warn-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_WUD
},
101 { "Wud", no_argument
, NULL
, OPTION_MACH_WUD
},
102 { "forbid-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_FUD
},
103 { "Fud", no_argument
, NULL
, OPTION_MACH_FUD
},
104 { "ignore-unportable-instructions", no_argument
, NULL
, OPTION_MACH_IUP
},
105 { "Wnup", no_argument
, NULL
, OPTION_MACH_IUP
},
106 { "warn-unportable-instructions", no_argument
, NULL
, OPTION_MACH_WUP
},
107 { "Wup", no_argument
, NULL
, OPTION_MACH_WUP
},
108 { "forbid-unportable-instructions", no_argument
, NULL
, OPTION_MACH_FUP
},
109 { "Fup", no_argument
, NULL
, OPTION_MACH_FUP
},
111 { NULL
, no_argument
, NULL
, 0 }
114 size_t md_longopts_size
= sizeof (md_longopts
);
116 extern int coff_flags
;
117 /* Instruction classes that silently assembled. */
118 static int ins_ok
= INS_Z80
| INS_UNDOC
;
119 /* Instruction classes that generate errors. */
120 static int ins_err
= ~(INS_Z80
| INS_UNDOC
);
121 /* eZ80 CPU mode (ADL or Z80) */
122 static int cpu_mode
= 0; /* 0 - Z80, 1 - ADL */
123 /* accept SDCC specific instruction encoding */
124 static int sdcc_compat
= 0;
125 /* accept colonless labels */
126 static int colonless_labels
= 0;
127 /* local label prefix (NULL - default) */
128 static const char *local_label_prefix
= NULL
;
129 /* floating point support */
130 typedef const char *(*str_to_float_t
)(char *litP
, int *sizeP
);
131 static str_to_float_t str_to_float
;
132 static str_to_float_t str_to_double
;
134 /* mode of current instruction */
135 #define INST_MODE_S 0 /* short data mode */
136 #define INST_MODE_IS 0 /* short instruction mode */
137 #define INST_MODE_L 2 /* long data mode */
138 #define INST_MODE_IL 1 /* long instruction mode */
139 #define INST_MODE_FORCED 4 /* CPU mode changed by instruction suffix*/
140 static char inst_mode
;
143 setup_instruction (const char *inst
, int *add
, int *sub
)
146 if (!strcmp (inst
, "idx-reg-halves"))
148 else if (!strcmp (inst
, "sli"))
150 else if (!strcmp (inst
, "op-ii-ld"))
152 else if (!strcmp (inst
, "in-f-c"))
154 else if (!strcmp (inst
, "out-c-0"))
164 str_to_zeda32 (char *litP
, int *sizeP
);
166 str_to_float48 (char *litP
, int *sizeP
);
168 static str_to_float_t
169 get_str_to_float (const char *arg
)
171 if (strcasecmp (arg
, "zeda32") == 0)
172 return str_to_zeda32
;
174 if (strcasecmp (arg
, "math48") == 0)
175 return str_to_float48
;
177 if (strcasecmp (arg
, "ieee754") != 0)
178 as_fatal (_("invalid floating point numbers type `%s'"), arg
);
183 setup_instruction_list (const char *list
, int *add
, int *sub
)
190 for (b
= list
; *b
!= '\0';)
197 if (sz
== 0 || sz
>= (int)sizeof (buf
))
199 as_bad (_("invalid INST in command line: %s"), b
);
204 if (setup_instruction (buf
, add
, sub
))
208 as_bad (_("invalid INST in command line: %s"), buf
);
219 md_parse_option (int c
, const char* arg
)
225 case OPTION_MACH_Z80
:
226 ins_ok
= (ins_ok
& INS_TUNE_MASK
) | INS_Z80
;
227 ins_err
= (ins_err
& INS_MARCH_MASK
) | (~INS_Z80
& INS_MARCH_MASK
);
229 case OPTION_MACH_R800
:
230 ins_ok
= INS_R800
| INS_IDX_HALF
;
231 ins_err
= INS_UNPORT
;
233 case OPTION_MACH_Z180
:
235 ins_err
= INS_UNDOC
| INS_UNPORT
;
237 case OPTION_MACH_EZ80_Z80
:
239 ins_err
= (INS_UNDOC
| INS_UNPORT
) & ~INS_IDX_HALF
;
242 case OPTION_MACH_EZ80_ADL
:
244 ins_err
= (INS_UNDOC
| INS_UNPORT
) & ~INS_IDX_HALF
;
247 case OPTION_MACH_GBZ80
:
249 ins_err
= INS_UNDOC
| INS_UNPORT
;
251 case OPTION_FLOAT_FORMAT
:
252 str_to_float
= get_str_to_float (arg
);
254 case OPTION_DOUBLE_FORMAT
:
255 str_to_double
= get_str_to_float (arg
);
257 case OPTION_MACH_INST
:
258 if ((ins_ok
& INS_GBZ80
) == 0)
259 return setup_instruction_list (arg
, & ins_ok
, & ins_err
);
261 case OPTION_MACH_NO_INST
:
262 if ((ins_ok
& INS_GBZ80
) == 0)
263 return setup_instruction_list (arg
, & ins_err
, & ins_ok
);
265 case OPTION_MACH_WUD
:
266 case OPTION_MACH_IUD
:
267 if ((ins_ok
& INS_GBZ80
) == 0)
270 ins_err
&= ~INS_UNDOC
;
273 case OPTION_MACH_WUP
:
274 case OPTION_MACH_IUP
:
275 if ((ins_ok
& INS_GBZ80
) == 0)
277 ins_ok
|= INS_UNDOC
| INS_UNPORT
;
278 ins_err
&= ~(INS_UNDOC
| INS_UNPORT
);
281 case OPTION_MACH_FUD
:
282 if ((ins_ok
& (INS_R800
| INS_GBZ80
)) == 0)
284 ins_ok
&= (INS_UNDOC
| INS_UNPORT
);
285 ins_err
|= INS_UNDOC
| INS_UNPORT
;
288 case OPTION_MACH_FUP
:
289 ins_ok
&= ~INS_UNPORT
;
290 ins_err
|= INS_UNPORT
;
292 case OPTION_COMPAT_LL_PREFIX
:
293 local_label_prefix
= (arg
&& *arg
) ? arg
: NULL
;
295 case OPTION_COMPAT_SDCC
:
297 local_label_prefix
= "_";
299 case OPTION_COMPAT_COLONLESS
:
300 colonless_labels
= 1;
308 md_show_usage (FILE * f
)
311 CPU model options:\n\
312 -z80\t\t\t assemble for Z80\n\
313 -r800\t\t\t assemble for R800\n\
314 -z180\t\t\t assemble for Z180\n\
315 -ez80\t\t\t assemble for eZ80 in Z80 mode by default\n\
316 -ez80-adl\t\t assemble for eZ80 in ADL mode by default\n\
318 Compatibility options:\n\
319 -local-prefix=TEXT\t treat labels prefixed by TEXT as local\n\
320 -colonless\t\t permit colonless labels\n\
321 -sdcc\t\t\t accept SDCC specific instruction syntax\n\
322 -float=FORMAT\t\t set floating point numbers format\n\
323 -double=FORMAT\t\t set floating point numbers format\n\
324 Where FORMAT one of:\n\
325 ieee754\t\t IEEE754 compatible\n\
326 zeda32\t\t\t Zeda z80float library 32 bit format\n\
327 math48\t\t 48 bit format from Math48 library\n\
329 Support for known undocumented instructions:\n\
330 -strict\t\t assemble only documented instructions\n\
331 -full\t\t\t assemble all undocumented instructions\n\
332 -with-inst=INST[,...]\n\
333 -Wnins INST[,...]\t assemble specified instruction(s)\n\
334 -without-inst=INST[,...]\n\
335 -Fins INST[,...]\t do not assemble specified instruction(s)\n\
336 Where INST is one of:\n\
337 idx-reg-halves\t instructions with halves of index registers\n\
338 sli\t\t\t instruction SLI/SLL\n\
339 op-ii-ld\t\t instructions like SLA (II+dd),R (opcodes DD/FD CB dd xx)\n\
340 in-f-c\t\t instruction IN F,(C)\n\
341 out-c-0\t\t instruction OUT (C),0\n\
344 -ignore-undocumented-instructions\n\
345 -Wnud\t\t\t silently assemble undocumented Z80-instructions that work on R800\n\
346 -ignore-unportable-instructions\n\
347 -Wnup\t\t\t silently assemble all undocumented Z80-instructions\n\
348 -warn-undocumented-instructions\n\
349 -Wud\t\t\t issue warnings for undocumented Z80-instructions that work on R800\n\
350 -warn-unportable-instructions\n\
351 -Wup\t\t\t issue warnings for other undocumented Z80-instructions\n\
352 -forbid-undocumented-instructions\n\
353 -Fud\t\t\t treat all undocumented Z80-instructions as errors\n\
354 -forbid-unportable-instructions\n\
355 -Fup\t\t\t treat undocumented Z80-instructions that do not work on R800 as errors\n\
357 Default: -z80 -ignore-undocumented-instructions -warn-unportable-instructions.\n");
360 static symbolS
* zero
;
367 #define R_STACKABLE (0x80)
368 #define R_ARITH (0x40)
371 #define R_INDEX (R_IX | R_IY)
380 #define REG_F (6 | 8)
385 #define REG_AF (3 | R_STACKABLE)
386 #define REG_BC (0 | R_STACKABLE | R_ARITH)
387 #define REG_DE (1 | R_STACKABLE | R_ARITH)
388 #define REG_HL (2 | R_STACKABLE | R_ARITH)
389 #define REG_IX (REG_HL | R_IX)
390 #define REG_IY (REG_HL | R_IY)
391 #define REG_SP (3 | R_ARITH)
393 static const struct reg_entry regtable
[] =
408 {"ixh",REG_H
| R_IX
},
409 {"ixl",REG_L
| R_IX
},
411 {"iyh",REG_H
| R_IY
},
412 {"iyl",REG_L
| R_IY
},
419 #define BUFLEN 8 /* Large enough for any keyword. */
424 expressionS nul
, reg
;
426 unsigned int i
, j
, k
;
429 if (ins_ok
& INS_EZ80
) /* if select EZ80 cpu then */
430 listing_lhs_width
= 6; /* use 6 bytes per line in the listing */
432 reg
.X_op
= O_register
;
434 reg
.X_add_symbol
= reg
.X_op_symbol
= 0;
435 for ( i
= 0 ; i
< ARRAY_SIZE ( regtable
) ; ++i
)
437 reg
.X_add_number
= regtable
[i
].number
;
438 k
= strlen ( regtable
[i
].name
);
442 for ( j
= ( 1<<k
) ; j
; --j
)
444 for ( k
= 0 ; regtable
[i
].name
[k
] ; ++k
)
446 buf
[k
] = ( j
& ( 1<<k
) ) ? TOUPPER (regtable
[i
].name
[k
]) : regtable
[i
].name
[k
];
448 symbolS
* psym
= symbol_find_or_make (buf
);
449 S_SET_SEGMENT (psym
, reg_section
);
450 symbol_set_value_expression (psym
, ®
);
454 p
= input_line_pointer
;
455 input_line_pointer
= (char *) "0";
458 input_line_pointer
= p
;
459 zero
= make_expr_symbol (& nul
);
460 /* We do not use relaxation (yet). */
469 switch (ins_ok
& INS_MARCH_MASK
)
472 if (ins_ok
& INS_UNPORT
)
473 mach_type
= bfd_mach_z80full
;
474 else if (ins_ok
& INS_UNDOC
)
475 mach_type
= bfd_mach_z80
;
477 mach_type
= bfd_mach_z80strict
;
480 mach_type
= bfd_mach_r800
;
483 mach_type
= bfd_mach_z180
;
486 mach_type
= bfd_mach_gbz80
;
489 mach_type
= cpu_mode
? bfd_mach_ez80_adl
: bfd_mach_ez80_z80
;
495 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach_type
);
498 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
500 z80_elf_final_processing (void)
503 switch (ins_ok
& INS_MARCH_MASK
)
506 elf_flags
= EF_Z80_MACH_Z80
;
509 elf_flags
= EF_Z80_MACH_R800
;
512 elf_flags
= EF_Z80_MACH_Z180
;
515 elf_flags
= EF_Z80_MACH_GBZ80
;
518 elf_flags
= cpu_mode
? EF_Z80_MACH_EZ80_ADL
: EF_Z80_MACH_EZ80_Z80
;
524 elf_elfheader (stdoutput
)->e_flags
= elf_flags
;
529 skip_space (const char *s
)
531 while (*s
== ' ' || *s
== '\t')
536 /* A non-zero return-value causes a continue in the
537 function read_a_source_file () in ../read.c. */
539 z80_start_line_hook (void)
544 /* Convert one character constants. */
545 for (p
= input_line_pointer
; *p
&& *p
!= '\n'; ++p
)
550 if (p
[1] != 0 && p
[1] != '\'' && p
[2] == '\'')
552 snprintf (buf
, 4, "%3d", (unsigned char)p
[1]);
560 for (quote
= *p
++; quote
!= *p
&& '\n' != *p
; ++p
)
564 as_bad (_("-- unterminated string"));
565 ignore_rest_of_line ();
571 *p
= (*skip_space (p
+ 1) == '(') ? '+' : ' ';
575 /* Check for <label>[:] [.](EQU|DEFL) <value>. */
576 if (is_name_beginner (*input_line_pointer
))
579 char c
, *rest
, *line_start
;
582 line_start
= input_line_pointer
;
586 c
= get_symbol_name (&name
);
587 rest
= input_line_pointer
+ 1;
589 if (ISSPACE (c
) && colonless_labels
)
593 bump_line_counters ();
598 if (c
== ':' && sdcc_compat
&& rest
[-2] != '$')
599 dollar_label_clear ();
602 /* remove second colon if SDCC compatibility enabled */
607 rest
= (char*)skip_space (rest
);
610 if (strncasecmp (rest
, "EQU", 3) == 0)
612 else if (strncasecmp (rest
, "DEFL", 4) == 0)
616 if (len
&& (!ISALPHA (rest
[len
])))
618 /* Handle assignment here. */
619 if (line_start
[-1] == '\n')
621 bump_line_counters ();
624 input_line_pointer
= rest
+ len
- 1;
625 /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
626 equals (name
, len
== 4);
631 /* Restore line and pointer. */
632 (void) restore_line_pointer (c
);
633 input_line_pointer
= line_start
;
640 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
646 md_atof (int type
, char *litP
, int *sizeP
)
653 return str_to_float (litP
, sizeP
);
658 return str_to_double (litP
, sizeP
);
661 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
665 md_section_align (segT seg ATTRIBUTE_UNUSED
, valueT size
)
671 md_pcrel_from (fixS
* fixp
)
673 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
676 typedef const char * (asfunc
)(char, char, const char*);
678 typedef struct _table_t
681 unsigned char prefix
;
682 unsigned char opcode
;
684 unsigned inss
; /*0 - all CPU types or list of supported INS_* */
687 /* Compares the key for structs that start with a char * to the key. */
689 key_cmp (const void * a
, const void * b
)
691 const char *str_a
, *str_b
;
693 str_a
= *((const char**)a
);
694 str_b
= *((const char**)b
);
695 return strcmp (str_a
, str_b
);
699 const char *key
= buf
;
701 /* Prevent an error on a line from also generating
702 a "junk at end of line" error message. */
703 static char err_flag
;
706 error (const char * message
)
711 as_bad ("%s", message
);
718 error (_("illegal operand"));
722 wrong_mach (int ins_type
)
724 if (ins_type
& ins_err
)
727 as_warn (_("undocumented instruction"));
731 check_mach (int ins_type
)
733 if ((ins_type
& ins_ok
) == 0)
734 wrong_mach (ins_type
);
737 /* Check whether an expression is indirect. */
739 is_indir (const char *s
)
745 /* Indirection is indicated with parentheses. */
748 for (p
= s
, depth
= 0; *p
&& *p
!= ','; ++p
)
754 for (quote
= *p
++; quote
!= *p
&& *p
!= '\n'; ++p
)
755 if (*p
== '\\' && p
[1])
765 p
= skip_space (p
+ 1);
771 error (_("mismatched parentheses"));
777 error (_("mismatched parentheses"));
782 /* Check whether a symbol involves a register. */
784 contains_register (symbolS
*sym
)
788 expressionS
* ex
= symbol_get_value_expression(sym
);
790 return (O_register
== ex
->X_op
)
791 || (ex
->X_add_symbol
&& contains_register(ex
->X_add_symbol
))
792 || (ex
->X_op_symbol
&& contains_register(ex
->X_op_symbol
));
798 /* Parse general expression, not looking for indexed addressing. */
800 parse_exp_not_indexed (const char *s
, expressionS
*op
)
807 if (sdcc_compat
&& (*p
== '<' || *p
== '>'))
811 case '<': /* LSB request */
814 case '>': /* MSB request */
815 make_shift
= cpu_mode
? 16 : 8;
822 op
->X_md
= indir
= is_indir (p
);
823 input_line_pointer
= (char*) s
;
828 error (_("missing operand"));
831 error (_("bad expression syntax"));
839 /* replace [op] by [op >> shift] */
841 op
->X_add_symbol
= make_expr_symbol (op
);
842 op
->X_add_number
= 0;
843 op
->X_op
= O_right_shift
;
844 memset (&data
, 0, sizeof (data
));
845 data
.X_op
= O_constant
;
846 data
.X_add_number
= make_shift
;
847 op
->X_op_symbol
= make_expr_symbol (&data
);
849 return input_line_pointer
;
853 unify_indexed (expressionS
*op
)
855 if (O_register
!= symbol_get_value_expression (op
->X_add_symbol
)->X_op
)
858 int rnum
= symbol_get_value_expression (op
->X_add_symbol
)->X_add_number
;
859 if ( ((REG_IX
!= rnum
) && (REG_IY
!= rnum
)) || contains_register (op
->X_op_symbol
))
865 /* Convert subtraction to addition of negative value. */
866 if (O_subtract
== op
->X_op
)
869 minus
.X_op
= O_uminus
;
870 minus
.X_add_number
= 0;
871 minus
.X_add_symbol
= op
->X_op_symbol
;
872 minus
.X_op_symbol
= 0;
873 op
->X_op_symbol
= make_expr_symbol (&minus
);
877 /* Clear X_add_number of the expression. */
878 if (op
->X_add_number
!= 0)
881 memset (&add
, 0, sizeof (add
));
883 add
.X_add_number
= op
->X_add_number
;
884 add
.X_add_symbol
= op
->X_op_symbol
;
886 op
->X_add_symbol
= make_expr_symbol (&add
);
889 op
->X_add_symbol
= op
->X_op_symbol
;
891 op
->X_add_number
= rnum
;
896 /* Parse expression, change operator to O_md1 for indexed addressing. */
898 parse_exp (const char *s
, expressionS
*op
)
900 const char* res
= parse_exp_not_indexed (s
, op
);
905 if (unify_indexed (op
) && op
->X_md
)
909 if (op
->X_md
&& ((REG_IX
== op
->X_add_number
) || (REG_IY
== op
->X_add_number
)))
911 op
->X_add_symbol
= zero
;
916 /* parse SDCC syntax where index register offset placed before parentheses */
917 if (sdcc_compat
&& is_indir (res
))
921 res
= parse_exp (res
, op
);
922 if (op
->X_op
!= O_md1
|| op
->X_add_symbol
!= zero
)
925 op
->X_add_symbol
= make_expr_symbol (&off
);
934 /* Condition codes, including some synonyms provided by HiTech zas. */
935 static const struct reg_entry cc_tab
[] =
953 /* Parse condition code. */
955 parse_cc (const char *s
, char * op
)
959 struct reg_entry
* cc_p
;
961 for (i
= 0; i
< BUFLEN
; ++i
)
963 if (!ISALPHA (s
[i
])) /* Condition codes consist of letters only. */
965 buf
[i
] = TOLOWER (s
[i
]);
969 && ((s
[i
] == 0) || (s
[i
] == ',')))
972 cc_p
= bsearch (&key
, cc_tab
, ARRAY_SIZE (cc_tab
),
973 sizeof (cc_tab
[0]), key_cmp
);
990 emit_insn (char prefix
, char opcode
, const char * args
)
1005 void z80_cons_fix_new (fragS
*frag_p
, int offset
, int nbytes
, expressionS
*exp
)
1007 bfd_reloc_code_real_type r
[4] =
1015 if (nbytes
< 1 || nbytes
> 4)
1017 as_bad (_("unsupported BFD relocation size %u"), nbytes
);
1021 fix_new_exp (frag_p
, offset
, nbytes
, exp
, 0, r
[nbytes
-1]);
1026 emit_data_val (expressionS
* val
, int size
)
1029 bfd_reloc_code_real_type r_type
;
1031 p
= frag_more (size
);
1032 if (val
->X_op
== O_constant
)
1035 for (i
= 0; i
< size
; ++i
)
1036 p
[i
] = (char)(val
->X_add_number
>> (i
*8));
1042 case 1: r_type
= BFD_RELOC_8
; break;
1043 case 2: r_type
= BFD_RELOC_16
; break;
1044 case 3: r_type
= BFD_RELOC_24
; break;
1045 case 4: r_type
= BFD_RELOC_32
; break;
1046 case 8: r_type
= BFD_RELOC_64
; break;
1048 as_fatal (_("invalid data size %d"), size
);
1051 if ( (val
->X_op
== O_register
)
1052 || (val
->X_op
== O_md1
)
1053 || contains_register (val
->X_add_symbol
)
1054 || contains_register (val
->X_op_symbol
))
1057 if (size
<= 2 && val
->X_op_symbol
)
1059 bfd_boolean simplify
= TRUE
;
1060 int shift
= symbol_get_value_expression (val
->X_op_symbol
)->X_add_number
;
1061 if (val
->X_op
== O_bit_and
&& shift
== (1 << (size
*8))-1)
1063 else if (val
->X_op
!= O_right_shift
)
1070 case 0: r_type
= BFD_RELOC_Z80_BYTE0
; break;
1071 case 8: r_type
= BFD_RELOC_Z80_BYTE1
; break;
1072 case 16: r_type
= BFD_RELOC_Z80_BYTE2
; break;
1073 case 24: r_type
= BFD_RELOC_Z80_BYTE3
; break;
1074 default: simplify
= FALSE
;
1077 else /* if (size == 2) */
1081 case 0: r_type
= BFD_RELOC_Z80_WORD0
; break;
1082 case 16: r_type
= BFD_RELOC_Z80_WORD1
; break;
1083 default: simplify
= FALSE
;
1089 val
->X_op
= O_symbol
;
1090 val
->X_op_symbol
= NULL
;
1091 val
->X_add_number
= 0;
1095 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, size
, val
, FALSE
, r_type
);
1099 emit_byte (expressionS
* val
, bfd_reloc_code_real_type r_type
)
1104 if (r_type
== BFD_RELOC_8
)
1106 emit_data_val (val
, 1);
1110 *p
= val
->X_add_number
;
1111 if ( contains_register (val
->X_add_symbol
) || contains_register (val
->X_op_symbol
) )
1115 else if ((r_type
== BFD_RELOC_8_PCREL
) && (val
->X_op
== O_constant
))
1117 as_bad (_("cannot make a relative jump to an absolute location"));
1119 else if (val
->X_op
== O_constant
)
1122 hi
= (BFD_RELOC_8
== r_type
) ? 255 : 127;
1124 if ((val
->X_add_number
< lo
) || (val
->X_add_number
> hi
))
1126 if (r_type
== BFD_RELOC_Z80_DISP8
)
1127 as_bad (_("offset too large"));
1129 as_warn (_("overflow"));
1134 /* For symbols only, constants are stored at begin of function */
1135 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 1, val
,
1136 (r_type
== BFD_RELOC_8_PCREL
) ? TRUE
: FALSE
, r_type
);
1141 emit_word (expressionS
* val
)
1143 emit_data_val (val
, (inst_mode
& INST_MODE_IL
) ? 3 : 2);
1147 emit_mx (char prefix
, char opcode
, int shift
, expressionS
* arg
)
1148 /* The operand m may be r, (hl), (ix+d), (iy+d),
1149 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1154 rnum
= arg
->X_add_number
;
1170 if ((prefix
== 0) && (rnum
& R_INDEX
))
1172 prefix
= (rnum
& R_IX
) ? 0xDD : 0xFD;
1173 if (!(ins_ok
& INS_EZ80
))
1174 check_mach (INS_IDX_HALF
);
1183 q
= frag_more (prefix
? 2 : 1);
1186 * q
++ = opcode
+ (rnum
<< shift
);
1189 if (ins_ok
& INS_GBZ80
)
1195 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1196 *q
= (prefix
) ? prefix
: (opcode
+ (6 << shift
));
1198 expressionS offset
= *arg
;
1199 offset
.X_op
= O_symbol
;
1200 offset
.X_add_number
= 0;
1201 emit_byte (&offset
, BFD_RELOC_Z80_DISP8
);
1206 *q
= opcode
+(6<<shift
);
1214 /* The operand m may be r, (hl), (ix+d), (iy+d),
1215 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1217 emit_m (char prefix
, char opcode
, const char *args
)
1222 p
= parse_exp (args
, &arg_m
);
1227 emit_mx (prefix
, opcode
, 0, &arg_m
);
1235 /* The operand m may be as above or one of the undocumented
1236 combinations (ix+d),r and (iy+d),r (if unportable instructions
1240 emit_mr (char prefix
, char opcode
, const char *args
)
1242 expressionS arg_m
, arg_r
;
1245 p
= parse_exp (args
, & arg_m
);
1252 p
= parse_exp (p
+ 1, & arg_r
);
1254 if ((arg_r
.X_md
== 0)
1255 && (arg_r
.X_op
== O_register
)
1256 && (arg_r
.X_add_number
< 8))
1257 opcode
+= arg_r
.X_add_number
- 6; /* Emit_mx () will add 6. */
1263 check_mach (INS_ROT_II_LD
);
1267 emit_mx (prefix
, opcode
, 0, & arg_m
);
1276 emit_sx (char prefix
, char opcode
, expressionS
* arg_p
)
1280 switch (arg_p
->X_op
)
1284 emit_mx (prefix
, opcode
, 0, arg_p
);
1291 q
= frag_more (prefix
? 2 : 1);
1295 emit_byte (arg_p
, BFD_RELOC_8
);
1300 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1302 emit_s (char prefix
, char opcode
, const char *args
)
1307 p
= parse_exp (args
, & arg_s
);
1308 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
1309 { /* possible instruction in generic format op A,x */
1310 if (!(ins_ok
& INS_EZ80
) && !sdcc_compat
)
1313 p
= parse_exp (p
, & arg_s
);
1315 emit_sx (prefix
, opcode
, & arg_s
);
1320 emit_call (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1323 const char *p
; char *q
;
1325 p
= parse_exp_not_indexed (args
, &addr
);
1337 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1339 emit_incdec (char prefix
, char opcode
, const char * args
)
1341 expressionS operand
;
1343 const char *p
; char *q
;
1345 p
= parse_exp (args
, &operand
);
1346 rnum
= operand
.X_add_number
;
1347 if ((! operand
.X_md
)
1348 && (operand
.X_op
== O_register
)
1351 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1353 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1354 *q
= prefix
+ ((rnum
& 3) << 4);
1358 if ((operand
.X_op
== O_md1
) || (operand
.X_op
== O_register
))
1359 emit_mx (0, opcode
, 3, & operand
);
1367 emit_jr (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1373 p
= parse_exp_not_indexed (args
, &addr
);
1380 addr
.X_add_number
--; /* pcrel computes after offset code */
1381 emit_byte (&addr
, BFD_RELOC_8_PCREL
);
1387 emit_jp (char prefix
, char opcode
, const char * args
)
1394 p
= parse_exp_not_indexed (args
, & addr
);
1397 rnum
= addr
.X_add_number
;
1398 if ((O_register
== addr
.X_op
) && (REG_HL
== (rnum
& ~R_INDEX
)))
1400 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1402 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1418 emit_im (char prefix
, char opcode
, const char * args
)
1424 p
= parse_exp (args
, & mode
);
1425 if (mode
.X_md
|| (mode
.X_op
!= O_constant
))
1428 switch (mode
.X_add_number
)
1432 ++mode
.X_add_number
;
1437 *q
= opcode
+ 8*mode
.X_add_number
;
1446 emit_pop (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1452 p
= parse_exp (args
, & regp
);
1454 && (regp
.X_op
== O_register
)
1455 && (regp
.X_add_number
& R_STACKABLE
))
1459 rnum
= regp
.X_add_number
;
1463 *q
++ = (rnum
&R_IX
)?0xDD:0xFD;
1467 *q
= opcode
+ ((rnum
& 3) << 4);
1476 emit_retcc (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1481 p
= parse_cc (args
, &cc
);
1487 return p
? p
: args
;
1491 emit_adc (char prefix
, char opcode
, const char * args
)
1498 p
= parse_exp (args
, &term
);
1501 error (_("bad instruction syntax"));
1505 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1508 switch (term
.X_add_number
)
1511 p
= emit_s (0, prefix
, p
);
1514 p
= parse_exp (p
, &term
);
1515 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1517 rnum
= term
.X_add_number
;
1518 if (R_ARITH
== (rnum
& (R_ARITH
| R_INDEX
)))
1522 *q
= opcode
+ ((rnum
& 3) << 4);
1534 emit_add (char prefix
, char opcode
, const char * args
)
1541 p
= parse_exp (args
, &term
);
1544 error (_("bad instruction syntax"));
1548 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1551 switch (term
.X_add_number
& ~R_INDEX
)
1554 p
= emit_s (0, prefix
, p
);
1557 lhs
= term
.X_add_number
;
1558 p
= parse_exp (p
, &term
);
1559 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1561 rhs
= term
.X_add_number
;
1563 && ((rhs
== lhs
) || ((rhs
& ~R_INDEX
) != REG_HL
)))
1565 q
= frag_more ((lhs
& R_INDEX
) ? 2 : 1);
1567 *q
++ = (lhs
& R_IX
) ? 0xDD : 0xFD;
1568 *q
= opcode
+ ((rhs
& 3) << 4);
1580 emit_bit (char prefix
, char opcode
, const char * args
)
1586 p
= parse_exp (args
, &b
);
1588 error (_("bad instruction syntax"));
1590 bn
= b
.X_add_number
;
1592 && (b
.X_op
== O_constant
)
1597 /* Bit : no optional third operand. */
1598 p
= emit_m (prefix
, opcode
+ (bn
<< 3), p
);
1600 /* Set, res : resulting byte can be copied to register. */
1601 p
= emit_mr (prefix
, opcode
+ (bn
<< 3), p
);
1609 emit_jpcc (char prefix
, char opcode
, const char * args
)
1614 p
= parse_cc (args
, & cc
);
1615 if (p
&& *p
++ == ',')
1616 p
= emit_call (0, opcode
+ cc
, p
);
1618 p
= (prefix
== (char)0xC3)
1619 ? emit_jp (0xE9, prefix
, args
)
1620 : emit_call (0, prefix
, args
);
1625 emit_jrcc (char prefix
, char opcode
, const char * args
)
1630 p
= parse_cc (args
, &cc
);
1631 if (p
&& *p
++ == ',')
1634 error (_("condition code invalid for jr"));
1636 p
= emit_jr (0, opcode
+ cc
, p
);
1639 p
= emit_jr (0, prefix
, args
);
1645 emit_ex (char prefix_in ATTRIBUTE_UNUSED
,
1646 char opcode_in ATTRIBUTE_UNUSED
, const char * args
)
1650 char prefix
, opcode
;
1652 p
= parse_exp_not_indexed (args
, &op
);
1656 error (_("bad instruction syntax"));
1660 prefix
= opcode
= 0;
1661 if (op
.X_op
== O_register
)
1662 switch (op
.X_add_number
| (op
.X_md
? 0x8000 : 0))
1665 if (TOLOWER (*p
++) == 'a' && TOLOWER (*p
++) == 'f')
1667 /* The scrubber changes '\'' to '`' in this context. */
1674 if (TOLOWER (*p
++) == 'h' && TOLOWER (*p
++) == 'l')
1678 p
= parse_exp (p
, & op
);
1679 if (op
.X_op
== O_register
1681 && (op
.X_add_number
& ~R_INDEX
) == REG_HL
)
1684 if (R_INDEX
& op
.X_add_number
)
1685 prefix
= (R_IX
& op
.X_add_number
) ? 0xDD : 0xFD;
1690 emit_insn (prefix
, opcode
, p
);
1698 emit_in (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1701 expressionS reg
, port
;
1705 p
= parse_exp (args
, ®
);
1708 error (_("bad instruction syntax"));
1712 p
= parse_exp (p
, &port
);
1714 && reg
.X_op
== O_register
1715 && (reg
.X_add_number
<= 7 || reg
.X_add_number
== REG_F
)
1718 if (port
.X_op
!= O_md1
&& port
.X_op
!= O_register
)
1720 if (REG_A
== reg
.X_add_number
)
1724 emit_byte (&port
, BFD_RELOC_8
);
1731 if (port
.X_add_number
== REG_C
|| port
.X_add_number
== REG_BC
)
1733 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
1735 else if (reg
.X_add_number
== REG_F
&& !(ins_ok
& INS_R800
))
1736 check_mach (INS_IN_F_C
);
1739 *q
= 0x40|((reg
.X_add_number
&7)<<3);
1751 emit_in0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1754 expressionS reg
, port
;
1758 p
= parse_exp (args
, ®
);
1761 error (_("bad instruction syntax"));
1765 p
= parse_exp (p
, &port
);
1767 && reg
.X_op
== O_register
1768 && reg
.X_add_number
<= 7
1770 && port
.X_op
!= O_md1
1771 && port
.X_op
!= O_register
)
1775 *q
= 0x00|(reg
.X_add_number
<< 3);
1776 emit_byte (&port
, BFD_RELOC_8
);
1784 emit_out (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1787 expressionS reg
, port
;
1791 p
= parse_exp (args
, & port
);
1794 error (_("bad instruction syntax"));
1797 p
= parse_exp (p
, ®
);
1799 { ill_op (); return p
; }
1800 /* Allow "out (c), 0" as unportable instruction. */
1801 if (reg
.X_op
== O_constant
&& reg
.X_add_number
== 0)
1803 check_mach (INS_OUT_C_0
);
1804 reg
.X_op
= O_register
;
1805 reg
.X_add_number
= 6;
1808 || reg
.X_op
!= O_register
1809 || reg
.X_add_number
> 7)
1812 if (port
.X_op
!= O_register
&& port
.X_op
!= O_md1
)
1814 if (REG_A
== reg
.X_add_number
)
1818 emit_byte (&port
, BFD_RELOC_8
);
1825 if (REG_C
== port
.X_add_number
|| port
.X_add_number
== REG_BC
)
1827 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
1831 *q
= 0x41 | (reg
.X_add_number
<< 3);
1840 emit_out0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1843 expressionS reg
, port
;
1847 p
= parse_exp (args
, & port
);
1850 error (_("bad instruction syntax"));
1853 p
= parse_exp (p
, ®
);
1855 && port
.X_op
!= O_register
1856 && port
.X_op
!= O_md1
1858 && reg
.X_op
== O_register
1859 && reg
.X_add_number
<= 7)
1863 *q
= 0x01 | (reg
.X_add_number
<< 3);
1864 emit_byte (&port
, BFD_RELOC_8
);
1872 emit_rst (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1878 p
= parse_exp_not_indexed (args
, &addr
);
1879 if (addr
.X_op
!= O_constant
)
1881 error ("rst needs constant address");
1885 if (addr
.X_add_number
& ~(7 << 3))
1890 *q
= opcode
+ (addr
.X_add_number
& (7 << 3));
1895 /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
1897 emit_ld_m_n (expressionS
*dst
, expressionS
*src
)
1901 expressionS dst_offset
;
1903 switch (dst
->X_add_number
)
1905 case REG_HL
: prefix
= 0x00; break;
1906 case REG_IX
: prefix
= 0xDD; break;
1907 case REG_IY
: prefix
= 0xFD; break;
1913 q
= frag_more (prefix
? 2 : 1);
1920 dst_offset
.X_op
= O_symbol
;
1921 dst_offset
.X_add_number
= 0;
1922 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
1924 emit_byte (src
, BFD_RELOC_8
);
1927 /* For 8-bit load register to memory instructions: LD (<expression>),r. */
1929 emit_ld_m_r (expressionS
*dst
, expressionS
*src
)
1933 expressionS dst_offset
;
1938 prefix
= (dst
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
1941 switch (dst
->X_add_number
)
1943 case REG_BC
: /* LD (BC),A */
1944 case REG_DE
: /* LD (DE),A */
1945 if (src
->X_add_number
== REG_A
)
1948 *q
= 0x02 | ((dst
->X_add_number
& 3) << 4);
1954 case REG_HL
: /* LD (HL),r or LD (ii+d),r */
1955 if (src
->X_add_number
<= 7)
1957 q
= frag_more (prefix
? 2 : 1);
1960 *q
= 0x70 | src
->X_add_number
;
1964 dst_offset
.X_op
= O_symbol
;
1965 dst_offset
.X_add_number
= 0;
1966 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
1974 default: /* LD (nn),A */
1975 if (src
->X_add_number
== REG_A
)
1987 /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
1989 emit_ld_m_rr (expressionS
*dst
, expressionS
*src
)
1994 expressionS dst_offset
;
1998 case O_md1
: /* eZ80 instructions LD (ii+d),rr */
1999 case O_register
: /* eZ80 instructions LD (HL),rr */
2000 if (!(ins_ok
& INS_EZ80
)) /* 16-bit indirect load group is supported by eZ80 only */
2002 switch (dst
->X_add_number
)
2004 case REG_IX
: prefix
= 0xDD; break;
2005 case REG_IY
: prefix
= 0xFD; break;
2006 case REG_HL
: prefix
= 0xED; break;
2010 switch (src
->X_add_number
)
2012 case REG_BC
: opcode
= 0x0F; break;
2013 case REG_DE
: opcode
= 0x1F; break;
2014 case REG_HL
: opcode
= 0x2F; break;
2015 case REG_IX
: opcode
= (prefix
!= 0xFD) ? 0x3F : 0x3E; break;
2016 case REG_IY
: opcode
= (prefix
!= 0xFD) ? 0x3E : 0x3F; break;
2020 q
= frag_more (prefix
? 2 : 1);
2023 if (prefix
== 0xFD || prefix
== 0xDD)
2026 dst_offset
.X_op
= O_symbol
;
2027 dst_offset
.X_add_number
= 0;
2028 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2031 default: /* LD (nn),rr */
2032 if (ins_ok
& INS_GBZ80
)
2034 /* GBZ80 supports only LD (nn),SP */
2035 if (src
->X_add_number
== REG_SP
)
2045 switch (src
->X_add_number
)
2047 case REG_BC
: prefix
= 0xED; opcode
= 0x43; break;
2048 case REG_DE
: prefix
= 0xED; opcode
= 0x53; break;
2049 case REG_HL
: prefix
= 0x00; opcode
= 0x22; break;
2050 case REG_IX
: prefix
= 0xDD; opcode
= 0x22; break;
2051 case REG_IY
: prefix
= 0xFD; opcode
= 0x22; break;
2052 case REG_SP
: prefix
= 0xED; opcode
= 0x73; break;
2057 q
= frag_more (prefix
? 2 : 1);
2066 emit_ld_r_m (expressionS
*dst
, expressionS
*src
)
2067 { /* for 8-bit memory load to register: LD r,(xxx) */
2071 expressionS src_offset
;
2073 if (dst
->X_add_number
== REG_A
&& src
->X_op
== O_register
)
2074 { /* LD A,(BC) or LD A,(DE) */
2075 switch (src
->X_add_number
)
2077 case REG_BC
: opcode
= 0x0A; break;
2078 case REG_DE
: opcode
= 0x1A; break;
2093 if (dst
->X_add_number
> 7)
2095 opcode
= 0x46; /* LD B,(HL) */
2096 switch (src
->X_add_number
)
2098 case REG_HL
: prefix
= 0x00; break;
2099 case REG_IX
: prefix
= 0xDD; break;
2100 case REG_IY
: prefix
= 0xFD; break;
2104 q
= frag_more (prefix
? 2 : 1);
2107 *q
= opcode
| ((dst
->X_add_number
& 7) << 3);
2111 src_offset
.X_op
= O_symbol
;
2112 src_offset
.X_add_number
= 0;
2113 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2116 default: /* LD A,(nn) */
2117 if (dst
->X_add_number
== REG_A
)
2127 emit_ld_r_n (expressionS
*dst
, expressionS
*src
)
2128 { /* for 8-bit immediate value load to register: LD r,n */
2132 switch (dst
->X_add_number
)
2155 q
= frag_more (prefix
? 2 : 1);
2158 if (ins_ok
& INS_GBZ80
)
2160 else if (!(ins_ok
& INS_EZ80
))
2161 check_mach (INS_IDX_HALF
);
2164 *q
= 0x06 | ((dst
->X_add_number
& 7) << 3);
2165 emit_byte (src
, BFD_RELOC_8
);
2169 emit_ld_r_r (expressionS
*dst
, expressionS
*src
)
2170 { /* mostly 8-bit load register from register instructions: LD r,r */
2171 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2177 switch (dst
->X_add_number
)
2180 switch (src
->X_add_number
)
2182 case REG_HL
: prefix
= 0x00; break;
2183 case REG_IX
: prefix
= 0xDD; break;
2184 case REG_IY
: prefix
= 0xFD; break;
2188 if (ins_ok
& INS_GBZ80
)
2193 if (!(ins_ok
& INS_EZ80
))
2195 if (src
->X_add_number
!= REG_I
)
2198 error (_("ADL mode instruction"));
2204 if (src
->X_add_number
== REG_HL
)
2206 if (!(ins_ok
& INS_EZ80
))
2209 error (_("ADL mode instruction"));
2213 else if (src
->X_add_number
== REG_A
)
2222 if (!(ins_ok
& INS_EZ80
) || (src
->X_add_number
!= REG_A
))
2225 error (_("ADL mode instruction"));
2230 if (src
->X_add_number
== REG_A
) /* LD R,A */
2239 if (src
->X_add_number
== REG_I
) /* LD A,I */
2245 else if (src
->X_add_number
== REG_R
) /* LD A,R */
2251 else if (src
->X_add_number
== REG_MB
) /* LD A,MB */
2253 if (!(ins_ok
& INS_EZ80
))
2258 error (_("ADL mode instruction"));
2289 switch (src
->X_add_number
)
2300 ill_op (); /* LD iiH/L,H/L are not permitted */
2304 if (prefix
== 0xFD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2305 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2311 if (prefix
== 0xDD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2312 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2319 opcode
= 0x40 + ((dst
->X_add_number
& 7) << 3) + (src
->X_add_number
& 7);
2321 if ((ins_ok
& INS_GBZ80
) && prefix
!= 0)
2323 if (ii_halves
&& !(ins_ok
& INS_EZ80
))
2324 check_mach (INS_IDX_HALF
);
2325 if (prefix
== 0 && (ins_ok
& INS_EZ80
))
2329 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2330 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2331 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2332 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2333 as_warn (_("unsupported instruction, assembled as NOP"));
2339 q
= frag_more (prefix
? 2 : 1);
2346 emit_ld_rr_m (expressionS
*dst
, expressionS
*src
)
2347 { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2351 expressionS src_offset
;
2353 /* GBZ80 has no support for 16-bit load from memory instructions */
2354 if (ins_ok
& INS_GBZ80
)
2360 case O_md1
: /* LD rr,(ii+d) */
2361 prefix
= (src
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2363 case O_register
: /* LD rr,(HL) */
2364 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2365 if (!(ins_ok
& INS_EZ80
))
2367 switch (dst
->X_add_number
)
2369 case REG_BC
: opcode
= 0x07; break;
2370 case REG_DE
: opcode
= 0x17; break;
2371 case REG_HL
: opcode
= 0x27; break;
2372 case REG_IX
: opcode
= (!prefix
|| prefix
== 0xDD) ? 0x37 : 0x31; break;
2373 case REG_IY
: opcode
= prefix
? ((prefix
== 0xDD) ? 0x31 : 0x37) : 0x36; break;
2383 src_offset
.X_op
= O_symbol
;
2384 src_offset
.X_add_number
= 0;
2385 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2388 default: /* LD rr,(nn) */
2389 switch (dst
->X_add_number
)
2391 case REG_BC
: prefix
= 0xED; opcode
= 0x4B; break;
2392 case REG_DE
: prefix
= 0xED; opcode
= 0x5B; break;
2393 case REG_HL
: prefix
= 0x00; opcode
= 0x2A; break;
2394 case REG_SP
: prefix
= 0xED; opcode
= 0x7B; break;
2395 case REG_IX
: prefix
= 0xDD; opcode
= 0x2A; break;
2396 case REG_IY
: prefix
= 0xFD; opcode
= 0x2A; break;
2400 q
= frag_more (prefix
? 2 : 1);
2410 emit_ld_rr_nn (expressionS
*dst
, expressionS
*src
)
2411 { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2414 int opcode
= 0x21; /* LD HL,nn */
2415 switch (dst
->X_add_number
)
2428 opcode
= 0x01 + ((dst
->X_add_number
& 3) << 4);
2434 if (prefix
&& (ins_ok
& INS_GBZ80
))
2436 q
= frag_more (prefix
? 2 : 1);
2444 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
2447 expressionS dst
, src
;
2450 p
= parse_exp (args
, & dst
);
2452 error (_("bad instruction syntax"));
2453 p
= parse_exp (p
, & src
);
2457 if (src
.X_op
== O_register
)
2459 if (src
.X_add_number
<= 7)
2460 emit_ld_m_r (& dst
, & src
); /* LD (xxx),r */
2462 emit_ld_m_rr (& dst
, & src
); /* LD (xxx),rr */
2465 emit_ld_m_n (& dst
, & src
); /* LD (hl),n or LD (ix/y+r),n */
2467 else if (dst
.X_op
== O_register
)
2471 if (dst
.X_add_number
<= 7)
2472 emit_ld_r_m (& dst
, & src
);
2474 emit_ld_rr_m (& dst
, & src
);
2476 else if (src
.X_op
== O_register
)
2477 emit_ld_r_r (& dst
, & src
);
2478 else if ((dst
.X_add_number
& ~R_INDEX
) <= 7)
2479 emit_ld_r_n (& dst
, & src
);
2481 emit_ld_rr_nn (& dst
, & src
);
2490 emit_lddldi (char prefix
, char opcode
, const char * args
)
2492 expressionS dst
, src
;
2496 if (!(ins_ok
& INS_GBZ80
))
2497 return emit_insn (prefix
, opcode
, args
);
2499 p
= parse_exp (args
, & dst
);
2501 error (_("bad instruction syntax"));
2502 p
= parse_exp (args
, & src
);
2504 if (dst
.X_op
!= O_register
|| src
.X_op
!= O_register
)
2507 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2508 opcode
= (opcode
& 0x08) * 2 + 0x22;
2511 && dst
.X_add_number
== REG_HL
2513 && src
.X_add_number
== REG_A
)
2514 opcode
|= 0x00; /* LDx (HL),A */
2515 else if (dst
.X_md
== 0
2516 && dst
.X_add_number
== REG_A
2518 && src
.X_add_number
== REG_HL
)
2519 opcode
|= 0x08; /* LDx A,(HL) */
2529 emit_ldh (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2532 expressionS dst
, src
;
2536 p
= parse_exp (args
, & dst
);
2539 error (_("bad instruction syntax"));
2543 p
= parse_exp (p
, & src
);
2545 && dst
.X_op
== O_register
2546 && dst
.X_add_number
== REG_A
2548 && src
.X_op
!= O_md1
2549 && src
.X_op
!= O_register
)
2553 emit_byte (& src
, BFD_RELOC_8
);
2555 else if (dst
.X_md
!= 0
2556 && dst
.X_op
!= O_md1
2558 && src
.X_op
== O_register
2559 && src
.X_add_number
== REG_A
)
2561 if (dst
.X_op
== O_register
)
2563 if (dst
.X_add_number
== REG_C
)
2575 emit_byte (& dst
, BFD_RELOC_8
);
2585 parse_lea_pea_args (const char * args
, expressionS
*op
)
2588 p
= parse_exp (args
, op
);
2589 if (sdcc_compat
&& *p
== ',' && op
->X_op
== O_register
)
2592 p
= parse_exp (p
+ 1, &off
);
2594 op
->X_add_symbol
= make_expr_symbol (&off
);
2600 emit_lea (char prefix
, char opcode
, const char * args
)
2602 expressionS dst
, src
;
2607 p
= parse_exp (args
, & dst
);
2608 if (dst
.X_md
!= 0 || dst
.X_op
!= O_register
)
2611 rnum
= dst
.X_add_number
;
2617 opcode
= 0x02 | ((rnum
& 0x03) << 4);
2620 opcode
= 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2623 opcode
= 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2630 error (_("bad instruction syntax"));
2632 p
= parse_lea_pea_args (p
, & src
);
2633 if (src
.X_md
!= 0 || src
.X_op
!= O_add
/*&& src.X_op != O_register*/)
2636 rnum
= src
.X_add_number
;
2641 case O_register
: /* permit instructions like LEA rr,IX without displacement specified */
2642 src
.X_add_symbol
= zero
;
2651 opcode
= (opcode
== (char)0x33) ? 0x55 : (opcode
|0x00);
2654 opcode
= (opcode
== (char)0x32) ? 0x54 : (opcode
|0x01);
2661 src
.X_op
= O_symbol
;
2662 src
.X_add_number
= 0;
2663 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2669 emit_mlt (char prefix
, char opcode
, const char * args
)
2675 p
= parse_exp (args
, & arg
);
2676 if (arg
.X_md
!= 0 || arg
.X_op
!= O_register
|| !(arg
.X_add_number
& R_ARITH
))
2681 *q
= opcode
| ((arg
.X_add_number
& 3) << 4);
2687 emit_pea (char prefix
, char opcode
, const char * args
)
2693 p
= parse_lea_pea_args (args
, & arg
);
2695 || (/*arg.X_op != O_register &&*/ arg
.X_op
!= O_add
)
2696 || !(arg
.X_add_number
& R_INDEX
))
2698 /* PEA ii without displacement is mostly typo,
2699 because there is PUSH instruction which is shorter and faster */
2700 /*if (arg.X_op == O_register)
2701 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
2705 *q
= opcode
+ (arg
.X_add_number
== REG_IY
? 1 : 0);
2707 arg
.X_op
= O_symbol
;
2708 arg
.X_add_number
= 0;
2709 emit_byte (& arg
, BFD_RELOC_Z80_DISP8
);
2715 emit_reti (char prefix
, char opcode
, const char * args
)
2717 if (ins_ok
& INS_GBZ80
)
2718 return emit_insn (0x00, 0xD9, args
);
2720 return emit_insn (prefix
, opcode
, args
);
2724 emit_tst (char prefix
, char opcode
, const char *args
)
2731 p
= parse_exp (args
, & arg_s
);
2732 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
2734 if (!(ins_ok
& INS_EZ80
))
2737 p
= parse_exp (p
, & arg_s
);
2740 rnum
= arg_s
.X_add_number
;
2747 rnum
= arg_s
.X_add_number
;
2748 if (arg_s
.X_md
!= 0)
2757 *q
= opcode
| (rnum
<< 3);
2765 emit_byte (& arg_s
, BFD_RELOC_8
);
2771 emit_tstio (char prefix
, char opcode
, const char *args
)
2777 p
= parse_exp (args
, & arg
);
2778 if (arg
.X_md
|| arg
.X_op
== O_register
|| arg
.X_op
== O_md1
)
2784 emit_byte (& arg
, BFD_RELOC_8
);
2790 emit_data (int size ATTRIBUTE_UNUSED
)
2797 if (is_it_end_of_statement ())
2799 demand_empty_rest_of_line ();
2802 p
= skip_space (input_line_pointer
);
2806 if (*p
== '\"' || *p
== '\'')
2808 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
2810 u
= frag_more (cnt
);
2813 as_warn (_("unterminated string"));
2815 p
= skip_space (p
+1);
2819 p
= parse_exp (p
, &exp
);
2820 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
2826 as_warn (_("parentheses ignored"));
2827 emit_byte (&exp
, BFD_RELOC_8
);
2831 while (*p
++ == ',') ;
2832 input_line_pointer
= (char *)(p
-1);
2841 if (is_it_end_of_statement ())
2843 demand_empty_rest_of_line ();
2846 p
= skip_space (input_line_pointer
);
2850 p
= parse_exp (p
, &exp
);
2851 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
2857 as_warn (_("parentheses ignored"));
2858 emit_data_val (&exp
, size
);
2860 } while (*p
++ == ',') ;
2861 input_line_pointer
= (char *)(p
-1);
2864 /* next functions were commented out because it is difficult to mix
2865 both ADL and Z80 mode instructions within one COFF file:
2866 objdump cannot recognize point of mode switching.
2869 set_cpu_mode (int mode
)
2871 if (ins_ok
& INS_EZ80
)
2874 error (_("CPU mode is unsupported by target"));
2878 assume (int arg ATTRIBUTE_UNUSED
)
2884 input_line_pointer
= (char*)skip_space (input_line_pointer
);
2885 c
= get_symbol_name (& name
);
2886 if (strncasecmp (name
, "ADL", 4) != 0)
2892 restore_line_pointer (c
);
2893 input_line_pointer
= (char*)skip_space (input_line_pointer
);
2894 if (*input_line_pointer
++ != '=')
2896 error (_("assignment expected"));
2899 input_line_pointer
= (char*)skip_space (input_line_pointer
);
2900 n
= get_single_number ();
2906 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2910 p
= skip_space (args
);
2911 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
2917 reg
= TOLOWER (*p
++);
2924 check_mach (INS_R800
);
2925 if (!*skip_space (p
))
2929 *q
= opcode
+ ((reg
- 'b') << 3);
2941 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2945 p
= skip_space (args
);
2946 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
2953 p
= parse_exp (p
, & reg
);
2955 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
2956 switch (reg
.X_add_number
)
2960 check_mach (INS_R800
);
2963 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
2973 assemble_suffix (const char **suffix
)
2976 const char sf
[8][4] =
2996 for (i
= 0; (i
< 3) && (ISALPHA (*p
)); i
++)
2997 sbuf
[i
] = TOLOWER (*p
++);
2998 if (*p
&& !ISSPACE (*p
))
3003 t
= bsearch (sbuf
, sf
, ARRAY_SIZE (sf
), sizeof (sf
[0]), (int(*)(const void*, const void*)) strcmp
);
3010 i
= cpu_mode
? 0x5B : 0x52;
3013 i
= cpu_mode
? 0x49 : 0x40;
3016 i
= cpu_mode
? 0x5B : 0x49;
3025 i
= cpu_mode
? 0x52 : 0x40;
3034 *frag_more (1) = (char)i
;
3037 case 0x40: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IS
; break;
3038 case 0x49: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IS
; break;
3039 case 0x52: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IL
; break;
3040 case 0x5B: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IL
; break;
3048 #if defined(OBJ_ELF)
3049 return obj_elf_section (arg
);
3050 #elif defined(OBJ_COFF)
3051 return obj_coff_section (arg
);
3053 #error Unknown object format
3063 as_fatal (_("Invalid directive"));
3066 ins_ok
&= INS_MARCH_MASK
;
3068 if (old_ins
!= ins_ok
)
3073 ignore (int arg ATTRIBUTE_UNUSED
)
3075 ignore_rest_of_line ();
3083 as_fatal (_("Invalid directive"));
3084 for (p
= input_line_pointer
; *p
&& *p
!= '(' && *p
!= '\n'; p
++)
3091 ignore_rest_of_line ();
3097 /* Port specific pseudo ops. */
3098 const pseudo_typeS md_pseudo_table
[] =
3100 { ".area", area
, 0},
3101 { ".assume", assume
, 0},
3102 { ".ez80", set_inss
, INS_EZ80
},
3103 { ".gbz80", set_inss
, INS_GBZ80
},
3104 { ".module", ignore
, 0},
3105 { ".optsdcc", ignore
, 0},
3106 { ".r800", set_inss
, INS_R800
},
3107 { ".set", s_set
, 0},
3108 { ".z180", set_inss
, INS_Z180
},
3109 { ".z80", set_inss
, INS_Z80
},
3110 { "db" , emit_data
, 1},
3111 { "d24", z80_cons
, 3},
3112 { "d32", z80_cons
, 4},
3113 { "def24", z80_cons
, 3},
3114 { "def32", z80_cons
, 4},
3115 { "defb", emit_data
, 1},
3116 { "defm", emit_data
, 1},
3117 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
3118 { "defw", z80_cons
, 2},
3119 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
3120 { "dw", z80_cons
, 2},
3121 { "psect", psect
, 0}, /* TODO: Translate attributes. */
3122 { "set", 0, 0}, /* Real instruction on z80. */
3126 static table_t instab
[] =
3128 { "adc", 0x88, 0x4A, emit_adc
, INS_ALL
},
3129 { "add", 0x80, 0x09, emit_add
, INS_ALL
},
3130 { "and", 0x00, 0xA0, emit_s
, INS_ALL
},
3131 { "bit", 0xCB, 0x40, emit_bit
, INS_ALL
},
3132 { "call", 0xCD, 0xC4, emit_jpcc
, INS_ALL
},
3133 { "ccf", 0x00, 0x3F, emit_insn
, INS_ALL
},
3134 { "cp", 0x00, 0xB8, emit_s
, INS_ALL
},
3135 { "cpd", 0xED, 0xA9, emit_insn
, INS_NOT_GBZ80
},
3136 { "cpdr", 0xED, 0xB9, emit_insn
, INS_NOT_GBZ80
},
3137 { "cpi", 0xED, 0xA1, emit_insn
, INS_NOT_GBZ80
},
3138 { "cpir", 0xED, 0xB1, emit_insn
, INS_NOT_GBZ80
},
3139 { "cpl", 0x00, 0x2F, emit_insn
, INS_ALL
},
3140 { "daa", 0x00, 0x27, emit_insn
, INS_ALL
},
3141 { "dec", 0x0B, 0x05, emit_incdec
,INS_ALL
},
3142 { "di", 0x00, 0xF3, emit_insn
, INS_ALL
},
3143 { "djnz", 0x00, 0x10, emit_jr
, INS_NOT_GBZ80
},
3144 { "ei", 0x00, 0xFB, emit_insn
, INS_ALL
},
3145 { "ex", 0x00, 0x00, emit_ex
, INS_NOT_GBZ80
},
3146 { "exx", 0x00, 0xD9, emit_insn
, INS_NOT_GBZ80
},
3147 { "halt", 0x00, 0x76, emit_insn
, INS_ALL
},
3148 { "im", 0xED, 0x46, emit_im
, INS_NOT_GBZ80
},
3149 { "in", 0x00, 0x00, emit_in
, INS_NOT_GBZ80
},
3150 { "in0", 0xED, 0x00, emit_in0
, INS_Z180
|INS_EZ80
},
3151 { "inc", 0x03, 0x04, emit_incdec
,INS_ALL
},
3152 { "ind", 0xED, 0xAA, emit_insn
, INS_NOT_GBZ80
},
3153 { "ind2", 0xED, 0x8C, emit_insn
, INS_EZ80
},
3154 { "ind2r",0xED, 0x9C, emit_insn
, INS_EZ80
},
3155 { "indm", 0xED, 0x8A, emit_insn
, INS_EZ80
},
3156 { "indmr",0xED, 0x9A, emit_insn
, INS_EZ80
},
3157 { "indr", 0xED, 0xBA, emit_insn
, INS_NOT_GBZ80
},
3158 { "indrx",0xED, 0xCA, emit_insn
, INS_EZ80
},
3159 { "ini", 0xED, 0xA2, emit_insn
, INS_NOT_GBZ80
},
3160 { "ini2", 0xED, 0x84, emit_insn
, INS_EZ80
},
3161 { "ini2r",0xED, 0x94, emit_insn
, INS_EZ80
},
3162 { "inim", 0xED, 0x82, emit_insn
, INS_EZ80
},
3163 { "inimr",0xED, 0x92, emit_insn
, INS_EZ80
},
3164 { "inir", 0xED, 0xB2, emit_insn
, INS_NOT_GBZ80
},
3165 { "inirx",0xED, 0xC2, emit_insn
, INS_EZ80
},
3166 { "jp", 0xC3, 0xC2, emit_jpcc
, INS_ALL
},
3167 { "jr", 0x18, 0x20, emit_jrcc
, INS_ALL
},
3168 { "ld", 0x00, 0x00, emit_ld
, INS_ALL
},
3169 { "ldd", 0xED, 0xA8, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3170 { "lddr", 0xED, 0xB8, emit_insn
, INS_NOT_GBZ80
},
3171 { "ldh", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3172 { "ldhl", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3173 { "ldi", 0xED, 0xA0, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3174 { "ldir", 0xED, 0xB0, emit_insn
, INS_NOT_GBZ80
},
3175 { "lea", 0xED, 0x02, emit_lea
, INS_EZ80
},
3176 { "mlt", 0xED, 0x4C, emit_mlt
, INS_Z180
|INS_EZ80
},
3177 { "mulub",0xED, 0xC5, emit_mulub
,INS_R800
},
3178 { "muluw",0xED, 0xC3, emit_muluw
,INS_R800
},
3179 { "neg", 0xed, 0x44, emit_insn
, INS_NOT_GBZ80
},
3180 { "nop", 0x00, 0x00, emit_insn
, INS_ALL
},
3181 { "or", 0x00, 0xB0, emit_s
, INS_ALL
},
3182 { "otd2r",0xED, 0xBC, emit_insn
, INS_EZ80
},
3183 { "otdm", 0xED, 0x8B, emit_insn
, INS_Z180
|INS_EZ80
},
3184 { "otdmr",0xED, 0x9B, emit_insn
, INS_Z180
|INS_EZ80
},
3185 { "otdr", 0xED, 0xBB, emit_insn
, INS_NOT_GBZ80
},
3186 { "otdrx",0xED, 0xCB, emit_insn
, INS_EZ80
},
3187 { "oti2r",0xED, 0xB4, emit_insn
, INS_EZ80
},
3188 { "otim", 0xED, 0x83, emit_insn
, INS_Z180
|INS_EZ80
},
3189 { "otimr",0xED, 0x93, emit_insn
, INS_Z180
|INS_EZ80
},
3190 { "otir", 0xED, 0xB3, emit_insn
, INS_NOT_GBZ80
},
3191 { "otirx",0xED, 0xC3, emit_insn
, INS_EZ80
},
3192 { "out", 0x00, 0x00, emit_out
, INS_NOT_GBZ80
},
3193 { "out0", 0xED, 0x01, emit_out0
, INS_Z180
|INS_EZ80
},
3194 { "outd", 0xED, 0xAB, emit_insn
, INS_NOT_GBZ80
},
3195 { "outd2",0xED, 0xAC, emit_insn
, INS_EZ80
},
3196 { "outi", 0xED, 0xA3, emit_insn
, INS_NOT_GBZ80
},
3197 { "outi2",0xED, 0xA4, emit_insn
, INS_EZ80
},
3198 { "pea", 0xED, 0x65, emit_pea
, INS_EZ80
},
3199 { "pop", 0x00, 0xC1, emit_pop
, INS_ALL
},
3200 { "push", 0x00, 0xC5, emit_pop
, INS_ALL
},
3201 { "res", 0xCB, 0x80, emit_bit
, INS_ALL
},
3202 { "ret", 0xC9, 0xC0, emit_retcc
,INS_ALL
},
3203 { "reti", 0xED, 0x4D, emit_reti
, INS_ALL
}, /*GBZ80 has its own opcode for it*/
3204 { "retn", 0xED, 0x45, emit_insn
, INS_NOT_GBZ80
},
3205 { "rl", 0xCB, 0x10, emit_mr
, INS_ALL
},
3206 { "rla", 0x00, 0x17, emit_insn
, INS_ALL
},
3207 { "rlc", 0xCB, 0x00, emit_mr
, INS_ALL
},
3208 { "rlca", 0x00, 0x07, emit_insn
, INS_ALL
},
3209 { "rld", 0xED, 0x6F, emit_insn
, INS_NOT_GBZ80
},
3210 { "rr", 0xCB, 0x18, emit_mr
, INS_ALL
},
3211 { "rra", 0x00, 0x1F, emit_insn
, INS_ALL
},
3212 { "rrc", 0xCB, 0x08, emit_mr
, INS_ALL
},
3213 { "rrca", 0x00, 0x0F, emit_insn
, INS_ALL
},
3214 { "rrd", 0xED, 0x67, emit_insn
, INS_NOT_GBZ80
},
3215 { "rsmix",0xED, 0x7E, emit_insn
, INS_EZ80
},
3216 { "rst", 0x00, 0xC7, emit_rst
, INS_ALL
},
3217 { "sbc", 0x98, 0x42, emit_adc
, INS_ALL
},
3218 { "scf", 0x00, 0x37, emit_insn
, INS_ALL
},
3219 { "set", 0xCB, 0xC0, emit_bit
, INS_ALL
},
3220 { "sla", 0xCB, 0x20, emit_mr
, INS_ALL
},
3221 { "sli", 0xCB, 0x30, emit_mr
, INS_SLI
},
3222 { "sll", 0xCB, 0x30, emit_mr
, INS_SLI
},
3223 { "slp", 0xED, 0x76, emit_insn
, INS_Z180
|INS_EZ80
},
3224 { "sra", 0xCB, 0x28, emit_mr
, INS_ALL
},
3225 { "srl", 0xCB, 0x38, emit_mr
, INS_ALL
},
3226 { "stmix",0xED, 0x7D, emit_insn
, INS_EZ80
},
3227 { "stop", 0x00, 0x10, emit_insn
, INS_GBZ80
},
3228 { "sub", 0x00, 0x90, emit_s
, INS_ALL
},
3229 { "swap", 0xCB, 0x30, emit_mr
, INS_GBZ80
},
3230 { "tst", 0xED, 0x04, emit_tst
, INS_Z180
|INS_EZ80
},
3231 { "tstio",0xED, 0x74, emit_tstio
,INS_Z180
|INS_EZ80
},
3232 { "xor", 0x00, 0xA8, emit_s
, INS_ALL
},
3236 md_assemble (char *str
)
3244 inst_mode
= cpu_mode
? (INST_MODE_L
| INST_MODE_IL
) : (INST_MODE_S
| INST_MODE_IS
);
3245 old_ptr
= input_line_pointer
;
3246 p
= skip_space (str
);
3247 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
) || ISDIGIT (*p
));)
3248 buf
[i
++] = TOLOWER (*p
++);
3252 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
3254 as_bad (_("Unknown instruction '%s'"), buf
);
3258 if ((*p
) && (!ISSPACE (*p
)))
3260 if (*p
!= '.' || !(ins_ok
& INS_EZ80
) || !assemble_suffix (&p
))
3262 as_bad (_("syntax error"));
3270 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
3271 sizeof (instab
[0]), key_cmp
);
3272 if (!insp
|| (insp
->inss
&& !(insp
->inss
& ins_ok
)))
3274 as_bad (_("Unknown instruction '%s'"), buf
);
3279 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
3281 if ((!err_flag
) && *p
)
3282 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
3287 input_line_pointer
= old_ptr
;
3291 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg ATTRIBUTE_UNUSED
)
3293 long val
= * (long *) valP
;
3294 char *p_lit
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3296 switch (fixP
->fx_r_type
)
3298 case BFD_RELOC_8_PCREL
:
3301 fixP
->fx_no_overflow
= 1;
3306 fixP
->fx_no_overflow
= (-128 <= val
&& val
< 128);
3307 if (!fixP
->fx_no_overflow
)
3308 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3309 _("relative jump out of range"));
3315 case BFD_RELOC_Z80_DISP8
:
3318 fixP
->fx_no_overflow
= 1;
3323 fixP
->fx_no_overflow
= (-128 <= val
&& val
< 128);
3324 if (!fixP
->fx_no_overflow
)
3325 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3326 _("index offset out of range"));
3332 case BFD_RELOC_Z80_BYTE0
:
3334 fixP
->fx_no_overflow
= 1;
3335 if (fixP
->fx_addsy
== NULL
)
3339 case BFD_RELOC_Z80_BYTE1
:
3340 *p_lit
++ = (val
>> 8);
3341 fixP
->fx_no_overflow
= 1;
3342 if (fixP
->fx_addsy
== NULL
)
3346 case BFD_RELOC_Z80_BYTE2
:
3347 *p_lit
++ = (val
>> 16);
3348 fixP
->fx_no_overflow
= 1;
3349 if (fixP
->fx_addsy
== NULL
)
3353 case BFD_RELOC_Z80_BYTE3
:
3354 *p_lit
++ = (val
>> 24);
3355 fixP
->fx_no_overflow
= 1;
3356 if (fixP
->fx_addsy
== NULL
)
3361 if (val
> 255 || val
< -128)
3362 as_warn_where (fixP
->fx_file
, fixP
->fx_line
, _("overflow"));
3364 fixP
->fx_no_overflow
= 1;
3365 if (fixP
->fx_addsy
== NULL
)
3369 case BFD_RELOC_Z80_WORD1
:
3370 *p_lit
++ = (val
>> 16);
3371 *p_lit
++ = (val
>> 24);
3372 fixP
->fx_no_overflow
= 1;
3373 if (fixP
->fx_addsy
== NULL
)
3377 case BFD_RELOC_Z80_WORD0
:
3380 *p_lit
++ = (val
>> 8);
3381 fixP
->fx_no_overflow
= 1;
3382 if (fixP
->fx_addsy
== NULL
)
3386 case BFD_RELOC_24
: /* Def24 may produce this. */
3388 *p_lit
++ = (val
>> 8);
3389 *p_lit
++ = (val
>> 16);
3390 fixP
->fx_no_overflow
= 1;
3391 if (fixP
->fx_addsy
== NULL
)
3395 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
3397 *p_lit
++ = (val
>> 8);
3398 *p_lit
++ = (val
>> 16);
3399 *p_lit
++ = (val
>> 24);
3400 if (fixP
->fx_addsy
== NULL
)
3405 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP
->fx_r_type
);
3410 /* GAS will call this to generate a reloc. GAS will pass the
3411 resulting reloc to `bfd_install_relocation'. This currently works
3412 poorly, as `bfd_install_relocation' often does the wrong thing, and
3413 instances of `tc_gen_reloc' have been written to work around the
3414 problems, which in turns makes it difficult to fix
3415 `bfd_install_relocation'. */
3417 /* If while processing a fixup, a reloc really
3418 needs to be created then it is done here. */
3421 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
3425 if (! bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
))
3427 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3428 _("reloc %d not supported by object file format"),
3429 (int) fixp
->fx_r_type
);
3433 reloc
= XNEW (arelent
);
3434 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3435 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3436 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3437 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3438 reloc
->addend
= fixp
->fx_offset
;
3444 z80_tc_label_is_local (const char *name
)
3448 if (local_label_prefix
== NULL
)
3450 for (p
= local_label_prefix
, n
= name
; *p
&& *n
&& *n
== *p
; p
++, n
++)
3455 /* Parse floating point number from string and compute mantissa and
3456 exponent. Mantissa is normalized.
3458 #define EXP_MIN -0x10000
3459 #define EXP_MAX 0x10000
3461 str_to_broken_float (bfd_boolean
*signP
, bfd_uint64_t
*mantissaP
, int *expP
)
3465 bfd_uint64_t mantissa
= 0;
3469 p
= (char*)skip_space (input_line_pointer
);
3472 if (sign
|| *p
== '+')
3474 if (strncasecmp (p
, "NaN", 3) == 0)
3478 input_line_pointer
= p
+ 3;
3481 if (strncasecmp (p
, "inf", 3) == 0)
3483 *mantissaP
= 1ull << 63;
3485 input_line_pointer
= p
+ 3;
3488 for (; ISDIGIT (*p
); ++p
)
3496 mantissa
= mantissa
* 10 + (*p
- '0');
3498 /* skip non-significant digits */
3499 for (; ISDIGIT (*p
); ++p
)
3505 if (!exponent
) /* If no precission overflow. */
3507 for (; ISDIGIT (*p
); ++p
, --exponent
)
3515 mantissa
= mantissa
* 10 + (*p
- '0');
3518 for (; ISDIGIT (*p
); ++p
)
3521 if (*p
== 'e' || *p
== 'E')
3527 if (es
|| *p
== '+')
3529 for (; ISDIGIT (*p
); ++p
)
3532 t
= t
* 10 + (*p
- '0');
3534 exponent
+= (es
) ? -t
: t
;
3536 if (ISALNUM (*p
) || *p
== '.')
3538 input_line_pointer
= p
;
3541 *mantissaP
= 1ull << 63;
3543 return 1; /* result is 0 */
3546 for (; mantissa
<= ~0ull/10; --exponent
)
3548 /* Now we have sign, mantissa, and signed decimal exponent
3549 need to recompute to binary exponent. */
3550 for (i
= 64; exponent
> 0; --exponent
)
3552 /* be sure that no integer overflow */
3553 while (mantissa
> ~0ull/10)
3560 for (; exponent
< 0; ++exponent
)
3562 while (!(mantissa
>> 63))
3570 for (; !(mantissa
>> 63); --i
)
3572 *mantissaP
= mantissa
;
3578 str_to_zeda32(char *litP
, int *sizeP
)
3580 bfd_uint64_t mantissa
;
3586 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
3587 return _("invalid syntax");
3588 /* I do not know why decrement is needed */
3590 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
3594 /* make 24 bit mantissa */
3596 /* check for overflow */
3603 if (exponent
< -127)
3608 else if (exponent
> 127)
3611 mantissa
= sign
? 0xc00000 : 0x400000;
3613 else if (mantissa
== 0)
3616 mantissa
= 0x200000;
3619 mantissa
&= (1ull << 23) - 1;
3620 for (i
= 0; i
< 24; i
+= 8)
3621 *litP
++ = (char)(mantissa
>> i
);
3622 *litP
= (char)(0x80 + exponent
);
3627 Math48 by Anders Hejlsberg support.
3628 Mantissa is 39 bits wide, exponent 8 bit wide.
3631 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
3632 bit 7-0: exponent+128 (0 - value is null)
3633 MIN: 2.938735877e-39
3634 MAX: 1.701411835e+38
3637 str_to_float48(char *litP
, int *sizeP
)
3639 bfd_uint64_t mantissa
;
3645 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
3646 return _("invalid syntax");
3647 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
3651 /* make 40 bit mantissa */
3653 /* check for overflow */
3659 if (exponent
< -127)
3661 memset (litP
, 0, 6);
3665 return _("overflow");
3667 mantissa
&= (1ull << 39) - 1;
3668 *litP
++ = (char)(0x80 + exponent
);
3669 for (i
= 0; i
< 40; i
+= 8)
3670 *litP
++ = (char)(mantissa
>> i
);