1 /* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800
2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
3 Contributed by Arnold Metselaar <arnold_m@operamail.com>
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
23 #include "safe-ctype.h"
26 #include "dwarf2dbg.h"
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 if (ins_ok
& INS_EZ80
) /* if select EZ80 cpu then */
496 listing_lhs_width
= 6; /* use 6 bytes per line in the listing */
498 reg
.X_op
= O_register
;
500 reg
.X_add_symbol
= reg
.X_op_symbol
= 0;
501 for ( i
= 0 ; i
< ARRAY_SIZE ( regtable
) ; ++i
)
503 if (regtable
[i
].isa
&& !(regtable
[i
].isa
& ins_ok
))
505 reg
.X_add_number
= regtable
[i
].number
;
506 k
= strlen ( regtable
[i
].name
);
510 for ( j
= ( 1<<k
) ; j
; --j
)
512 for ( k
= 0 ; regtable
[i
].name
[k
] ; ++k
)
514 buf
[k
] = ( j
& ( 1<<k
) ) ? TOUPPER (regtable
[i
].name
[k
]) : regtable
[i
].name
[k
];
516 symbolS
* psym
= symbol_find_or_make (buf
);
517 S_SET_SEGMENT (psym
, reg_section
);
518 symbol_set_value_expression (psym
, ®
);
522 p
= input_line_pointer
;
523 input_line_pointer
= (char *) "0";
526 input_line_pointer
= p
;
527 zero
= make_expr_symbol (& nul
);
528 /* We do not use relaxation (yet). */
537 switch (ins_ok
& INS_MARCH_MASK
)
540 mach_type
= bfd_mach_z80
;
543 mach_type
= bfd_mach_r800
;
546 mach_type
= bfd_mach_z180
;
549 mach_type
= bfd_mach_gbz80
;
552 mach_type
= cpu_mode
? bfd_mach_ez80_adl
: bfd_mach_ez80_z80
;
555 mach_type
= bfd_mach_z80n
;
560 bfd_set_arch_mach (stdoutput
, TARGET_ARCH
, mach_type
);
563 #if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
565 z80_elf_final_processing (void)
566 {/* nothing to do, all is done by BFD itself */
569 elf_elfheader (stdoutput)->e_flags = elf_flags;
575 skip_space (const char *s
)
577 while (*s
== ' ' || *s
== '\t')
582 /* A non-zero return-value causes a continue in the
583 function read_a_source_file () in ../read.c. */
585 z80_start_line_hook (void)
590 /* Convert one character constants. */
591 for (p
= input_line_pointer
; *p
&& *p
!= '\n'; ++p
)
596 if (p
[1] != 0 && p
[1] != '\'' && p
[2] == '\'')
598 snprintf (buf
, 4, "%3d", (unsigned char)p
[1]);
606 for (quote
= *p
++; quote
!= *p
&& '\n' != *p
; ++p
)
610 as_bad (_("-- unterminated string"));
611 ignore_rest_of_line ();
617 *p
= (*skip_space (p
+ 1) == '(') ? '+' : ' ';
621 /* Check for <label>[:] =|([.](EQU|DEFL)) <value>. */
622 if (is_name_beginner (*input_line_pointer
))
625 char c
, *rest
, *line_start
;
628 line_start
= input_line_pointer
;
631 c
= get_symbol_name (&name
);
632 rest
= input_line_pointer
+ 1;
633 if (c
== ':' && *rest
== ':')
635 /* remove second colon if SDCC compatibility enabled */
640 rest
= (char*)skip_space (rest
);
642 len
= (rest
[1] == '=') ? 2 : 1;
647 if (strncasecmp (rest
, "EQU", 3) == 0)
649 else if (strncasecmp (rest
, "DEFL", 4) == 0)
654 if (len
&& (len
<= 2 || !ISALPHA (rest
[len
])))
656 /* Handle assignment here. */
657 if (line_start
[-1] == '\n')
659 bump_line_counters ();
662 input_line_pointer
= rest
+ len
- 1;
663 /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
666 case 1: /* label = expr */
667 case 4: /* label DEFL expr */
670 case 2: /* label == expr */
671 case 3: /* label EQU expr */
679 /* Restore line and pointer. */
680 (void) restore_line_pointer (c
);
681 input_line_pointer
= line_start
;
688 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
694 md_atof (int type
, char *litP
, int *sizeP
)
703 return str_to_float (litP
, sizeP
);
710 return str_to_double (litP
, sizeP
);
713 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
717 md_section_align (segT seg ATTRIBUTE_UNUSED
, valueT size
)
723 md_pcrel_from (fixS
* fixp
)
725 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
728 typedef const char * (asfunc
)(char, char, const char*);
730 typedef struct _table_t
733 unsigned char prefix
;
734 unsigned char opcode
;
736 unsigned inss
; /*0 - all CPU types or list of supported INS_* */
739 /* Compares the key for structs that start with a char * to the key. */
741 key_cmp (const void * a
, const void * b
)
743 const char *str_a
, *str_b
;
745 str_a
= *((const char**)a
);
746 str_b
= *((const char**)b
);
747 return strcmp (str_a
, str_b
);
751 const char *key
= buf
;
753 /* Prevent an error on a line from also generating
754 a "junk at end of line" error message. */
755 static char err_flag
;
758 error (const char * message
)
763 as_bad ("%s", message
);
770 error (_("illegal operand"));
774 wrong_mach (int ins_type
)
776 if (ins_type
& ins_err
)
779 as_warn (_("undocumented instruction"));
783 check_mach (int ins_type
)
785 if ((ins_type
& ins_ok
) == 0)
786 wrong_mach (ins_type
);
789 /* Check whether an expression is indirect. */
791 is_indir (const char *s
)
797 /* Indirection is indicated with parentheses. */
800 for (p
= s
, depth
= 0; *p
&& *p
!= ','; ++p
)
806 for (quote
= *p
++; quote
!= *p
&& *p
!= '\n'; ++p
)
807 if (*p
== '\\' && p
[1])
817 p
= skip_space (p
+ 1);
823 error (_("mismatched parentheses"));
829 error (_("mismatched parentheses"));
834 /* Check whether a symbol involves a register. */
836 contains_register (symbolS
*sym
)
840 expressionS
* ex
= symbol_get_value_expression (sym
);
849 if (ex
->X_op_symbol
&& contains_register (ex
->X_op_symbol
))
854 if (ex
->X_add_symbol
&& contains_register (ex
->X_add_symbol
))
866 /* Parse general expression, not looking for indexed addressing. */
868 parse_exp_not_indexed (const char *s
, expressionS
*op
)
875 if (sdcc_compat
&& (*p
== '<' || *p
== '>'))
879 case '<': /* LSB request */
882 case '>': /* MSB request */
883 make_shift
= cpu_mode
? 16 : 8;
890 op
->X_md
= indir
= is_indir (p
);
891 if (indir
&& (ins_ok
& INS_GBZ80
))
892 { /* check for instructions like ld a,(hl+), ld (hl-),a */
893 p
= skip_space (p
+1);
894 if (!strncasecmp (p
, "hl", 2))
897 if (*skip_space(p
+1) == ')' && (*p
== '+' || *p
== '-'))
900 op
->X_add_symbol
= NULL
;
901 op
->X_add_number
= (*p
== '+') ? REG_HL
: -REG_HL
;
902 input_line_pointer
= (char*)skip_space(p
+ 1) + 1;
903 return input_line_pointer
;
907 input_line_pointer
= (char*) s
;
912 error (_("missing operand"));
915 error (_("bad expression syntax"));
923 /* replace [op] by [op >> shift] */
925 op
->X_add_symbol
= make_expr_symbol (op
);
926 op
->X_add_number
= 0;
927 op
->X_op
= O_right_shift
;
928 memset (&data
, 0, sizeof (data
));
929 data
.X_op
= O_constant
;
930 data
.X_add_number
= make_shift
;
931 op
->X_op_symbol
= make_expr_symbol (&data
);
933 return input_line_pointer
;
937 unify_indexed (expressionS
*op
)
939 if (O_register
!= symbol_get_value_expression (op
->X_add_symbol
)->X_op
)
942 int rnum
= symbol_get_value_expression (op
->X_add_symbol
)->X_add_number
;
943 if ( ((REG_IX
!= rnum
) && (REG_IY
!= rnum
)) || contains_register (op
->X_op_symbol
))
949 /* Convert subtraction to addition of negative value. */
950 if (O_subtract
== op
->X_op
)
953 minus
.X_op
= O_uminus
;
954 minus
.X_add_number
= 0;
955 minus
.X_add_symbol
= op
->X_op_symbol
;
956 minus
.X_op_symbol
= 0;
957 op
->X_op_symbol
= make_expr_symbol (&minus
);
961 /* Clear X_add_number of the expression. */
962 if (op
->X_add_number
!= 0)
965 memset (&add
, 0, sizeof (add
));
967 add
.X_add_number
= op
->X_add_number
;
968 add
.X_add_symbol
= op
->X_op_symbol
;
970 op
->X_add_symbol
= make_expr_symbol (&add
);
973 op
->X_add_symbol
= op
->X_op_symbol
;
975 op
->X_add_number
= rnum
;
980 /* Parse expression, change operator to O_md1 for indexed addressing. */
982 parse_exp (const char *s
, expressionS
*op
)
984 const char* res
= parse_exp_not_indexed (s
, op
);
989 if (unify_indexed (op
) && op
->X_md
)
993 if (op
->X_md
&& ((REG_IX
== op
->X_add_number
) || (REG_IY
== op
->X_add_number
)))
995 op
->X_add_symbol
= zero
;
1000 /* parse SDCC syntax where index register offset placed before parentheses */
1001 if (sdcc_compat
&& is_indir (res
))
1005 res
= parse_exp (res
, op
);
1006 if (op
->X_op
!= O_md1
|| op
->X_add_symbol
!= zero
)
1009 op
->X_add_symbol
= make_expr_symbol (&off
);
1018 /* Condition codes, including some synonyms provided by HiTech zas. */
1019 static const struct reg_entry cc_tab
[] =
1021 { "age", 6 << 3, INS_ALL
},
1022 { "alt", 7 << 3, INS_ALL
},
1023 { "c", 3 << 3, INS_ALL
},
1024 { "di", 4 << 3, INS_ALL
},
1025 { "ei", 5 << 3, INS_ALL
},
1026 { "lge", 2 << 3, INS_ALL
},
1027 { "llt", 3 << 3, INS_ALL
},
1028 { "m", 7 << 3, INS_ALL
},
1029 { "nc", 2 << 3, INS_ALL
},
1030 { "nz", 0 << 3, INS_ALL
},
1031 { "p", 6 << 3, INS_ALL
},
1032 { "pe", 5 << 3, INS_ALL
},
1033 { "po", 4 << 3, INS_ALL
},
1034 { "z", 1 << 3, INS_ALL
},
1037 /* Parse condition code. */
1039 parse_cc (const char *s
, char * op
)
1043 struct reg_entry
* cc_p
;
1045 for (i
= 0; i
< BUFLEN
; ++i
)
1047 if (!ISALPHA (s
[i
])) /* Condition codes consist of letters only. */
1049 buf
[i
] = TOLOWER (s
[i
]);
1053 && ((s
[i
] == 0) || (s
[i
] == ',')))
1056 cc_p
= bsearch (&key
, cc_tab
, ARRAY_SIZE (cc_tab
),
1057 sizeof (cc_tab
[0]), key_cmp
);
1074 emit_insn (char prefix
, char opcode
, const char * args
)
1089 void z80_cons_fix_new (fragS
*frag_p
, int offset
, int nbytes
, expressionS
*exp
)
1091 bfd_reloc_code_real_type r
[4] =
1099 if (nbytes
< 1 || nbytes
> 4)
1101 as_bad (_("unsupported BFD relocation size %u"), nbytes
);
1105 fix_new_exp (frag_p
, offset
, nbytes
, exp
, 0, r
[nbytes
-1]);
1110 emit_data_val (expressionS
* val
, int size
)
1113 bfd_reloc_code_real_type r_type
;
1115 p
= frag_more (size
);
1116 if (val
->X_op
== O_constant
)
1119 for (i
= 0; i
< size
; ++i
)
1120 p
[i
] = (char)(val
->X_add_number
>> (i
*8));
1126 case 1: r_type
= BFD_RELOC_8
; break;
1127 case 2: r_type
= BFD_RELOC_16
; break;
1128 case 3: r_type
= BFD_RELOC_24
; break;
1129 case 4: r_type
= BFD_RELOC_32
; break;
1130 case 8: r_type
= BFD_RELOC_64
; break;
1132 as_fatal (_("invalid data size %d"), size
);
1135 if ( (val
->X_op
== O_register
)
1136 || (val
->X_op
== O_md1
)
1137 || contains_register (val
->X_add_symbol
)
1138 || contains_register (val
->X_op_symbol
))
1141 if (size
<= 2 && val
->X_op_symbol
)
1143 bfd_boolean simplify
= TRUE
;
1144 int shift
= symbol_get_value_expression (val
->X_op_symbol
)->X_add_number
;
1145 if (val
->X_op
== O_bit_and
&& shift
== (1 << (size
*8))-1)
1147 else if (val
->X_op
!= O_right_shift
)
1154 case 0: r_type
= BFD_RELOC_Z80_BYTE0
; break;
1155 case 8: r_type
= BFD_RELOC_Z80_BYTE1
; break;
1156 case 16: r_type
= BFD_RELOC_Z80_BYTE2
; break;
1157 case 24: r_type
= BFD_RELOC_Z80_BYTE3
; break;
1158 default: simplify
= FALSE
;
1161 else /* if (size == 2) */
1165 case 0: r_type
= BFD_RELOC_Z80_WORD0
; break;
1166 case 16: r_type
= BFD_RELOC_Z80_WORD1
; break;
1167 default: simplify
= FALSE
;
1173 val
->X_op
= O_symbol
;
1174 val
->X_op_symbol
= NULL
;
1175 val
->X_add_number
= 0;
1179 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, size
, val
, FALSE
, r_type
);
1183 emit_byte (expressionS
* val
, bfd_reloc_code_real_type r_type
)
1187 if (r_type
== BFD_RELOC_8
)
1189 emit_data_val (val
, 1);
1193 *p
= val
->X_add_number
;
1194 if (contains_register (val
->X_add_symbol
) || contains_register (val
->X_op_symbol
))
1198 else if ((r_type
== BFD_RELOC_8_PCREL
) && (val
->X_op
== O_constant
))
1200 as_bad (_("cannot make a relative jump to an absolute location"));
1202 else if (val
->X_op
== O_constant
)
1204 if ((val
->X_add_number
< -128) || (val
->X_add_number
>= 128))
1206 if (r_type
== BFD_RELOC_Z80_DISP8
)
1207 as_bad (_("index overflow (%+ld)"), val
->X_add_number
);
1209 as_bad (_("offset overflow (%+ld)"), val
->X_add_number
);
1214 /* For symbols only, constants are stored at begin of function. */
1215 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, 1, val
,
1216 (r_type
== BFD_RELOC_8_PCREL
) ? TRUE
: FALSE
, r_type
);
1221 emit_word (expressionS
* val
)
1223 emit_data_val (val
, (inst_mode
& INST_MODE_IL
) ? 3 : 2);
1227 emit_mx (char prefix
, char opcode
, int shift
, expressionS
* arg
)
1228 /* The operand m may be r, (hl), (ix+d), (iy+d),
1229 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1234 rnum
= arg
->X_add_number
;
1250 if ((prefix
== 0) && (rnum
& R_INDEX
))
1252 prefix
= (rnum
& R_IX
) ? 0xDD : 0xFD;
1253 if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
1254 check_mach (INS_IDX_HALF
);
1263 q
= frag_more (prefix
? 2 : 1);
1266 * q
++ = opcode
+ (rnum
<< shift
);
1269 if (ins_ok
& INS_GBZ80
)
1275 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1276 *q
= (prefix
) ? prefix
: (opcode
+ (6 << shift
));
1278 expressionS offset
= *arg
;
1279 offset
.X_op
= O_symbol
;
1280 offset
.X_add_number
= 0;
1281 emit_byte (&offset
, BFD_RELOC_Z80_DISP8
);
1286 *q
= opcode
+(6<<shift
);
1294 /* The operand m may be r, (hl), (ix+d), (iy+d),
1295 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1297 emit_m (char prefix
, char opcode
, const char *args
)
1302 p
= parse_exp (args
, &arg_m
);
1307 emit_mx (prefix
, opcode
, 0, &arg_m
);
1315 /* The operand m may be as above or one of the undocumented
1316 combinations (ix+d),r and (iy+d),r (if unportable instructions
1320 emit_mr (char prefix
, char opcode
, const char *args
)
1322 expressionS arg_m
, arg_r
;
1325 p
= parse_exp (args
, & arg_m
);
1332 p
= parse_exp (p
+ 1, & arg_r
);
1334 if ((arg_r
.X_md
== 0)
1335 && (arg_r
.X_op
== O_register
)
1336 && (arg_r
.X_add_number
< 8))
1337 opcode
+= arg_r
.X_add_number
- 6; /* Emit_mx () will add 6. */
1343 if (!(ins_ok
& INS_Z80N
))
1344 check_mach (INS_ROT_II_LD
);
1348 emit_mx (prefix
, opcode
, 0, & arg_m
);
1357 emit_sx (char prefix
, char opcode
, expressionS
* arg_p
)
1361 switch (arg_p
->X_op
)
1365 emit_mx (prefix
, opcode
, 0, arg_p
);
1372 q
= frag_more (prefix
? 2 : 1);
1376 emit_byte (arg_p
, BFD_RELOC_8
);
1381 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1383 emit_s (char prefix
, char opcode
, const char *args
)
1388 p
= parse_exp (args
, & arg_s
);
1389 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
1390 { /* possible instruction in generic format op A,x */
1391 if (!(ins_ok
& INS_EZ80
) && !sdcc_compat
)
1394 p
= parse_exp (p
, & arg_s
);
1396 emit_sx (prefix
, opcode
, & arg_s
);
1401 emit_sub (char prefix
, char opcode
, const char *args
)
1406 if (!(ins_ok
& INS_GBZ80
))
1407 return emit_s (prefix
, opcode
, args
);
1408 p
= parse_exp (args
, & arg_s
);
1411 error (_("bad instruction syntax"));
1415 if (arg_s
.X_md
!= 0 || arg_s
.X_op
!= O_register
|| arg_s
.X_add_number
!= REG_A
)
1418 p
= parse_exp (p
, & arg_s
);
1420 emit_sx (prefix
, opcode
, & arg_s
);
1425 emit_swap (char prefix
, char opcode
, const char *args
)
1431 if (!(ins_ok
& INS_Z80N
))
1432 return emit_mr (prefix
, opcode
, args
);
1434 /* check for alias swap a for swapnib of Z80N */
1435 p
= parse_exp (args
, ®
);
1436 if (reg
.X_md
!= 0 || reg
.X_op
!= O_register
|| reg
.X_add_number
!= REG_A
)
1446 emit_call (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1449 const char *p
; char *q
;
1451 p
= parse_exp_not_indexed (args
, &addr
);
1463 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1465 emit_incdec (char prefix
, char opcode
, const char * args
)
1467 expressionS operand
;
1469 const char *p
; char *q
;
1471 p
= parse_exp (args
, &operand
);
1472 rnum
= operand
.X_add_number
;
1473 if ((! operand
.X_md
)
1474 && (operand
.X_op
== O_register
)
1477 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1479 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1480 *q
= prefix
+ ((rnum
& 3) << 4);
1484 if ((operand
.X_op
== O_md1
) || (operand
.X_op
== O_register
))
1485 emit_mx (0, opcode
, 3, & operand
);
1493 emit_jr (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1499 p
= parse_exp_not_indexed (args
, &addr
);
1506 addr
.X_add_number
--; /* pcrel computes after offset code */
1507 emit_byte (&addr
, BFD_RELOC_8_PCREL
);
1513 emit_jp (char prefix
, char opcode
, const char * args
)
1520 p
= parse_exp_not_indexed (args
, & addr
);
1523 rnum
= addr
.X_add_number
;
1524 if ((O_register
== addr
.X_op
) && (REG_HL
== (rnum
& ~R_INDEX
)))
1526 q
= frag_more ((rnum
& R_INDEX
) ? 2 : 1);
1528 *q
++ = (rnum
& R_IX
) ? 0xDD : 0xFD;
1531 else if (addr
.X_op
== O_register
&& rnum
== REG_C
&& (ins_ok
& INS_Z80N
))
1550 emit_im (char prefix
, char opcode
, const char * args
)
1556 p
= parse_exp (args
, & mode
);
1557 if (mode
.X_md
|| (mode
.X_op
!= O_constant
))
1560 switch (mode
.X_add_number
)
1564 ++mode
.X_add_number
;
1569 *q
= opcode
+ 8*mode
.X_add_number
;
1578 emit_pop (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1584 p
= parse_exp (args
, & regp
);
1586 && (regp
.X_op
== O_register
)
1587 && (regp
.X_add_number
& R_STACKABLE
))
1591 rnum
= regp
.X_add_number
;
1595 *q
++ = (rnum
&R_IX
)?0xDD:0xFD;
1599 *q
= opcode
+ ((rnum
& 3) << 4);
1608 emit_push (char prefix
, char opcode
, const char * args
)
1614 p
= parse_exp (args
, & arg
);
1615 if (arg
.X_op
== O_register
)
1616 return emit_pop (prefix
, opcode
, args
);
1618 if (arg
.X_md
|| arg
.X_op
== O_md1
|| !(ins_ok
& INS_Z80N
))
1626 fix_new_exp (frag_now
, q
- frag_now
->fr_literal
, 2, &arg
, FALSE
,
1627 BFD_RELOC_Z80_16_BE
);
1633 emit_retcc (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
1638 p
= parse_cc (args
, &cc
);
1644 return p
? p
: args
;
1648 emit_adc (char prefix
, char opcode
, const char * args
)
1655 p
= parse_exp (args
, &term
);
1658 error (_("bad instruction syntax"));
1662 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1665 switch (term
.X_add_number
)
1668 p
= emit_s (0, prefix
, p
);
1671 p
= parse_exp (p
, &term
);
1672 if ((!term
.X_md
) && (term
.X_op
== O_register
))
1674 rnum
= term
.X_add_number
;
1675 if (R_ARITH
== (rnum
& (R_ARITH
| R_INDEX
)))
1679 *q
= opcode
+ ((rnum
& 3) << 4);
1691 emit_add (char prefix
, char opcode
, const char * args
)
1698 p
= parse_exp (args
, &term
);
1701 error (_("bad instruction syntax"));
1705 if ((term
.X_md
) || (term
.X_op
!= O_register
))
1708 switch (term
.X_add_number
)
1711 p
= emit_s (0, prefix
, p
);
1714 p
= parse_exp (p
, &term
);
1715 if (!(ins_ok
& INS_GBZ80
) || term
.X_md
|| term
.X_op
== O_register
)
1719 emit_byte (&term
, BFD_RELOC_Z80_DISP8
);
1723 if (!(ins_ok
& INS_Z80N
))
1732 lhs
= term
.X_add_number
;
1733 p
= parse_exp (p
, &term
);
1734 rhs
= term
.X_add_number
;
1735 if (term
.X_md
!= 0 || term
.X_op
== O_md1
)
1737 else if ((term
.X_op
== O_register
) && (rhs
& R_ARITH
) && (rhs
== lhs
|| (rhs
& ~R_INDEX
) != REG_HL
))
1741 q
= frag_more ((lhs
& R_INDEX
) ? 2 : 1);
1743 *q
++ = (lhs
& R_IX
) ? 0xDD : 0xFD;
1744 *q
= opcode
+ ((rhs
& 3) << 4);
1748 else if (!(lhs
& R_INDEX
) && (ins_ok
& INS_Z80N
))
1750 if (term
.X_op
== O_register
&& rhs
== REG_A
)
1751 { /* ADD BC/DE/HL,A */
1754 *q
= 0x33 - (lhs
& 3);
1757 else if (term
.X_op
!= O_register
&& term
.X_op
!= O_md1
)
1758 { /* ADD BC/DE/HL,nn */
1761 *q
= 0x36 - (lhs
& 3);
1774 emit_bit (char prefix
, char opcode
, const char * args
)
1780 p
= parse_exp (args
, &b
);
1782 error (_("bad instruction syntax"));
1784 bn
= b
.X_add_number
;
1786 && (b
.X_op
== O_constant
)
1791 /* Bit : no optional third operand. */
1792 p
= emit_m (prefix
, opcode
+ (bn
<< 3), p
);
1794 /* Set, res : resulting byte can be copied to register. */
1795 p
= emit_mr (prefix
, opcode
+ (bn
<< 3), p
);
1802 /* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
1804 emit_bshft (char prefix
, char opcode
, const char * args
)
1810 p
= parse_exp (args
, & r1
);
1812 error (_("bad instruction syntax"));
1813 p
= parse_exp (p
, & r2
);
1814 if (r1
.X_md
|| r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_DE
||
1815 r2
.X_md
|| r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_B
)
1824 emit_jpcc (char prefix
, char opcode
, const char * args
)
1829 p
= parse_cc (args
, & cc
);
1830 if (p
&& *p
++ == ',')
1831 p
= emit_call (0, opcode
+ cc
, p
);
1833 p
= (prefix
== (char)0xC3)
1834 ? emit_jp (0xE9, prefix
, args
)
1835 : emit_call (0, prefix
, args
);
1840 emit_jrcc (char prefix
, char opcode
, const char * args
)
1845 p
= parse_cc (args
, &cc
);
1846 if (p
&& *p
++ == ',')
1849 error (_("condition code invalid for jr"));
1851 p
= emit_jr (0, opcode
+ cc
, p
);
1854 p
= emit_jr (0, prefix
, args
);
1860 emit_ex (char prefix_in ATTRIBUTE_UNUSED
,
1861 char opcode_in ATTRIBUTE_UNUSED
, const char * args
)
1865 char prefix
, opcode
;
1867 p
= parse_exp_not_indexed (args
, &op
);
1871 error (_("bad instruction syntax"));
1875 prefix
= opcode
= 0;
1876 if (op
.X_op
== O_register
)
1877 switch (op
.X_add_number
| (op
.X_md
? 0x8000 : 0))
1880 if (TOLOWER (*p
++) == 'a' && TOLOWER (*p
++) == 'f')
1882 /* The scrubber changes '\'' to '`' in this context. */
1889 if (TOLOWER (*p
++) == 'h' && TOLOWER (*p
++) == 'l')
1893 p
= parse_exp (p
, & op
);
1894 if (op
.X_op
== O_register
1896 && (op
.X_add_number
& ~R_INDEX
) == REG_HL
)
1899 if (R_INDEX
& op
.X_add_number
)
1900 prefix
= (R_IX
& op
.X_add_number
) ? 0xDD : 0xFD;
1905 emit_insn (prefix
, opcode
, p
);
1913 emit_in (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1916 expressionS reg
, port
;
1920 p
= parse_exp (args
, ®
);
1921 if (reg
.X_md
&& reg
.X_op
== O_register
&& reg
.X_add_number
== REG_C
)
1922 { /* permit instruction in (c) as alias for in f,(c) */
1925 reg
.X_add_number
= REG_F
;
1931 error (_("bad instruction syntax"));
1934 p
= parse_exp (p
, &port
);
1937 && reg
.X_op
== O_register
1938 && (reg
.X_add_number
<= 7 || reg
.X_add_number
== REG_F
)
1941 if (port
.X_op
!= O_md1
&& port
.X_op
!= O_register
)
1943 if (REG_A
== reg
.X_add_number
)
1947 emit_byte (&port
, BFD_RELOC_8
);
1954 if (port
.X_add_number
== REG_C
|| port
.X_add_number
== REG_BC
)
1956 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
1958 else if (reg
.X_add_number
== REG_F
&& !(ins_ok
& (INS_R800
|INS_Z80N
)))
1959 check_mach (INS_IN_F_C
);
1962 *q
= 0x40|((reg
.X_add_number
&7)<<3);
1974 emit_in0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
1977 expressionS reg
, port
;
1981 p
= parse_exp (args
, ®
);
1984 error (_("bad instruction syntax"));
1988 p
= parse_exp (p
, &port
);
1990 && reg
.X_op
== O_register
1991 && reg
.X_add_number
<= 7
1993 && port
.X_op
!= O_md1
1994 && port
.X_op
!= O_register
)
1998 *q
= 0x00|(reg
.X_add_number
<< 3);
1999 emit_byte (&port
, BFD_RELOC_8
);
2007 emit_out (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2010 expressionS reg
, port
;
2014 p
= parse_exp (args
, & port
);
2017 error (_("bad instruction syntax"));
2020 p
= parse_exp (p
, ®
);
2022 { ill_op (); return p
; }
2023 /* Allow "out (c), 0" as unportable instruction. */
2024 if (reg
.X_op
== O_constant
&& reg
.X_add_number
== 0)
2026 if (!(ins_ok
& INS_Z80N
))
2027 check_mach (INS_OUT_C_0
);
2028 reg
.X_op
= O_register
;
2029 reg
.X_add_number
= 6;
2032 || reg
.X_op
!= O_register
2033 || reg
.X_add_number
> 7)
2036 if (port
.X_op
!= O_register
&& port
.X_op
!= O_md1
)
2038 if (REG_A
== reg
.X_add_number
)
2042 emit_byte (&port
, BFD_RELOC_8
);
2049 if (REG_C
== port
.X_add_number
|| port
.X_add_number
== REG_BC
)
2051 if (port
.X_add_number
== REG_BC
&& !(ins_ok
& INS_EZ80
))
2055 *q
= 0x41 | (reg
.X_add_number
<< 3);
2064 emit_out0 (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2067 expressionS reg
, port
;
2071 p
= parse_exp (args
, & port
);
2074 error (_("bad instruction syntax"));
2077 p
= parse_exp (p
, ®
);
2079 && port
.X_op
!= O_register
2080 && port
.X_op
!= O_md1
2082 && reg
.X_op
== O_register
2083 && reg
.X_add_number
<= 7)
2087 *q
= 0x01 | (reg
.X_add_number
<< 3);
2088 emit_byte (&port
, BFD_RELOC_8
);
2096 emit_rst (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2102 p
= parse_exp_not_indexed (args
, &addr
);
2103 if (addr
.X_op
!= O_constant
)
2105 error ("rst needs constant address");
2109 if (addr
.X_add_number
& ~(7 << 3))
2114 *q
= opcode
+ (addr
.X_add_number
& (7 << 3));
2119 /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
2121 emit_ld_m_n (expressionS
*dst
, expressionS
*src
)
2125 expressionS dst_offset
;
2127 switch (dst
->X_add_number
)
2129 case REG_HL
: prefix
= 0x00; break;
2130 case REG_IX
: prefix
= 0xDD; break;
2131 case REG_IY
: prefix
= 0xFD; break;
2137 q
= frag_more (prefix
? 2 : 1);
2144 dst_offset
.X_op
= O_symbol
;
2145 dst_offset
.X_add_number
= 0;
2146 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2148 emit_byte (src
, BFD_RELOC_8
);
2151 /* For 8-bit load register to memory instructions: LD (<expression>),r. */
2153 emit_ld_m_r (expressionS
*dst
, expressionS
*src
)
2157 expressionS dst_offset
;
2162 if (ins_ok
& INS_GBZ80
)
2163 { /* LD (HL+),A or LD (HL-),A */
2164 if (src
->X_op
!= O_register
|| src
->X_add_number
!= REG_A
)
2166 *frag_more (1) = (dst
->X_add_number
== REG_HL
) ? 0x22 : 0x32;
2170 prefix
= (dst
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2173 switch (dst
->X_add_number
)
2175 case REG_BC
: /* LD (BC),A */
2176 case REG_DE
: /* LD (DE),A */
2177 if (src
->X_add_number
== REG_A
)
2180 *q
= 0x02 | ((dst
->X_add_number
& 3) << 4);
2186 case REG_HL
: /* LD (HL),r or LD (ii+d),r */
2187 if (src
->X_add_number
<= 7)
2189 q
= frag_more (prefix
? 2 : 1);
2192 *q
= 0x70 | src
->X_add_number
;
2196 dst_offset
.X_op
= O_symbol
;
2197 dst_offset
.X_add_number
= 0;
2198 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2206 default: /* LD (nn),A */
2207 if (src
->X_add_number
== REG_A
)
2210 *q
= (ins_ok
& INS_GBZ80
) ? 0xEA : 0x32;
2219 /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
2221 emit_ld_m_rr (expressionS
*dst
, expressionS
*src
)
2226 expressionS dst_offset
;
2230 case O_md1
: /* eZ80 instructions LD (ii+d),rr */
2231 case O_register
: /* eZ80 instructions LD (HL),rr */
2232 if (!(ins_ok
& INS_EZ80
)) /* 16-bit indirect load group is supported by eZ80 only */
2234 switch (dst
->X_add_number
)
2236 case REG_IX
: prefix
= 0xDD; break;
2237 case REG_IY
: prefix
= 0xFD; break;
2238 case REG_HL
: prefix
= 0xED; break;
2242 switch (src
->X_add_number
)
2244 case REG_BC
: opcode
= 0x0F; break;
2245 case REG_DE
: opcode
= 0x1F; break;
2246 case REG_HL
: opcode
= 0x2F; break;
2247 case REG_IX
: opcode
= (prefix
!= 0xFD) ? 0x3F : 0x3E; break;
2248 case REG_IY
: opcode
= (prefix
!= 0xFD) ? 0x3E : 0x3F; break;
2252 q
= frag_more (prefix
? 2 : 1);
2255 if (prefix
== 0xFD || prefix
== 0xDD)
2258 dst_offset
.X_op
= O_symbol
;
2259 dst_offset
.X_add_number
= 0;
2260 emit_byte (& dst_offset
, BFD_RELOC_Z80_DISP8
);
2263 default: /* LD (nn),rr */
2264 if (ins_ok
& INS_GBZ80
)
2266 /* GBZ80 supports only LD (nn),SP */
2267 if (src
->X_add_number
== REG_SP
)
2277 switch (src
->X_add_number
)
2279 case REG_BC
: prefix
= 0xED; opcode
= 0x43; break;
2280 case REG_DE
: prefix
= 0xED; opcode
= 0x53; break;
2281 case REG_HL
: prefix
= 0x00; opcode
= 0x22; break;
2282 case REG_IX
: prefix
= 0xDD; opcode
= 0x22; break;
2283 case REG_IY
: prefix
= 0xFD; opcode
= 0x22; break;
2284 case REG_SP
: prefix
= 0xED; opcode
= 0x73; break;
2289 q
= frag_more (prefix
? 2 : 1);
2298 emit_ld_r_m (expressionS
*dst
, expressionS
*src
)
2299 { /* for 8-bit memory load to register: LD r,(xxx) */
2303 expressionS src_offset
;
2305 if (dst
->X_add_number
== REG_A
&& src
->X_op
== O_register
)
2306 { /* LD A,(BC) or LD A,(DE) */
2307 switch (src
->X_add_number
)
2309 case REG_BC
: opcode
= 0x0A; break;
2310 case REG_DE
: opcode
= 0x1A; break;
2324 if (ins_ok
& INS_GBZ80
)
2325 { /* LD A,(HL+) or LD A,(HL-) */
2326 if (dst
->X_op
== O_register
&& dst
->X_add_number
== REG_A
)
2327 *frag_more (1) = (src
->X_add_number
== REG_HL
) ? 0x2A : 0x3A;
2334 if (dst
->X_add_number
> 7)
2336 opcode
= 0x46; /* LD B,(HL) */
2337 switch (src
->X_add_number
)
2339 case REG_HL
: prefix
= 0x00; break;
2340 case REG_IX
: prefix
= 0xDD; break;
2341 case REG_IY
: prefix
= 0xFD; break;
2345 q
= frag_more (prefix
? 2 : 1);
2348 *q
= opcode
| ((dst
->X_add_number
& 7) << 3);
2352 src_offset
.X_op
= O_symbol
;
2353 src_offset
.X_add_number
= 0;
2354 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2357 default: /* LD A,(nn) */
2358 if (dst
->X_add_number
== REG_A
)
2361 *q
= (ins_ok
& INS_GBZ80
) ? 0xFA : 0x3A;
2368 emit_ld_r_n (expressionS
*dst
, expressionS
*src
)
2369 { /* for 8-bit immediate value load to register: LD r,n */
2373 switch (dst
->X_add_number
)
2395 q
= frag_more (prefix
? 2 : 1);
2398 if (ins_ok
& INS_GBZ80
)
2400 else if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2401 check_mach (INS_IDX_HALF
);
2404 *q
= 0x06 | ((dst
->X_add_number
& 7) << 3);
2405 emit_byte (src
, BFD_RELOC_8
);
2409 emit_ld_r_r (expressionS
*dst
, expressionS
*src
)
2410 { /* mostly 8-bit load register from register instructions: LD r,r */
2411 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2417 switch (dst
->X_add_number
)
2420 switch (src
->X_add_number
)
2422 case REG_HL
: prefix
= 0x00; break;
2423 case REG_IX
: prefix
= 0xDD; break;
2424 case REG_IY
: prefix
= 0xFD; break;
2431 if (!(ins_ok
& INS_EZ80
))
2433 if (src
->X_add_number
!= REG_I
)
2436 error (_("ADL mode instruction"));
2442 if (src
->X_add_number
== REG_HL
)
2444 if (!(ins_ok
& INS_EZ80
))
2447 error (_("ADL mode instruction"));
2451 else if (src
->X_add_number
== REG_A
)
2460 if (!(ins_ok
& INS_EZ80
) || (src
->X_add_number
!= REG_A
))
2463 error (_("ADL mode instruction"));
2468 if (src
->X_add_number
== REG_A
) /* LD R,A */
2477 if (src
->X_add_number
== REG_I
) /* LD A,I */
2483 else if (src
->X_add_number
== REG_R
) /* LD A,R */
2489 else if (src
->X_add_number
== REG_MB
) /* LD A,MB */
2491 if (!(ins_ok
& INS_EZ80
))
2496 error (_("ADL mode instruction"));
2527 switch (src
->X_add_number
)
2538 ill_op (); /* LD iiH/L,H/L are not permitted */
2542 if (prefix
== 0xFD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2543 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2549 if (prefix
== 0xDD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2550 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2557 opcode
= 0x40 + ((dst
->X_add_number
& 7) << 3) + (src
->X_add_number
& 7);
2559 if ((ins_ok
& INS_GBZ80
) && prefix
!= 0)
2561 if (ii_halves
&& !(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2562 check_mach (INS_IDX_HALF
);
2563 if (prefix
== 0 && (ins_ok
& INS_EZ80
))
2567 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2568 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2569 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2570 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2571 as_warn (_("unsupported instruction, assembled as NOP"));
2577 q
= frag_more (prefix
? 2 : 1);
2584 emit_ld_rr_m (expressionS
*dst
, expressionS
*src
)
2585 { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2589 expressionS src_offset
;
2591 /* GBZ80 has no support for 16-bit load from memory instructions */
2592 if (ins_ok
& INS_GBZ80
)
2598 case O_md1
: /* LD rr,(ii+d) */
2599 prefix
= (src
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2601 case O_register
: /* LD rr,(HL) */
2602 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2603 if (!(ins_ok
& INS_EZ80
))
2605 switch (dst
->X_add_number
)
2607 case REG_BC
: opcode
= 0x07; break;
2608 case REG_DE
: opcode
= 0x17; break;
2609 case REG_HL
: opcode
= 0x27; break;
2610 case REG_IX
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x37 : 0x31; break;
2611 case REG_IY
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x31 : 0x37; break;
2621 src_offset
.X_op
= O_symbol
;
2622 src_offset
.X_add_number
= 0;
2623 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2626 default: /* LD rr,(nn) */
2627 switch (dst
->X_add_number
)
2629 case REG_BC
: prefix
= 0xED; opcode
= 0x4B; break;
2630 case REG_DE
: prefix
= 0xED; opcode
= 0x5B; break;
2631 case REG_HL
: prefix
= 0x00; opcode
= 0x2A; break;
2632 case REG_SP
: prefix
= 0xED; opcode
= 0x7B; break;
2633 case REG_IX
: prefix
= 0xDD; opcode
= 0x2A; break;
2634 case REG_IY
: prefix
= 0xFD; opcode
= 0x2A; break;
2638 q
= frag_more (prefix
? 2 : 1);
2648 emit_ld_rr_nn (expressionS
*dst
, expressionS
*src
)
2649 { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2652 int opcode
= 0x21; /* LD HL,nn */
2653 switch (dst
->X_add_number
)
2666 opcode
= 0x01 + ((dst
->X_add_number
& 3) << 4);
2672 if (prefix
&& (ins_ok
& INS_GBZ80
))
2674 q
= frag_more (prefix
? 2 : 1);
2682 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
2685 expressionS dst
, src
;
2688 p
= parse_exp (args
, & dst
);
2690 error (_("bad instruction syntax"));
2691 p
= parse_exp (p
, & src
);
2695 if (src
.X_op
== O_register
)
2697 if (src
.X_add_number
<= 7)
2698 emit_ld_m_r (& dst
, & src
); /* LD (xxx),r */
2700 emit_ld_m_rr (& dst
, & src
); /* LD (xxx),rr */
2703 emit_ld_m_n (& dst
, & src
); /* LD (hl),n or LD (ix/y+r),n */
2705 else if (dst
.X_op
== O_register
)
2709 if (dst
.X_add_number
<= 7)
2710 emit_ld_r_m (& dst
, & src
);
2712 emit_ld_rr_m (& dst
, & src
);
2714 else if (src
.X_op
== O_register
)
2715 emit_ld_r_r (& dst
, & src
);
2716 else if ((dst
.X_add_number
& ~R_INDEX
) <= 7)
2717 emit_ld_r_n (& dst
, & src
);
2719 emit_ld_rr_nn (& dst
, & src
);
2728 emit_lddldi (char prefix
, char opcode
, const char * args
)
2730 expressionS dst
, src
;
2734 if (!(ins_ok
& INS_GBZ80
))
2735 return emit_insn (prefix
, opcode
, args
);
2737 p
= parse_exp (args
, & dst
);
2739 error (_("bad instruction syntax"));
2740 p
= parse_exp (p
, & src
);
2742 if (dst
.X_op
!= O_register
|| src
.X_op
!= O_register
)
2745 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2746 opcode
= (opcode
& 0x08) * 2 + 0x22;
2749 && dst
.X_add_number
== REG_HL
2751 && src
.X_add_number
== REG_A
)
2752 opcode
|= 0x00; /* LDx (HL),A */
2753 else if (dst
.X_md
== 0
2754 && dst
.X_add_number
== REG_A
2756 && src
.X_add_number
== REG_HL
)
2757 opcode
|= 0x08; /* LDx A,(HL) */
2767 emit_ldh (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2770 expressionS dst
, src
;
2774 p
= parse_exp (args
, & dst
);
2777 error (_("bad instruction syntax"));
2781 p
= parse_exp (p
, & src
);
2783 && dst
.X_op
== O_register
2784 && dst
.X_add_number
== REG_A
2786 && src
.X_op
!= O_md1
)
2788 if (src
.X_op
!= O_register
)
2792 emit_byte (& src
, BFD_RELOC_8
);
2794 else if (src
.X_add_number
== REG_C
)
2795 *frag_more (1) = 0xF2;
2799 else if (dst
.X_md
!= 0
2800 && dst
.X_op
!= O_md1
2802 && src
.X_op
== O_register
2803 && src
.X_add_number
== REG_A
)
2805 if (dst
.X_op
== O_register
)
2807 if (dst
.X_add_number
== REG_C
)
2819 emit_byte (& dst
, BFD_RELOC_8
);
2829 emit_ldhl (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2831 expressionS dst
, src
;
2834 p
= parse_exp (args
, & dst
);
2837 error (_("bad instruction syntax"));
2841 p
= parse_exp (p
, & src
);
2842 if (dst
.X_md
|| dst
.X_op
!= O_register
|| dst
.X_add_number
!= REG_SP
2843 || src
.X_md
|| src
.X_op
== O_register
|| src
.X_op
== O_md1
)
2847 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2852 parse_lea_pea_args (const char * args
, expressionS
*op
)
2855 p
= parse_exp (args
, op
);
2856 if (sdcc_compat
&& *p
== ',' && op
->X_op
== O_register
)
2859 p
= parse_exp (p
+ 1, &off
);
2861 op
->X_add_symbol
= make_expr_symbol (&off
);
2867 emit_lea (char prefix
, char opcode
, const char * args
)
2869 expressionS dst
, src
;
2874 p
= parse_exp (args
, & dst
);
2875 if (dst
.X_md
!= 0 || dst
.X_op
!= O_register
)
2878 rnum
= dst
.X_add_number
;
2884 opcode
= 0x02 | ((rnum
& 0x03) << 4);
2887 opcode
= 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2890 opcode
= 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2897 error (_("bad instruction syntax"));
2899 p
= parse_lea_pea_args (p
, & src
);
2900 if (src
.X_md
!= 0 || src
.X_op
!= O_add
/*&& src.X_op != O_register*/)
2903 rnum
= src
.X_add_number
;
2908 case O_register
: /* permit instructions like LEA rr,IX without displacement specified */
2909 src
.X_add_symbol
= zero
;
2918 opcode
= (opcode
== (char)0x33) ? 0x55 : (opcode
|0x00);
2921 opcode
= (opcode
== (char)0x32) ? 0x54 : (opcode
|0x01);
2928 src
.X_op
= O_symbol
;
2929 src
.X_add_number
= 0;
2930 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2936 emit_mlt (char prefix
, char opcode
, const char * args
)
2942 p
= parse_exp (args
, & arg
);
2943 if (arg
.X_md
!= 0 || arg
.X_op
!= O_register
|| !(arg
.X_add_number
& R_ARITH
))
2947 if (ins_ok
& INS_Z80N
)
2949 if (arg
.X_add_number
!= REG_DE
)
2957 *q
= opcode
| ((arg
.X_add_number
& 3) << 4);
2963 /* MUL D,E (Z80N only) */
2965 emit_mul (char prefix
, char opcode
, const char * args
)
2971 p
= parse_exp (args
, & r1
);
2973 error (_("bad instruction syntax"));
2974 p
= parse_exp (p
, & r2
);
2976 if (r1
.X_md
!= 0 || r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_D
||
2977 r2
.X_md
!= 0 || r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_E
)
2988 emit_nextreg (char prefix
, char opcode ATTRIBUTE_UNUSED
, const char * args
)
2994 p
= parse_exp (args
, & rr
);
2996 error (_("bad instruction syntax"));
2997 p
= parse_exp (p
, & nn
);
2998 if (rr
.X_md
!= 0 || rr
.X_op
== O_register
|| rr
.X_op
== O_md1
||
2999 nn
.X_md
!= 0 || nn
.X_op
== O_md1
)
3003 emit_byte (&rr
, BFD_RELOC_8
);
3004 if (nn
.X_op
== O_register
&& nn
.X_add_number
== REG_A
)
3006 else if (nn
.X_op
!= O_register
)
3009 emit_byte (&nn
, BFD_RELOC_8
);
3017 emit_pea (char prefix
, char opcode
, const char * args
)
3023 p
= parse_lea_pea_args (args
, & arg
);
3025 || (/*arg.X_op != O_register &&*/ arg
.X_op
!= O_add
)
3026 || !(arg
.X_add_number
& R_INDEX
))
3028 /* PEA ii without displacement is mostly typo,
3029 because there is PUSH instruction which is shorter and faster */
3030 /*if (arg.X_op == O_register)
3031 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3035 *q
= opcode
+ (arg
.X_add_number
== REG_IY
? 1 : 0);
3037 arg
.X_op
= O_symbol
;
3038 arg
.X_add_number
= 0;
3039 emit_byte (& arg
, BFD_RELOC_Z80_DISP8
);
3045 emit_reti (char prefix
, char opcode
, const char * args
)
3047 if (ins_ok
& INS_GBZ80
)
3048 return emit_insn (0x00, 0xD9, args
);
3050 return emit_insn (prefix
, opcode
, args
);
3054 emit_tst (char prefix
, char opcode
, const char *args
)
3061 p
= parse_exp (args
, & arg_s
);
3062 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
3064 if (!(ins_ok
& INS_EZ80
))
3067 p
= parse_exp (p
, & arg_s
);
3070 rnum
= arg_s
.X_add_number
;
3077 rnum
= arg_s
.X_add_number
;
3078 if (arg_s
.X_md
!= 0)
3087 *q
= opcode
| (rnum
<< 3);
3093 if (ins_ok
& INS_Z80N
)
3103 emit_byte (& arg_s
, BFD_RELOC_8
);
3109 emit_insn_n (char prefix
, char opcode
, const char *args
)
3115 p
= parse_exp (args
, & arg
);
3116 if (arg
.X_md
|| arg
.X_op
== O_register
|| arg
.X_op
== O_md1
)
3122 emit_byte (& arg
, BFD_RELOC_8
);
3128 emit_data (int size ATTRIBUTE_UNUSED
)
3135 if (is_it_end_of_statement ())
3137 demand_empty_rest_of_line ();
3140 p
= skip_space (input_line_pointer
);
3144 if (*p
== '\"' || *p
== '\'')
3146 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
3148 u
= frag_more (cnt
);
3151 as_warn (_("unterminated string"));
3153 p
= skip_space (p
+1);
3157 p
= parse_exp (p
, &exp
);
3158 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3164 as_warn (_("parentheses ignored"));
3165 emit_byte (&exp
, BFD_RELOC_8
);
3169 while (*p
++ == ',') ;
3170 input_line_pointer
= (char *)(p
-1);
3179 if (is_it_end_of_statement ())
3181 demand_empty_rest_of_line ();
3184 p
= skip_space (input_line_pointer
);
3188 p
= parse_exp (p
, &exp
);
3189 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3195 as_warn (_("parentheses ignored"));
3196 emit_data_val (&exp
, size
);
3198 } while (*p
++ == ',') ;
3199 input_line_pointer
= (char *)(p
-1);
3202 /* next functions were commented out because it is difficult to mix
3203 both ADL and Z80 mode instructions within one COFF file:
3204 objdump cannot recognize point of mode switching.
3207 set_cpu_mode (int mode
)
3209 if (ins_ok
& INS_EZ80
)
3212 error (_("CPU mode is unsupported by target"));
3216 assume (int arg ATTRIBUTE_UNUSED
)
3222 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3223 c
= get_symbol_name (& name
);
3224 if (strncasecmp (name
, "ADL", 4) != 0)
3230 restore_line_pointer (c
);
3231 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3232 if (*input_line_pointer
++ != '=')
3234 error (_("assignment expected"));
3237 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3238 n
= get_single_number ();
3244 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3248 p
= skip_space (args
);
3249 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
3255 reg
= TOLOWER (*p
++);
3262 check_mach (INS_R800
);
3263 if (!*skip_space (p
))
3267 *q
= opcode
+ ((reg
- 'b') << 3);
3279 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3283 p
= skip_space (args
);
3284 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
3291 p
= parse_exp (p
, & reg
);
3293 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
3294 switch (reg
.X_add_number
)
3298 check_mach (INS_R800
);
3301 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
3311 assemble_suffix (const char **suffix
)
3314 const char sf
[8][4] =
3334 for (i
= 0; (i
< 3) && (ISALPHA (*p
)); i
++)
3335 sbuf
[i
] = TOLOWER (*p
++);
3336 if (*p
&& !ISSPACE (*p
))
3341 t
= bsearch (sbuf
, sf
, ARRAY_SIZE (sf
), sizeof (sf
[0]), (int(*)(const void*, const void*)) strcmp
);
3348 i
= cpu_mode
? 0x5B : 0x52;
3351 i
= cpu_mode
? 0x49 : 0x40;
3354 i
= cpu_mode
? 0x5B : 0x49;
3363 i
= cpu_mode
? 0x52 : 0x40;
3372 *frag_more (1) = (char)i
;
3375 case 0x40: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IS
; break;
3376 case 0x49: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IS
; break;
3377 case 0x52: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IL
; break;
3378 case 0x5B: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IL
; break;
3386 #if defined(OBJ_ELF)
3387 return obj_elf_section (arg
);
3388 #elif defined(OBJ_COFF)
3389 return obj_coff_section (arg
);
3391 #error Unknown object format
3401 as_fatal (_("Invalid directive"));
3404 ins_ok
&= INS_MARCH_MASK
;
3406 if (old_ins
!= ins_ok
)
3411 ignore (int arg ATTRIBUTE_UNUSED
)
3413 ignore_rest_of_line ();
3421 as_fatal (_("Invalid directive"));
3422 for (p
= input_line_pointer
; *p
&& *p
!= '(' && *p
!= '\n'; p
++)
3429 ignore_rest_of_line ();
3435 /* Port specific pseudo ops. */
3436 const pseudo_typeS md_pseudo_table
[] =
3438 { ".area", area
, 0},
3439 { ".assume", assume
, 0},
3440 { ".ez80", set_inss
, INS_EZ80
},
3441 { ".gbz80", set_inss
, INS_GBZ80
},
3442 { ".module", ignore
, 0},
3443 { ".optsdcc", ignore
, 0},
3444 { ".r800", set_inss
, INS_R800
},
3445 { ".set", s_set
, 0},
3446 { ".z180", set_inss
, INS_Z180
},
3447 { ".z80", set_inss
, INS_Z80
},
3448 { ".z80n", set_inss
, INS_Z80N
},
3449 { "db" , emit_data
, 1},
3450 { "d24", z80_cons
, 3},
3451 { "d32", z80_cons
, 4},
3452 { "def24", z80_cons
, 3},
3453 { "def32", z80_cons
, 4},
3454 { "defb", emit_data
, 1},
3455 { "defm", emit_data
, 1},
3456 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
3457 { "defw", z80_cons
, 2},
3458 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
3459 { "dw", z80_cons
, 2},
3460 { "psect", psect
, 0}, /* TODO: Translate attributes. */
3461 { "set", 0, 0}, /* Real instruction on z80. */
3462 { "xdef", s_globl
, 0}, /* Synonym for .GLOBAL */
3463 { "xref", s_ignore
, 0}, /* Synonym for .EXTERN */
3467 static table_t instab
[] =
3469 { "adc", 0x88, 0x4A, emit_adc
, INS_ALL
},
3470 { "add", 0x80, 0x09, emit_add
, INS_ALL
},
3471 { "and", 0x00, 0xA0, emit_s
, INS_ALL
},
3472 { "bit", 0xCB, 0x40, emit_bit
, INS_ALL
},
3473 { "brlc", 0xED, 0x2C, emit_bshft
,INS_Z80N
},
3474 { "bsla", 0xED, 0x28, emit_bshft
,INS_Z80N
},
3475 { "bsra", 0xED, 0x29, emit_bshft
,INS_Z80N
},
3476 { "bsrf", 0xED, 0x2B, emit_bshft
,INS_Z80N
},
3477 { "bsrl", 0xED, 0x2A, emit_bshft
,INS_Z80N
},
3478 { "call", 0xCD, 0xC4, emit_jpcc
, INS_ALL
},
3479 { "ccf", 0x00, 0x3F, emit_insn
, INS_ALL
},
3480 { "cp", 0x00, 0xB8, emit_s
, INS_ALL
},
3481 { "cpd", 0xED, 0xA9, emit_insn
, INS_NOT_GBZ80
},
3482 { "cpdr", 0xED, 0xB9, emit_insn
, INS_NOT_GBZ80
},
3483 { "cpi", 0xED, 0xA1, emit_insn
, INS_NOT_GBZ80
},
3484 { "cpir", 0xED, 0xB1, emit_insn
, INS_NOT_GBZ80
},
3485 { "cpl", 0x00, 0x2F, emit_insn
, INS_ALL
},
3486 { "daa", 0x00, 0x27, emit_insn
, INS_ALL
},
3487 { "dec", 0x0B, 0x05, emit_incdec
,INS_ALL
},
3488 { "di", 0x00, 0xF3, emit_insn
, INS_ALL
},
3489 { "djnz", 0x00, 0x10, emit_jr
, INS_NOT_GBZ80
},
3490 { "ei", 0x00, 0xFB, emit_insn
, INS_ALL
},
3491 { "ex", 0x00, 0x00, emit_ex
, INS_NOT_GBZ80
},
3492 { "exx", 0x00, 0xD9, emit_insn
, INS_NOT_GBZ80
},
3493 { "halt", 0x00, 0x76, emit_insn
, INS_ALL
},
3494 { "im", 0xED, 0x46, emit_im
, INS_NOT_GBZ80
},
3495 { "in", 0x00, 0x00, emit_in
, INS_NOT_GBZ80
},
3496 { "in0", 0xED, 0x00, emit_in0
, INS_Z180
|INS_EZ80
},
3497 { "inc", 0x03, 0x04, emit_incdec
,INS_ALL
},
3498 { "ind", 0xED, 0xAA, emit_insn
, INS_NOT_GBZ80
},
3499 { "ind2", 0xED, 0x8C, emit_insn
, INS_EZ80
},
3500 { "ind2r",0xED, 0x9C, emit_insn
, INS_EZ80
},
3501 { "indm", 0xED, 0x8A, emit_insn
, INS_EZ80
},
3502 { "indmr",0xED, 0x9A, emit_insn
, INS_EZ80
},
3503 { "indr", 0xED, 0xBA, emit_insn
, INS_NOT_GBZ80
},
3504 { "indrx",0xED, 0xCA, emit_insn
, INS_EZ80
},
3505 { "ini", 0xED, 0xA2, emit_insn
, INS_NOT_GBZ80
},
3506 { "ini2", 0xED, 0x84, emit_insn
, INS_EZ80
},
3507 { "ini2r",0xED, 0x94, emit_insn
, INS_EZ80
},
3508 { "inim", 0xED, 0x82, emit_insn
, INS_EZ80
},
3509 { "inimr",0xED, 0x92, emit_insn
, INS_EZ80
},
3510 { "inir", 0xED, 0xB2, emit_insn
, INS_NOT_GBZ80
},
3511 { "inirx",0xED, 0xC2, emit_insn
, INS_EZ80
},
3512 { "jp", 0xC3, 0xC2, emit_jpcc
, INS_ALL
},
3513 { "jr", 0x18, 0x20, emit_jrcc
, INS_ALL
},
3514 { "ld", 0x00, 0x00, emit_ld
, INS_ALL
},
3515 { "ldd", 0xED, 0xA8, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3516 { "lddr", 0xED, 0xB8, emit_insn
, INS_NOT_GBZ80
},
3517 { "lddrx",0xED, 0xBC, emit_insn
, INS_Z80N
},
3518 { "lddx", 0xED, 0xAC, emit_insn
, INS_Z80N
},
3519 { "ldh", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3520 { "ldhl", 0x00, 0xF8, emit_ldhl
, INS_GBZ80
},
3521 { "ldi", 0xED, 0xA0, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3522 { "ldir", 0xED, 0xB0, emit_insn
, INS_NOT_GBZ80
},
3523 { "ldirx",0xED, 0xB4, emit_insn
, INS_Z80N
},
3524 { "ldix", 0xED, 0xA4, emit_insn
, INS_Z80N
},
3525 { "ldpirx",0xED,0xB7, emit_insn
, INS_Z80N
},
3526 { "ldws", 0xED, 0xA5, emit_insn
, INS_Z80N
},
3527 { "lea", 0xED, 0x02, emit_lea
, INS_EZ80
},
3528 { "mirror",0xED,0x24, emit_insn
, INS_Z80N
},
3529 { "mlt", 0xED, 0x4C, emit_mlt
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3530 { "mul", 0xED, 0x30, emit_mul
, INS_Z80N
},
3531 { "mulub",0xED, 0xC5, emit_mulub
,INS_R800
},
3532 { "muluw",0xED, 0xC3, emit_muluw
,INS_R800
},
3533 { "neg", 0xED, 0x44, emit_insn
, INS_NOT_GBZ80
},
3534 { "nextreg",0xED,0x91,emit_nextreg
,INS_Z80N
},
3535 { "nop", 0x00, 0x00, emit_insn
, INS_ALL
},
3536 { "or", 0x00, 0xB0, emit_s
, INS_ALL
},
3537 { "otd2r",0xED, 0xBC, emit_insn
, INS_EZ80
},
3538 { "otdm", 0xED, 0x8B, emit_insn
, INS_Z180
|INS_EZ80
},
3539 { "otdmr",0xED, 0x9B, emit_insn
, INS_Z180
|INS_EZ80
},
3540 { "otdr", 0xED, 0xBB, emit_insn
, INS_NOT_GBZ80
},
3541 { "otdrx",0xED, 0xCB, emit_insn
, INS_EZ80
},
3542 { "oti2r",0xED, 0xB4, emit_insn
, INS_EZ80
},
3543 { "otim", 0xED, 0x83, emit_insn
, INS_Z180
|INS_EZ80
},
3544 { "otimr",0xED, 0x93, emit_insn
, INS_Z180
|INS_EZ80
},
3545 { "otir", 0xED, 0xB3, emit_insn
, INS_NOT_GBZ80
},
3546 { "otirx",0xED, 0xC3, emit_insn
, INS_EZ80
},
3547 { "out", 0x00, 0x00, emit_out
, INS_NOT_GBZ80
},
3548 { "out0", 0xED, 0x01, emit_out0
, INS_Z180
|INS_EZ80
},
3549 { "outd", 0xED, 0xAB, emit_insn
, INS_NOT_GBZ80
},
3550 { "outd2",0xED, 0xAC, emit_insn
, INS_EZ80
},
3551 { "outi", 0xED, 0xA3, emit_insn
, INS_NOT_GBZ80
},
3552 { "outi2",0xED, 0xA4, emit_insn
, INS_EZ80
},
3553 { "outinb",0xED,0x90, emit_insn
, INS_Z80N
},
3554 { "pea", 0xED, 0x65, emit_pea
, INS_EZ80
},
3555 { "pixelad",0xED,0x94,emit_insn
, INS_Z80N
},
3556 { "pixeldn",0xED,0x93,emit_insn
, INS_Z80N
},
3557 { "pop", 0x00, 0xC1, emit_pop
, INS_ALL
},
3558 { "push", 0x00, 0xC5, emit_push
, INS_ALL
},
3559 { "res", 0xCB, 0x80, emit_bit
, INS_ALL
},
3560 { "ret", 0xC9, 0xC0, emit_retcc
,INS_ALL
},
3561 { "reti", 0xED, 0x4D, emit_reti
, INS_ALL
}, /*GBZ80 has its own opcode for it*/
3562 { "retn", 0xED, 0x45, emit_insn
, INS_NOT_GBZ80
},
3563 { "rl", 0xCB, 0x10, emit_mr
, INS_ALL
},
3564 { "rla", 0x00, 0x17, emit_insn
, INS_ALL
},
3565 { "rlc", 0xCB, 0x00, emit_mr
, INS_ALL
},
3566 { "rlca", 0x00, 0x07, emit_insn
, INS_ALL
},
3567 { "rld", 0xED, 0x6F, emit_insn
, INS_NOT_GBZ80
},
3568 { "rr", 0xCB, 0x18, emit_mr
, INS_ALL
},
3569 { "rra", 0x00, 0x1F, emit_insn
, INS_ALL
},
3570 { "rrc", 0xCB, 0x08, emit_mr
, INS_ALL
},
3571 { "rrca", 0x00, 0x0F, emit_insn
, INS_ALL
},
3572 { "rrd", 0xED, 0x67, emit_insn
, INS_NOT_GBZ80
},
3573 { "rsmix",0xED, 0x7E, emit_insn
, INS_EZ80
},
3574 { "rst", 0x00, 0xC7, emit_rst
, INS_ALL
},
3575 { "sbc", 0x98, 0x42, emit_adc
, INS_ALL
},
3576 { "scf", 0x00, 0x37, emit_insn
, INS_ALL
},
3577 { "set", 0xCB, 0xC0, emit_bit
, INS_ALL
},
3578 { "setae",0xED, 0x95, emit_insn
, INS_Z80N
},
3579 { "sl1", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3580 { "sla", 0xCB, 0x20, emit_mr
, INS_ALL
},
3581 { "sli", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3582 { "sll", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3583 { "slp", 0xED, 0x76, emit_insn
, INS_Z180
|INS_EZ80
},
3584 { "sra", 0xCB, 0x28, emit_mr
, INS_ALL
},
3585 { "srl", 0xCB, 0x38, emit_mr
, INS_ALL
},
3586 { "stmix",0xED, 0x7D, emit_insn
, INS_EZ80
},
3587 { "stop", 0x00, 0x10, emit_insn
, INS_GBZ80
},
3588 { "sub", 0x00, 0x90, emit_sub
, INS_ALL
},
3589 { "swap", 0xCB, 0x30, emit_swap
, INS_GBZ80
|INS_Z80N
},
3590 { "swapnib",0xED,0x23,emit_insn
, INS_Z80N
},
3591 { "test", 0xED, 0x27, emit_insn_n
, INS_Z80N
},
3592 { "tst", 0xED, 0x04, emit_tst
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3593 { "tstio",0xED, 0x74, emit_insn_n
,INS_Z180
|INS_EZ80
},
3594 { "xor", 0x00, 0xA8, emit_s
, INS_ALL
},
3598 md_assemble (char *str
)
3606 inst_mode
= cpu_mode
? (INST_MODE_L
| INST_MODE_IL
) : (INST_MODE_S
| INST_MODE_IS
);
3607 old_ptr
= input_line_pointer
;
3608 p
= skip_space (str
);
3609 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
) || ISDIGIT (*p
));)
3610 buf
[i
++] = TOLOWER (*p
++);
3614 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
3616 as_bad (_("Unknown instruction '%s'"), buf
);
3620 dwarf2_emit_insn (0);
3621 if ((*p
) && (!ISSPACE (*p
)))
3623 if (*p
!= '.' || !(ins_ok
& INS_EZ80
) || !assemble_suffix (&p
))
3625 as_bad (_("syntax error"));
3633 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
3634 sizeof (instab
[0]), key_cmp
);
3635 if (!insp
|| (insp
->inss
&& !(insp
->inss
& ins_ok
)))
3638 as_bad (_("Unknown instruction `%s'"), buf
);
3642 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
3644 if ((!err_flag
) && *p
)
3645 as_bad (_("junk at end of line, "
3646 "first unrecognized character is `%c'"), *p
);
3650 input_line_pointer
= old_ptr
;
3654 is_overflow (long value
, unsigned bitsize
)
3656 long fieldmask
= (1 << bitsize
) - 1;
3657 long signmask
= ~fieldmask
;
3658 long a
= value
& fieldmask
;
3659 long ss
= a
& signmask
;
3660 if (ss
!= 0 && ss
!= (signmask
& fieldmask
))
3666 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg
)
3669 char *p_lit
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3671 if (fixP
->fx_addsy
== NULL
)
3673 else if (fixP
->fx_pcrel
)
3675 segT s
= S_GET_SEGMENT (fixP
->fx_addsy
);
3676 if (s
== seg
|| s
== absolute_section
)
3678 val
+= S_GET_VALUE (fixP
->fx_addsy
);
3683 switch (fixP
->fx_r_type
)
3685 case BFD_RELOC_8_PCREL
:
3686 case BFD_RELOC_Z80_DISP8
:
3691 case BFD_RELOC_Z80_16_BE
:
3692 fixP
->fx_no_overflow
= 0;
3695 fixP
->fx_no_overflow
= 1;
3699 switch (fixP
->fx_r_type
)
3701 case BFD_RELOC_8_PCREL
:
3702 case BFD_RELOC_Z80_DISP8
:
3703 if (fixP
->fx_done
&& (val
< -0x80 || val
> 0x7f))
3704 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3705 _("8-bit signed offset out of range (%+ld)"), val
);
3709 case BFD_RELOC_Z80_BYTE0
:
3713 case BFD_RELOC_Z80_BYTE1
:
3714 *p_lit
++ = (val
>> 8);
3717 case BFD_RELOC_Z80_BYTE2
:
3718 *p_lit
++ = (val
>> 16);
3721 case BFD_RELOC_Z80_BYTE3
:
3722 *p_lit
++ = (val
>> 24);
3726 if (fixP
->fx_done
&& is_overflow(val
, 8))
3727 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3728 _("8-bit overflow (%+ld)"), val
);
3732 case BFD_RELOC_Z80_WORD1
:
3733 *p_lit
++ = (val
>> 16);
3734 *p_lit
++ = (val
>> 24);
3737 case BFD_RELOC_Z80_WORD0
:
3739 *p_lit
++ = (val
>> 8);
3743 if (fixP
->fx_done
&& is_overflow(val
, 16))
3744 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3745 _("16-bit overflow (%+ld)"), val
);
3747 *p_lit
++ = (val
>> 8);
3750 case BFD_RELOC_24
: /* Def24 may produce this. */
3751 if (fixP
->fx_done
&& is_overflow(val
, 24))
3752 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3753 _("24-bit overflow (%+ld)"), val
);
3755 *p_lit
++ = (val
>> 8);
3756 *p_lit
++ = (val
>> 16);
3759 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
3760 if (fixP
->fx_done
&& is_overflow(val
, 32))
3761 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3762 _("32-bit overflow (%+ld)"), val
);
3764 *p_lit
++ = (val
>> 8);
3765 *p_lit
++ = (val
>> 16);
3766 *p_lit
++ = (val
>> 24);
3769 case BFD_RELOC_Z80_16_BE
: /* Z80N PUSH nn instruction produce this. */
3770 *p_lit
++ = val
>> 8;
3775 printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP
->fx_r_type
);
3780 /* GAS will call this to generate a reloc. GAS will pass the
3781 resulting reloc to `bfd_install_relocation'. This currently works
3782 poorly, as `bfd_install_relocation' often does the wrong thing, and
3783 instances of `tc_gen_reloc' have been written to work around the
3784 problems, which in turns makes it difficult to fix
3785 `bfd_install_relocation'. */
3787 /* If while processing a fixup, a reloc really
3788 needs to be created then it is done here. */
3791 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
3795 if (fixp
->fx_subsy
!= NULL
)
3797 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _("expression too complex"));
3801 reloc
= XNEW (arelent
);
3802 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3803 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3804 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3805 reloc
->addend
= fixp
->fx_offset
;
3806 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3807 if (reloc
->howto
== NULL
)
3809 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3810 _("reloc %d not supported by object file format"),
3811 (int) fixp
->fx_r_type
);
3815 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
3816 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3817 reloc
->address
= fixp
->fx_offset
;
3823 z80_tc_labels_without_colon (void)
3825 return colonless_labels
;
3829 z80_tc_label_is_local (const char *name
)
3833 if (local_label_prefix
== NULL
)
3835 for (p
= local_label_prefix
, n
= name
; *p
&& *n
&& *n
== *p
; p
++, n
++)
3840 /* Parse floating point number from string and compute mantissa and
3841 exponent. Mantissa is normalized.
3843 #define EXP_MIN -0x10000
3844 #define EXP_MAX 0x10000
3846 str_to_broken_float (bfd_boolean
*signP
, bfd_uint64_t
*mantissaP
, int *expP
)
3850 bfd_uint64_t mantissa
= 0;
3854 p
= (char*)skip_space (input_line_pointer
);
3857 if (sign
|| *p
== '+')
3859 if (strncasecmp (p
, "NaN", 3) == 0)
3863 input_line_pointer
= p
+ 3;
3866 if (strncasecmp (p
, "inf", 3) == 0)
3868 *mantissaP
= 1ull << 63;
3870 input_line_pointer
= p
+ 3;
3873 for (; ISDIGIT (*p
); ++p
)
3881 mantissa
= mantissa
* 10 + (*p
- '0');
3883 /* skip non-significant digits */
3884 for (; ISDIGIT (*p
); ++p
)
3890 if (!exponent
) /* If no precision overflow. */
3892 for (; ISDIGIT (*p
); ++p
, --exponent
)
3900 mantissa
= mantissa
* 10 + (*p
- '0');
3903 for (; ISDIGIT (*p
); ++p
)
3906 if (*p
== 'e' || *p
== 'E')
3912 if (es
|| *p
== '+')
3914 for (; ISDIGIT (*p
); ++p
)
3917 t
= t
* 10 + (*p
- '0');
3919 exponent
+= (es
) ? -t
: t
;
3921 if (ISALNUM (*p
) || *p
== '.')
3923 input_line_pointer
= p
;
3926 *mantissaP
= 1ull << 63;
3928 return 1; /* result is 0 */
3931 for (; mantissa
<= ~0ull/10; --exponent
)
3933 /* Now we have sign, mantissa, and signed decimal exponent
3934 need to recompute to binary exponent. */
3935 for (i
= 64; exponent
> 0; --exponent
)
3937 /* be sure that no integer overflow */
3938 while (mantissa
> ~0ull/10)
3945 for (; exponent
< 0; ++exponent
)
3947 while (!(mantissa
>> 63))
3955 for (; !(mantissa
>> 63); --i
)
3957 *mantissaP
= mantissa
;
3963 str_to_zeda32(char *litP
, int *sizeP
)
3965 bfd_uint64_t mantissa
;
3971 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
3972 return _("invalid syntax");
3973 /* I do not know why decrement is needed */
3975 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
3979 /* make 24 bit mantissa */
3981 /* check for overflow */
3988 if (exponent
< -127)
3993 else if (exponent
> 127)
3996 mantissa
= sign
? 0xc00000 : 0x400000;
3998 else if (mantissa
== 0)
4001 mantissa
= 0x200000;
4004 mantissa
&= (1ull << 23) - 1;
4005 for (i
= 0; i
< 24; i
+= 8)
4006 *litP
++ = (char)(mantissa
>> i
);
4007 *litP
= (char)(0x80 + exponent
);
4012 Math48 by Anders Hejlsberg support.
4013 Mantissa is 39 bits wide, exponent 8 bit wide.
4016 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4017 bit 7-0: exponent+128 (0 - value is null)
4018 MIN: 2.938735877e-39
4019 MAX: 1.701411835e+38
4022 str_to_float48(char *litP
, int *sizeP
)
4024 bfd_uint64_t mantissa
;
4030 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
4031 return _("invalid syntax");
4032 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4036 /* make 40 bit mantissa */
4038 /* check for overflow */
4044 if (exponent
< -127)
4046 memset (litP
, 0, 6);
4050 return _("overflow");
4052 mantissa
&= (1ull << 39) - 1;
4053 *litP
++ = (char)(0x80 + exponent
);
4054 for (i
= 0; i
< 40; i
+= 8)
4055 *litP
++ = (char)(mantissa
>> i
);
4060 str_to_ieee754_h(char *litP
, int *sizeP
)
4062 return ieee_md_atof ('h', litP
, sizeP
, FALSE
);
4066 str_to_ieee754_s(char *litP
, int *sizeP
)
4068 return ieee_md_atof ('s', litP
, sizeP
, FALSE
);
4072 str_to_ieee754_d(char *litP
, int *sizeP
)
4074 return ieee_md_atof ('d', litP
, sizeP
, FALSE
);
4077 #ifdef TARGET_USE_CFIPOP
4078 /* Initialize the DWARF-2 unwind information for this procedure. */
4080 z80_tc_frame_initial_instructions (void)
4082 static int sp_regno
= -1;
4085 sp_regno
= z80_tc_regname_to_dw2regnum ("sp");
4087 cfi_add_CFA_def_cfa (sp_regno
, 0);
4091 z80_tc_regname_to_dw2regnum (const char *regname
)
4093 static const char *regs
[] =
4094 { /* same registers as for GDB */
4095 "af", "bc", "de", "hl",
4096 "sp", "pc", "ix", "iy",
4097 "af_", "bc_", "de_", "hl_",
4102 for (i
= 0; i
< ARRAY_SIZE(regs
); ++i
)
4103 if (!strcasecmp (regs
[i
], regname
))
4110 /* Implement DWARF2_ADDR_SIZE. */
4112 z80_dwarf2_addr_size (const bfd
*abfd
)
4114 switch (bfd_get_mach (abfd
))
4116 case bfd_mach_ez80_adl
: