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 EXTENTION 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 precission FP numbers format\n\
413 -fp-d=FORMAT\t\t set double precission 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
)
2396 q
= frag_more (prefix
? 2 : 1);
2399 if (ins_ok
& INS_GBZ80
)
2401 else if (!(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2402 check_mach (INS_IDX_HALF
);
2405 *q
= 0x06 | ((dst
->X_add_number
& 7) << 3);
2406 emit_byte (src
, BFD_RELOC_8
);
2410 emit_ld_r_r (expressionS
*dst
, expressionS
*src
)
2411 { /* mostly 8-bit load register from register instructions: LD r,r */
2412 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2418 switch (dst
->X_add_number
)
2421 switch (src
->X_add_number
)
2423 case REG_HL
: prefix
= 0x00; break;
2424 case REG_IX
: prefix
= 0xDD; break;
2425 case REG_IY
: prefix
= 0xFD; break;
2432 if (!(ins_ok
& INS_EZ80
))
2434 if (src
->X_add_number
!= REG_I
)
2437 error (_("ADL mode instruction"));
2443 if (src
->X_add_number
== REG_HL
)
2445 if (!(ins_ok
& INS_EZ80
))
2448 error (_("ADL mode instruction"));
2452 else if (src
->X_add_number
== REG_A
)
2461 if (!(ins_ok
& INS_EZ80
) || (src
->X_add_number
!= REG_A
))
2464 error (_("ADL mode instruction"));
2469 if (src
->X_add_number
== REG_A
) /* LD R,A */
2478 if (src
->X_add_number
== REG_I
) /* LD A,I */
2484 else if (src
->X_add_number
== REG_R
) /* LD A,R */
2490 else if (src
->X_add_number
== REG_MB
) /* LD A,MB */
2492 if (!(ins_ok
& INS_EZ80
))
2497 error (_("ADL mode instruction"));
2528 switch (src
->X_add_number
)
2539 ill_op (); /* LD iiH/L,H/L are not permitted */
2543 if (prefix
== 0xFD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2544 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2550 if (prefix
== 0xDD || dst
->X_add_number
== REG_H
|| dst
->X_add_number
== REG_L
)
2551 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2558 opcode
= 0x40 + ((dst
->X_add_number
& 7) << 3) + (src
->X_add_number
& 7);
2560 if ((ins_ok
& INS_GBZ80
) && prefix
!= 0)
2562 if (ii_halves
&& !(ins_ok
& (INS_EZ80
|INS_R800
|INS_Z80N
)))
2563 check_mach (INS_IDX_HALF
);
2564 if (prefix
== 0 && (ins_ok
& INS_EZ80
))
2568 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2569 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2570 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2571 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2572 as_warn (_("unsupported instruction, assembled as NOP"));
2578 q
= frag_more (prefix
? 2 : 1);
2585 emit_ld_rr_m (expressionS
*dst
, expressionS
*src
)
2586 { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2590 expressionS src_offset
;
2592 /* GBZ80 has no support for 16-bit load from memory instructions */
2593 if (ins_ok
& INS_GBZ80
)
2599 case O_md1
: /* LD rr,(ii+d) */
2600 prefix
= (src
->X_add_number
== REG_IX
) ? 0xDD : 0xFD;
2602 case O_register
: /* LD rr,(HL) */
2603 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2604 if (!(ins_ok
& INS_EZ80
))
2606 switch (dst
->X_add_number
)
2608 case REG_BC
: opcode
= 0x07; break;
2609 case REG_DE
: opcode
= 0x17; break;
2610 case REG_HL
: opcode
= 0x27; break;
2611 case REG_IX
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x37 : 0x31; break;
2612 case REG_IY
: opcode
= (prefix
== 0xED || prefix
== 0xDD) ? 0x31 : 0x37; break;
2622 src_offset
.X_op
= O_symbol
;
2623 src_offset
.X_add_number
= 0;
2624 emit_byte (& src_offset
, BFD_RELOC_Z80_DISP8
);
2627 default: /* LD rr,(nn) */
2628 switch (dst
->X_add_number
)
2630 case REG_BC
: prefix
= 0xED; opcode
= 0x4B; break;
2631 case REG_DE
: prefix
= 0xED; opcode
= 0x5B; break;
2632 case REG_HL
: prefix
= 0x00; opcode
= 0x2A; break;
2633 case REG_SP
: prefix
= 0xED; opcode
= 0x7B; break;
2634 case REG_IX
: prefix
= 0xDD; opcode
= 0x2A; break;
2635 case REG_IY
: prefix
= 0xFD; opcode
= 0x2A; break;
2639 q
= frag_more (prefix
? 2 : 1);
2649 emit_ld_rr_nn (expressionS
*dst
, expressionS
*src
)
2650 { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2653 int opcode
= 0x21; /* LD HL,nn */
2654 switch (dst
->X_add_number
)
2667 opcode
= 0x01 + ((dst
->X_add_number
& 3) << 4);
2673 if (prefix
&& (ins_ok
& INS_GBZ80
))
2675 q
= frag_more (prefix
? 2 : 1);
2683 emit_ld (char prefix_in ATTRIBUTE_UNUSED
, char opcode_in ATTRIBUTE_UNUSED
,
2686 expressionS dst
, src
;
2689 p
= parse_exp (args
, & dst
);
2691 error (_("bad instruction syntax"));
2692 p
= parse_exp (p
, & src
);
2696 if (src
.X_op
== O_register
)
2698 if (src
.X_add_number
<= 7)
2699 emit_ld_m_r (& dst
, & src
); /* LD (xxx),r */
2701 emit_ld_m_rr (& dst
, & src
); /* LD (xxx),rr */
2704 emit_ld_m_n (& dst
, & src
); /* LD (hl),n or LD (ix/y+r),n */
2706 else if (dst
.X_op
== O_register
)
2710 if (dst
.X_add_number
<= 7)
2711 emit_ld_r_m (& dst
, & src
);
2713 emit_ld_rr_m (& dst
, & src
);
2715 else if (src
.X_op
== O_register
)
2716 emit_ld_r_r (& dst
, & src
);
2717 else if ((dst
.X_add_number
& ~R_INDEX
) <= 7)
2718 emit_ld_r_n (& dst
, & src
);
2720 emit_ld_rr_nn (& dst
, & src
);
2729 emit_lddldi (char prefix
, char opcode
, const char * args
)
2731 expressionS dst
, src
;
2735 if (!(ins_ok
& INS_GBZ80
))
2736 return emit_insn (prefix
, opcode
, args
);
2738 p
= parse_exp (args
, & dst
);
2740 error (_("bad instruction syntax"));
2741 p
= parse_exp (p
, & src
);
2743 if (dst
.X_op
!= O_register
|| src
.X_op
!= O_register
)
2746 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2747 opcode
= (opcode
& 0x08) * 2 + 0x22;
2750 && dst
.X_add_number
== REG_HL
2752 && src
.X_add_number
== REG_A
)
2753 opcode
|= 0x00; /* LDx (HL),A */
2754 else if (dst
.X_md
== 0
2755 && dst
.X_add_number
== REG_A
2757 && src
.X_add_number
== REG_HL
)
2758 opcode
|= 0x08; /* LDx A,(HL) */
2768 emit_ldh (char prefix ATTRIBUTE_UNUSED
, char opcode ATTRIBUTE_UNUSED
,
2771 expressionS dst
, src
;
2775 p
= parse_exp (args
, & dst
);
2778 error (_("bad instruction syntax"));
2782 p
= parse_exp (p
, & src
);
2784 && dst
.X_op
== O_register
2785 && dst
.X_add_number
== REG_A
2787 && src
.X_op
!= O_md1
)
2789 if (src
.X_op
!= O_register
)
2793 emit_byte (& src
, BFD_RELOC_8
);
2795 else if (src
.X_add_number
== REG_C
)
2796 *frag_more (1) = 0xF2;
2800 else if (dst
.X_md
!= 0
2801 && dst
.X_op
!= O_md1
2803 && src
.X_op
== O_register
2804 && src
.X_add_number
== REG_A
)
2806 if (dst
.X_op
== O_register
)
2808 if (dst
.X_add_number
== REG_C
)
2820 emit_byte (& dst
, BFD_RELOC_8
);
2830 emit_ldhl (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
2832 expressionS dst
, src
;
2835 p
= parse_exp (args
, & dst
);
2838 error (_("bad instruction syntax"));
2842 p
= parse_exp (p
, & src
);
2843 if (dst
.X_md
|| dst
.X_op
!= O_register
|| dst
.X_add_number
!= REG_SP
2844 || src
.X_md
|| src
.X_op
== O_register
|| src
.X_op
== O_md1
)
2848 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2853 parse_lea_pea_args (const char * args
, expressionS
*op
)
2856 p
= parse_exp (args
, op
);
2857 if (sdcc_compat
&& *p
== ',' && op
->X_op
== O_register
)
2860 p
= parse_exp (p
+ 1, &off
);
2862 op
->X_add_symbol
= make_expr_symbol (&off
);
2868 emit_lea (char prefix
, char opcode
, const char * args
)
2870 expressionS dst
, src
;
2875 p
= parse_exp (args
, & dst
);
2876 if (dst
.X_md
!= 0 || dst
.X_op
!= O_register
)
2879 rnum
= dst
.X_add_number
;
2885 opcode
= 0x02 | ((rnum
& 0x03) << 4);
2888 opcode
= 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2891 opcode
= 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2898 error (_("bad instruction syntax"));
2900 p
= parse_lea_pea_args (p
, & src
);
2901 if (src
.X_md
!= 0 || src
.X_op
!= O_add
/*&& src.X_op != O_register*/)
2904 rnum
= src
.X_add_number
;
2909 case O_register
: /* permit instructions like LEA rr,IX without displacement specified */
2910 src
.X_add_symbol
= zero
;
2919 opcode
= (opcode
== (char)0x33) ? 0x55 : (opcode
|0x00);
2922 opcode
= (opcode
== (char)0x32) ? 0x54 : (opcode
|0x01);
2929 src
.X_op
= O_symbol
;
2930 src
.X_add_number
= 0;
2931 emit_byte (& src
, BFD_RELOC_Z80_DISP8
);
2937 emit_mlt (char prefix
, char opcode
, const char * args
)
2943 p
= parse_exp (args
, & arg
);
2944 if (arg
.X_md
!= 0 || arg
.X_op
!= O_register
|| !(arg
.X_add_number
& R_ARITH
))
2948 if (ins_ok
& INS_Z80N
)
2950 if (arg
.X_add_number
!= REG_DE
)
2958 *q
= opcode
| ((arg
.X_add_number
& 3) << 4);
2964 /* MUL D,E (Z80N only) */
2966 emit_mul (char prefix
, char opcode
, const char * args
)
2972 p
= parse_exp (args
, & r1
);
2974 error (_("bad instruction syntax"));
2975 p
= parse_exp (p
, & r2
);
2977 if (r1
.X_md
!= 0 || r1
.X_op
!= O_register
|| r1
.X_add_number
!= REG_D
||
2978 r2
.X_md
!= 0 || r2
.X_op
!= O_register
|| r2
.X_add_number
!= REG_E
)
2989 emit_nextreg (char prefix
, char opcode ATTRIBUTE_UNUSED
, const char * args
)
2995 p
= parse_exp (args
, & rr
);
2997 error (_("bad instruction syntax"));
2998 p
= parse_exp (p
, & nn
);
2999 if (rr
.X_md
!= 0 || rr
.X_op
== O_register
|| rr
.X_op
== O_md1
||
3000 nn
.X_md
!= 0 || nn
.X_op
== O_md1
)
3004 emit_byte (&rr
, BFD_RELOC_8
);
3005 if (nn
.X_op
== O_register
&& nn
.X_add_number
== REG_A
)
3007 else if (nn
.X_op
!= O_register
)
3010 emit_byte (&nn
, BFD_RELOC_8
);
3018 emit_pea (char prefix
, char opcode
, const char * args
)
3024 p
= parse_lea_pea_args (args
, & arg
);
3026 || (/*arg.X_op != O_register &&*/ arg
.X_op
!= O_add
)
3027 || !(arg
.X_add_number
& R_INDEX
))
3029 /* PEA ii without displacement is mostly typo,
3030 because there is PUSH instruction which is shorter and faster */
3031 /*if (arg.X_op == O_register)
3032 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3036 *q
= opcode
+ (arg
.X_add_number
== REG_IY
? 1 : 0);
3038 arg
.X_op
= O_symbol
;
3039 arg
.X_add_number
= 0;
3040 emit_byte (& arg
, BFD_RELOC_Z80_DISP8
);
3046 emit_reti (char prefix
, char opcode
, const char * args
)
3048 if (ins_ok
& INS_GBZ80
)
3049 return emit_insn (0x00, 0xD9, args
);
3051 return emit_insn (prefix
, opcode
, args
);
3055 emit_tst (char prefix
, char opcode
, const char *args
)
3062 p
= parse_exp (args
, & arg_s
);
3063 if (*p
== ',' && arg_s
.X_md
== 0 && arg_s
.X_op
== O_register
&& arg_s
.X_add_number
== REG_A
)
3065 if (!(ins_ok
& INS_EZ80
))
3068 p
= parse_exp (p
, & arg_s
);
3071 rnum
= arg_s
.X_add_number
;
3078 rnum
= arg_s
.X_add_number
;
3079 if (arg_s
.X_md
!= 0)
3088 *q
= opcode
| (rnum
<< 3);
3094 if (ins_ok
& INS_Z80N
)
3104 emit_byte (& arg_s
, BFD_RELOC_8
);
3110 emit_insn_n (char prefix
, char opcode
, const char *args
)
3116 p
= parse_exp (args
, & arg
);
3117 if (arg
.X_md
|| arg
.X_op
== O_register
|| arg
.X_op
== O_md1
)
3123 emit_byte (& arg
, BFD_RELOC_8
);
3129 emit_data (int size ATTRIBUTE_UNUSED
)
3136 if (is_it_end_of_statement ())
3138 demand_empty_rest_of_line ();
3141 p
= skip_space (input_line_pointer
);
3145 if (*p
== '\"' || *p
== '\'')
3147 for (quote
= *p
, q
= ++p
, cnt
= 0; *p
&& quote
!= *p
; ++p
, ++cnt
)
3149 u
= frag_more (cnt
);
3152 as_warn (_("unterminated string"));
3154 p
= skip_space (p
+1);
3158 p
= parse_exp (p
, &exp
);
3159 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3165 as_warn (_("parentheses ignored"));
3166 emit_byte (&exp
, BFD_RELOC_8
);
3170 while (*p
++ == ',') ;
3171 input_line_pointer
= (char *)(p
-1);
3180 if (is_it_end_of_statement ())
3182 demand_empty_rest_of_line ();
3185 p
= skip_space (input_line_pointer
);
3189 p
= parse_exp (p
, &exp
);
3190 if (exp
.X_op
== O_md1
|| exp
.X_op
== O_register
)
3196 as_warn (_("parentheses ignored"));
3197 emit_data_val (&exp
, size
);
3199 } while (*p
++ == ',') ;
3200 input_line_pointer
= (char *)(p
-1);
3203 /* next functions were commented out because it is difficult to mix
3204 both ADL and Z80 mode instructions within one COFF file:
3205 objdump cannot recognize point of mode switching.
3208 set_cpu_mode (int mode
)
3210 if (ins_ok
& INS_EZ80
)
3213 error (_("CPU mode is unsupported by target"));
3217 assume (int arg ATTRIBUTE_UNUSED
)
3223 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3224 c
= get_symbol_name (& name
);
3225 if (strncasecmp (name
, "ADL", 4) != 0)
3231 restore_line_pointer (c
);
3232 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3233 if (*input_line_pointer
++ != '=')
3235 error (_("assignment expected"));
3238 input_line_pointer
= (char*)skip_space (input_line_pointer
);
3239 n
= get_single_number ();
3245 emit_mulub (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3249 p
= skip_space (args
);
3250 if (TOLOWER (*p
++) != 'a' || *p
++ != ',')
3256 reg
= TOLOWER (*p
++);
3263 check_mach (INS_R800
);
3264 if (!*skip_space (p
))
3268 *q
= opcode
+ ((reg
- 'b') << 3);
3280 emit_muluw (char prefix ATTRIBUTE_UNUSED
, char opcode
, const char * args
)
3284 p
= skip_space (args
);
3285 if (TOLOWER (*p
++) != 'h' || TOLOWER (*p
++) != 'l' || *p
++ != ',')
3292 p
= parse_exp (p
, & reg
);
3294 if ((!reg
.X_md
) && reg
.X_op
== O_register
)
3295 switch (reg
.X_add_number
)
3299 check_mach (INS_R800
);
3302 *q
= opcode
+ ((reg
.X_add_number
& 3) << 4);
3312 assemble_suffix (const char **suffix
)
3315 const char sf
[8][4] =
3335 for (i
= 0; (i
< 3) && (ISALPHA (*p
)); i
++)
3336 sbuf
[i
] = TOLOWER (*p
++);
3337 if (*p
&& !ISSPACE (*p
))
3342 t
= bsearch (sbuf
, sf
, ARRAY_SIZE (sf
), sizeof (sf
[0]), (int(*)(const void*, const void*)) strcmp
);
3349 i
= cpu_mode
? 0x5B : 0x52;
3352 i
= cpu_mode
? 0x49 : 0x40;
3355 i
= cpu_mode
? 0x5B : 0x49;
3364 i
= cpu_mode
? 0x52 : 0x40;
3373 *frag_more (1) = (char)i
;
3376 case 0x40: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IS
; break;
3377 case 0x49: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IS
; break;
3378 case 0x52: inst_mode
= INST_MODE_FORCED
| INST_MODE_S
| INST_MODE_IL
; break;
3379 case 0x5B: inst_mode
= INST_MODE_FORCED
| INST_MODE_L
| INST_MODE_IL
; break;
3387 #if defined(OBJ_ELF)
3388 return obj_elf_section (arg
);
3389 #elif defined(OBJ_COFF)
3390 return obj_coff_section (arg
);
3392 #error Unknown object format
3402 as_fatal (_("Invalid directive"));
3405 ins_ok
&= INS_MARCH_MASK
;
3407 if (old_ins
!= ins_ok
)
3412 ignore (int arg ATTRIBUTE_UNUSED
)
3414 ignore_rest_of_line ();
3422 as_fatal (_("Invalid directive"));
3423 for (p
= input_line_pointer
; *p
&& *p
!= '(' && *p
!= '\n'; p
++)
3430 ignore_rest_of_line ();
3436 /* Port specific pseudo ops. */
3437 const pseudo_typeS md_pseudo_table
[] =
3439 { ".area", area
, 0},
3440 { ".assume", assume
, 0},
3441 { ".ez80", set_inss
, INS_EZ80
},
3442 { ".gbz80", set_inss
, INS_GBZ80
},
3443 { ".module", ignore
, 0},
3444 { ".optsdcc", ignore
, 0},
3445 { ".r800", set_inss
, INS_R800
},
3446 { ".set", s_set
, 0},
3447 { ".z180", set_inss
, INS_Z180
},
3448 { ".z80", set_inss
, INS_Z80
},
3449 { ".z80n", set_inss
, INS_Z80N
},
3450 { "db" , emit_data
, 1},
3451 { "d24", z80_cons
, 3},
3452 { "d32", z80_cons
, 4},
3453 { "def24", z80_cons
, 3},
3454 { "def32", z80_cons
, 4},
3455 { "defb", emit_data
, 1},
3456 { "defm", emit_data
, 1},
3457 { "defs", s_space
, 1}, /* Synonym for ds on some assemblers. */
3458 { "defw", z80_cons
, 2},
3459 { "ds", s_space
, 1}, /* Fill with bytes rather than words. */
3460 { "dw", z80_cons
, 2},
3461 { "psect", psect
, 0}, /* TODO: Translate attributes. */
3462 { "set", 0, 0}, /* Real instruction on z80. */
3463 { "xdef", s_globl
, 0}, /* Synonym for .GLOBAL */
3464 { "xref", s_ignore
, 0}, /* Synonym for .EXTERN */
3468 static table_t instab
[] =
3470 { "adc", 0x88, 0x4A, emit_adc
, INS_ALL
},
3471 { "add", 0x80, 0x09, emit_add
, INS_ALL
},
3472 { "and", 0x00, 0xA0, emit_s
, INS_ALL
},
3473 { "bit", 0xCB, 0x40, emit_bit
, INS_ALL
},
3474 { "brlc", 0xED, 0x2C, emit_bshft
,INS_Z80N
},
3475 { "bsla", 0xED, 0x28, emit_bshft
,INS_Z80N
},
3476 { "bsra", 0xED, 0x29, emit_bshft
,INS_Z80N
},
3477 { "bsrf", 0xED, 0x2B, emit_bshft
,INS_Z80N
},
3478 { "bsrl", 0xED, 0x2A, emit_bshft
,INS_Z80N
},
3479 { "call", 0xCD, 0xC4, emit_jpcc
, INS_ALL
},
3480 { "ccf", 0x00, 0x3F, emit_insn
, INS_ALL
},
3481 { "cp", 0x00, 0xB8, emit_s
, INS_ALL
},
3482 { "cpd", 0xED, 0xA9, emit_insn
, INS_NOT_GBZ80
},
3483 { "cpdr", 0xED, 0xB9, emit_insn
, INS_NOT_GBZ80
},
3484 { "cpi", 0xED, 0xA1, emit_insn
, INS_NOT_GBZ80
},
3485 { "cpir", 0xED, 0xB1, emit_insn
, INS_NOT_GBZ80
},
3486 { "cpl", 0x00, 0x2F, emit_insn
, INS_ALL
},
3487 { "daa", 0x00, 0x27, emit_insn
, INS_ALL
},
3488 { "dec", 0x0B, 0x05, emit_incdec
,INS_ALL
},
3489 { "di", 0x00, 0xF3, emit_insn
, INS_ALL
},
3490 { "djnz", 0x00, 0x10, emit_jr
, INS_NOT_GBZ80
},
3491 { "ei", 0x00, 0xFB, emit_insn
, INS_ALL
},
3492 { "ex", 0x00, 0x00, emit_ex
, INS_NOT_GBZ80
},
3493 { "exx", 0x00, 0xD9, emit_insn
, INS_NOT_GBZ80
},
3494 { "halt", 0x00, 0x76, emit_insn
, INS_ALL
},
3495 { "im", 0xED, 0x46, emit_im
, INS_NOT_GBZ80
},
3496 { "in", 0x00, 0x00, emit_in
, INS_NOT_GBZ80
},
3497 { "in0", 0xED, 0x00, emit_in0
, INS_Z180
|INS_EZ80
},
3498 { "inc", 0x03, 0x04, emit_incdec
,INS_ALL
},
3499 { "ind", 0xED, 0xAA, emit_insn
, INS_NOT_GBZ80
},
3500 { "ind2", 0xED, 0x8C, emit_insn
, INS_EZ80
},
3501 { "ind2r",0xED, 0x9C, emit_insn
, INS_EZ80
},
3502 { "indm", 0xED, 0x8A, emit_insn
, INS_EZ80
},
3503 { "indmr",0xED, 0x9A, emit_insn
, INS_EZ80
},
3504 { "indr", 0xED, 0xBA, emit_insn
, INS_NOT_GBZ80
},
3505 { "indrx",0xED, 0xCA, emit_insn
, INS_EZ80
},
3506 { "ini", 0xED, 0xA2, emit_insn
, INS_NOT_GBZ80
},
3507 { "ini2", 0xED, 0x84, emit_insn
, INS_EZ80
},
3508 { "ini2r",0xED, 0x94, emit_insn
, INS_EZ80
},
3509 { "inim", 0xED, 0x82, emit_insn
, INS_EZ80
},
3510 { "inimr",0xED, 0x92, emit_insn
, INS_EZ80
},
3511 { "inir", 0xED, 0xB2, emit_insn
, INS_NOT_GBZ80
},
3512 { "inirx",0xED, 0xC2, emit_insn
, INS_EZ80
},
3513 { "jp", 0xC3, 0xC2, emit_jpcc
, INS_ALL
},
3514 { "jr", 0x18, 0x20, emit_jrcc
, INS_ALL
},
3515 { "ld", 0x00, 0x00, emit_ld
, INS_ALL
},
3516 { "ldd", 0xED, 0xA8, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3517 { "lddr", 0xED, 0xB8, emit_insn
, INS_NOT_GBZ80
},
3518 { "lddrx",0xED, 0xBC, emit_insn
, INS_Z80N
},
3519 { "lddx", 0xED, 0xAC, emit_insn
, INS_Z80N
},
3520 { "ldh", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3521 { "ldhl", 0x00, 0xF8, emit_ldhl
, INS_GBZ80
},
3522 { "ldi", 0xED, 0xA0, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3523 { "ldir", 0xED, 0xB0, emit_insn
, INS_NOT_GBZ80
},
3524 { "ldirx",0xED, 0xB4, emit_insn
, INS_Z80N
},
3525 { "ldix", 0xED, 0xA4, emit_insn
, INS_Z80N
},
3526 { "ldpirx",0xED,0xB7, emit_insn
, INS_Z80N
},
3527 { "ldws", 0xED, 0xA5, emit_insn
, INS_Z80N
},
3528 { "lea", 0xED, 0x02, emit_lea
, INS_EZ80
},
3529 { "mirror",0xED,0x24, emit_insn
, INS_Z80N
},
3530 { "mlt", 0xED, 0x4C, emit_mlt
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3531 { "mul", 0xED, 0x30, emit_mul
, INS_Z80N
},
3532 { "mulub",0xED, 0xC5, emit_mulub
,INS_R800
},
3533 { "muluw",0xED, 0xC3, emit_muluw
,INS_R800
},
3534 { "neg", 0xED, 0x44, emit_insn
, INS_NOT_GBZ80
},
3535 { "nextreg",0xED,0x91,emit_nextreg
,INS_Z80N
},
3536 { "nop", 0x00, 0x00, emit_insn
, INS_ALL
},
3537 { "or", 0x00, 0xB0, emit_s
, INS_ALL
},
3538 { "otd2r",0xED, 0xBC, emit_insn
, INS_EZ80
},
3539 { "otdm", 0xED, 0x8B, emit_insn
, INS_Z180
|INS_EZ80
},
3540 { "otdmr",0xED, 0x9B, emit_insn
, INS_Z180
|INS_EZ80
},
3541 { "otdr", 0xED, 0xBB, emit_insn
, INS_NOT_GBZ80
},
3542 { "otdrx",0xED, 0xCB, emit_insn
, INS_EZ80
},
3543 { "oti2r",0xED, 0xB4, emit_insn
, INS_EZ80
},
3544 { "otim", 0xED, 0x83, emit_insn
, INS_Z180
|INS_EZ80
},
3545 { "otimr",0xED, 0x93, emit_insn
, INS_Z180
|INS_EZ80
},
3546 { "otir", 0xED, 0xB3, emit_insn
, INS_NOT_GBZ80
},
3547 { "otirx",0xED, 0xC3, emit_insn
, INS_EZ80
},
3548 { "out", 0x00, 0x00, emit_out
, INS_NOT_GBZ80
},
3549 { "out0", 0xED, 0x01, emit_out0
, INS_Z180
|INS_EZ80
},
3550 { "outd", 0xED, 0xAB, emit_insn
, INS_NOT_GBZ80
},
3551 { "outd2",0xED, 0xAC, emit_insn
, INS_EZ80
},
3552 { "outi", 0xED, 0xA3, emit_insn
, INS_NOT_GBZ80
},
3553 { "outi2",0xED, 0xA4, emit_insn
, INS_EZ80
},
3554 { "outinb",0xED,0x90, emit_insn
, INS_Z80N
},
3555 { "pea", 0xED, 0x65, emit_pea
, INS_EZ80
},
3556 { "pixelad",0xED,0x94,emit_insn
, INS_Z80N
},
3557 { "pixeldn",0xED,0x93,emit_insn
, INS_Z80N
},
3558 { "pop", 0x00, 0xC1, emit_pop
, INS_ALL
},
3559 { "push", 0x00, 0xC5, emit_push
, INS_ALL
},
3560 { "res", 0xCB, 0x80, emit_bit
, INS_ALL
},
3561 { "ret", 0xC9, 0xC0, emit_retcc
,INS_ALL
},
3562 { "reti", 0xED, 0x4D, emit_reti
, INS_ALL
}, /*GBZ80 has its own opcode for it*/
3563 { "retn", 0xED, 0x45, emit_insn
, INS_NOT_GBZ80
},
3564 { "rl", 0xCB, 0x10, emit_mr
, INS_ALL
},
3565 { "rla", 0x00, 0x17, emit_insn
, INS_ALL
},
3566 { "rlc", 0xCB, 0x00, emit_mr
, INS_ALL
},
3567 { "rlca", 0x00, 0x07, emit_insn
, INS_ALL
},
3568 { "rld", 0xED, 0x6F, emit_insn
, INS_NOT_GBZ80
},
3569 { "rr", 0xCB, 0x18, emit_mr
, INS_ALL
},
3570 { "rra", 0x00, 0x1F, emit_insn
, INS_ALL
},
3571 { "rrc", 0xCB, 0x08, emit_mr
, INS_ALL
},
3572 { "rrca", 0x00, 0x0F, emit_insn
, INS_ALL
},
3573 { "rrd", 0xED, 0x67, emit_insn
, INS_NOT_GBZ80
},
3574 { "rsmix",0xED, 0x7E, emit_insn
, INS_EZ80
},
3575 { "rst", 0x00, 0xC7, emit_rst
, INS_ALL
},
3576 { "sbc", 0x98, 0x42, emit_adc
, INS_ALL
},
3577 { "scf", 0x00, 0x37, emit_insn
, INS_ALL
},
3578 { "set", 0xCB, 0xC0, emit_bit
, INS_ALL
},
3579 { "setae",0xED, 0x95, emit_insn
, INS_Z80N
},
3580 { "sl1", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3581 { "sla", 0xCB, 0x20, emit_mr
, INS_ALL
},
3582 { "sli", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3583 { "sll", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3584 { "slp", 0xED, 0x76, emit_insn
, INS_Z180
|INS_EZ80
},
3585 { "sra", 0xCB, 0x28, emit_mr
, INS_ALL
},
3586 { "srl", 0xCB, 0x38, emit_mr
, INS_ALL
},
3587 { "stmix",0xED, 0x7D, emit_insn
, INS_EZ80
},
3588 { "stop", 0x00, 0x10, emit_insn
, INS_GBZ80
},
3589 { "sub", 0x00, 0x90, emit_sub
, INS_ALL
},
3590 { "swap", 0xCB, 0x30, emit_swap
, INS_GBZ80
|INS_Z80N
},
3591 { "swapnib",0xED,0x23,emit_insn
, INS_Z80N
},
3592 { "test", 0xED, 0x27, emit_insn_n
, INS_Z80N
},
3593 { "tst", 0xED, 0x04, emit_tst
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3594 { "tstio",0xED, 0x74, emit_insn_n
,INS_Z180
|INS_EZ80
},
3595 { "xor", 0x00, 0xA8, emit_s
, INS_ALL
},
3599 md_assemble (char *str
)
3607 inst_mode
= cpu_mode
? (INST_MODE_L
| INST_MODE_IL
) : (INST_MODE_S
| INST_MODE_IS
);
3608 old_ptr
= input_line_pointer
;
3609 p
= skip_space (str
);
3610 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
) || ISDIGIT (*p
));)
3611 buf
[i
++] = TOLOWER (*p
++);
3615 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
3617 as_bad (_("Unknown instruction '%s'"), buf
);
3621 dwarf2_emit_insn (0);
3622 if ((*p
) && (!ISSPACE (*p
)))
3624 if (*p
!= '.' || !(ins_ok
& INS_EZ80
) || !assemble_suffix (&p
))
3626 as_bad (_("syntax error"));
3634 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
3635 sizeof (instab
[0]), key_cmp
);
3636 if (!insp
|| (insp
->inss
&& !(insp
->inss
& ins_ok
)))
3639 as_bad (_("Unknown instruction `%s'"), buf
);
3643 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
3645 if ((!err_flag
) && *p
)
3646 as_bad (_("junk at end of line, "
3647 "first unrecognized character is `%c'"), *p
);
3651 input_line_pointer
= old_ptr
;
3655 is_overflow (long value
, unsigned bitsize
)
3657 long fieldmask
= (1 << bitsize
) - 1;
3658 long signmask
= ~fieldmask
;
3659 long a
= value
& fieldmask
;
3660 long ss
= a
& signmask
;
3661 if (ss
!= 0 && ss
!= (signmask
& fieldmask
))
3667 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg
)
3670 char *p_lit
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3672 if (fixP
->fx_addsy
== NULL
)
3674 else if (fixP
->fx_pcrel
)
3676 segT s
= S_GET_SEGMENT (fixP
->fx_addsy
);
3677 if (s
== seg
|| s
== absolute_section
)
3679 val
+= S_GET_VALUE (fixP
->fx_addsy
);
3684 switch (fixP
->fx_r_type
)
3686 case BFD_RELOC_8_PCREL
:
3687 case BFD_RELOC_Z80_DISP8
:
3692 case BFD_RELOC_Z80_16_BE
:
3693 fixP
->fx_no_overflow
= 0;
3696 fixP
->fx_no_overflow
= 1;
3700 switch (fixP
->fx_r_type
)
3702 case BFD_RELOC_8_PCREL
:
3703 case BFD_RELOC_Z80_DISP8
:
3704 if (fixP
->fx_done
&& (val
< -0x80 || val
> 0x7f))
3705 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3706 _("8-bit signed offset out of range (%+ld)"), val
);
3710 case BFD_RELOC_Z80_BYTE0
:
3714 case BFD_RELOC_Z80_BYTE1
:
3715 *p_lit
++ = (val
>> 8);
3718 case BFD_RELOC_Z80_BYTE2
:
3719 *p_lit
++ = (val
>> 16);
3722 case BFD_RELOC_Z80_BYTE3
:
3723 *p_lit
++ = (val
>> 24);
3727 if (fixP
->fx_done
&& is_overflow(val
, 8))
3728 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3729 _("8-bit overflow (%+ld)"), val
);
3733 case BFD_RELOC_Z80_WORD1
:
3734 *p_lit
++ = (val
>> 16);
3735 *p_lit
++ = (val
>> 24);
3738 case BFD_RELOC_Z80_WORD0
:
3740 *p_lit
++ = (val
>> 8);
3744 if (fixP
->fx_done
&& is_overflow(val
, 16))
3745 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3746 _("16-bit overflow (%+ld)"), val
);
3748 *p_lit
++ = (val
>> 8);
3751 case BFD_RELOC_24
: /* Def24 may produce this. */
3752 if (fixP
->fx_done
&& is_overflow(val
, 24))
3753 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3754 _("24-bit overflow (%+ld)"), val
);
3756 *p_lit
++ = (val
>> 8);
3757 *p_lit
++ = (val
>> 16);
3760 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
3761 if (fixP
->fx_done
&& is_overflow(val
, 32))
3762 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3763 _("32-bit overflow (%+ld)"), val
);
3765 *p_lit
++ = (val
>> 8);
3766 *p_lit
++ = (val
>> 16);
3767 *p_lit
++ = (val
>> 24);
3770 case BFD_RELOC_Z80_16_BE
: /* Z80N PUSH nn instruction produce this. */
3771 *p_lit
++ = val
>> 8;
3776 printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP
->fx_r_type
);
3781 /* GAS will call this to generate a reloc. GAS will pass the
3782 resulting reloc to `bfd_install_relocation'. This currently works
3783 poorly, as `bfd_install_relocation' often does the wrong thing, and
3784 instances of `tc_gen_reloc' have been written to work around the
3785 problems, which in turns makes it difficult to fix
3786 `bfd_install_relocation'. */
3788 /* If while processing a fixup, a reloc really
3789 needs to be created then it is done here. */
3792 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
3796 if (fixp
->fx_subsy
!= NULL
)
3798 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _("expression too complex"));
3802 reloc
= XNEW (arelent
);
3803 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3804 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3805 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3806 reloc
->addend
= fixp
->fx_offset
;
3807 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3808 if (reloc
->howto
== NULL
)
3810 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3811 _("reloc %d not supported by object file format"),
3812 (int) fixp
->fx_r_type
);
3816 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
3817 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3818 reloc
->address
= fixp
->fx_offset
;
3824 z80_tc_labels_without_colon (void)
3826 return colonless_labels
;
3830 z80_tc_label_is_local (const char *name
)
3834 if (local_label_prefix
== NULL
)
3836 for (p
= local_label_prefix
, n
= name
; *p
&& *n
&& *n
== *p
; p
++, n
++)
3841 /* Parse floating point number from string and compute mantissa and
3842 exponent. Mantissa is normalized.
3844 #define EXP_MIN -0x10000
3845 #define EXP_MAX 0x10000
3847 str_to_broken_float (bfd_boolean
*signP
, bfd_uint64_t
*mantissaP
, int *expP
)
3851 bfd_uint64_t mantissa
= 0;
3855 p
= (char*)skip_space (input_line_pointer
);
3858 if (sign
|| *p
== '+')
3860 if (strncasecmp (p
, "NaN", 3) == 0)
3864 input_line_pointer
= p
+ 3;
3867 if (strncasecmp (p
, "inf", 3) == 0)
3869 *mantissaP
= 1ull << 63;
3871 input_line_pointer
= p
+ 3;
3874 for (; ISDIGIT (*p
); ++p
)
3882 mantissa
= mantissa
* 10 + (*p
- '0');
3884 /* skip non-significant digits */
3885 for (; ISDIGIT (*p
); ++p
)
3891 if (!exponent
) /* If no precission overflow. */
3893 for (; ISDIGIT (*p
); ++p
, --exponent
)
3901 mantissa
= mantissa
* 10 + (*p
- '0');
3904 for (; ISDIGIT (*p
); ++p
)
3907 if (*p
== 'e' || *p
== 'E')
3913 if (es
|| *p
== '+')
3915 for (; ISDIGIT (*p
); ++p
)
3918 t
= t
* 10 + (*p
- '0');
3920 exponent
+= (es
) ? -t
: t
;
3922 if (ISALNUM (*p
) || *p
== '.')
3924 input_line_pointer
= p
;
3927 *mantissaP
= 1ull << 63;
3929 return 1; /* result is 0 */
3932 for (; mantissa
<= ~0ull/10; --exponent
)
3934 /* Now we have sign, mantissa, and signed decimal exponent
3935 need to recompute to binary exponent. */
3936 for (i
= 64; exponent
> 0; --exponent
)
3938 /* be sure that no integer overflow */
3939 while (mantissa
> ~0ull/10)
3946 for (; exponent
< 0; ++exponent
)
3948 while (!(mantissa
>> 63))
3956 for (; !(mantissa
>> 63); --i
)
3958 *mantissaP
= mantissa
;
3964 str_to_zeda32(char *litP
, int *sizeP
)
3966 bfd_uint64_t mantissa
;
3972 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
3973 return _("invalid syntax");
3974 /* I do not know why decrement is needed */
3976 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
3980 /* make 24 bit mantissa */
3982 /* check for overflow */
3989 if (exponent
< -127)
3994 else if (exponent
> 127)
3997 mantissa
= sign
? 0xc00000 : 0x400000;
3999 else if (mantissa
== 0)
4002 mantissa
= 0x200000;
4005 mantissa
&= (1ull << 23) - 1;
4006 for (i
= 0; i
< 24; i
+= 8)
4007 *litP
++ = (char)(mantissa
>> i
);
4008 *litP
= (char)(0x80 + exponent
);
4013 Math48 by Anders Hejlsberg support.
4014 Mantissa is 39 bits wide, exponent 8 bit wide.
4017 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4018 bit 7-0: exponent+128 (0 - value is null)
4019 MIN: 2.938735877e-39
4020 MAX: 1.701411835e+38
4023 str_to_float48(char *litP
, int *sizeP
)
4025 bfd_uint64_t mantissa
;
4031 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
4032 return _("invalid syntax");
4033 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4037 /* make 40 bit mantissa */
4039 /* check for overflow */
4045 if (exponent
< -127)
4047 memset (litP
, 0, 6);
4051 return _("overflow");
4053 mantissa
&= (1ull << 39) - 1;
4054 *litP
++ = (char)(0x80 + exponent
);
4055 for (i
= 0; i
< 40; i
+= 8)
4056 *litP
++ = (char)(mantissa
>> i
);
4061 str_to_ieee754_h(char *litP
, int *sizeP
)
4063 return ieee_md_atof ('h', litP
, sizeP
, FALSE
);
4067 str_to_ieee754_s(char *litP
, int *sizeP
)
4069 return ieee_md_atof ('s', litP
, sizeP
, FALSE
);
4073 str_to_ieee754_d(char *litP
, int *sizeP
)
4075 return ieee_md_atof ('d', litP
, sizeP
, FALSE
);
4078 #ifdef TARGET_USE_CFIPOP
4079 /* Initialize the DWARF-2 unwind information for this procedure. */
4081 z80_tc_frame_initial_instructions (void)
4083 static int sp_regno
= -1;
4086 sp_regno
= z80_tc_regname_to_dw2regnum ("sp");
4088 cfi_add_CFA_def_cfa (sp_regno
, 0);
4092 z80_tc_regname_to_dw2regnum (const char *regname
)
4094 static const char *regs
[] =
4095 { /* same registers as for GDB */
4096 "af", "bc", "de", "hl",
4097 "sp", "pc", "ix", "iy",
4098 "af_", "bc_", "de_", "hl_",
4103 for (i
= 0; i
< ARRAY_SIZE(regs
); ++i
)
4104 if (!strcasecmp (regs
[i
], regname
))
4111 /* Implement DWARF2_ADDR_SIZE. */
4113 z80_dwarf2_addr_size (const bfd
*abfd
)
4115 switch (bfd_get_mach (abfd
))
4117 case bfd_mach_ez80_adl
: