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 bfd_boolean 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;
1180 default: simplify
= FALSE
;
1186 val
->X_op
= O_symbol
;
1187 val
->X_op_symbol
= NULL
;
1188 val
->X_add_number
= 0;
1192 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, size
, val
, FALSE
, r_type
);
1196 emit_byte (expressionS
* val
, bfd_reloc_code_real_type r_type
)
1200 if (r_type
== BFD_RELOC_8
)
1202 emit_data_val (val
, 1);
1206 *p
= val
->X_add_number
;
1207 if (contains_register (val
->X_add_symbol
) || contains_register (val
->X_op_symbol
))
1211 else if ((r_type
== BFD_RELOC_8_PCREL
) && (val
->X_op
== O_constant
))
1213 as_bad (_("cannot make a relative jump to an absolute location"));
1215 else if (val
->X_op
== O_constant
)
1217 if ((val
->X_add_number
< -128) || (val
->X_add_number
>= 128))
1219 if (r_type
== BFD_RELOC_Z80_DISP8
)
1220 as_bad (_("index overflow (%+ld)"), val
->X_add_number
);
1222 as_bad (_("offset overflow (%+ld)"), val
->X_add_number
);
1227 /* For symbols only, constants are stored at begin of function. */
1228 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 1, val
,
1229 r_type
== BFD_RELOC_8_PCREL
, r_type
);
1234 emit_word (expressionS
* val
)
1236 emit_data_val (val
, (inst_mode
& INST_MODE_IL
) ? 3 : 2);
1240 emit_mx (char prefix
, char opcode
, int shift
, expressionS
* arg
)
1241 /* The operand m may be r, (hl), (ix+d), (iy+d),
1242 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1247 rnum
= arg
->X_add_number
;
1263 if ((prefix
== 0) && (rnum
& R_INDEX
))
1265 prefix
= (rnum
& R_IX
) ? 0xDD : 0xFD;
1266 if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
1267 check_mach (INS_IDX_HALF
);
1276 q
= frag_more (prefix
? 2 : 1);
1279 * q
++ = opcode
+ (rnum
<< shift
);
1282 if (ins_ok
& INS_GBZ80
)
1288 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1289 *q
= (prefix
) ? prefix
: (opcode
+ (6 << shift
));
1291 expressionS offset
= *arg
;
1292 offset
.X_op
= O_symbol
;
1293 offset
.X_add_number
= 0;
1294 emit_byte (&offset
, BFD_RELOC_Z80_DISP8
);
1299 *q
= opcode
+(6<<shift
);
1307 /* The operand m may be r, (hl), (ix+d), (iy+d),
1308 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1310 emit_m (char prefix
, char opcode
, const char *args
)
1315 p
= parse_exp (args
, &arg_m
);
1320 emit_mx (prefix
, opcode
, 0, &arg_m
);
1328 /* The operand m may be as above or one of the undocumented
1329 combinations (ix+d),r and (iy+d),r (if unportable instructions
1333 emit_mr (char prefix
, char opcode
, const char *args
)
1335 expressionS arg_m
, arg_r
;
1338 p
= parse_exp (args
, & arg_m
);
1345 p
= parse_exp (p
+ 1, & arg_r
);
1347 if ((arg_r
.X_md
== 0)
1348 && (arg_r
.X_op
== O_register
)
1349 && (arg_r
.X_add_number
< 8))
1350 opcode
+= arg_r
.X_add_number
- 6; /* Emit_mx () will add 6. */
1356 if (!(ins_ok
& INS_Z80N
))
1357 check_mach (INS_ROT_II_LD
);
1361 emit_mx (prefix
, opcode
, 0, & arg_m
);
1370 emit_sx (char prefix
, char opcode
, expressionS
* arg_p
)
1374 switch (arg_p
->X_op
)
1378 emit_mx (prefix
, opcode
, 0, arg_p
);
1385 q
= frag_more (prefix
? 2 : 1);
1389 emit_byte (arg_p
, BFD_RELOC_8
);
1394 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1396 emit_s (char prefix
, char opcode
, const char *args
)
1401 p
= parse_exp (args
, & arg_s
);
1402 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
1403 { /* possible instruction in generic format op A,x */
1404 if (!(ins_ok
& INS_EZ80
) && !sdcc_compat
)
1407 p
= parse_exp (p
, & arg_s
);
1409 emit_sx (prefix
, opcode
, & arg_s
);
1414 emit_sub (char prefix
, char opcode
, const char *args
)
1419 if (!(ins_ok
& INS_GBZ80
))
1420 return emit_s (prefix
, opcode
, args
);
1421 p
= parse_exp (args
, & arg_s
);
1424 error (_("bad instruction syntax"));
1428 if (arg_s
.X_md
!= 0 || arg_s
.X_op
!= O_register
|| arg_s
.X_add_number
!= REG_A
)
1431 p
= parse_exp (p
, & arg_s
);
1433 emit_sx (prefix
, opcode
, & arg_s
);
1438 emit_swap (char prefix
, char opcode
, const char *args
)
1444 if (!(ins_ok
& INS_Z80N
))
1445 return emit_mr (prefix
, opcode
, args
);
1447 /* check for alias swap a for swapnib of Z80N */
1448 p
= parse_exp (args
, ®
);
1449 if (reg
.X_md
!= 0 || reg
.X_op
!= O_register
|| reg
.X_add_number
!= REG_A
)
1459 emit_call (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1462 const char *p
; char *q
;
1464 p
= parse_exp_not_indexed (args
, &addr
);
1476 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1478 emit_incdec (char prefix
, char opcode
, const char * args
)
1480 expressionS operand
;
1482 const char *p
; char *q
;
1484 p
= parse_exp (args
, &operand
);
1485 rnum
= operand
.X_add_number
;
1486 if ((! operand
.X_md
)
1487 && (operand
.X_op
== O_register
)
1490 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1492 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1493 *q
= prefix
+ ((rnum
& 3) << 4);
1497 if ((operand
.X_op
== O_md1
) || (operand
.X_op
== O_register
))
1498 emit_mx (0, opcode
, 3, & operand
);
1506 emit_jr (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1512 p
= parse_exp_not_indexed (args
, &addr
);
1519 addr
.X_add_number
--; /* pcrel computes after offset code */
1520 emit_byte (&addr
, BFD_RELOC_8_PCREL
);
1526 emit_jp (char prefix
, char opcode
, const char * args
)
1533 p
= parse_exp_not_indexed (args
, & addr
);
1536 rnum
= addr
.X_add_number
;
1537 if ((O_register
== addr
.X_op
) && (REG_HL
== (rnum
& ~R_INDEX
)))
1539 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1541 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1544 else if (addr
.X_op
== O_register
&& rnum
== REG_C
&& (ins_ok
& INS_Z80N
))
1563 emit_im (char prefix
, char opcode
, const char * args
)
1569 p
= parse_exp (args
, & mode
);
1570 if (mode
.X_md
|| (mode
.X_op
!= O_constant
))
1573 switch (mode
.X_add_number
)
1577 ++mode
.X_add_number
;
1582 *q
= opcode
+ 8*mode
.X_add_number
;
1591 emit_pop (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1597 p
= parse_exp (args
, & regp
);
1599 && (regp
.X_op
== O_register
)
1600 && (regp
.X_add_number
& R_STACKABLE
))
1604 rnum
= regp
.X_add_number
;
1608 *q
++ = (rnum
&R_IX
)?0xDD:0xFD;
1612 *q
= opcode
+ ((rnum
& 3) << 4);
1621 emit_push (char prefix
, char opcode
, const char * args
)
1627 p
= parse_exp (args
, & arg
);
1628 if (arg
.X_op
== O_register
)
1629 return emit_pop (prefix
, opcode
, args
);
1631 if (arg
.X_md
|| arg
.X_op
== O_md1
|| !(ins_ok
& INS_Z80N
))
1639 fix_new_exp (frag_now
, q
- frag_now
->fr_literal
, 2, &arg
, FALSE
,
1640 BFD_RELOC_Z80_16_BE
);
1646 emit_retcc (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1651 p
= parse_cc (args
, &cc
);
1657 return p
? p
: args
;
1661 emit_adc (char prefix
, char opcode
, const char * args
)
1668 p
= parse_exp (args
, &term
);
1671 error (_("bad instruction syntax"));
1675 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1678 switch (term
.X_add_number
)
1681 p
= emit_s (0, prefix
, p
);
1684 p
= parse_exp (p
, &term
);
1685 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1687 rnum
= term
.X_add_number
;
1688 if (R_ARITH
== (rnum
& (R_ARITH
| R_INDEX
)))
1692 *q
= opcode
+ ((rnum
& 3) << 4);
1704 emit_add (char prefix
, char opcode
, const char * args
)
1711 p
= parse_exp (args
, &term
);
1714 error (_("bad instruction syntax"));
1718 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1721 switch (term
.X_add_number
)
1724 p
= emit_s (0, prefix
, p
);
1727 p
= parse_exp (p
, &term
);
1728 if (!(ins_ok
& INS_GBZ80
) || term
.X_md
|| term
.X_op
== O_register
)
1732 emit_byte (&term
, BFD_RELOC_Z80_DISP8
);
1736 if (!(ins_ok
& INS_Z80N
))
1745 lhs
= term
.X_add_number
;
1746 p
= parse_exp (p
, &term
);
1747 rhs
= term
.X_add_number
;
1748 if (term
.X_md
!= 0 || term
.X_op
== O_md1
)
1750 else if ((term
.X_op
== O_register
) && (rhs
& R_ARITH
) && (rhs
== lhs
|| (rhs
& ~R_INDEX
) != REG_HL
))
1754 q
= frag_more ((lhs
& R_INDEX
) ? 2 : 1);
1756 *q
++ = (lhs
& R_IX
) ? 0xDD : 0xFD;
1757 *q
= opcode
+ ((rhs
& 3) << 4);
1761 else if (!(lhs
& R_INDEX
) && (ins_ok
& INS_Z80N
))
1763 if (term
.X_op
== O_register
&& rhs
== REG_A
)
1764 { /* ADD BC/DE/HL,A */
1767 *q
= 0x33 - (lhs
& 3);
1770 else if (term
.X_op
!= O_register
&& term
.X_op
!= O_md1
)
1771 { /* ADD BC/DE/HL,nn */
1774 *q
= 0x36 - (lhs
& 3);
1787 emit_bit (char prefix
, char opcode
, const char * args
)
1793 p
= parse_exp (args
, &b
);
1795 error (_("bad instruction syntax"));
1797 bn
= b
.X_add_number
;
1799 && (b
.X_op
== O_constant
)
1804 /* Bit : no optional third operand. */
1805 p
= emit_m (prefix
, opcode
+ (bn
<< 3), p
);
1807 /* Set, res : resulting byte can be copied to register. */
1808 p
= emit_mr (prefix
, opcode
+ (bn
<< 3), p
);
1815 /* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
1817 emit_bshft (char prefix
, char opcode
, const char * args
)
1823 p
= parse_exp (args
, & r1
);
1825 error (_("bad instruction syntax"));
1826 p
= parse_exp (p
, & r2
);
1827 if (r1
.X_md
|| r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_DE
||
1828 r2
.X_md
|| r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_B
)
1837 emit_jpcc (char prefix
, char opcode
, const char * args
)
1842 p
= parse_cc (args
, & cc
);
1843 if (p
&& *p
++ == ',')
1844 p
= emit_call (0, opcode
+ cc
, p
);
1846 p
= (prefix
== (char)0xC3)
1847 ? emit_jp (0xE9, prefix
, args
)
1848 : emit_call (0, prefix
, args
);
1853 emit_jrcc (char prefix
, char opcode
, const char * args
)
1858 p
= parse_cc (args
, &cc
);
1859 if (p
&& *p
++ == ',')
1862 error (_("condition code invalid for jr"));
1864 p
= emit_jr (0, opcode
+ cc
, p
);
1867 p
= emit_jr (0, prefix
, args
);
1873 emit_ex (char prefix_in ATTRIBUTE_UNUSED
,
1874 char opcode_in ATTRIBUTE_UNUSED
, const char * args
)
1878 char prefix
, opcode
;
1880 p
= parse_exp_not_indexed (args
, &op
);
1884 error (_("bad instruction syntax"));
1888 prefix
= opcode
= 0;
1889 if (op
.X_op
== O_register
)
1890 switch (op
.X_add_number
| (op
.X_md
? 0x8000 : 0))
1893 if (TOLOWER (*p
++) == 'a' && TOLOWER (*p
++) == 'f')
1895 /* The scrubber changes '\'' to '`' in this context. */
1902 if (TOLOWER (*p
++) == 'h' && TOLOWER (*p
++) == 'l')
1906 p
= parse_exp (p
, & op
);
1907 if (op
.X_op
== O_register
1909 && (op
.X_add_number
& ~R_INDEX
) == REG_HL
)
1912 if (R_INDEX
& op
.X_add_number
)
1913 prefix
= (R_IX
& op
.X_add_number
) ? 0xDD : 0xFD;
1918 emit_insn (prefix
, opcode
, p
);
1926 emit_in (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1929 expressionS reg
, port
;
1933 p
= parse_exp (args
, ®
);
1934 if (reg
.X_md
&& reg
.X_op
== O_register
&& reg
.X_add_number
== REG_C
)
1935 { /* permit instruction in (c) as alias for in f,(c) */
1938 reg
.X_add_number
= REG_F
;
1944 error (_("bad instruction syntax"));
1947 p
= parse_exp (p
, &port
);
1950 && reg
.X_op
== O_register
1951 && (reg
.X_add_number
<= 7 || reg
.X_add_number
== REG_F
)
1954 if (port
.X_op
!= O_md1
&& port
.X_op
!= O_register
)
1956 if (REG_A
== reg
.X_add_number
)
1960 emit_byte (&port
, BFD_RELOC_8
);
1967 if (port
.X_add_number
== REG_C
|| port
.X_add_number
== REG_BC
)
1969 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
1971 else if (reg
.X_add_number
== REG_F
&& !(ins_ok
& (INS_R800
|INS_Z80N
)))
1972 check_mach (INS_IN_F_C
);
1975 *q
= 0x40|((reg
.X_add_number
&7)<<3);
1987 emit_in0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1990 expressionS reg
, port
;
1994 p
= parse_exp (args
, ®
);
1997 error (_("bad instruction syntax"));
2001 p
= parse_exp (p
, &port
);
2003 && reg
.X_op
== O_register
2004 && reg
.X_add_number
<= 7
2006 && port
.X_op
!= O_md1
2007 && port
.X_op
!= O_register
)
2011 *q
= 0x00|(reg
.X_add_number
<< 3);
2012 emit_byte (&port
, BFD_RELOC_8
);
2020 emit_out (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2023 expressionS reg
, port
;
2027 p
= parse_exp (args
, & port
);
2030 error (_("bad instruction syntax"));
2033 p
= parse_exp (p
, ®
);
2035 { ill_op (); return p
; }
2036 /* Allow "out (c), 0" as unportable instruction. */
2037 if (reg
.X_op
== O_constant
&& reg
.X_add_number
== 0)
2039 if (!(ins_ok
& INS_Z80N
))
2040 check_mach (INS_OUT_C_0
);
2041 reg
.X_op
= O_register
;
2042 reg
.X_add_number
= 6;
2045 || reg
.X_op
!= O_register
2046 || reg
.X_add_number
> 7)
2049 if (port
.X_op
!= O_register
&& port
.X_op
!= O_md1
)
2051 if (REG_A
== reg
.X_add_number
)
2055 emit_byte (&port
, BFD_RELOC_8
);
2062 if (REG_C
== port
.X_add_number
|| port
.X_add_number
== REG_BC
)
2064 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
2068 *q
= 0x41 | (reg
.X_add_number
<< 3);
2077 emit_out0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2080 expressionS reg
, port
;
2084 p
= parse_exp (args
, & port
);
2087 error (_("bad instruction syntax"));
2090 p
= parse_exp (p
, ®
);
2092 && port
.X_op
!= O_register
2093 && port
.X_op
!= O_md1
2095 && reg
.X_op
== O_register
2096 && reg
.X_add_number
<= 7)
2100 *q
= 0x01 | (reg
.X_add_number
<< 3);
2101 emit_byte (&port
, BFD_RELOC_8
);
2109 emit_rst (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2115 p
= parse_exp_not_indexed (args
, &addr
);
2116 if (addr
.X_op
!= O_constant
)
2118 error ("rst needs constant address");
2122 if (addr
.X_add_number
& ~(7 << 3))
2127 *q
= opcode
+ (addr
.X_add_number
& (7 << 3));
2132 /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
2134 emit_ld_m_n (expressionS
*dst
, expressionS
*src
)
2138 expressionS dst_offset
;
2140 switch (dst
->X_add_number
)
2142 case REG_HL
: prefix
= 0x00; break;
2143 case REG_IX
: prefix
= 0xDD; break;
2144 case REG_IY
: prefix
= 0xFD; break;
2150 q
= frag_more (prefix
? 2 : 1);
2157 dst_offset
.X_op
= O_symbol
;
2158 dst_offset
.X_add_number
= 0;
2159 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2161 emit_byte (src
, BFD_RELOC_8
);
2164 /* For 8-bit load register to memory instructions: LD (<expression>),r. */
2166 emit_ld_m_r (expressionS
*dst
, expressionS
*src
)
2170 expressionS dst_offset
;
2175 if (ins_ok
& INS_GBZ80
)
2176 { /* LD (HL+),A or LD (HL-),A */
2177 if (src
->X_op
!= O_register
|| src
->X_add_number
!= REG_A
)
2179 *frag_more (1) = (dst
->X_add_number
== REG_HL
) ? 0x22 : 0x32;
2183 prefix
= (dst
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2186 switch (dst
->X_add_number
)
2188 case REG_BC
: /* LD (BC),A */
2189 case REG_DE
: /* LD (DE),A */
2190 if (src
->X_add_number
== REG_A
)
2193 *q
= 0x02 | ((dst
->X_add_number
& 3) << 4);
2199 case REG_HL
: /* LD (HL),r or LD (ii+d),r */
2200 if (src
->X_add_number
<= 7)
2202 q
= frag_more (prefix
? 2 : 1);
2205 *q
= 0x70 | src
->X_add_number
;
2209 dst_offset
.X_op
= O_symbol
;
2210 dst_offset
.X_add_number
= 0;
2211 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2219 default: /* LD (nn),A */
2220 if (src
->X_add_number
== REG_A
)
2223 *q
= (ins_ok
& INS_GBZ80
) ? 0xEA : 0x32;
2232 /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
2234 emit_ld_m_rr (expressionS
*dst
, expressionS
*src
)
2239 expressionS dst_offset
;
2243 case O_md1
: /* eZ80 instructions LD (ii+d),rr */
2244 case O_register
: /* eZ80 instructions LD (HL),rr */
2245 if (!(ins_ok
& INS_EZ80
)) /* 16-bit indirect load group is supported by eZ80 only */
2247 switch (dst
->X_add_number
)
2249 case REG_IX
: prefix
= 0xDD; break;
2250 case REG_IY
: prefix
= 0xFD; break;
2251 case REG_HL
: prefix
= 0xED; break;
2255 switch (src
->X_add_number
)
2257 case REG_BC
: opcode
= 0x0F; break;
2258 case REG_DE
: opcode
= 0x1F; break;
2259 case REG_HL
: opcode
= 0x2F; break;
2260 case REG_IX
: opcode
= (prefix
!= 0xFD) ? 0x3F : 0x3E; break;
2261 case REG_IY
: opcode
= (prefix
!= 0xFD) ? 0x3E : 0x3F; break;
2265 q
= frag_more (prefix
? 2 : 1);
2268 if (prefix
== 0xFD || prefix
== 0xDD)
2271 dst_offset
.X_op
= O_symbol
;
2272 dst_offset
.X_add_number
= 0;
2273 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2276 default: /* LD (nn),rr */
2277 if (ins_ok
& INS_GBZ80
)
2279 /* GBZ80 supports only LD (nn),SP */
2280 if (src
->X_add_number
== REG_SP
)
2290 switch (src
->X_add_number
)
2292 case REG_BC
: prefix
= 0xED; opcode
= 0x43; break;
2293 case REG_DE
: prefix
= 0xED; opcode
= 0x53; break;
2294 case REG_HL
: prefix
= 0x00; opcode
= 0x22; break;
2295 case REG_IX
: prefix
= 0xDD; opcode
= 0x22; break;
2296 case REG_IY
: prefix
= 0xFD; opcode
= 0x22; break;
2297 case REG_SP
: prefix
= 0xED; opcode
= 0x73; break;
2302 q
= frag_more (prefix
? 2 : 1);
2311 emit_ld_r_m (expressionS
*dst
, expressionS
*src
)
2312 { /* for 8-bit memory load to register: LD r,(xxx) */
2316 expressionS src_offset
;
2318 if (dst
->X_add_number
== REG_A
&& src
->X_op
== O_register
)
2319 { /* LD A,(BC) or LD A,(DE) */
2320 switch (src
->X_add_number
)
2322 case REG_BC
: opcode
= 0x0A; break;
2323 case REG_DE
: opcode
= 0x1A; break;
2337 if (ins_ok
& INS_GBZ80
)
2338 { /* LD A,(HL+) or LD A,(HL-) */
2339 if (dst
->X_op
== O_register
&& dst
->X_add_number
== REG_A
)
2340 *frag_more (1) = (src
->X_add_number
== REG_HL
) ? 0x2A : 0x3A;
2347 if (dst
->X_add_number
> 7)
2349 opcode
= 0x46; /* LD B,(HL) */
2350 switch (src
->X_add_number
)
2352 case REG_HL
: prefix
= 0x00; break;
2353 case REG_IX
: prefix
= 0xDD; break;
2354 case REG_IY
: prefix
= 0xFD; break;
2358 q
= frag_more (prefix
? 2 : 1);
2361 *q
= opcode
| ((dst
->X_add_number
& 7) << 3);
2365 src_offset
.X_op
= O_symbol
;
2366 src_offset
.X_add_number
= 0;
2367 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2370 default: /* LD A,(nn) */
2371 if (dst
->X_add_number
== REG_A
)
2374 *q
= (ins_ok
& INS_GBZ80
) ? 0xFA : 0x3A;
2381 emit_ld_r_n (expressionS
*dst
, expressionS
*src
)
2382 { /* for 8-bit immediate value load to register: LD r,n */
2386 switch (dst
->X_add_number
)
2408 q
= frag_more (prefix
? 2 : 1);
2411 if (ins_ok
& INS_GBZ80
)
2413 else if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2414 check_mach (INS_IDX_HALF
);
2417 *q
= 0x06 | ((dst
->X_add_number
& 7) << 3);
2418 emit_byte (src
, BFD_RELOC_8
);
2422 emit_ld_r_r (expressionS
*dst
, expressionS
*src
)
2423 { /* mostly 8-bit load register from register instructions: LD r,r */
2424 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2430 switch (dst
->X_add_number
)
2433 switch (src
->X_add_number
)
2435 case REG_HL
: prefix
= 0x00; break;
2436 case REG_IX
: prefix
= 0xDD; break;
2437 case REG_IY
: prefix
= 0xFD; break;
2444 if (!(ins_ok
& INS_EZ80
))
2446 if (src
->X_add_number
!= REG_I
)
2449 error (_("ADL mode instruction"));
2455 if (src
->X_add_number
== REG_HL
)
2457 if (!(ins_ok
& INS_EZ80
))
2460 error (_("ADL mode instruction"));
2464 else if (src
->X_add_number
== REG_A
)
2473 if (!(ins_ok
& INS_EZ80
) || (src
->X_add_number
!= REG_A
))
2476 error (_("ADL mode instruction"));
2481 if (src
->X_add_number
== REG_A
) /* LD R,A */
2490 if (src
->X_add_number
== REG_I
) /* LD A,I */
2496 else if (src
->X_add_number
== REG_R
) /* LD A,R */
2502 else if (src
->X_add_number
== REG_MB
) /* LD A,MB */
2504 if (!(ins_ok
& INS_EZ80
))
2509 error (_("ADL mode instruction"));
2540 switch (src
->X_add_number
)
2551 ill_op (); /* LD iiH/L,H/L are not permitted */
2555 if (prefix
== 0xFD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2556 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2562 if (prefix
== 0xDD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2563 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2570 opcode
= 0x40 + ((dst
->X_add_number
& 7) << 3) + (src
->X_add_number
& 7);
2572 if ((ins_ok
& INS_GBZ80
) && prefix
!= 0)
2574 if (ii_halves
&& !(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2575 check_mach (INS_IDX_HALF
);
2576 if (prefix
== 0 && (ins_ok
& INS_EZ80
))
2580 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2581 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2582 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2583 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2584 as_warn (_("unsupported instruction, assembled as NOP"));
2590 q
= frag_more (prefix
? 2 : 1);
2597 emit_ld_rr_m (expressionS
*dst
, expressionS
*src
)
2598 { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2602 expressionS src_offset
;
2604 /* GBZ80 has no support for 16-bit load from memory instructions */
2605 if (ins_ok
& INS_GBZ80
)
2611 case O_md1
: /* LD rr,(ii+d) */
2612 prefix
= (src
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2614 case O_register
: /* LD rr,(HL) */
2615 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2616 if (!(ins_ok
& INS_EZ80
))
2618 switch (dst
->X_add_number
)
2620 case REG_BC
: opcode
= 0x07; break;
2621 case REG_DE
: opcode
= 0x17; break;
2622 case REG_HL
: opcode
= 0x27; break;
2623 case REG_IX
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x37 : 0x31; break;
2624 case REG_IY
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x31 : 0x37; break;
2634 src_offset
.X_op
= O_symbol
;
2635 src_offset
.X_add_number
= 0;
2636 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2639 default: /* LD rr,(nn) */
2640 switch (dst
->X_add_number
)
2642 case REG_BC
: prefix
= 0xED; opcode
= 0x4B; break;
2643 case REG_DE
: prefix
= 0xED; opcode
= 0x5B; break;
2644 case REG_HL
: prefix
= 0x00; opcode
= 0x2A; break;
2645 case REG_SP
: prefix
= 0xED; opcode
= 0x7B; break;
2646 case REG_IX
: prefix
= 0xDD; opcode
= 0x2A; break;
2647 case REG_IY
: prefix
= 0xFD; opcode
= 0x2A; break;
2651 q
= frag_more (prefix
? 2 : 1);
2661 emit_ld_rr_nn (expressionS
*dst
, expressionS
*src
)
2662 { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2665 int opcode
= 0x21; /* LD HL,nn */
2666 switch (dst
->X_add_number
)
2679 opcode
= 0x01 + ((dst
->X_add_number
& 3) << 4);
2685 if (prefix
&& (ins_ok
& INS_GBZ80
))
2687 q
= frag_more (prefix
? 2 : 1);
2695 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
2698 expressionS dst
, src
;
2701 p
= parse_exp (args
, & dst
);
2703 error (_("bad instruction syntax"));
2704 p
= parse_exp (p
, & src
);
2708 if (src
.X_op
== O_register
)
2710 if (src
.X_add_number
<= 7)
2711 emit_ld_m_r (& dst
, & src
); /* LD (xxx),r */
2713 emit_ld_m_rr (& dst
, & src
); /* LD (xxx),rr */
2716 emit_ld_m_n (& dst
, & src
); /* LD (hl),n or LD (ix/y+r),n */
2718 else if (dst
.X_op
== O_register
)
2722 if (dst
.X_add_number
<= 7)
2723 emit_ld_r_m (& dst
, & src
);
2725 emit_ld_rr_m (& dst
, & src
);
2727 else if (src
.X_op
== O_register
)
2728 emit_ld_r_r (& dst
, & src
);
2729 else if ((dst
.X_add_number
& ~R_INDEX
) <= 7)
2730 emit_ld_r_n (& dst
, & src
);
2732 emit_ld_rr_nn (& dst
, & src
);
2741 emit_lddldi (char prefix
, char opcode
, const char * args
)
2743 expressionS dst
, src
;
2747 if (!(ins_ok
& INS_GBZ80
))
2748 return emit_insn (prefix
, opcode
, args
);
2750 p
= parse_exp (args
, & dst
);
2752 error (_("bad instruction syntax"));
2753 p
= parse_exp (p
, & src
);
2755 if (dst
.X_op
!= O_register
|| src
.X_op
!= O_register
)
2758 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2759 opcode
= (opcode
& 0x08) * 2 + 0x22;
2762 && dst
.X_add_number
== REG_HL
2764 && src
.X_add_number
== REG_A
)
2765 opcode
|= 0x00; /* LDx (HL),A */
2766 else if (dst
.X_md
== 0
2767 && dst
.X_add_number
== REG_A
2769 && src
.X_add_number
== REG_HL
)
2770 opcode
|= 0x08; /* LDx A,(HL) */
2780 emit_ldh (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2783 expressionS dst
, src
;
2787 p
= parse_exp (args
, & dst
);
2790 error (_("bad instruction syntax"));
2794 p
= parse_exp (p
, & src
);
2796 && dst
.X_op
== O_register
2797 && dst
.X_add_number
== REG_A
2799 && src
.X_op
!= O_md1
)
2801 if (src
.X_op
!= O_register
)
2805 emit_byte (& src
, BFD_RELOC_8
);
2807 else if (src
.X_add_number
== REG_C
)
2808 *frag_more (1) = 0xF2;
2812 else if (dst
.X_md
!= 0
2813 && dst
.X_op
!= O_md1
2815 && src
.X_op
== O_register
2816 && src
.X_add_number
== REG_A
)
2818 if (dst
.X_op
== O_register
)
2820 if (dst
.X_add_number
== REG_C
)
2832 emit_byte (& dst
, BFD_RELOC_8
);
2842 emit_ldhl (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2844 expressionS dst
, src
;
2847 p
= parse_exp (args
, & dst
);
2850 error (_("bad instruction syntax"));
2854 p
= parse_exp (p
, & src
);
2855 if (dst
.X_md
|| dst
.X_op
!= O_register
|| dst
.X_add_number
!= REG_SP
2856 || src
.X_md
|| src
.X_op
== O_register
|| src
.X_op
== O_md1
)
2860 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2865 parse_lea_pea_args (const char * args
, expressionS
*op
)
2868 p
= parse_exp (args
, op
);
2869 if (sdcc_compat
&& *p
== ',' && op
->X_op
== O_register
)
2872 p
= parse_exp (p
+ 1, &off
);
2874 op
->X_add_symbol
= make_expr_symbol (&off
);
2880 emit_lea (char prefix
, char opcode
, const char * args
)
2882 expressionS dst
, src
;
2887 p
= parse_exp (args
, & dst
);
2888 if (dst
.X_md
!= 0 || dst
.X_op
!= O_register
)
2891 rnum
= dst
.X_add_number
;
2897 opcode
= 0x02 | ((rnum
& 0x03) << 4);
2900 opcode
= 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2903 opcode
= 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2910 error (_("bad instruction syntax"));
2912 p
= parse_lea_pea_args (p
, & src
);
2913 if (src
.X_md
!= 0 || src
.X_op
!= O_add
/*&& src.X_op != O_register*/)
2916 rnum
= src
.X_add_number
;
2921 case O_register
: /* permit instructions like LEA rr,IX without displacement specified */
2922 src
.X_add_symbol
= zero
;
2931 opcode
= (opcode
== (char)0x33) ? 0x55 : (opcode
|0x00);
2934 opcode
= (opcode
== (char)0x32) ? 0x54 : (opcode
|0x01);
2941 src
.X_op
= O_symbol
;
2942 src
.X_add_number
= 0;
2943 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2949 emit_mlt (char prefix
, char opcode
, const char * args
)
2955 p
= parse_exp (args
, & arg
);
2956 if (arg
.X_md
!= 0 || arg
.X_op
!= O_register
|| !(arg
.X_add_number
& R_ARITH
))
2960 if (ins_ok
& INS_Z80N
)
2962 if (arg
.X_add_number
!= REG_DE
)
2970 *q
= opcode
| ((arg
.X_add_number
& 3) << 4);
2976 /* MUL D,E (Z80N only) */
2978 emit_mul (char prefix
, char opcode
, const char * args
)
2984 p
= parse_exp (args
, & r1
);
2986 error (_("bad instruction syntax"));
2987 p
= parse_exp (p
, & r2
);
2989 if (r1
.X_md
!= 0 || r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_D
||
2990 r2
.X_md
!= 0 || r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_E
)
3001 emit_nextreg (char prefix
, char opcode ATTRIBUTE_UNUSED
, const char * args
)
3007 p
= parse_exp (args
, & rr
);
3009 error (_("bad instruction syntax"));
3010 p
= parse_exp (p
, & nn
);
3011 if (rr
.X_md
!= 0 || rr
.X_op
== O_register
|| rr
.X_op
== O_md1
||
3012 nn
.X_md
!= 0 || nn
.X_op
== O_md1
)
3016 emit_byte (&rr
, BFD_RELOC_8
);
3017 if (nn
.X_op
== O_register
&& nn
.X_add_number
== REG_A
)
3019 else if (nn
.X_op
!= O_register
)
3022 emit_byte (&nn
, BFD_RELOC_8
);
3030 emit_pea (char prefix
, char opcode
, const char * args
)
3036 p
= parse_lea_pea_args (args
, & arg
);
3038 || (/*arg.X_op != O_register &&*/ arg
.X_op
!= O_add
)
3039 || !(arg
.X_add_number
& R_INDEX
))
3041 /* PEA ii without displacement is mostly typo,
3042 because there is PUSH instruction which is shorter and faster */
3043 /*if (arg.X_op == O_register)
3044 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3048 *q
= opcode
+ (arg
.X_add_number
== REG_IY
? 1 : 0);
3050 arg
.X_op
= O_symbol
;
3051 arg
.X_add_number
= 0;
3052 emit_byte (& arg
, BFD_RELOC_Z80_DISP8
);
3058 emit_reti (char prefix
, char opcode
, const char * args
)
3060 if (ins_ok
& INS_GBZ80
)
3061 return emit_insn (0x00, 0xD9, args
);
3063 return emit_insn (prefix
, opcode
, args
);
3067 emit_tst (char prefix
, char opcode
, const char *args
)
3074 p
= parse_exp (args
, & arg_s
);
3075 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
3077 if (!(ins_ok
& INS_EZ80
))
3080 p
= parse_exp (p
, & arg_s
);
3083 rnum
= arg_s
.X_add_number
;
3090 rnum
= arg_s
.X_add_number
;
3091 if (arg_s
.X_md
!= 0)
3100 *q
= opcode
| (rnum
<< 3);
3106 if (ins_ok
& INS_Z80N
)
3116 emit_byte (& arg_s
, BFD_RELOC_8
);
3122 emit_insn_n (char prefix
, char opcode
, const char *args
)
3128 p
= parse_exp (args
, & arg
);
3129 if (arg
.X_md
|| arg
.X_op
== O_register
|| arg
.X_op
== O_md1
)
3135 emit_byte (& arg
, BFD_RELOC_8
);
3141 emit_data (int size ATTRIBUTE_UNUSED
)
3148 if (is_it_end_of_statement ())
3150 demand_empty_rest_of_line ();
3153 p
= skip_space (input_line_pointer
);
3157 if (*p
== '\"' || *p
== '\'')
3159 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
3161 u
= frag_more (cnt
);
3164 as_warn (_("unterminated string"));
3166 p
= skip_space (p
+1);
3170 p
= parse_exp (p
, &exp
);
3171 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3177 as_warn (_("parentheses ignored"));
3178 emit_byte (&exp
, BFD_RELOC_8
);
3182 while (*p
++ == ',') ;
3183 input_line_pointer
= (char *)(p
-1);
3192 if (is_it_end_of_statement ())
3194 demand_empty_rest_of_line ();
3197 p
= skip_space (input_line_pointer
);
3201 p
= parse_exp (p
, &exp
);
3202 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3208 as_warn (_("parentheses ignored"));
3209 emit_data_val (&exp
, size
);
3211 } while (*p
++ == ',') ;
3212 input_line_pointer
= (char *)(p
-1);
3215 /* next functions were commented out because it is difficult to mix
3216 both ADL and Z80 mode instructions within one COFF file:
3217 objdump cannot recognize point of mode switching.
3220 set_cpu_mode (int mode
)
3222 if (ins_ok
& INS_EZ80
)
3225 error (_("CPU mode is unsupported by target"));
3229 assume (int arg ATTRIBUTE_UNUSED
)
3235 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3236 c
= get_symbol_name (& name
);
3237 if (strncasecmp (name
, "ADL", 4) != 0)
3243 restore_line_pointer (c
);
3244 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3245 if (*input_line_pointer
++ != '=')
3247 error (_("assignment expected"));
3250 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3251 n
= get_single_number ();
3257 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3261 p
= skip_space (args
);
3262 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
3268 reg
= TOLOWER (*p
++);
3275 check_mach (INS_R800
);
3276 if (!*skip_space (p
))
3280 *q
= opcode
+ ((reg
- 'b') << 3);
3292 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3296 p
= skip_space (args
);
3297 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
3304 p
= parse_exp (p
, & reg
);
3306 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
3307 switch (reg
.X_add_number
)
3311 check_mach (INS_R800
);
3314 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
3324 assemble_suffix (const char **suffix
)
3327 const char sf
[8][4] =
3347 for (i
= 0; (i
< 3) && (ISALPHA (*p
)); i
++)
3348 sbuf
[i
] = TOLOWER (*p
++);
3349 if (*p
&& !ISSPACE (*p
))
3354 t
= bsearch (sbuf
, sf
, ARRAY_SIZE (sf
), sizeof (sf
[0]), (int(*)(const void*, const void*)) strcmp
);
3361 i
= cpu_mode
? 0x5B : 0x52;
3364 i
= cpu_mode
? 0x49 : 0x40;
3367 i
= cpu_mode
? 0x5B : 0x49;
3376 i
= cpu_mode
? 0x52 : 0x40;
3385 *frag_more (1) = (char)i
;
3388 case 0x40: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IS
; break;
3389 case 0x49: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IS
; break;
3390 case 0x52: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IL
; break;
3391 case 0x5B: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IL
; break;
3399 #if defined(OBJ_ELF)
3400 return obj_elf_section (arg
);
3401 #elif defined(OBJ_COFF)
3402 return obj_coff_section (arg
);
3404 #error Unknown object format
3414 as_fatal (_("Invalid directive"));
3417 ins_ok
&= INS_MARCH_MASK
;
3419 if (old_ins
!= ins_ok
)
3424 ignore (int arg ATTRIBUTE_UNUSED
)
3426 ignore_rest_of_line ();
3434 as_fatal (_("Invalid directive"));
3435 for (p
= input_line_pointer
; *p
&& *p
!= '(' && *p
!= '\n'; p
++)
3442 ignore_rest_of_line ();
3448 /* Handle the .bss pseudo-op. */
3451 s_bss (int ignore ATTRIBUTE_UNUSED
)
3453 subseg_set (bss_section
, 0);
3454 demand_empty_rest_of_line ();
3457 /* Port specific pseudo ops. */
3458 const pseudo_typeS md_pseudo_table
[] =
3460 { ".area", area
, 0},
3461 { ".assume", assume
, 0},
3462 { ".ez80", set_inss
, INS_EZ80
},
3463 { ".gbz80", set_inss
, INS_GBZ80
},
3464 { ".module", ignore
, 0},
3465 { ".optsdcc", ignore
, 0},
3466 { ".r800", set_inss
, INS_R800
},
3467 { ".set", s_set
, 0},
3468 { ".z180", set_inss
, INS_Z180
},
3469 { ".hd64", set_inss
, INS_Z180
},
3470 { ".z80", set_inss
, INS_Z80
},
3471 { ".z80n", set_inss
, INS_Z80N
},
3473 { "db" , emit_data
, 1},
3474 { "d24", z80_cons
, 3},
3475 { "d32", z80_cons
, 4},
3476 { "def24", z80_cons
, 3},
3477 { "def32", z80_cons
, 4},
3478 { "defb", emit_data
, 1},
3479 { "defm", emit_data
, 1},
3480 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
3481 { "defw", z80_cons
, 2},
3482 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
3483 { "dw", z80_cons
, 2},
3484 { "psect", psect
, 0}, /* TODO: Translate attributes. */
3485 { "set", 0, 0}, /* Real instruction on z80. */
3486 { "xdef", s_globl
, 0}, /* Synonym for .GLOBAL */
3487 { "xref", s_ignore
, 0}, /* Synonym for .EXTERN */
3491 static table_t instab
[] =
3493 { "adc", 0x88, 0x4A, emit_adc
, INS_ALL
},
3494 { "add", 0x80, 0x09, emit_add
, INS_ALL
},
3495 { "and", 0x00, 0xA0, emit_s
, INS_ALL
},
3496 { "bit", 0xCB, 0x40, emit_bit
, INS_ALL
},
3497 { "brlc", 0xED, 0x2C, emit_bshft
,INS_Z80N
},
3498 { "bsla", 0xED, 0x28, emit_bshft
,INS_Z80N
},
3499 { "bsra", 0xED, 0x29, emit_bshft
,INS_Z80N
},
3500 { "bsrf", 0xED, 0x2B, emit_bshft
,INS_Z80N
},
3501 { "bsrl", 0xED, 0x2A, emit_bshft
,INS_Z80N
},
3502 { "call", 0xCD, 0xC4, emit_jpcc
, INS_ALL
},
3503 { "ccf", 0x00, 0x3F, emit_insn
, INS_ALL
},
3504 { "cp", 0x00, 0xB8, emit_s
, INS_ALL
},
3505 { "cpd", 0xED, 0xA9, emit_insn
, INS_NOT_GBZ80
},
3506 { "cpdr", 0xED, 0xB9, emit_insn
, INS_NOT_GBZ80
},
3507 { "cpi", 0xED, 0xA1, emit_insn
, INS_NOT_GBZ80
},
3508 { "cpir", 0xED, 0xB1, emit_insn
, INS_NOT_GBZ80
},
3509 { "cpl", 0x00, 0x2F, emit_insn
, INS_ALL
},
3510 { "daa", 0x00, 0x27, emit_insn
, INS_ALL
},
3511 { "dec", 0x0B, 0x05, emit_incdec
,INS_ALL
},
3512 { "di", 0x00, 0xF3, emit_insn
, INS_ALL
},
3513 { "djnz", 0x00, 0x10, emit_jr
, INS_NOT_GBZ80
},
3514 { "ei", 0x00, 0xFB, emit_insn
, INS_ALL
},
3515 { "ex", 0x00, 0x00, emit_ex
, INS_NOT_GBZ80
},
3516 { "exx", 0x00, 0xD9, emit_insn
, INS_NOT_GBZ80
},
3517 { "halt", 0x00, 0x76, emit_insn
, INS_ALL
},
3518 { "im", 0xED, 0x46, emit_im
, INS_NOT_GBZ80
},
3519 { "in", 0x00, 0x00, emit_in
, INS_NOT_GBZ80
},
3520 { "in0", 0xED, 0x00, emit_in0
, INS_Z180
|INS_EZ80
},
3521 { "inc", 0x03, 0x04, emit_incdec
,INS_ALL
},
3522 { "ind", 0xED, 0xAA, emit_insn
, INS_NOT_GBZ80
},
3523 { "ind2", 0xED, 0x8C, emit_insn
, INS_EZ80
},
3524 { "ind2r",0xED, 0x9C, emit_insn
, INS_EZ80
},
3525 { "indm", 0xED, 0x8A, emit_insn
, INS_EZ80
},
3526 { "indmr",0xED, 0x9A, emit_insn
, INS_EZ80
},
3527 { "indr", 0xED, 0xBA, emit_insn
, INS_NOT_GBZ80
},
3528 { "indrx",0xED, 0xCA, emit_insn
, INS_EZ80
},
3529 { "ini", 0xED, 0xA2, emit_insn
, INS_NOT_GBZ80
},
3530 { "ini2", 0xED, 0x84, emit_insn
, INS_EZ80
},
3531 { "ini2r",0xED, 0x94, emit_insn
, INS_EZ80
},
3532 { "inim", 0xED, 0x82, emit_insn
, INS_EZ80
},
3533 { "inimr",0xED, 0x92, emit_insn
, INS_EZ80
},
3534 { "inir", 0xED, 0xB2, emit_insn
, INS_NOT_GBZ80
},
3535 { "inirx",0xED, 0xC2, emit_insn
, INS_EZ80
},
3536 { "jp", 0xC3, 0xC2, emit_jpcc
, INS_ALL
},
3537 { "jr", 0x18, 0x20, emit_jrcc
, INS_ALL
},
3538 { "ld", 0x00, 0x00, emit_ld
, INS_ALL
},
3539 { "ldd", 0xED, 0xA8, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3540 { "lddr", 0xED, 0xB8, emit_insn
, INS_NOT_GBZ80
},
3541 { "lddrx",0xED, 0xBC, emit_insn
, INS_Z80N
},
3542 { "lddx", 0xED, 0xAC, emit_insn
, INS_Z80N
},
3543 { "ldh", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3544 { "ldhl", 0x00, 0xF8, emit_ldhl
, INS_GBZ80
},
3545 { "ldi", 0xED, 0xA0, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3546 { "ldir", 0xED, 0xB0, emit_insn
, INS_NOT_GBZ80
},
3547 { "ldirx",0xED, 0xB4, emit_insn
, INS_Z80N
},
3548 { "ldix", 0xED, 0xA4, emit_insn
, INS_Z80N
},
3549 { "ldpirx",0xED,0xB7, emit_insn
, INS_Z80N
},
3550 { "ldws", 0xED, 0xA5, emit_insn
, INS_Z80N
},
3551 { "lea", 0xED, 0x02, emit_lea
, INS_EZ80
},
3552 { "mirror",0xED,0x24, emit_insn
, INS_Z80N
},
3553 { "mlt", 0xED, 0x4C, emit_mlt
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3554 { "mul", 0xED, 0x30, emit_mul
, INS_Z80N
},
3555 { "mulub",0xED, 0xC5, emit_mulub
,INS_R800
},
3556 { "muluw",0xED, 0xC3, emit_muluw
,INS_R800
},
3557 { "neg", 0xED, 0x44, emit_insn
, INS_NOT_GBZ80
},
3558 { "nextreg",0xED,0x91,emit_nextreg
,INS_Z80N
},
3559 { "nop", 0x00, 0x00, emit_insn
, INS_ALL
},
3560 { "or", 0x00, 0xB0, emit_s
, INS_ALL
},
3561 { "otd2r",0xED, 0xBC, emit_insn
, INS_EZ80
},
3562 { "otdm", 0xED, 0x8B, emit_insn
, INS_Z180
|INS_EZ80
},
3563 { "otdmr",0xED, 0x9B, emit_insn
, INS_Z180
|INS_EZ80
},
3564 { "otdr", 0xED, 0xBB, emit_insn
, INS_NOT_GBZ80
},
3565 { "otdrx",0xED, 0xCB, emit_insn
, INS_EZ80
},
3566 { "oti2r",0xED, 0xB4, emit_insn
, INS_EZ80
},
3567 { "otim", 0xED, 0x83, emit_insn
, INS_Z180
|INS_EZ80
},
3568 { "otimr",0xED, 0x93, emit_insn
, INS_Z180
|INS_EZ80
},
3569 { "otir", 0xED, 0xB3, emit_insn
, INS_NOT_GBZ80
},
3570 { "otirx",0xED, 0xC3, emit_insn
, INS_EZ80
},
3571 { "out", 0x00, 0x00, emit_out
, INS_NOT_GBZ80
},
3572 { "out0", 0xED, 0x01, emit_out0
, INS_Z180
|INS_EZ80
},
3573 { "outd", 0xED, 0xAB, emit_insn
, INS_NOT_GBZ80
},
3574 { "outd2",0xED, 0xAC, emit_insn
, INS_EZ80
},
3575 { "outi", 0xED, 0xA3, emit_insn
, INS_NOT_GBZ80
},
3576 { "outi2",0xED, 0xA4, emit_insn
, INS_EZ80
},
3577 { "outinb",0xED,0x90, emit_insn
, INS_Z80N
},
3578 { "pea", 0xED, 0x65, emit_pea
, INS_EZ80
},
3579 { "pixelad",0xED,0x94,emit_insn
, INS_Z80N
},
3580 { "pixeldn",0xED,0x93,emit_insn
, INS_Z80N
},
3581 { "pop", 0x00, 0xC1, emit_pop
, INS_ALL
},
3582 { "push", 0x00, 0xC5, emit_push
, INS_ALL
},
3583 { "res", 0xCB, 0x80, emit_bit
, INS_ALL
},
3584 { "ret", 0xC9, 0xC0, emit_retcc
,INS_ALL
},
3585 { "reti", 0xED, 0x4D, emit_reti
, INS_ALL
}, /*GBZ80 has its own opcode for it*/
3586 { "retn", 0xED, 0x45, emit_insn
, INS_NOT_GBZ80
},
3587 { "rl", 0xCB, 0x10, emit_mr
, INS_ALL
},
3588 { "rla", 0x00, 0x17, emit_insn
, INS_ALL
},
3589 { "rlc", 0xCB, 0x00, emit_mr
, INS_ALL
},
3590 { "rlca", 0x00, 0x07, emit_insn
, INS_ALL
},
3591 { "rld", 0xED, 0x6F, emit_insn
, INS_NOT_GBZ80
},
3592 { "rr", 0xCB, 0x18, emit_mr
, INS_ALL
},
3593 { "rra", 0x00, 0x1F, emit_insn
, INS_ALL
},
3594 { "rrc", 0xCB, 0x08, emit_mr
, INS_ALL
},
3595 { "rrca", 0x00, 0x0F, emit_insn
, INS_ALL
},
3596 { "rrd", 0xED, 0x67, emit_insn
, INS_NOT_GBZ80
},
3597 { "rsmix",0xED, 0x7E, emit_insn
, INS_EZ80
},
3598 { "rst", 0x00, 0xC7, emit_rst
, INS_ALL
},
3599 { "sbc", 0x98, 0x42, emit_adc
, INS_ALL
},
3600 { "scf", 0x00, 0x37, emit_insn
, INS_ALL
},
3601 { "set", 0xCB, 0xC0, emit_bit
, INS_ALL
},
3602 { "setae",0xED, 0x95, emit_insn
, INS_Z80N
},
3603 { "sl1", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3604 { "sla", 0xCB, 0x20, emit_mr
, INS_ALL
},
3605 { "sli", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3606 { "sll", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3607 { "slp", 0xED, 0x76, emit_insn
, INS_Z180
|INS_EZ80
},
3608 { "sra", 0xCB, 0x28, emit_mr
, INS_ALL
},
3609 { "srl", 0xCB, 0x38, emit_mr
, INS_ALL
},
3610 { "stmix",0xED, 0x7D, emit_insn
, INS_EZ80
},
3611 { "stop", 0x00, 0x10, emit_insn
, INS_GBZ80
},
3612 { "sub", 0x00, 0x90, emit_sub
, INS_ALL
},
3613 { "swap", 0xCB, 0x30, emit_swap
, INS_GBZ80
|INS_Z80N
},
3614 { "swapnib",0xED,0x23,emit_insn
, INS_Z80N
},
3615 { "test", 0xED, 0x27, emit_insn_n
, INS_Z80N
},
3616 { "tst", 0xED, 0x04, emit_tst
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3617 { "tstio",0xED, 0x74, emit_insn_n
,INS_Z180
|INS_EZ80
},
3618 { "xor", 0x00, 0xA8, emit_s
, INS_ALL
},
3622 md_assemble (char *str
)
3630 inst_mode
= cpu_mode
? (INST_MODE_L
| INST_MODE_IL
) : (INST_MODE_S
| INST_MODE_IS
);
3631 old_ptr
= input_line_pointer
;
3632 p
= skip_space (str
);
3633 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
) || ISDIGIT (*p
));)
3634 buf
[i
++] = TOLOWER (*p
++);
3638 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
3640 as_bad (_("Unknown instruction '%s'"), buf
);
3644 dwarf2_emit_insn (0);
3645 if ((*p
) && (!ISSPACE (*p
)))
3647 if (*p
!= '.' || !(ins_ok
& INS_EZ80
) || !assemble_suffix (&p
))
3649 as_bad (_("syntax error"));
3657 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
3658 sizeof (instab
[0]), key_cmp
);
3659 if (!insp
|| (insp
->inss
&& !(insp
->inss
& ins_ok
)))
3662 as_bad (_("Unknown instruction `%s'"), buf
);
3666 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
3668 if ((!err_flag
) && *p
)
3669 as_bad (_("junk at end of line, "
3670 "first unrecognized character is `%c'"), *p
);
3674 input_line_pointer
= old_ptr
;
3678 is_overflow (long value
, unsigned bitsize
)
3680 long fieldmask
= (2UL << (bitsize
- 1)) - 1;
3681 long signmask
= ~fieldmask
;
3682 long a
= value
& fieldmask
;
3683 long ss
= a
& signmask
;
3684 if (ss
!= 0 && ss
!= (signmask
& fieldmask
))
3690 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg
)
3693 char *p_lit
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3695 if (fixP
->fx_addsy
== NULL
)
3697 else if (fixP
->fx_pcrel
)
3699 segT s
= S_GET_SEGMENT (fixP
->fx_addsy
);
3700 if (s
== seg
|| s
== absolute_section
)
3702 val
+= S_GET_VALUE (fixP
->fx_addsy
);
3707 switch (fixP
->fx_r_type
)
3709 case BFD_RELOC_8_PCREL
:
3710 case BFD_RELOC_Z80_DISP8
:
3715 case BFD_RELOC_Z80_16_BE
:
3716 fixP
->fx_no_overflow
= 0;
3719 fixP
->fx_no_overflow
= 1;
3723 switch (fixP
->fx_r_type
)
3725 case BFD_RELOC_8_PCREL
:
3726 case BFD_RELOC_Z80_DISP8
:
3727 if (fixP
->fx_done
&& (val
< -0x80 || val
> 0x7f))
3728 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3729 _("8-bit signed offset out of range (%+ld)"), val
);
3733 case BFD_RELOC_Z80_BYTE0
:
3737 case BFD_RELOC_Z80_BYTE1
:
3738 *p_lit
++ = (val
>> 8);
3741 case BFD_RELOC_Z80_BYTE2
:
3742 *p_lit
++ = (val
>> 16);
3745 case BFD_RELOC_Z80_BYTE3
:
3746 *p_lit
++ = (val
>> 24);
3750 if (fixP
->fx_done
&& is_overflow(val
, 8))
3751 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3752 _("8-bit overflow (%+ld)"), val
);
3756 case BFD_RELOC_Z80_WORD1
:
3757 *p_lit
++ = (val
>> 16);
3758 *p_lit
++ = (val
>> 24);
3761 case BFD_RELOC_Z80_WORD0
:
3763 *p_lit
++ = (val
>> 8);
3767 if (fixP
->fx_done
&& is_overflow(val
, 16))
3768 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3769 _("16-bit overflow (%+ld)"), val
);
3771 *p_lit
++ = (val
>> 8);
3774 case BFD_RELOC_24
: /* Def24 may produce this. */
3775 if (fixP
->fx_done
&& is_overflow(val
, 24))
3776 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3777 _("24-bit overflow (%+ld)"), val
);
3779 *p_lit
++ = (val
>> 8);
3780 *p_lit
++ = (val
>> 16);
3783 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
3784 if (fixP
->fx_done
&& is_overflow(val
, 32))
3785 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3786 _("32-bit overflow (%+ld)"), val
);
3788 *p_lit
++ = (val
>> 8);
3789 *p_lit
++ = (val
>> 16);
3790 *p_lit
++ = (val
>> 24);
3793 case BFD_RELOC_Z80_16_BE
: /* Z80N PUSH nn instruction produce this. */
3794 *p_lit
++ = val
>> 8;
3799 printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP
->fx_r_type
);
3804 /* GAS will call this to generate a reloc. GAS will pass the
3805 resulting reloc to `bfd_install_relocation'. This currently works
3806 poorly, as `bfd_install_relocation' often does the wrong thing, and
3807 instances of `tc_gen_reloc' have been written to work around the
3808 problems, which in turns makes it difficult to fix
3809 `bfd_install_relocation'. */
3811 /* If while processing a fixup, a reloc really
3812 needs to be created then it is done here. */
3815 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
3819 if (fixp
->fx_subsy
!= NULL
)
3821 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _("expression too complex"));
3825 reloc
= XNEW (arelent
);
3826 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3827 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3828 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3829 reloc
->addend
= fixp
->fx_offset
;
3830 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3831 if (reloc
->howto
== NULL
)
3833 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3834 _("reloc %d not supported by object file format"),
3835 (int) fixp
->fx_r_type
);
3839 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
3840 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3841 reloc
->address
= fixp
->fx_offset
;
3847 z80_tc_labels_without_colon (void)
3849 return colonless_labels
;
3853 z80_tc_label_is_local (const char *name
)
3857 if (local_label_prefix
== NULL
)
3859 for (p
= local_label_prefix
, n
= name
; *p
&& *n
&& *n
== *p
; p
++, n
++)
3864 /* Parse floating point number from string and compute mantissa and
3865 exponent. Mantissa is normalized.
3867 #define EXP_MIN -0x10000
3868 #define EXP_MAX 0x10000
3870 str_to_broken_float (bfd_boolean
*signP
, bfd_uint64_t
*mantissaP
, int *expP
)
3874 bfd_uint64_t mantissa
= 0;
3878 p
= (char*)skip_space (input_line_pointer
);
3881 if (sign
|| *p
== '+')
3883 if (strncasecmp (p
, "NaN", 3) == 0)
3887 input_line_pointer
= p
+ 3;
3890 if (strncasecmp (p
, "inf", 3) == 0)
3892 *mantissaP
= 1ull << 63;
3894 input_line_pointer
= p
+ 3;
3897 for (; ISDIGIT (*p
); ++p
)
3905 mantissa
= mantissa
* 10 + (*p
- '0');
3907 /* skip non-significant digits */
3908 for (; ISDIGIT (*p
); ++p
)
3914 if (!exponent
) /* If no precision overflow. */
3916 for (; ISDIGIT (*p
); ++p
, --exponent
)
3924 mantissa
= mantissa
* 10 + (*p
- '0');
3927 for (; ISDIGIT (*p
); ++p
)
3930 if (*p
== 'e' || *p
== 'E')
3936 if (es
|| *p
== '+')
3938 for (; ISDIGIT (*p
); ++p
)
3941 t
= t
* 10 + (*p
- '0');
3943 exponent
+= (es
) ? -t
: t
;
3945 if (ISALNUM (*p
) || *p
== '.')
3947 input_line_pointer
= p
;
3950 *mantissaP
= 1ull << 63;
3952 return 1; /* result is 0 */
3955 for (; mantissa
<= ~0ull/10; --exponent
)
3957 /* Now we have sign, mantissa, and signed decimal exponent
3958 need to recompute to binary exponent. */
3959 for (i
= 64; exponent
> 0; --exponent
)
3961 /* be sure that no integer overflow */
3962 while (mantissa
> ~0ull/10)
3969 for (; exponent
< 0; ++exponent
)
3971 while (!(mantissa
>> 63))
3979 for (; !(mantissa
>> 63); --i
)
3981 *mantissaP
= mantissa
;
3987 str_to_zeda32(char *litP
, int *sizeP
)
3989 bfd_uint64_t mantissa
;
3995 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
3996 return _("invalid syntax");
3997 /* I do not know why decrement is needed */
3999 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
4003 /* make 24 bit mantissa */
4005 /* check for overflow */
4012 if (exponent
< -127)
4017 else if (exponent
> 127)
4020 mantissa
= sign
? 0xc00000 : 0x400000;
4022 else if (mantissa
== 0)
4025 mantissa
= 0x200000;
4028 mantissa
&= (1ull << 23) - 1;
4029 for (i
= 0; i
< 24; i
+= 8)
4030 *litP
++ = (char)(mantissa
>> i
);
4031 *litP
= (char)(0x80 + exponent
);
4036 Math48 by Anders Hejlsberg support.
4037 Mantissa is 39 bits wide, exponent 8 bit wide.
4040 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4041 bit 7-0: exponent+128 (0 - value is null)
4042 MIN: 2.938735877e-39
4043 MAX: 1.701411835e+38
4046 str_to_float48(char *litP
, int *sizeP
)
4048 bfd_uint64_t mantissa
;
4054 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
4055 return _("invalid syntax");
4056 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4060 /* make 40 bit mantissa */
4062 /* check for overflow */
4068 if (exponent
< -127)
4070 memset (litP
, 0, 6);
4074 return _("overflow");
4076 mantissa
&= (1ull << 39) - 1;
4077 *litP
++ = (char)(0x80 + exponent
);
4078 for (i
= 0; i
< 40; i
+= 8)
4079 *litP
++ = (char)(mantissa
>> i
);
4084 str_to_ieee754_h(char *litP
, int *sizeP
)
4086 return ieee_md_atof ('h', litP
, sizeP
, FALSE
);
4090 str_to_ieee754_s(char *litP
, int *sizeP
)
4092 return ieee_md_atof ('s', litP
, sizeP
, FALSE
);
4096 str_to_ieee754_d(char *litP
, int *sizeP
)
4098 return ieee_md_atof ('d', litP
, sizeP
, FALSE
);
4101 #ifdef TARGET_USE_CFIPOP
4102 /* Initialize the DWARF-2 unwind information for this procedure. */
4104 z80_tc_frame_initial_instructions (void)
4106 static int sp_regno
= -1;
4109 sp_regno
= z80_tc_regname_to_dw2regnum ("sp");
4111 cfi_add_CFA_def_cfa (sp_regno
, 0);
4115 z80_tc_regname_to_dw2regnum (const char *regname
)
4117 static const char *regs
[] =
4118 { /* same registers as for GDB */
4119 "af", "bc", "de", "hl",
4120 "sp", "pc", "ix", "iy",
4121 "af_", "bc_", "de_", "hl_",
4126 for (i
= 0; i
< ARRAY_SIZE(regs
); ++i
)
4127 if (!strcasecmp (regs
[i
], regname
))
4134 /* Implement DWARF2_ADDR_SIZE. */
4136 z80_dwarf2_addr_size (const bfd
*abfd
)
4138 switch (bfd_get_mach (abfd
))
4140 case bfd_mach_ez80_adl
: