1 /* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800
2 Copyright (C) 2005-2021 Free Software Foundation, Inc.
3 Contributed by Arnold Metselaar <arnold_m@operamail.com>
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 #include "safe-ctype.h"
26 #include "dwarf2dbg.h"
27 #include "dw2gencfi.h"
29 /* Exported constants. */
30 const char comment_chars
[] = ";\0";
31 const char line_comment_chars
[] = "#;\0";
32 const char line_separator_chars
[] = "\0";
33 const char EXP_CHARS
[] = "eE\0";
34 const char FLT_CHARS
[] = "RrDdFfSsHh\0";
36 /* For machine specific options. */
37 const char * md_shortopts
= ""; /* None yet. */
41 OPTION_MARCH
= OPTION_MD_BASE
,
55 OPTION_FP_SINGLE_FORMAT
,
56 OPTION_FP_DOUBLE_FORMAT
,
57 OPTION_COMPAT_LL_PREFIX
,
58 OPTION_COMPAT_COLONLESS
,
62 #define INS_Z80 (1 << 0)
63 #define INS_R800 (1 << 1)
64 #define INS_GBZ80 (1 << 2)
65 #define INS_Z180 (1 << 3)
66 #define INS_EZ80 (1 << 4)
67 #define INS_Z80N (1 << 5)
68 #define INS_MARCH_MASK 0xffff
70 #define INS_IDX_HALF (1 << 16)
71 #define INS_IN_F_C (1 << 17)
72 #define INS_OUT_C_0 (1 << 18)
73 #define INS_SLI (1 << 19)
74 #define INS_ROT_II_LD (1 << 20) /* instructions like SLA (ii+d),r; which is: LD r,(ii+d); SLA r; LD (ii+d),r */
75 #define INS_TUNE_MASK 0xffff0000
77 #define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80 | INS_Z80N)
80 #define INS_UNDOC (INS_IDX_HALF | INS_IN_F_C)
81 #define INS_UNPORT (INS_OUT_C_0 | INS_SLI | INS_ROT_II_LD)
83 struct option md_longopts
[] =
85 { "march", required_argument
, NULL
, OPTION_MARCH
},
86 { "z80", no_argument
, NULL
, OPTION_MACH_Z80
},
87 { "r800", no_argument
, NULL
, OPTION_MACH_R800
},
88 { "z180", no_argument
, NULL
, OPTION_MACH_Z180
},
89 { "ez80", no_argument
, NULL
, OPTION_MACH_EZ80_Z80
},
90 { "ez80-adl", no_argument
, NULL
, OPTION_MACH_EZ80_ADL
},
91 { "fp-s", required_argument
, NULL
, OPTION_FP_SINGLE_FORMAT
},
92 { "fp-d", required_argument
, NULL
, OPTION_FP_DOUBLE_FORMAT
},
93 { "strict", no_argument
, NULL
, OPTION_MACH_FUD
},
94 { "full", no_argument
, NULL
, OPTION_MACH_IUP
},
95 { "with-inst", required_argument
, NULL
, OPTION_MACH_INST
},
96 { "Wnins", required_argument
, NULL
, OPTION_MACH_INST
},
97 { "without-inst", required_argument
, NULL
, OPTION_MACH_NO_INST
},
98 { "local-prefix", required_argument
, NULL
, OPTION_COMPAT_LL_PREFIX
},
99 { "colonless", no_argument
, NULL
, OPTION_COMPAT_COLONLESS
},
100 { "sdcc", no_argument
, NULL
, OPTION_COMPAT_SDCC
},
101 { "Fins", required_argument
, NULL
, OPTION_MACH_NO_INST
},
102 { "ignore-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_IUD
},
103 { "Wnud", no_argument
, NULL
, OPTION_MACH_IUD
},
104 { "warn-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_WUD
},
105 { "Wud", no_argument
, NULL
, OPTION_MACH_WUD
},
106 { "forbid-undocumented-instructions", no_argument
, NULL
, OPTION_MACH_FUD
},
107 { "Fud", no_argument
, NULL
, OPTION_MACH_FUD
},
108 { "ignore-unportable-instructions", no_argument
, NULL
, OPTION_MACH_IUP
},
109 { "Wnup", no_argument
, NULL
, OPTION_MACH_IUP
},
110 { "warn-unportable-instructions", no_argument
, NULL
, OPTION_MACH_WUP
},
111 { "Wup", no_argument
, NULL
, OPTION_MACH_WUP
},
112 { "forbid-unportable-instructions", no_argument
, NULL
, OPTION_MACH_FUP
},
113 { "Fup", no_argument
, NULL
, OPTION_MACH_FUP
},
115 { NULL
, no_argument
, NULL
, 0 }
118 size_t md_longopts_size
= sizeof (md_longopts
);
120 extern int coff_flags
;
121 /* Instruction classes that silently assembled. */
122 static int ins_ok
= INS_Z80
| INS_UNDOC
;
123 /* Instruction classes that generate errors. */
124 static int ins_err
= ~(INS_Z80
| INS_UNDOC
);
125 /* eZ80 CPU mode (ADL or Z80) */
126 static int cpu_mode
= 0; /* 0 - Z80, 1 - ADL */
127 /* accept SDCC specific instruction encoding */
128 static int sdcc_compat
= 0;
129 /* accept colonless labels */
130 static int colonless_labels
= 0;
131 /* local label prefix (NULL - default) */
132 static const char *local_label_prefix
= NULL
;
133 /* floating point support */
134 typedef const char *(*str_to_float_t
)(char *litP
, int *sizeP
);
135 static str_to_float_t str_to_float
;
136 static str_to_float_t str_to_double
;
138 /* mode of current instruction */
139 #define INST_MODE_S 0 /* short data mode */
140 #define INST_MODE_IS 0 /* short instruction mode */
141 #define INST_MODE_L 2 /* long data mode */
142 #define INST_MODE_IL 1 /* long instruction mode */
143 #define INST_MODE_FORCED 4 /* CPU mode changed by instruction suffix*/
144 static char inst_mode
;
155 static const struct match_info
158 {"z80", INS_Z80
, 0, 0, "Zilog Z80" },
159 {"ez80", INS_EZ80
, 0, 0, "Zilog eZ80" },
160 {"gbz80", INS_GBZ80
, INS_UNDOC
|INS_UNPORT
, 0, "GameBoy Z80" },
161 {"r800", INS_R800
, INS_UNPORT
, 0, "Ascii R800" },
162 {"z180", INS_Z180
, INS_UNDOC
|INS_UNPORT
, 0, "Zilog Z180" },
163 {"z80n", INS_Z80N
, 0, 0, "Z80 Next" }
166 static const struct match_info
169 {"full", INS_UNDOC
|INS_UNPORT
, 0, 0, "assemble all known instructions" },
170 {"adl", 0, 0, 1, "eZ80 ADL mode by default" },
171 {"xyhl", INS_IDX_HALF
, 0, 0, "instructions with halves of index registers" },
172 {"infc", INS_IN_F_C
, 0, 0, "instruction IN F,(C)" },
173 {"outc0", INS_OUT_C_0
, 0, 0, "instruction OUT (C),0" },
174 {"sli", INS_SLI
, 0, 0, "instruction known as SLI, SLL, or SL1" },
175 {"xdcb", INS_ROT_II_LD
, 0, 0, "instructions like RL (IX+d),R (DD/FD CB dd oo)" }
179 setup_march (const char *name
, int *ok
, int *err
, int *mode
)
182 size_t len
= strcspn (name
, "+-");
183 for (i
= 0; i
< ARRAY_SIZE (match_cpu_table
); ++i
)
184 if (!strncasecmp (name
, match_cpu_table
[i
].name
, len
)
185 && strlen (match_cpu_table
[i
].name
) == len
)
187 *ok
= match_cpu_table
[i
].ins_ok
;
188 *err
= match_cpu_table
[i
].ins_err
;
189 *mode
= match_cpu_table
[i
].cpu_mode
;
193 if (i
>= ARRAY_SIZE (match_cpu_table
))
194 as_fatal (_("Invalid CPU is specified: %s"), name
);
198 name
= &name
[len
+ 1];
199 len
= strcspn (name
, "+-");
200 for (i
= 0; i
< ARRAY_SIZE (match_ext_table
); ++i
)
201 if (!strncasecmp (name
, match_ext_table
[i
].name
, len
)
202 && strlen (match_ext_table
[i
].name
) == len
)
206 *ok
|= match_ext_table
[i
].ins_ok
;
207 *err
&= ~match_ext_table
[i
].ins_ok
;
208 *mode
|= match_ext_table
[i
].cpu_mode
;
212 *ok
&= ~match_ext_table
[i
].ins_ok
;
213 *err
|= match_ext_table
[i
].ins_ok
;
214 *mode
&= ~match_ext_table
[i
].cpu_mode
;
218 if (i
>= ARRAY_SIZE (match_ext_table
))
219 as_fatal (_("Invalid EXTENSION is specified: %s"), name
);
224 setup_instruction (const char *inst
, int *add
, int *sub
)
227 if (!strcmp (inst
, "idx-reg-halves"))
229 else if (!strcmp (inst
, "sli"))
231 else if (!strcmp (inst
, "op-ii-ld"))
233 else if (!strcmp (inst
, "in-f-c"))
235 else if (!strcmp (inst
, "out-c-0"))
245 str_to_zeda32 (char *litP
, int *sizeP
);
247 str_to_float48 (char *litP
, int *sizeP
);
249 str_to_ieee754_h (char *litP
, int *sizeP
);
251 str_to_ieee754_s (char *litP
, int *sizeP
);
253 str_to_ieee754_d (char *litP
, int *sizeP
);
255 static str_to_float_t
256 get_str_to_float (const char *arg
)
258 if (strcasecmp (arg
, "zeda32") == 0)
259 return str_to_zeda32
;
261 if (strcasecmp (arg
, "math48") == 0)
262 return str_to_float48
;
264 if (strcasecmp (arg
, "half") != 0)
265 return str_to_ieee754_h
;
267 if (strcasecmp (arg
, "single") != 0)
268 return str_to_ieee754_s
;
270 if (strcasecmp (arg
, "double") != 0)
271 return str_to_ieee754_d
;
273 if (strcasecmp (arg
, "ieee754") == 0)
274 as_fatal (_("invalid floating point numbers type `%s'"), arg
);
279 setup_instruction_list (const char *list
, int *add
, int *sub
)
286 for (b
= list
; *b
!= '\0';)
293 if (sz
== 0 || sz
>= (int)sizeof (buf
))
295 as_bad (_("invalid INST in command line: %s"), b
);
300 if (setup_instruction (buf
, add
, sub
))
304 as_bad (_("invalid INST in command line: %s"), buf
);
315 md_parse_option (int c
, const char* arg
)
322 setup_march (arg
, & ins_ok
, & ins_err
, & cpu_mode
);
324 case OPTION_MACH_Z80
:
325 setup_march ("z80", & ins_ok
, & ins_err
, & cpu_mode
);
327 case OPTION_MACH_R800
:
328 setup_march ("r800", & ins_ok
, & ins_err
, & cpu_mode
);
330 case OPTION_MACH_Z180
:
331 setup_march ("z180", & ins_ok
, & ins_err
, & cpu_mode
);
333 case OPTION_MACH_EZ80_Z80
:
334 setup_march ("ez80", & ins_ok
, & ins_err
, & cpu_mode
);
336 case OPTION_MACH_EZ80_ADL
:
337 setup_march ("ez80+adl", & ins_ok
, & ins_err
, & cpu_mode
);
339 case OPTION_FP_SINGLE_FORMAT
:
340 str_to_float
= get_str_to_float (arg
);
342 case OPTION_FP_DOUBLE_FORMAT
:
343 str_to_double
= get_str_to_float (arg
);
345 case OPTION_MACH_INST
:
346 if ((ins_ok
& INS_GBZ80
) == 0)
347 return setup_instruction_list (arg
, & ins_ok
, & ins_err
);
349 case OPTION_MACH_NO_INST
:
350 if ((ins_ok
& INS_GBZ80
) == 0)
351 return setup_instruction_list (arg
, & ins_err
, & ins_ok
);
353 case OPTION_MACH_WUD
:
354 case OPTION_MACH_IUD
:
355 if ((ins_ok
& INS_GBZ80
) == 0)
358 ins_err
&= ~INS_UNDOC
;
361 case OPTION_MACH_WUP
:
362 case OPTION_MACH_IUP
:
363 if ((ins_ok
& INS_GBZ80
) == 0)
365 ins_ok
|= INS_UNDOC
| INS_UNPORT
;
366 ins_err
&= ~(INS_UNDOC
| INS_UNPORT
);
369 case OPTION_MACH_FUD
:
370 if ((ins_ok
& (INS_R800
| INS_GBZ80
)) == 0)
372 ins_ok
&= (INS_UNDOC
| INS_UNPORT
);
373 ins_err
|= INS_UNDOC
| INS_UNPORT
;
376 case OPTION_MACH_FUP
:
377 ins_ok
&= ~INS_UNPORT
;
378 ins_err
|= INS_UNPORT
;
380 case OPTION_COMPAT_LL_PREFIX
:
381 local_label_prefix
= (arg
&& *arg
) ? arg
: NULL
;
383 case OPTION_COMPAT_SDCC
:
386 case OPTION_COMPAT_COLONLESS
:
387 colonless_labels
= 1;
395 md_show_usage (FILE * f
)
399 CPU model options:\n\
400 -march=CPU[+EXT...][-EXT...]\n\
401 \t\t\t generate code for CPU, where CPU is one of:\n"));
402 for (i
= 0; i
< ARRAY_SIZE(match_cpu_table
); ++i
)
403 fprintf (f
, " %-8s\t\t %s\n", match_cpu_table
[i
].name
, match_cpu_table
[i
].comment
);
404 fprintf (f
, _("And EXT is combination (+EXT - add, -EXT - remove) of:\n"));
405 for (i
= 0; i
< ARRAY_SIZE(match_ext_table
); ++i
)
406 fprintf (f
, " %-8s\t\t %s\n", match_ext_table
[i
].name
, match_ext_table
[i
].comment
);
408 Compatibility options:\n\
409 -local-prefix=TEXT\t treat labels prefixed by TEXT as local\n\
410 -colonless\t\t permit colonless labels\n\
411 -sdcc\t\t\t accept SDCC specific instruction syntax\n\
412 -fp-s=FORMAT\t\t set single precision FP numbers format\n\
413 -fp-d=FORMAT\t\t set double precision FP numbers format\n\
414 Where FORMAT one of:\n\
415 ieee754\t\t IEEE754 compatible (depends on directive)\n\
416 half\t\t\t IEEE754 half precision (16 bit)\n\
417 single\t\t IEEE754 single precision (32 bit)\n\
418 double\t\t IEEE754 double precision (64 bit)\n\
419 zeda32\t\t Zeda z80float library 32 bit format\n\
420 math48\t\t 48 bit format from Math48 library\n\
422 Default: -march=z80+xyhl+infc\n"));
425 static symbolS
* zero
;
433 #define R_STACKABLE (0x80)
434 #define R_ARITH (0x40)
437 #define R_INDEX (R_IX | R_IY)
446 #define REG_F (6 | 8)
451 #define REG_AF (3 | R_STACKABLE)
452 #define REG_BC (0 | R_STACKABLE | R_ARITH)
453 #define REG_DE (1 | R_STACKABLE | R_ARITH)
454 #define REG_HL (2 | R_STACKABLE | R_ARITH)
455 #define REG_IX (REG_HL | R_IX)
456 #define REG_IY (REG_HL | R_IY)
457 #define REG_SP (3 | R_ARITH)
459 static const struct reg_entry regtable
[] =
461 {"a", REG_A
, INS_ALL
},
462 {"af", REG_AF
, INS_ALL
},
463 {"b", REG_B
, INS_ALL
},
464 {"bc", REG_BC
, INS_ALL
},
465 {"c", REG_C
, INS_ALL
},
466 {"d", REG_D
, INS_ALL
},
467 {"de", REG_DE
, INS_ALL
},
468 {"e", REG_E
, INS_ALL
},
469 {"f", REG_F
, INS_IN_F_C
| INS_Z80N
| INS_R800
},
470 {"h", REG_H
, INS_ALL
},
471 {"hl", REG_HL
, INS_ALL
},
472 {"i", REG_I
, INS_NOT_GBZ80
},
473 {"ix", REG_IX
, INS_NOT_GBZ80
},
474 {"ixh", REG_H
| R_IX
, INS_IDX_HALF
| INS_EZ80
| INS_R800
| INS_Z80N
},
475 {"ixl", REG_L
| R_IX
, INS_IDX_HALF
| INS_EZ80
| INS_R800
| INS_Z80N
},
476 {"iy", REG_IY
, INS_NOT_GBZ80
},
477 {"iyh", REG_H
| R_IY
, INS_IDX_HALF
| INS_EZ80
| INS_R800
| INS_Z80N
},
478 {"iyl", REG_L
| R_IY
, INS_IDX_HALF
| INS_EZ80
| INS_R800
| INS_Z80N
},
479 {"l", REG_L
, INS_ALL
},
480 {"mb", REG_MB
, INS_EZ80
},
481 {"r", REG_R
, INS_NOT_GBZ80
},
482 {"sp", REG_SP
, INS_ALL
},
485 #define BUFLEN 8 /* Large enough for any keyword. */
490 expressionS nul
, reg
;
492 unsigned int i
, j
, k
;
495 memset (®
, 0, sizeof (reg
));
496 memset (&nul
, 0, sizeof (nul
));
498 if (ins_ok
& INS_EZ80
) /* if select EZ80 cpu then */
499 listing_lhs_width
= 6; /* use 6 bytes per line in the listing */
501 reg
.X_op
= O_register
;
503 reg
.X_add_symbol
= reg
.X_op_symbol
= 0;
504 for ( i
= 0 ; i
< ARRAY_SIZE ( regtable
) ; ++i
)
506 if (regtable
[i
].isa
&& !(regtable
[i
].isa
& ins_ok
))
508 reg
.X_add_number
= regtable
[i
].number
;
509 k
= strlen ( regtable
[i
].name
);
513 for ( j
= ( 1<<k
) ; j
; --j
)
515 for ( k
= 0 ; regtable
[i
].name
[k
] ; ++k
)
517 buf
[k
] = ( j
& ( 1<<k
) ) ? TOUPPER (regtable
[i
].name
[k
]) : regtable
[i
].name
[k
];
519 symbolS
* psym
= symbol_find_or_make (buf
);
520 S_SET_SEGMENT (psym
, reg_section
);
521 symbol_set_value_expression (psym
, ®
);
525 p
= input_line_pointer
;
526 input_line_pointer
= (char *) "0";
529 input_line_pointer
= p
;
530 zero
= make_expr_symbol (& nul
);
531 /* We do not use relaxation (yet). */
540 switch (ins_ok
& INS_MARCH_MASK
)
543 mach_type
= bfd_mach_z80
;
546 mach_type
= bfd_mach_r800
;
549 mach_type
= bfd_mach_z180
;
552 mach_type
= bfd_mach_gbz80
;
555 mach_type
= cpu_mode
? bfd_mach_ez80_adl
: bfd_mach_ez80_z80
;
558 mach_type
= bfd_mach_z80n
;
563 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach_type
);
566 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
568 z80_elf_final_processing (void)
569 {/* nothing to do, all is done by BFD itself */
572 elf_elfheader (stdoutput)->e_flags = elf_flags;
578 skip_space (const char *s
)
580 while (*s
== ' ' || *s
== '\t')
585 /* A non-zero return-value causes a continue in the
586 function read_a_source_file () in ../read.c. */
588 z80_start_line_hook (void)
593 /* Convert one character constants. */
594 for (p
= input_line_pointer
; *p
&& *p
!= '\n'; ++p
)
599 if (p
[1] != 0 && p
[1] != '\'' && p
[2] == '\'')
601 snprintf (buf
, 4, "%3d", (unsigned char)p
[1]);
609 for (quote
= *p
++; quote
!= *p
&& '\n' != *p
; ++p
)
613 as_bad (_("-- unterminated string"));
614 ignore_rest_of_line ();
618 case '#': /* force to use next expression as immediate value in SDCC */
621 if (ISSPACE(p
[1]) && *skip_space (p
+ 1) == '(')
622 { /* ld a,# (expr)... -> ld a,0+(expr)... */
626 else /* ld a,#(expr)... -> ld a,+(expr); ld a,#expr -> ld a, expr */
627 *p
= (p
[1] == '(') ? '+' : ' ';
631 /* Check for <label>[:] =|([.](EQU|DEFL)) <value>. */
632 if (is_name_beginner (*input_line_pointer
))
635 char c
, *rest
, *line_start
;
638 line_start
= input_line_pointer
;
641 c
= get_symbol_name (&name
);
642 rest
= input_line_pointer
+ 1;
643 if (c
== ':' && *rest
== ':')
645 /* remove second colon if SDCC compatibility enabled */
650 rest
= (char*)skip_space (rest
);
652 len
= (rest
[1] == '=') ? 2 : 1;
657 if (strncasecmp (rest
, "EQU", 3) == 0)
659 else if (strncasecmp (rest
, "DEFL", 4) == 0)
664 if (len
&& (len
<= 2 || !ISALPHA (rest
[len
])))
666 /* Handle assignment here. */
667 if (line_start
[-1] == '\n')
669 bump_line_counters ();
672 input_line_pointer
= rest
+ len
- 1;
673 /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
676 case 1: /* label = expr */
677 case 4: /* label DEFL expr */
680 case 2: /* label == expr */
681 case 3: /* label EQU expr */
689 /* Restore line and pointer. */
690 (void) restore_line_pointer (c
);
691 input_line_pointer
= line_start
;
698 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
704 md_atof (int type
, char *litP
, int *sizeP
)
713 return str_to_float (litP
, sizeP
);
720 return str_to_double (litP
, sizeP
);
723 return ieee_md_atof (type
, litP
, sizeP
, false);
727 md_section_align (segT seg ATTRIBUTE_UNUSED
, valueT size
)
733 md_pcrel_from (fixS
* fixp
)
735 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
738 typedef const char * (asfunc
)(char, char, const char*);
740 typedef struct _table_t
743 unsigned char prefix
;
744 unsigned char opcode
;
746 unsigned inss
; /*0 - all CPU types or list of supported INS_* */
749 /* Compares the key for structs that start with a char * to the key. */
751 key_cmp (const void * a
, const void * b
)
753 const char *str_a
, *str_b
;
755 str_a
= *((const char**)a
);
756 str_b
= *((const char**)b
);
757 return strcmp (str_a
, str_b
);
761 const char *key
= buf
;
763 /* Prevent an error on a line from also generating
764 a "junk at end of line" error message. */
765 static char err_flag
;
768 error (const char * message
)
773 as_bad ("%s", message
);
780 error (_("illegal operand"));
784 wrong_mach (int ins_type
)
786 if (ins_type
& ins_err
)
789 as_warn (_("undocumented instruction"));
793 check_mach (int ins_type
)
795 if ((ins_type
& ins_ok
) == 0)
796 wrong_mach (ins_type
);
799 /* Check whether an expression is indirect. */
801 is_indir (const char *s
)
807 /* Indirection is indicated with parentheses. */
810 for (p
= s
, depth
= 0; *p
&& *p
!= ','; ++p
)
816 for (quote
= *p
++; quote
!= *p
&& *p
!= '\n'; ++p
)
817 if (*p
== '\\' && p
[1])
827 p
= skip_space (p
+ 1);
833 error (_("mismatched parentheses"));
839 error (_("mismatched parentheses"));
844 /* Check whether a symbol involves a register. */
846 contains_register (symbolS
*sym
)
850 expressionS
* ex
= symbol_get_value_expression (sym
);
859 if (ex
->X_op_symbol
&& contains_register (ex
->X_op_symbol
))
864 if (ex
->X_add_symbol
&& contains_register (ex
->X_add_symbol
))
876 /* Parse general expression, not looking for indexed addressing. */
878 parse_exp_not_indexed (const char *s
, expressionS
*op
)
884 memset (op
, 0, sizeof (*op
));
886 if (sdcc_compat
&& (*p
== '<' || *p
== '>'))
890 case '<': /* LSB request */
893 case '>': /* MSB request */
894 make_shift
= cpu_mode
? 16 : 8;
901 if (make_shift
== -1)
902 indir
= is_indir (p
);
906 if (indir
&& (ins_ok
& INS_GBZ80
))
907 { /* check for instructions like ld a,(hl+), ld (hl-),a */
908 p
= skip_space (p
+1);
909 if (!strncasecmp (p
, "hl", 2))
912 if (*skip_space(p
+1) == ')' && (*p
== '+' || *p
== '-'))
915 op
->X_add_symbol
= NULL
;
916 op
->X_add_number
= (*p
== '+') ? REG_HL
: -REG_HL
;
917 input_line_pointer
= (char*)skip_space(p
+ 1) + 1;
918 return input_line_pointer
;
922 input_line_pointer
= (char*) s
;
927 error (_("missing operand"));
930 error (_("bad expression syntax"));
938 /* replace [op] by [op >> shift] */
940 op
->X_add_symbol
= make_expr_symbol (op
);
941 op
->X_add_number
= 0;
942 op
->X_op
= O_right_shift
;
943 memset (&data
, 0, sizeof (data
));
944 data
.X_op
= O_constant
;
945 data
.X_add_number
= make_shift
;
946 op
->X_op_symbol
= make_expr_symbol (&data
);
948 return input_line_pointer
;
952 unify_indexed (expressionS
*op
)
954 if (O_register
!= symbol_get_value_expression (op
->X_add_symbol
)->X_op
)
957 int rnum
= symbol_get_value_expression (op
->X_add_symbol
)->X_add_number
;
958 if ( ((REG_IX
!= rnum
) && (REG_IY
!= rnum
)) || contains_register (op
->X_op_symbol
))
964 /* Convert subtraction to addition of negative value. */
965 if (O_subtract
== op
->X_op
)
968 memset (&minus
, 0, sizeof (minus
));
969 minus
.X_op
= O_uminus
;
970 minus
.X_add_symbol
= op
->X_op_symbol
;
971 op
->X_op_symbol
= make_expr_symbol (&minus
);
975 /* Clear X_add_number of the expression. */
976 if (op
->X_add_number
!= 0)
979 memset (&add
, 0, sizeof (add
));
981 add
.X_add_number
= op
->X_add_number
;
982 add
.X_add_symbol
= op
->X_op_symbol
;
983 op
->X_add_symbol
= make_expr_symbol (&add
);
986 op
->X_add_symbol
= op
->X_op_symbol
;
988 op
->X_add_number
= rnum
;
993 /* Parse expression, change operator to O_md1 for indexed addressing. */
995 parse_exp (const char *s
, expressionS
*op
)
997 const char* res
= parse_exp_not_indexed (s
, op
);
1002 if (unify_indexed (op
) && op
->X_md
)
1006 if (op
->X_md
&& ((REG_IX
== op
->X_add_number
) || (REG_IY
== op
->X_add_number
)))
1008 op
->X_add_symbol
= zero
;
1013 /* parse SDCC syntax where index register offset placed before parentheses */
1014 if (sdcc_compat
&& is_indir (res
))
1018 res
= parse_exp (res
, op
);
1019 if (op
->X_op
!= O_md1
|| op
->X_add_symbol
!= zero
)
1022 op
->X_add_symbol
= make_expr_symbol (&off
);
1031 /* Condition codes, including some synonyms provided by HiTech zas. */
1032 static const struct reg_entry cc_tab
[] =
1034 { "age", 6 << 3, INS_ALL
},
1035 { "alt", 7 << 3, INS_ALL
},
1036 { "c", 3 << 3, INS_ALL
},
1037 { "di", 4 << 3, INS_ALL
},
1038 { "ei", 5 << 3, INS_ALL
},
1039 { "lge", 2 << 3, INS_ALL
},
1040 { "llt", 3 << 3, INS_ALL
},
1041 { "m", 7 << 3, INS_ALL
},
1042 { "nc", 2 << 3, INS_ALL
},
1043 { "nz", 0 << 3, INS_ALL
},
1044 { "p", 6 << 3, INS_ALL
},
1045 { "pe", 5 << 3, INS_ALL
},
1046 { "po", 4 << 3, INS_ALL
},
1047 { "z", 1 << 3, INS_ALL
},
1050 /* Parse condition code. */
1052 parse_cc (const char *s
, char * op
)
1056 struct reg_entry
* cc_p
;
1058 for (i
= 0; i
< BUFLEN
; ++i
)
1060 if (!ISALPHA (s
[i
])) /* Condition codes consist of letters only. */
1062 buf
[i
] = TOLOWER (s
[i
]);
1066 && ((s
[i
] == 0) || (s
[i
] == ',')))
1069 cc_p
= bsearch (&key
, cc_tab
, ARRAY_SIZE (cc_tab
),
1070 sizeof (cc_tab
[0]), key_cmp
);
1087 emit_insn (char prefix
, char opcode
, const char * args
)
1102 void z80_cons_fix_new (fragS
*frag_p
, int offset
, int nbytes
, expressionS
*exp
)
1104 bfd_reloc_code_real_type r
[4] =
1112 if (nbytes
< 1 || nbytes
> 4)
1114 as_bad (_("unsupported BFD relocation size %u"), nbytes
);
1118 fix_new_exp (frag_p
, offset
, nbytes
, exp
, 0, r
[nbytes
-1]);
1123 emit_data_val (expressionS
* val
, int size
)
1126 bfd_reloc_code_real_type r_type
;
1128 p
= frag_more (size
);
1129 if (val
->X_op
== O_constant
)
1132 for (i
= 0; i
< size
; ++i
)
1133 p
[i
] = (char)(val
->X_add_number
>> (i
*8));
1139 case 1: r_type
= BFD_RELOC_8
; break;
1140 case 2: r_type
= BFD_RELOC_16
; break;
1141 case 3: r_type
= BFD_RELOC_24
; break;
1142 case 4: r_type
= BFD_RELOC_32
; break;
1143 case 8: r_type
= BFD_RELOC_64
; break;
1145 as_fatal (_("invalid data size %d"), size
);
1148 if ( (val
->X_op
== O_register
)
1149 || (val
->X_op
== O_md1
)
1150 || contains_register (val
->X_add_symbol
)
1151 || contains_register (val
->X_op_symbol
))
1154 if (size
<= 2 && val
->X_op_symbol
)
1156 bool simplify
= true;
1157 int shift
= symbol_get_value_expression (val
->X_op_symbol
)->X_add_number
;
1158 if (val
->X_op
== O_bit_and
&& shift
== (1 << (size
*8))-1)
1160 else if (val
->X_op
!= O_right_shift
)
1167 case 0: r_type
= BFD_RELOC_Z80_BYTE0
; break;
1168 case 8: r_type
= BFD_RELOC_Z80_BYTE1
; break;
1169 case 16: r_type
= BFD_RELOC_Z80_BYTE2
; break;
1170 case 24: r_type
= BFD_RELOC_Z80_BYTE3
; break;
1171 default: simplify
= false;
1174 else /* if (size == 2) */
1178 case 0: r_type
= BFD_RELOC_Z80_WORD0
; break;
1179 case 16: r_type
= BFD_RELOC_Z80_WORD1
; break;
1181 case 24: /* add two byte fixups */
1182 val
->X_op
= O_symbol
;
1183 val
->X_op_symbol
= NULL
;
1184 val
->X_add_number
= 0;
1187 fix_new_exp (frag_now
, p
++ - frag_now
->fr_literal
, 1, val
, false,
1188 BFD_RELOC_Z80_BYTE1
);
1189 /* prepare to next byte */
1190 r_type
= BFD_RELOC_Z80_BYTE2
;
1193 r_type
= BFD_RELOC_Z80_BYTE3
; /* high byte will be 0 */
1197 default: simplify
= false;
1203 val
->X_op
= O_symbol
;
1204 val
->X_op_symbol
= NULL
;
1205 val
->X_add_number
= 0;
1209 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, size
, val
, false, r_type
);
1213 emit_byte (expressionS
* val
, bfd_reloc_code_real_type r_type
)
1217 if (r_type
== BFD_RELOC_8
)
1219 emit_data_val (val
, 1);
1223 *p
= val
->X_add_number
;
1224 if (contains_register (val
->X_add_symbol
) || contains_register (val
->X_op_symbol
))
1228 else if ((r_type
== BFD_RELOC_8_PCREL
) && (val
->X_op
== O_constant
))
1230 as_bad (_("cannot make a relative jump to an absolute location"));
1232 else if (val
->X_op
== O_constant
)
1234 if ((val
->X_add_number
< -128) || (val
->X_add_number
>= 128))
1236 if (r_type
== BFD_RELOC_Z80_DISP8
)
1237 as_bad (_("index overflow (%+ld)"), val
->X_add_number
);
1239 as_bad (_("offset overflow (%+ld)"), val
->X_add_number
);
1244 /* For symbols only, constants are stored at begin of function. */
1245 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 1, val
,
1246 r_type
== BFD_RELOC_8_PCREL
, r_type
);
1251 emit_word (expressionS
* val
)
1253 emit_data_val (val
, (inst_mode
& INST_MODE_IL
) ? 3 : 2);
1257 emit_mx (char prefix
, char opcode
, int shift
, expressionS
* arg
)
1258 /* The operand m may be r, (hl), (ix+d), (iy+d),
1259 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1264 rnum
= arg
->X_add_number
;
1280 if ((prefix
== 0) && (rnum
& R_INDEX
))
1282 prefix
= (rnum
& R_IX
) ? 0xDD : 0xFD;
1283 if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
1284 check_mach (INS_IDX_HALF
);
1293 q
= frag_more (prefix
? 2 : 1);
1296 * q
++ = opcode
+ (rnum
<< shift
);
1299 if (ins_ok
& INS_GBZ80
)
1305 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1306 *q
= (prefix
) ? prefix
: (opcode
+ (6 << shift
));
1308 expressionS offset
= *arg
;
1309 offset
.X_op
= O_symbol
;
1310 offset
.X_add_number
= 0;
1311 emit_byte (&offset
, BFD_RELOC_Z80_DISP8
);
1316 *q
= opcode
+(6<<shift
);
1324 /* The operand m may be r, (hl), (ix+d), (iy+d),
1325 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1327 emit_m (char prefix
, char opcode
, const char *args
)
1332 p
= parse_exp (args
, &arg_m
);
1337 emit_mx (prefix
, opcode
, 0, &arg_m
);
1345 /* The operand m may be as above or one of the undocumented
1346 combinations (ix+d),r and (iy+d),r (if unportable instructions
1350 emit_mr (char prefix
, char opcode
, const char *args
)
1352 expressionS arg_m
, arg_r
;
1355 p
= parse_exp (args
, & arg_m
);
1362 p
= parse_exp (p
+ 1, & arg_r
);
1364 if ((arg_r
.X_md
== 0)
1365 && (arg_r
.X_op
== O_register
)
1366 && (arg_r
.X_add_number
< 8))
1367 opcode
+= arg_r
.X_add_number
- 6; /* Emit_mx () will add 6. */
1373 if (!(ins_ok
& INS_Z80N
))
1374 check_mach (INS_ROT_II_LD
);
1378 emit_mx (prefix
, opcode
, 0, & arg_m
);
1387 emit_sx (char prefix
, char opcode
, expressionS
* arg_p
)
1391 switch (arg_p
->X_op
)
1395 emit_mx (prefix
, opcode
, 0, arg_p
);
1402 q
= frag_more (prefix
? 2 : 1);
1406 emit_byte (arg_p
, BFD_RELOC_8
);
1411 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1413 emit_s (char prefix
, char opcode
, const char *args
)
1418 p
= parse_exp (args
, & arg_s
);
1419 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
1420 { /* possible instruction in generic format op A,x */
1421 if (!(ins_ok
& INS_EZ80
) && !sdcc_compat
)
1424 p
= parse_exp (p
, & arg_s
);
1426 emit_sx (prefix
, opcode
, & arg_s
);
1431 emit_sub (char prefix
, char opcode
, const char *args
)
1436 if (!(ins_ok
& INS_GBZ80
))
1437 return emit_s (prefix
, opcode
, args
);
1438 p
= parse_exp (args
, & arg_s
);
1441 error (_("bad instruction syntax"));
1445 if (arg_s
.X_md
!= 0 || arg_s
.X_op
!= O_register
|| arg_s
.X_add_number
!= REG_A
)
1448 p
= parse_exp (p
, & arg_s
);
1450 emit_sx (prefix
, opcode
, & arg_s
);
1455 emit_swap (char prefix
, char opcode
, const char *args
)
1461 if (!(ins_ok
& INS_Z80N
))
1462 return emit_mr (prefix
, opcode
, args
);
1464 /* check for alias swap a for swapnib of Z80N */
1465 p
= parse_exp (args
, ®
);
1466 if (reg
.X_md
!= 0 || reg
.X_op
!= O_register
|| reg
.X_add_number
!= REG_A
)
1476 emit_call (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1479 const char *p
; char *q
;
1481 p
= parse_exp_not_indexed (args
, &addr
);
1493 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1495 emit_incdec (char prefix
, char opcode
, const char * args
)
1497 expressionS operand
;
1499 const char *p
; char *q
;
1501 p
= parse_exp (args
, &operand
);
1502 rnum
= operand
.X_add_number
;
1503 if ((! operand
.X_md
)
1504 && (operand
.X_op
== O_register
)
1507 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1509 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1510 *q
= prefix
+ ((rnum
& 3) << 4);
1514 if ((operand
.X_op
== O_md1
) || (operand
.X_op
== O_register
))
1515 emit_mx (0, opcode
, 3, & operand
);
1523 emit_jr (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1529 p
= parse_exp_not_indexed (args
, &addr
);
1536 addr
.X_add_number
--; /* pcrel computes after offset code */
1537 emit_byte (&addr
, BFD_RELOC_8_PCREL
);
1543 emit_jp (char prefix
, char opcode
, const char * args
)
1550 p
= parse_exp_not_indexed (args
, & addr
);
1553 rnum
= addr
.X_add_number
;
1554 if ((O_register
== addr
.X_op
) && (REG_HL
== (rnum
& ~R_INDEX
)))
1556 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1558 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1561 else if (addr
.X_op
== O_register
&& rnum
== REG_C
&& (ins_ok
& INS_Z80N
))
1580 emit_im (char prefix
, char opcode
, const char * args
)
1586 p
= parse_exp (args
, & mode
);
1587 if (mode
.X_md
|| (mode
.X_op
!= O_constant
))
1590 switch (mode
.X_add_number
)
1594 ++mode
.X_add_number
;
1599 *q
= opcode
+ 8*mode
.X_add_number
;
1608 emit_pop (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1614 p
= parse_exp (args
, & regp
);
1616 && (regp
.X_op
== O_register
)
1617 && (regp
.X_add_number
& R_STACKABLE
))
1621 rnum
= regp
.X_add_number
;
1625 *q
++ = (rnum
&R_IX
)?0xDD:0xFD;
1629 *q
= opcode
+ ((rnum
& 3) << 4);
1638 emit_push (char prefix
, char opcode
, const char * args
)
1644 p
= parse_exp (args
, & arg
);
1645 if (arg
.X_op
== O_register
)
1646 return emit_pop (prefix
, opcode
, args
);
1648 if (arg
.X_md
|| arg
.X_op
== O_md1
|| !(ins_ok
& INS_Z80N
))
1656 fix_new_exp (frag_now
, q
- frag_now
->fr_literal
, 2, &arg
, false,
1657 BFD_RELOC_Z80_16_BE
);
1663 emit_retcc (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1668 p
= parse_cc (args
, &cc
);
1674 return p
? p
: args
;
1678 emit_adc (char prefix
, char opcode
, const char * args
)
1685 p
= parse_exp (args
, &term
);
1688 error (_("bad instruction syntax"));
1692 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1695 switch (term
.X_add_number
)
1698 p
= emit_s (0, prefix
, p
);
1701 p
= parse_exp (p
, &term
);
1702 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1704 rnum
= term
.X_add_number
;
1705 if (R_ARITH
== (rnum
& (R_ARITH
| R_INDEX
)))
1709 *q
= opcode
+ ((rnum
& 3) << 4);
1721 emit_add (char prefix
, char opcode
, const char * args
)
1728 p
= parse_exp (args
, &term
);
1731 error (_("bad instruction syntax"));
1735 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1738 switch (term
.X_add_number
)
1741 p
= emit_s (0, prefix
, p
);
1744 p
= parse_exp (p
, &term
);
1745 if (!(ins_ok
& INS_GBZ80
) || term
.X_md
|| term
.X_op
== O_register
)
1749 emit_byte (&term
, BFD_RELOC_Z80_DISP8
);
1753 if (!(ins_ok
& INS_Z80N
))
1762 lhs
= term
.X_add_number
;
1763 p
= parse_exp (p
, &term
);
1764 rhs
= term
.X_add_number
;
1765 if (term
.X_md
!= 0 || term
.X_op
== O_md1
)
1767 else if ((term
.X_op
== O_register
) && (rhs
& R_ARITH
) && (rhs
== lhs
|| (rhs
& ~R_INDEX
) != REG_HL
))
1771 q
= frag_more ((lhs
& R_INDEX
) ? 2 : 1);
1773 *q
++ = (lhs
& R_IX
) ? 0xDD : 0xFD;
1774 *q
= opcode
+ ((rhs
& 3) << 4);
1778 else if (!(lhs
& R_INDEX
) && (ins_ok
& INS_Z80N
))
1780 if (term
.X_op
== O_register
&& rhs
== REG_A
)
1781 { /* ADD BC/DE/HL,A */
1784 *q
= 0x33 - (lhs
& 3);
1787 else if (term
.X_op
!= O_register
&& term
.X_op
!= O_md1
)
1788 { /* ADD BC/DE/HL,nn */
1791 *q
= 0x36 - (lhs
& 3);
1804 emit_bit (char prefix
, char opcode
, const char * args
)
1810 p
= parse_exp (args
, &b
);
1812 error (_("bad instruction syntax"));
1814 bn
= b
.X_add_number
;
1816 && (b
.X_op
== O_constant
)
1821 /* Bit : no optional third operand. */
1822 p
= emit_m (prefix
, opcode
+ (bn
<< 3), p
);
1824 /* Set, res : resulting byte can be copied to register. */
1825 p
= emit_mr (prefix
, opcode
+ (bn
<< 3), p
);
1832 /* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
1834 emit_bshft (char prefix
, char opcode
, const char * args
)
1840 p
= parse_exp (args
, & r1
);
1842 error (_("bad instruction syntax"));
1843 p
= parse_exp (p
, & r2
);
1844 if (r1
.X_md
|| r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_DE
||
1845 r2
.X_md
|| r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_B
)
1854 emit_jpcc (char prefix
, char opcode
, const char * args
)
1859 p
= parse_cc (args
, & cc
);
1860 if (p
&& *p
++ == ',')
1861 p
= emit_call (0, opcode
+ cc
, p
);
1863 p
= (prefix
== (char)0xC3)
1864 ? emit_jp (0xE9, prefix
, args
)
1865 : emit_call (0, prefix
, args
);
1870 emit_jrcc (char prefix
, char opcode
, const char * args
)
1875 p
= parse_cc (args
, &cc
);
1876 if (p
&& *p
++ == ',')
1879 error (_("condition code invalid for jr"));
1881 p
= emit_jr (0, opcode
+ cc
, p
);
1884 p
= emit_jr (0, prefix
, args
);
1890 emit_ex (char prefix_in ATTRIBUTE_UNUSED
,
1891 char opcode_in ATTRIBUTE_UNUSED
, const char * args
)
1895 char prefix
, opcode
;
1897 p
= parse_exp_not_indexed (args
, &op
);
1901 error (_("bad instruction syntax"));
1905 prefix
= opcode
= 0;
1906 if (op
.X_op
== O_register
)
1907 switch (op
.X_add_number
| (op
.X_md
? 0x8000 : 0))
1910 if (TOLOWER (*p
++) == 'a' && TOLOWER (*p
++) == 'f')
1912 /* The scrubber changes '\'' to '`' in this context. */
1919 if (TOLOWER (*p
++) == 'h' && TOLOWER (*p
++) == 'l')
1923 p
= parse_exp (p
, & op
);
1924 if (op
.X_op
== O_register
1926 && (op
.X_add_number
& ~R_INDEX
) == REG_HL
)
1929 if (R_INDEX
& op
.X_add_number
)
1930 prefix
= (R_IX
& op
.X_add_number
) ? 0xDD : 0xFD;
1935 emit_insn (prefix
, opcode
, p
);
1943 emit_in (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1946 expressionS reg
, port
;
1950 p
= parse_exp (args
, ®
);
1951 if (reg
.X_md
&& reg
.X_op
== O_register
&& reg
.X_add_number
== REG_C
)
1952 { /* permit instruction in (c) as alias for in f,(c) */
1955 reg
.X_add_number
= REG_F
;
1961 error (_("bad instruction syntax"));
1964 p
= parse_exp (p
, &port
);
1967 && reg
.X_op
== O_register
1968 && (reg
.X_add_number
<= 7 || reg
.X_add_number
== REG_F
)
1971 if (port
.X_op
!= O_md1
&& port
.X_op
!= O_register
)
1973 if (REG_A
== reg
.X_add_number
)
1977 emit_byte (&port
, BFD_RELOC_8
);
1984 if (port
.X_add_number
== REG_C
|| port
.X_add_number
== REG_BC
)
1986 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
1988 else if (reg
.X_add_number
== REG_F
&& !(ins_ok
& (INS_R800
|INS_Z80N
)))
1989 check_mach (INS_IN_F_C
);
1992 *q
= 0x40|((reg
.X_add_number
&7)<<3);
2004 emit_in0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2007 expressionS reg
, port
;
2011 p
= parse_exp (args
, ®
);
2014 error (_("bad instruction syntax"));
2018 p
= parse_exp (p
, &port
);
2020 && reg
.X_op
== O_register
2021 && reg
.X_add_number
<= 7
2023 && port
.X_op
!= O_md1
2024 && port
.X_op
!= O_register
)
2028 *q
= 0x00|(reg
.X_add_number
<< 3);
2029 emit_byte (&port
, BFD_RELOC_8
);
2037 emit_out (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2040 expressionS reg
, port
;
2044 p
= parse_exp (args
, & port
);
2047 error (_("bad instruction syntax"));
2050 p
= parse_exp (p
, ®
);
2052 { ill_op (); return p
; }
2053 /* Allow "out (c), 0" as unportable instruction. */
2054 if (reg
.X_op
== O_constant
&& reg
.X_add_number
== 0)
2056 if (!(ins_ok
& INS_Z80N
))
2057 check_mach (INS_OUT_C_0
);
2058 reg
.X_op
= O_register
;
2059 reg
.X_add_number
= 6;
2062 || reg
.X_op
!= O_register
2063 || reg
.X_add_number
> 7)
2066 if (port
.X_op
!= O_register
&& port
.X_op
!= O_md1
)
2068 if (REG_A
== reg
.X_add_number
)
2072 emit_byte (&port
, BFD_RELOC_8
);
2079 if (REG_C
== port
.X_add_number
|| port
.X_add_number
== REG_BC
)
2081 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
2085 *q
= 0x41 | (reg
.X_add_number
<< 3);
2094 emit_out0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2097 expressionS reg
, port
;
2101 p
= parse_exp (args
, & port
);
2104 error (_("bad instruction syntax"));
2107 p
= parse_exp (p
, ®
);
2109 && port
.X_op
!= O_register
2110 && port
.X_op
!= O_md1
2112 && reg
.X_op
== O_register
2113 && reg
.X_add_number
<= 7)
2117 *q
= 0x01 | (reg
.X_add_number
<< 3);
2118 emit_byte (&port
, BFD_RELOC_8
);
2126 emit_rst (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2132 p
= parse_exp_not_indexed (args
, &addr
);
2133 if (addr
.X_op
!= O_constant
)
2135 error ("rst needs constant address");
2139 if (addr
.X_add_number
& ~(7 << 3))
2144 *q
= opcode
+ (addr
.X_add_number
& (7 << 3));
2149 /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
2151 emit_ld_m_n (expressionS
*dst
, expressionS
*src
)
2155 expressionS dst_offset
;
2157 switch (dst
->X_add_number
)
2159 case REG_HL
: prefix
= 0x00; break;
2160 case REG_IX
: prefix
= 0xDD; break;
2161 case REG_IY
: prefix
= 0xFD; break;
2167 q
= frag_more (prefix
? 2 : 1);
2174 dst_offset
.X_op
= O_symbol
;
2175 dst_offset
.X_add_number
= 0;
2176 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2178 emit_byte (src
, BFD_RELOC_8
);
2181 /* For 8-bit load register to memory instructions: LD (<expression>),r. */
2183 emit_ld_m_r (expressionS
*dst
, expressionS
*src
)
2187 expressionS dst_offset
;
2192 if (ins_ok
& INS_GBZ80
)
2193 { /* LD (HL+),A or LD (HL-),A */
2194 if (src
->X_op
!= O_register
|| src
->X_add_number
!= REG_A
)
2196 *frag_more (1) = (dst
->X_add_number
== REG_HL
) ? 0x22 : 0x32;
2200 prefix
= (dst
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2203 switch (dst
->X_add_number
)
2205 case REG_BC
: /* LD (BC),A */
2206 case REG_DE
: /* LD (DE),A */
2207 if (src
->X_add_number
== REG_A
)
2210 *q
= 0x02 | ((dst
->X_add_number
& 3) << 4);
2216 case REG_HL
: /* LD (HL),r or LD (ii+d),r */
2217 if (src
->X_add_number
<= 7)
2219 q
= frag_more (prefix
? 2 : 1);
2222 *q
= 0x70 | src
->X_add_number
;
2226 dst_offset
.X_op
= O_symbol
;
2227 dst_offset
.X_add_number
= 0;
2228 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2236 default: /* LD (nn),A */
2237 if (src
->X_add_number
== REG_A
)
2240 *q
= (ins_ok
& INS_GBZ80
) ? 0xEA : 0x32;
2249 /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
2251 emit_ld_m_rr (expressionS
*dst
, expressionS
*src
)
2256 expressionS dst_offset
;
2260 case O_md1
: /* eZ80 instructions LD (ii+d),rr */
2261 case O_register
: /* eZ80 instructions LD (HL),rr */
2262 if (!(ins_ok
& INS_EZ80
)) /* 16-bit indirect load group is supported by eZ80 only */
2264 switch (dst
->X_add_number
)
2266 case REG_IX
: prefix
= 0xDD; break;
2267 case REG_IY
: prefix
= 0xFD; break;
2268 case REG_HL
: prefix
= 0xED; break;
2272 switch (src
->X_add_number
)
2274 case REG_BC
: opcode
= 0x0F; break;
2275 case REG_DE
: opcode
= 0x1F; break;
2276 case REG_HL
: opcode
= 0x2F; break;
2277 case REG_IX
: opcode
= (prefix
!= 0xFD) ? 0x3F : 0x3E; break;
2278 case REG_IY
: opcode
= (prefix
!= 0xFD) ? 0x3E : 0x3F; break;
2282 q
= frag_more (prefix
? 2 : 1);
2285 if (prefix
== 0xFD || prefix
== 0xDD)
2288 dst_offset
.X_op
= O_symbol
;
2289 dst_offset
.X_add_number
= 0;
2290 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2293 default: /* LD (nn),rr */
2294 if (ins_ok
& INS_GBZ80
)
2296 /* GBZ80 supports only LD (nn),SP */
2297 if (src
->X_add_number
== REG_SP
)
2307 switch (src
->X_add_number
)
2309 case REG_BC
: prefix
= 0xED; opcode
= 0x43; break;
2310 case REG_DE
: prefix
= 0xED; opcode
= 0x53; break;
2311 case REG_HL
: prefix
= 0x00; opcode
= 0x22; break;
2312 case REG_IX
: prefix
= 0xDD; opcode
= 0x22; break;
2313 case REG_IY
: prefix
= 0xFD; opcode
= 0x22; break;
2314 case REG_SP
: prefix
= 0xED; opcode
= 0x73; break;
2319 q
= frag_more (prefix
? 2 : 1);
2328 emit_ld_r_m (expressionS
*dst
, expressionS
*src
)
2329 { /* for 8-bit memory load to register: LD r,(xxx) */
2333 expressionS src_offset
;
2335 if (dst
->X_add_number
== REG_A
&& src
->X_op
== O_register
)
2336 { /* LD A,(BC) or LD A,(DE) */
2337 switch (src
->X_add_number
)
2339 case REG_BC
: opcode
= 0x0A; break;
2340 case REG_DE
: opcode
= 0x1A; break;
2354 if (ins_ok
& INS_GBZ80
)
2355 { /* LD A,(HL+) or LD A,(HL-) */
2356 if (dst
->X_op
== O_register
&& dst
->X_add_number
== REG_A
)
2357 *frag_more (1) = (src
->X_add_number
== REG_HL
) ? 0x2A : 0x3A;
2364 if (dst
->X_add_number
> 7)
2366 opcode
= 0x46; /* LD B,(HL) */
2367 switch (src
->X_add_number
)
2369 case REG_HL
: prefix
= 0x00; break;
2370 case REG_IX
: prefix
= 0xDD; break;
2371 case REG_IY
: prefix
= 0xFD; break;
2375 q
= frag_more (prefix
? 2 : 1);
2378 *q
= opcode
| ((dst
->X_add_number
& 7) << 3);
2382 src_offset
.X_op
= O_symbol
;
2383 src_offset
.X_add_number
= 0;
2384 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2387 default: /* LD A,(nn) */
2388 if (dst
->X_add_number
== REG_A
)
2391 *q
= (ins_ok
& INS_GBZ80
) ? 0xFA : 0x3A;
2398 emit_ld_r_n (expressionS
*dst
, expressionS
*src
)
2399 { /* for 8-bit immediate value load to register: LD r,n */
2403 switch (dst
->X_add_number
)
2425 q
= frag_more (prefix
? 2 : 1);
2428 if (ins_ok
& INS_GBZ80
)
2430 else if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2431 check_mach (INS_IDX_HALF
);
2434 *q
= 0x06 | ((dst
->X_add_number
& 7) << 3);
2435 emit_byte (src
, BFD_RELOC_8
);
2439 emit_ld_r_r (expressionS
*dst
, expressionS
*src
)
2440 { /* mostly 8-bit load register from register instructions: LD r,r */
2441 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2447 switch (dst
->X_add_number
)
2450 switch (src
->X_add_number
)
2452 case REG_HL
: prefix
= 0x00; break;
2453 case REG_IX
: prefix
= 0xDD; break;
2454 case REG_IY
: prefix
= 0xFD; break;
2461 if (!(ins_ok
& INS_EZ80
))
2463 if (src
->X_add_number
!= REG_I
)
2466 error (_("ADL mode instruction"));
2472 if (src
->X_add_number
== REG_HL
)
2474 if (!(ins_ok
& INS_EZ80
))
2477 error (_("ADL mode instruction"));
2481 else if (src
->X_add_number
== REG_A
)
2490 if (!(ins_ok
& INS_EZ80
) || (src
->X_add_number
!= REG_A
))
2493 error (_("ADL mode instruction"));
2498 if (src
->X_add_number
== REG_A
) /* LD R,A */
2507 if (src
->X_add_number
== REG_I
) /* LD A,I */
2513 else if (src
->X_add_number
== REG_R
) /* LD A,R */
2519 else if (src
->X_add_number
== REG_MB
) /* LD A,MB */
2521 if (!(ins_ok
& INS_EZ80
))
2526 error (_("ADL mode instruction"));
2557 switch (src
->X_add_number
)
2568 ill_op (); /* LD iiH/L,H/L are not permitted */
2572 if (prefix
== 0xFD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2573 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2579 if (prefix
== 0xDD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2580 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2587 opcode
= 0x40 + ((dst
->X_add_number
& 7) << 3) + (src
->X_add_number
& 7);
2589 if ((ins_ok
& INS_GBZ80
) && prefix
!= 0)
2591 if (ii_halves
&& !(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2592 check_mach (INS_IDX_HALF
);
2593 if (prefix
== 0 && (ins_ok
& INS_EZ80
))
2597 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2598 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2599 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2600 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2601 as_warn (_("unsupported instruction, assembled as NOP"));
2607 q
= frag_more (prefix
? 2 : 1);
2614 emit_ld_rr_m (expressionS
*dst
, expressionS
*src
)
2615 { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2619 expressionS src_offset
;
2621 /* GBZ80 has no support for 16-bit load from memory instructions */
2622 if (ins_ok
& INS_GBZ80
)
2628 case O_md1
: /* LD rr,(ii+d) */
2629 prefix
= (src
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2631 case O_register
: /* LD rr,(HL) */
2632 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2633 if (!(ins_ok
& INS_EZ80
))
2635 switch (dst
->X_add_number
)
2637 case REG_BC
: opcode
= 0x07; break;
2638 case REG_DE
: opcode
= 0x17; break;
2639 case REG_HL
: opcode
= 0x27; break;
2640 case REG_IX
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x37 : 0x31; break;
2641 case REG_IY
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x31 : 0x37; break;
2651 src_offset
.X_op
= O_symbol
;
2652 src_offset
.X_add_number
= 0;
2653 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2656 default: /* LD rr,(nn) */
2657 switch (dst
->X_add_number
)
2659 case REG_BC
: prefix
= 0xED; opcode
= 0x4B; break;
2660 case REG_DE
: prefix
= 0xED; opcode
= 0x5B; break;
2661 case REG_HL
: prefix
= 0x00; opcode
= 0x2A; break;
2662 case REG_SP
: prefix
= 0xED; opcode
= 0x7B; break;
2663 case REG_IX
: prefix
= 0xDD; opcode
= 0x2A; break;
2664 case REG_IY
: prefix
= 0xFD; opcode
= 0x2A; break;
2668 q
= frag_more (prefix
? 2 : 1);
2678 emit_ld_rr_nn (expressionS
*dst
, expressionS
*src
)
2679 { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2682 int opcode
= 0x21; /* LD HL,nn */
2683 switch (dst
->X_add_number
)
2696 opcode
= 0x01 + ((dst
->X_add_number
& 3) << 4);
2702 if (prefix
&& (ins_ok
& INS_GBZ80
))
2704 q
= frag_more (prefix
? 2 : 1);
2712 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
2715 expressionS dst
, src
;
2718 p
= parse_exp (args
, & dst
);
2720 error (_("bad instruction syntax"));
2721 p
= parse_exp (p
, & src
);
2725 if (src
.X_op
== O_register
)
2727 if (src
.X_add_number
<= 7)
2728 emit_ld_m_r (& dst
, & src
); /* LD (xxx),r */
2730 emit_ld_m_rr (& dst
, & src
); /* LD (xxx),rr */
2733 emit_ld_m_n (& dst
, & src
); /* LD (hl),n or LD (ix/y+r),n */
2735 else if (dst
.X_op
== O_register
)
2739 if (dst
.X_add_number
<= 7)
2740 emit_ld_r_m (& dst
, & src
);
2742 emit_ld_rr_m (& dst
, & src
);
2744 else if (src
.X_op
== O_register
)
2745 emit_ld_r_r (& dst
, & src
);
2746 else if ((dst
.X_add_number
& ~R_INDEX
) <= 7)
2747 emit_ld_r_n (& dst
, & src
);
2749 emit_ld_rr_nn (& dst
, & src
);
2758 emit_lddldi (char prefix
, char opcode
, const char * args
)
2760 expressionS dst
, src
;
2764 if (!(ins_ok
& INS_GBZ80
))
2765 return emit_insn (prefix
, opcode
, args
);
2767 p
= parse_exp (args
, & dst
);
2769 error (_("bad instruction syntax"));
2770 p
= parse_exp (p
, & src
);
2772 if (dst
.X_op
!= O_register
|| src
.X_op
!= O_register
)
2775 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2776 opcode
= (opcode
& 0x08) * 2 + 0x22;
2779 && dst
.X_add_number
== REG_HL
2781 && src
.X_add_number
== REG_A
)
2782 opcode
|= 0x00; /* LDx (HL),A */
2783 else if (dst
.X_md
== 0
2784 && dst
.X_add_number
== REG_A
2786 && src
.X_add_number
== REG_HL
)
2787 opcode
|= 0x08; /* LDx A,(HL) */
2797 emit_ldh (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2800 expressionS dst
, src
;
2804 p
= parse_exp (args
, & dst
);
2807 error (_("bad instruction syntax"));
2811 p
= parse_exp (p
, & src
);
2813 && dst
.X_op
== O_register
2814 && dst
.X_add_number
== REG_A
2816 && src
.X_op
!= O_md1
)
2818 if (src
.X_op
!= O_register
)
2822 emit_byte (& src
, BFD_RELOC_8
);
2824 else if (src
.X_add_number
== REG_C
)
2825 *frag_more (1) = 0xF2;
2829 else if (dst
.X_md
!= 0
2830 && dst
.X_op
!= O_md1
2832 && src
.X_op
== O_register
2833 && src
.X_add_number
== REG_A
)
2835 if (dst
.X_op
== O_register
)
2837 if (dst
.X_add_number
== REG_C
)
2849 emit_byte (& dst
, BFD_RELOC_8
);
2859 emit_ldhl (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2861 expressionS dst
, src
;
2864 p
= parse_exp (args
, & dst
);
2867 error (_("bad instruction syntax"));
2871 p
= parse_exp (p
, & src
);
2872 if (dst
.X_md
|| dst
.X_op
!= O_register
|| dst
.X_add_number
!= REG_SP
2873 || src
.X_md
|| src
.X_op
== O_register
|| src
.X_op
== O_md1
)
2877 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2882 parse_lea_pea_args (const char * args
, expressionS
*op
)
2885 p
= parse_exp (args
, op
);
2886 if (sdcc_compat
&& *p
== ',' && op
->X_op
== O_register
)
2889 p
= parse_exp (p
+ 1, &off
);
2891 op
->X_add_symbol
= make_expr_symbol (&off
);
2897 emit_lea (char prefix
, char opcode
, const char * args
)
2899 expressionS dst
, src
;
2904 p
= parse_exp (args
, & dst
);
2905 if (dst
.X_md
!= 0 || dst
.X_op
!= O_register
)
2908 rnum
= dst
.X_add_number
;
2914 opcode
= 0x02 | ((rnum
& 0x03) << 4);
2917 opcode
= 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2920 opcode
= 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2927 error (_("bad instruction syntax"));
2929 p
= parse_lea_pea_args (p
, & src
);
2930 if (src
.X_md
!= 0 || src
.X_op
!= O_add
/*&& src.X_op != O_register*/)
2933 rnum
= src
.X_add_number
;
2938 case O_register
: /* permit instructions like LEA rr,IX without displacement specified */
2939 src
.X_add_symbol
= zero
;
2948 opcode
= (opcode
== (char)0x33) ? 0x55 : (opcode
|0x00);
2951 opcode
= (opcode
== (char)0x32) ? 0x54 : (opcode
|0x01);
2958 src
.X_op
= O_symbol
;
2959 src
.X_add_number
= 0;
2960 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2966 emit_mlt (char prefix
, char opcode
, const char * args
)
2972 p
= parse_exp (args
, & arg
);
2973 if (arg
.X_md
!= 0 || arg
.X_op
!= O_register
|| !(arg
.X_add_number
& R_ARITH
))
2977 if (ins_ok
& INS_Z80N
)
2979 if (arg
.X_add_number
!= REG_DE
)
2987 *q
= opcode
| ((arg
.X_add_number
& 3) << 4);
2993 /* MUL D,E (Z80N only) */
2995 emit_mul (char prefix
, char opcode
, const char * args
)
3001 p
= parse_exp (args
, & r1
);
3003 error (_("bad instruction syntax"));
3004 p
= parse_exp (p
, & r2
);
3006 if (r1
.X_md
!= 0 || r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_D
||
3007 r2
.X_md
!= 0 || r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_E
)
3018 emit_nextreg (char prefix
, char opcode ATTRIBUTE_UNUSED
, const char * args
)
3024 p
= parse_exp (args
, & rr
);
3026 error (_("bad instruction syntax"));
3027 p
= parse_exp (p
, & nn
);
3028 if (rr
.X_md
!= 0 || rr
.X_op
== O_register
|| rr
.X_op
== O_md1
||
3029 nn
.X_md
!= 0 || nn
.X_op
== O_md1
)
3033 emit_byte (&rr
, BFD_RELOC_8
);
3034 if (nn
.X_op
== O_register
&& nn
.X_add_number
== REG_A
)
3036 else if (nn
.X_op
!= O_register
)
3039 emit_byte (&nn
, BFD_RELOC_8
);
3047 emit_pea (char prefix
, char opcode
, const char * args
)
3053 p
= parse_lea_pea_args (args
, & arg
);
3055 || (/*arg.X_op != O_register &&*/ arg
.X_op
!= O_add
)
3056 || !(arg
.X_add_number
& R_INDEX
))
3058 /* PEA ii without displacement is mostly typo,
3059 because there is PUSH instruction which is shorter and faster */
3060 /*if (arg.X_op == O_register)
3061 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3065 *q
= opcode
+ (arg
.X_add_number
== REG_IY
? 1 : 0);
3067 arg
.X_op
= O_symbol
;
3068 arg
.X_add_number
= 0;
3069 emit_byte (& arg
, BFD_RELOC_Z80_DISP8
);
3075 emit_reti (char prefix
, char opcode
, const char * args
)
3077 if (ins_ok
& INS_GBZ80
)
3078 return emit_insn (0x00, 0xD9, args
);
3080 return emit_insn (prefix
, opcode
, args
);
3084 emit_tst (char prefix
, char opcode
, const char *args
)
3091 p
= parse_exp (args
, & arg_s
);
3092 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
3094 if (!(ins_ok
& INS_EZ80
))
3097 p
= parse_exp (p
, & arg_s
);
3100 rnum
= arg_s
.X_add_number
;
3107 rnum
= arg_s
.X_add_number
;
3108 if (arg_s
.X_md
!= 0)
3117 *q
= opcode
| (rnum
<< 3);
3123 if (ins_ok
& INS_Z80N
)
3133 emit_byte (& arg_s
, BFD_RELOC_8
);
3139 emit_insn_n (char prefix
, char opcode
, const char *args
)
3145 p
= parse_exp (args
, & arg
);
3146 if (arg
.X_md
|| arg
.X_op
== O_register
|| arg
.X_op
== O_md1
)
3152 emit_byte (& arg
, BFD_RELOC_8
);
3158 emit_data (int size ATTRIBUTE_UNUSED
)
3165 if (is_it_end_of_statement ())
3167 demand_empty_rest_of_line ();
3170 p
= skip_space (input_line_pointer
);
3174 if (*p
== '\"' || *p
== '\'')
3176 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
3178 u
= frag_more (cnt
);
3181 as_warn (_("unterminated string"));
3183 p
= skip_space (p
+1);
3187 p
= parse_exp (p
, &exp
);
3188 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3194 as_warn (_("parentheses ignored"));
3195 emit_byte (&exp
, BFD_RELOC_8
);
3199 while (*p
++ == ',') ;
3200 input_line_pointer
= (char *)(p
-1);
3209 if (is_it_end_of_statement ())
3211 demand_empty_rest_of_line ();
3214 p
= skip_space (input_line_pointer
);
3218 p
= parse_exp (p
, &exp
);
3219 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3225 as_warn (_("parentheses ignored"));
3226 emit_data_val (&exp
, size
);
3228 } while (*p
++ == ',') ;
3229 input_line_pointer
= (char *)(p
-1);
3232 /* next functions were commented out because it is difficult to mix
3233 both ADL and Z80 mode instructions within one COFF file:
3234 objdump cannot recognize point of mode switching.
3237 set_cpu_mode (int mode
)
3239 if (ins_ok
& INS_EZ80
)
3242 error (_("CPU mode is unsupported by target"));
3246 assume (int arg ATTRIBUTE_UNUSED
)
3252 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3253 c
= get_symbol_name (& name
);
3254 if (strncasecmp (name
, "ADL", 4) != 0)
3260 restore_line_pointer (c
);
3261 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3262 if (*input_line_pointer
++ != '=')
3264 error (_("assignment expected"));
3267 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3268 n
= get_single_number ();
3274 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3278 p
= skip_space (args
);
3279 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
3285 reg
= TOLOWER (*p
++);
3292 check_mach (INS_R800
);
3293 if (!*skip_space (p
))
3297 *q
= opcode
+ ((reg
- 'b') << 3);
3309 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3313 p
= skip_space (args
);
3314 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
3321 p
= parse_exp (p
, & reg
);
3323 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
3324 switch (reg
.X_add_number
)
3328 check_mach (INS_R800
);
3331 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
3341 assemble_suffix (const char **suffix
)
3344 const char sf
[8][4] =
3364 for (i
= 0; (i
< 3) && (ISALPHA (*p
)); i
++)
3365 sbuf
[i
] = TOLOWER (*p
++);
3366 if (*p
&& !ISSPACE (*p
))
3371 t
= bsearch (sbuf
, sf
, ARRAY_SIZE (sf
), sizeof (sf
[0]), (int(*)(const void*, const void*)) strcmp
);
3378 i
= cpu_mode
? 0x5B : 0x52;
3381 i
= cpu_mode
? 0x49 : 0x40;
3384 i
= cpu_mode
? 0x5B : 0x49;
3393 i
= cpu_mode
? 0x52 : 0x40;
3402 *frag_more (1) = (char)i
;
3405 case 0x40: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IS
; break;
3406 case 0x49: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IS
; break;
3407 case 0x52: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IL
; break;
3408 case 0x5B: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IL
; break;
3416 #if defined(OBJ_ELF)
3417 return obj_elf_section (arg
);
3418 #elif defined(OBJ_COFF)
3419 return obj_coff_section (arg
);
3421 #error Unknown object format
3431 as_fatal (_("Invalid directive"));
3434 ins_ok
&= INS_MARCH_MASK
;
3436 if (old_ins
!= ins_ok
)
3441 ignore (int arg ATTRIBUTE_UNUSED
)
3443 ignore_rest_of_line ();
3451 as_fatal (_("Invalid directive"));
3452 for (p
= input_line_pointer
; *p
&& *p
!= '(' && *p
!= '\n'; p
++)
3459 ignore_rest_of_line ();
3465 /* Handle the .bss pseudo-op. */
3468 s_bss (int ignore ATTRIBUTE_UNUSED
)
3470 subseg_set (bss_section
, 0);
3471 demand_empty_rest_of_line ();
3474 /* Port specific pseudo ops. */
3475 const pseudo_typeS md_pseudo_table
[] =
3477 { ".area", area
, 0},
3478 { ".assume", assume
, 0},
3479 { ".ez80", set_inss
, INS_EZ80
},
3480 { ".gbz80", set_inss
, INS_GBZ80
},
3481 { ".module", ignore
, 0},
3482 { ".optsdcc", ignore
, 0},
3483 { ".r800", set_inss
, INS_R800
},
3484 { ".set", s_set
, 0},
3485 { ".z180", set_inss
, INS_Z180
},
3486 { ".hd64", set_inss
, INS_Z180
},
3487 { ".z80", set_inss
, INS_Z80
},
3488 { ".z80n", set_inss
, INS_Z80N
},
3490 { "db" , emit_data
, 1},
3491 { "d24", z80_cons
, 3},
3492 { "d32", z80_cons
, 4},
3493 { "def24", z80_cons
, 3},
3494 { "def32", z80_cons
, 4},
3495 { "defb", emit_data
, 1},
3496 { "defm", emit_data
, 1},
3497 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
3498 { "defw", z80_cons
, 2},
3499 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
3500 { "dw", z80_cons
, 2},
3501 { "psect", psect
, 0}, /* TODO: Translate attributes. */
3502 { "set", 0, 0}, /* Real instruction on z80. */
3503 { "xdef", s_globl
, 0}, /* Synonym for .GLOBAL */
3504 { "xref", s_ignore
, 0}, /* Synonym for .EXTERN */
3508 static table_t instab
[] =
3510 { "adc", 0x88, 0x4A, emit_adc
, INS_ALL
},
3511 { "add", 0x80, 0x09, emit_add
, INS_ALL
},
3512 { "and", 0x00, 0xA0, emit_s
, INS_ALL
},
3513 { "bit", 0xCB, 0x40, emit_bit
, INS_ALL
},
3514 { "brlc", 0xED, 0x2C, emit_bshft
,INS_Z80N
},
3515 { "bsla", 0xED, 0x28, emit_bshft
,INS_Z80N
},
3516 { "bsra", 0xED, 0x29, emit_bshft
,INS_Z80N
},
3517 { "bsrf", 0xED, 0x2B, emit_bshft
,INS_Z80N
},
3518 { "bsrl", 0xED, 0x2A, emit_bshft
,INS_Z80N
},
3519 { "call", 0xCD, 0xC4, emit_jpcc
, INS_ALL
},
3520 { "ccf", 0x00, 0x3F, emit_insn
, INS_ALL
},
3521 { "cp", 0x00, 0xB8, emit_s
, INS_ALL
},
3522 { "cpd", 0xED, 0xA9, emit_insn
, INS_NOT_GBZ80
},
3523 { "cpdr", 0xED, 0xB9, emit_insn
, INS_NOT_GBZ80
},
3524 { "cpi", 0xED, 0xA1, emit_insn
, INS_NOT_GBZ80
},
3525 { "cpir", 0xED, 0xB1, emit_insn
, INS_NOT_GBZ80
},
3526 { "cpl", 0x00, 0x2F, emit_insn
, INS_ALL
},
3527 { "daa", 0x00, 0x27, emit_insn
, INS_ALL
},
3528 { "dec", 0x0B, 0x05, emit_incdec
,INS_ALL
},
3529 { "di", 0x00, 0xF3, emit_insn
, INS_ALL
},
3530 { "djnz", 0x00, 0x10, emit_jr
, INS_NOT_GBZ80
},
3531 { "ei", 0x00, 0xFB, emit_insn
, INS_ALL
},
3532 { "ex", 0x00, 0x00, emit_ex
, INS_NOT_GBZ80
},
3533 { "exx", 0x00, 0xD9, emit_insn
, INS_NOT_GBZ80
},
3534 { "halt", 0x00, 0x76, emit_insn
, INS_ALL
},
3535 { "im", 0xED, 0x46, emit_im
, INS_NOT_GBZ80
},
3536 { "in", 0x00, 0x00, emit_in
, INS_NOT_GBZ80
},
3537 { "in0", 0xED, 0x00, emit_in0
, INS_Z180
|INS_EZ80
},
3538 { "inc", 0x03, 0x04, emit_incdec
,INS_ALL
},
3539 { "ind", 0xED, 0xAA, emit_insn
, INS_NOT_GBZ80
},
3540 { "ind2", 0xED, 0x8C, emit_insn
, INS_EZ80
},
3541 { "ind2r",0xED, 0x9C, emit_insn
, INS_EZ80
},
3542 { "indm", 0xED, 0x8A, emit_insn
, INS_EZ80
},
3543 { "indmr",0xED, 0x9A, emit_insn
, INS_EZ80
},
3544 { "indr", 0xED, 0xBA, emit_insn
, INS_NOT_GBZ80
},
3545 { "indrx",0xED, 0xCA, emit_insn
, INS_EZ80
},
3546 { "ini", 0xED, 0xA2, emit_insn
, INS_NOT_GBZ80
},
3547 { "ini2", 0xED, 0x84, emit_insn
, INS_EZ80
},
3548 { "ini2r",0xED, 0x94, emit_insn
, INS_EZ80
},
3549 { "inim", 0xED, 0x82, emit_insn
, INS_EZ80
},
3550 { "inimr",0xED, 0x92, emit_insn
, INS_EZ80
},
3551 { "inir", 0xED, 0xB2, emit_insn
, INS_NOT_GBZ80
},
3552 { "inirx",0xED, 0xC2, emit_insn
, INS_EZ80
},
3553 { "jp", 0xC3, 0xC2, emit_jpcc
, INS_ALL
},
3554 { "jr", 0x18, 0x20, emit_jrcc
, INS_ALL
},
3555 { "ld", 0x00, 0x00, emit_ld
, INS_ALL
},
3556 { "ldd", 0xED, 0xA8, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3557 { "lddr", 0xED, 0xB8, emit_insn
, INS_NOT_GBZ80
},
3558 { "lddrx",0xED, 0xBC, emit_insn
, INS_Z80N
},
3559 { "lddx", 0xED, 0xAC, emit_insn
, INS_Z80N
},
3560 { "ldh", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3561 { "ldhl", 0x00, 0xF8, emit_ldhl
, INS_GBZ80
},
3562 { "ldi", 0xED, 0xA0, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3563 { "ldir", 0xED, 0xB0, emit_insn
, INS_NOT_GBZ80
},
3564 { "ldirx",0xED, 0xB4, emit_insn
, INS_Z80N
},
3565 { "ldix", 0xED, 0xA4, emit_insn
, INS_Z80N
},
3566 { "ldpirx",0xED,0xB7, emit_insn
, INS_Z80N
},
3567 { "ldws", 0xED, 0xA5, emit_insn
, INS_Z80N
},
3568 { "lea", 0xED, 0x02, emit_lea
, INS_EZ80
},
3569 { "mirror",0xED,0x24, emit_insn
, INS_Z80N
},
3570 { "mlt", 0xED, 0x4C, emit_mlt
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3571 { "mul", 0xED, 0x30, emit_mul
, INS_Z80N
},
3572 { "mulub",0xED, 0xC5, emit_mulub
,INS_R800
},
3573 { "muluw",0xED, 0xC3, emit_muluw
,INS_R800
},
3574 { "neg", 0xED, 0x44, emit_insn
, INS_NOT_GBZ80
},
3575 { "nextreg",0xED,0x91,emit_nextreg
,INS_Z80N
},
3576 { "nop", 0x00, 0x00, emit_insn
, INS_ALL
},
3577 { "or", 0x00, 0xB0, emit_s
, INS_ALL
},
3578 { "otd2r",0xED, 0xBC, emit_insn
, INS_EZ80
},
3579 { "otdm", 0xED, 0x8B, emit_insn
, INS_Z180
|INS_EZ80
},
3580 { "otdmr",0xED, 0x9B, emit_insn
, INS_Z180
|INS_EZ80
},
3581 { "otdr", 0xED, 0xBB, emit_insn
, INS_NOT_GBZ80
},
3582 { "otdrx",0xED, 0xCB, emit_insn
, INS_EZ80
},
3583 { "oti2r",0xED, 0xB4, emit_insn
, INS_EZ80
},
3584 { "otim", 0xED, 0x83, emit_insn
, INS_Z180
|INS_EZ80
},
3585 { "otimr",0xED, 0x93, emit_insn
, INS_Z180
|INS_EZ80
},
3586 { "otir", 0xED, 0xB3, emit_insn
, INS_NOT_GBZ80
},
3587 { "otirx",0xED, 0xC3, emit_insn
, INS_EZ80
},
3588 { "out", 0x00, 0x00, emit_out
, INS_NOT_GBZ80
},
3589 { "out0", 0xED, 0x01, emit_out0
, INS_Z180
|INS_EZ80
},
3590 { "outd", 0xED, 0xAB, emit_insn
, INS_NOT_GBZ80
},
3591 { "outd2",0xED, 0xAC, emit_insn
, INS_EZ80
},
3592 { "outi", 0xED, 0xA3, emit_insn
, INS_NOT_GBZ80
},
3593 { "outi2",0xED, 0xA4, emit_insn
, INS_EZ80
},
3594 { "outinb",0xED,0x90, emit_insn
, INS_Z80N
},
3595 { "pea", 0xED, 0x65, emit_pea
, INS_EZ80
},
3596 { "pixelad",0xED,0x94,emit_insn
, INS_Z80N
},
3597 { "pixeldn",0xED,0x93,emit_insn
, INS_Z80N
},
3598 { "pop", 0x00, 0xC1, emit_pop
, INS_ALL
},
3599 { "push", 0x00, 0xC5, emit_push
, INS_ALL
},
3600 { "res", 0xCB, 0x80, emit_bit
, INS_ALL
},
3601 { "ret", 0xC9, 0xC0, emit_retcc
,INS_ALL
},
3602 { "reti", 0xED, 0x4D, emit_reti
, INS_ALL
}, /*GBZ80 has its own opcode for it*/
3603 { "retn", 0xED, 0x45, emit_insn
, INS_NOT_GBZ80
},
3604 { "rl", 0xCB, 0x10, emit_mr
, INS_ALL
},
3605 { "rla", 0x00, 0x17, emit_insn
, INS_ALL
},
3606 { "rlc", 0xCB, 0x00, emit_mr
, INS_ALL
},
3607 { "rlca", 0x00, 0x07, emit_insn
, INS_ALL
},
3608 { "rld", 0xED, 0x6F, emit_insn
, INS_NOT_GBZ80
},
3609 { "rr", 0xCB, 0x18, emit_mr
, INS_ALL
},
3610 { "rra", 0x00, 0x1F, emit_insn
, INS_ALL
},
3611 { "rrc", 0xCB, 0x08, emit_mr
, INS_ALL
},
3612 { "rrca", 0x00, 0x0F, emit_insn
, INS_ALL
},
3613 { "rrd", 0xED, 0x67, emit_insn
, INS_NOT_GBZ80
},
3614 { "rsmix",0xED, 0x7E, emit_insn
, INS_EZ80
},
3615 { "rst", 0x00, 0xC7, emit_rst
, INS_ALL
},
3616 { "sbc", 0x98, 0x42, emit_adc
, INS_ALL
},
3617 { "scf", 0x00, 0x37, emit_insn
, INS_ALL
},
3618 { "set", 0xCB, 0xC0, emit_bit
, INS_ALL
},
3619 { "setae",0xED, 0x95, emit_insn
, INS_Z80N
},
3620 { "sl1", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3621 { "sla", 0xCB, 0x20, emit_mr
, INS_ALL
},
3622 { "sli", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3623 { "sll", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3624 { "slp", 0xED, 0x76, emit_insn
, INS_Z180
|INS_EZ80
},
3625 { "sra", 0xCB, 0x28, emit_mr
, INS_ALL
},
3626 { "srl", 0xCB, 0x38, emit_mr
, INS_ALL
},
3627 { "stmix",0xED, 0x7D, emit_insn
, INS_EZ80
},
3628 { "stop", 0x00, 0x10, emit_insn
, INS_GBZ80
},
3629 { "sub", 0x00, 0x90, emit_sub
, INS_ALL
},
3630 { "swap", 0xCB, 0x30, emit_swap
, INS_GBZ80
|INS_Z80N
},
3631 { "swapnib",0xED,0x23,emit_insn
, INS_Z80N
},
3632 { "test", 0xED, 0x27, emit_insn_n
, INS_Z80N
},
3633 { "tst", 0xED, 0x04, emit_tst
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3634 { "tstio",0xED, 0x74, emit_insn_n
,INS_Z180
|INS_EZ80
},
3635 { "xor", 0x00, 0xA8, emit_s
, INS_ALL
},
3639 md_assemble (char *str
)
3647 inst_mode
= cpu_mode
? (INST_MODE_L
| INST_MODE_IL
) : (INST_MODE_S
| INST_MODE_IS
);
3648 old_ptr
= input_line_pointer
;
3649 p
= skip_space (str
);
3650 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
) || ISDIGIT (*p
));)
3651 buf
[i
++] = TOLOWER (*p
++);
3655 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
3657 as_bad (_("Unknown instruction '%s'"), buf
);
3661 dwarf2_emit_insn (0);
3662 if ((*p
) && (!ISSPACE (*p
)))
3664 if (*p
!= '.' || !(ins_ok
& INS_EZ80
) || !assemble_suffix (&p
))
3666 as_bad (_("syntax error"));
3674 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
3675 sizeof (instab
[0]), key_cmp
);
3676 if (!insp
|| (insp
->inss
&& !(insp
->inss
& ins_ok
)))
3679 as_bad (_("Unknown instruction `%s'"), buf
);
3683 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
3685 if ((!err_flag
) && *p
)
3686 as_bad (_("junk at end of line, "
3687 "first unrecognized character is `%c'"), *p
);
3691 input_line_pointer
= old_ptr
;
3695 is_overflow (long value
, unsigned bitsize
)
3697 long fieldmask
= (2UL << (bitsize
- 1)) - 1;
3698 long signmask
= ~fieldmask
;
3699 long a
= value
& fieldmask
;
3700 long ss
= a
& signmask
;
3701 if (ss
!= 0 && ss
!= (signmask
& fieldmask
))
3707 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg
)
3710 char *p_lit
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3712 if (fixP
->fx_addsy
== NULL
)
3714 else if (fixP
->fx_pcrel
)
3716 segT s
= S_GET_SEGMENT (fixP
->fx_addsy
);
3717 if (s
== seg
|| s
== absolute_section
)
3719 val
+= S_GET_VALUE (fixP
->fx_addsy
);
3724 switch (fixP
->fx_r_type
)
3726 case BFD_RELOC_8_PCREL
:
3727 case BFD_RELOC_Z80_DISP8
:
3732 case BFD_RELOC_Z80_16_BE
:
3733 fixP
->fx_no_overflow
= 0;
3736 fixP
->fx_no_overflow
= 1;
3740 switch (fixP
->fx_r_type
)
3742 case BFD_RELOC_8_PCREL
:
3743 case BFD_RELOC_Z80_DISP8
:
3744 if (fixP
->fx_done
&& (val
< -0x80 || val
> 0x7f))
3745 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3746 _("8-bit signed offset out of range (%+ld)"), val
);
3750 case BFD_RELOC_Z80_BYTE0
:
3754 case BFD_RELOC_Z80_BYTE1
:
3755 *p_lit
++ = (val
>> 8);
3758 case BFD_RELOC_Z80_BYTE2
:
3759 *p_lit
++ = (val
>> 16);
3762 case BFD_RELOC_Z80_BYTE3
:
3763 *p_lit
++ = (val
>> 24);
3767 if (fixP
->fx_done
&& is_overflow(val
, 8))
3768 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3769 _("8-bit overflow (%+ld)"), val
);
3773 case BFD_RELOC_Z80_WORD1
:
3774 *p_lit
++ = (val
>> 16);
3775 *p_lit
++ = (val
>> 24);
3778 case BFD_RELOC_Z80_WORD0
:
3780 *p_lit
++ = (val
>> 8);
3784 if (fixP
->fx_done
&& is_overflow(val
, 16))
3785 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3786 _("16-bit overflow (%+ld)"), val
);
3788 *p_lit
++ = (val
>> 8);
3791 case BFD_RELOC_24
: /* Def24 may produce this. */
3792 if (fixP
->fx_done
&& is_overflow(val
, 24))
3793 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3794 _("24-bit overflow (%+ld)"), val
);
3796 *p_lit
++ = (val
>> 8);
3797 *p_lit
++ = (val
>> 16);
3800 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
3801 if (fixP
->fx_done
&& is_overflow(val
, 32))
3802 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3803 _("32-bit overflow (%+ld)"), val
);
3805 *p_lit
++ = (val
>> 8);
3806 *p_lit
++ = (val
>> 16);
3807 *p_lit
++ = (val
>> 24);
3810 case BFD_RELOC_Z80_16_BE
: /* Z80N PUSH nn instruction produce this. */
3811 *p_lit
++ = val
>> 8;
3816 printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP
->fx_r_type
);
3821 /* GAS will call this to generate a reloc. GAS will pass the
3822 resulting reloc to `bfd_install_relocation'. This currently works
3823 poorly, as `bfd_install_relocation' often does the wrong thing, and
3824 instances of `tc_gen_reloc' have been written to work around the
3825 problems, which in turns makes it difficult to fix
3826 `bfd_install_relocation'. */
3828 /* If while processing a fixup, a reloc really
3829 needs to be created then it is done here. */
3832 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
3836 if (fixp
->fx_subsy
!= NULL
)
3838 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _("expression too complex"));
3842 reloc
= XNEW (arelent
);
3843 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3844 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3845 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3846 reloc
->addend
= fixp
->fx_offset
;
3847 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3848 if (reloc
->howto
== NULL
)
3850 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3851 _("reloc %d not supported by object file format"),
3852 (int) fixp
->fx_r_type
);
3856 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
3857 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3858 reloc
->address
= fixp
->fx_offset
;
3864 z80_tc_labels_without_colon (void)
3866 return colonless_labels
;
3870 z80_tc_label_is_local (const char *name
)
3874 if (local_label_prefix
== NULL
)
3876 for (p
= local_label_prefix
, n
= name
; *p
&& *n
&& *n
== *p
; p
++, n
++)
3881 /* Parse floating point number from string and compute mantissa and
3882 exponent. Mantissa is normalized.
3884 #define EXP_MIN -0x10000
3885 #define EXP_MAX 0x10000
3887 str_to_broken_float (bool *signP
, bfd_uint64_t
*mantissaP
, int *expP
)
3891 bfd_uint64_t mantissa
= 0;
3895 p
= (char*)skip_space (input_line_pointer
);
3898 if (sign
|| *p
== '+')
3900 if (strncasecmp (p
, "NaN", 3) == 0)
3904 input_line_pointer
= p
+ 3;
3907 if (strncasecmp (p
, "inf", 3) == 0)
3909 *mantissaP
= 1ull << 63;
3911 input_line_pointer
= p
+ 3;
3914 for (; ISDIGIT (*p
); ++p
)
3922 mantissa
= mantissa
* 10 + (*p
- '0');
3924 /* skip non-significant digits */
3925 for (; ISDIGIT (*p
); ++p
)
3931 if (!exponent
) /* If no precision overflow. */
3933 for (; ISDIGIT (*p
); ++p
, --exponent
)
3941 mantissa
= mantissa
* 10 + (*p
- '0');
3944 for (; ISDIGIT (*p
); ++p
)
3947 if (*p
== 'e' || *p
== 'E')
3953 if (es
|| *p
== '+')
3955 for (; ISDIGIT (*p
); ++p
)
3958 t
= t
* 10 + (*p
- '0');
3960 exponent
+= (es
) ? -t
: t
;
3962 if (ISALNUM (*p
) || *p
== '.')
3964 input_line_pointer
= p
;
3967 *mantissaP
= 1ull << 63;
3969 return 1; /* result is 0 */
3972 for (; mantissa
<= ~0ull/10; --exponent
)
3974 /* Now we have sign, mantissa, and signed decimal exponent
3975 need to recompute to binary exponent. */
3976 for (i
= 64; exponent
> 0; --exponent
)
3978 /* be sure that no integer overflow */
3979 while (mantissa
> ~0ull/10)
3986 for (; exponent
< 0; ++exponent
)
3988 while (!(mantissa
>> 63))
3996 for (; !(mantissa
>> 63); --i
)
3998 *mantissaP
= mantissa
;
4004 str_to_zeda32(char *litP
, int *sizeP
)
4006 bfd_uint64_t mantissa
;
4012 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
4013 return _("invalid syntax");
4014 /* I do not know why decrement is needed */
4016 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
4020 /* make 24 bit mantissa */
4022 /* check for overflow */
4029 if (exponent
< -127)
4034 else if (exponent
> 127)
4037 mantissa
= sign
? 0xc00000 : 0x400000;
4039 else if (mantissa
== 0)
4042 mantissa
= 0x200000;
4045 mantissa
&= (1ull << 23) - 1;
4046 for (i
= 0; i
< 24; i
+= 8)
4047 *litP
++ = (char)(mantissa
>> i
);
4048 *litP
= (char)(0x80 + exponent
);
4053 Math48 by Anders Hejlsberg support.
4054 Mantissa is 39 bits wide, exponent 8 bit wide.
4057 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4058 bit 7-0: exponent+128 (0 - value is null)
4059 MIN: 2.938735877e-39
4060 MAX: 1.701411835e+38
4063 str_to_float48(char *litP
, int *sizeP
)
4065 bfd_uint64_t mantissa
;
4071 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
4072 return _("invalid syntax");
4073 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4077 /* make 40 bit mantissa */
4079 /* check for overflow */
4085 if (exponent
< -127)
4087 memset (litP
, 0, 6);
4091 return _("overflow");
4093 mantissa
&= (1ull << 39) - 1;
4094 *litP
++ = (char)(0x80 + exponent
);
4095 for (i
= 0; i
< 40; i
+= 8)
4096 *litP
++ = (char)(mantissa
>> i
);
4101 str_to_ieee754_h(char *litP
, int *sizeP
)
4103 return ieee_md_atof ('h', litP
, sizeP
, false);
4107 str_to_ieee754_s(char *litP
, int *sizeP
)
4109 return ieee_md_atof ('s', litP
, sizeP
, false);
4113 str_to_ieee754_d(char *litP
, int *sizeP
)
4115 return ieee_md_atof ('d', litP
, sizeP
, false);
4118 #ifdef TARGET_USE_CFIPOP
4119 /* Initialize the DWARF-2 unwind information for this procedure. */
4121 z80_tc_frame_initial_instructions (void)
4123 static int sp_regno
= -1;
4126 sp_regno
= z80_tc_regname_to_dw2regnum ("sp");
4128 cfi_add_CFA_def_cfa (sp_regno
, 0);
4132 z80_tc_regname_to_dw2regnum (const char *regname
)
4134 static const char *regs
[] =
4135 { /* same registers as for GDB */
4136 "af", "bc", "de", "hl",
4137 "sp", "pc", "ix", "iy",
4138 "af_", "bc_", "de_", "hl_",
4143 for (i
= 0; i
< ARRAY_SIZE(regs
); ++i
)
4144 if (!strcasecmp (regs
[i
], regname
))
4151 /* Implement DWARF2_ADDR_SIZE. */
4153 z80_dwarf2_addr_size (const bfd
*abfd
)
4155 switch (bfd_get_mach (abfd
))
4157 case bfd_mach_ez80_adl
: