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. */
3466 static table_t instab
[] =
3468 { "adc", 0x88, 0x4A, emit_adc
, INS_ALL
},
3469 { "add", 0x80, 0x09, emit_add
, INS_ALL
},
3470 { "and", 0x00, 0xA0, emit_s
, INS_ALL
},
3471 { "bit", 0xCB, 0x40, emit_bit
, INS_ALL
},
3472 { "brlc", 0xED, 0x2C, emit_bshft
,INS_Z80N
},
3473 { "bsla", 0xED, 0x28, emit_bshft
,INS_Z80N
},
3474 { "bsra", 0xED, 0x29, emit_bshft
,INS_Z80N
},
3475 { "bsrf", 0xED, 0x2B, emit_bshft
,INS_Z80N
},
3476 { "bsrl", 0xED, 0x2A, emit_bshft
,INS_Z80N
},
3477 { "call", 0xCD, 0xC4, emit_jpcc
, INS_ALL
},
3478 { "ccf", 0x00, 0x3F, emit_insn
, INS_ALL
},
3479 { "cp", 0x00, 0xB8, emit_s
, INS_ALL
},
3480 { "cpd", 0xED, 0xA9, emit_insn
, INS_NOT_GBZ80
},
3481 { "cpdr", 0xED, 0xB9, emit_insn
, INS_NOT_GBZ80
},
3482 { "cpi", 0xED, 0xA1, emit_insn
, INS_NOT_GBZ80
},
3483 { "cpir", 0xED, 0xB1, emit_insn
, INS_NOT_GBZ80
},
3484 { "cpl", 0x00, 0x2F, emit_insn
, INS_ALL
},
3485 { "daa", 0x00, 0x27, emit_insn
, INS_ALL
},
3486 { "dec", 0x0B, 0x05, emit_incdec
,INS_ALL
},
3487 { "di", 0x00, 0xF3, emit_insn
, INS_ALL
},
3488 { "djnz", 0x00, 0x10, emit_jr
, INS_NOT_GBZ80
},
3489 { "ei", 0x00, 0xFB, emit_insn
, INS_ALL
},
3490 { "ex", 0x00, 0x00, emit_ex
, INS_NOT_GBZ80
},
3491 { "exx", 0x00, 0xD9, emit_insn
, INS_NOT_GBZ80
},
3492 { "halt", 0x00, 0x76, emit_insn
, INS_ALL
},
3493 { "im", 0xED, 0x46, emit_im
, INS_NOT_GBZ80
},
3494 { "in", 0x00, 0x00, emit_in
, INS_NOT_GBZ80
},
3495 { "in0", 0xED, 0x00, emit_in0
, INS_Z180
|INS_EZ80
},
3496 { "inc", 0x03, 0x04, emit_incdec
,INS_ALL
},
3497 { "ind", 0xED, 0xAA, emit_insn
, INS_NOT_GBZ80
},
3498 { "ind2", 0xED, 0x8C, emit_insn
, INS_EZ80
},
3499 { "ind2r",0xED, 0x9C, emit_insn
, INS_EZ80
},
3500 { "indm", 0xED, 0x8A, emit_insn
, INS_EZ80
},
3501 { "indmr",0xED, 0x9A, emit_insn
, INS_EZ80
},
3502 { "indr", 0xED, 0xBA, emit_insn
, INS_NOT_GBZ80
},
3503 { "indrx",0xED, 0xCA, emit_insn
, INS_EZ80
},
3504 { "ini", 0xED, 0xA2, emit_insn
, INS_NOT_GBZ80
},
3505 { "ini2", 0xED, 0x84, emit_insn
, INS_EZ80
},
3506 { "ini2r",0xED, 0x94, emit_insn
, INS_EZ80
},
3507 { "inim", 0xED, 0x82, emit_insn
, INS_EZ80
},
3508 { "inimr",0xED, 0x92, emit_insn
, INS_EZ80
},
3509 { "inir", 0xED, 0xB2, emit_insn
, INS_NOT_GBZ80
},
3510 { "inirx",0xED, 0xC2, emit_insn
, INS_EZ80
},
3511 { "jp", 0xC3, 0xC2, emit_jpcc
, INS_ALL
},
3512 { "jr", 0x18, 0x20, emit_jrcc
, INS_ALL
},
3513 { "ld", 0x00, 0x00, emit_ld
, INS_ALL
},
3514 { "ldd", 0xED, 0xA8, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3515 { "lddr", 0xED, 0xB8, emit_insn
, INS_NOT_GBZ80
},
3516 { "lddrx",0xED, 0xBC, emit_insn
, INS_Z80N
},
3517 { "lddx", 0xED, 0xAC, emit_insn
, INS_Z80N
},
3518 { "ldh", 0xE0, 0x00, emit_ldh
, INS_GBZ80
},
3519 { "ldhl", 0x00, 0xF8, emit_ldhl
, INS_GBZ80
},
3520 { "ldi", 0xED, 0xA0, emit_lddldi
,INS_ALL
}, /* GBZ80 has special meaning */
3521 { "ldir", 0xED, 0xB0, emit_insn
, INS_NOT_GBZ80
},
3522 { "ldirx",0xED, 0xB4, emit_insn
, INS_Z80N
},
3523 { "ldix", 0xED, 0xA4, emit_insn
, INS_Z80N
},
3524 { "ldpirx",0xED,0xB7, emit_insn
, INS_Z80N
},
3525 { "ldws", 0xED, 0xA5, emit_insn
, INS_Z80N
},
3526 { "lea", 0xED, 0x02, emit_lea
, INS_EZ80
},
3527 { "mirror",0xED,0x24, emit_insn
, INS_Z80N
},
3528 { "mlt", 0xED, 0x4C, emit_mlt
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3529 { "mul", 0xED, 0x30, emit_mul
, INS_Z80N
},
3530 { "mulub",0xED, 0xC5, emit_mulub
,INS_R800
},
3531 { "muluw",0xED, 0xC3, emit_muluw
,INS_R800
},
3532 { "neg", 0xED, 0x44, emit_insn
, INS_NOT_GBZ80
},
3533 { "nextreg",0xED,0x91,emit_nextreg
,INS_Z80N
},
3534 { "nop", 0x00, 0x00, emit_insn
, INS_ALL
},
3535 { "or", 0x00, 0xB0, emit_s
, INS_ALL
},
3536 { "otd2r",0xED, 0xBC, emit_insn
, INS_EZ80
},
3537 { "otdm", 0xED, 0x8B, emit_insn
, INS_Z180
|INS_EZ80
},
3538 { "otdmr",0xED, 0x9B, emit_insn
, INS_Z180
|INS_EZ80
},
3539 { "otdr", 0xED, 0xBB, emit_insn
, INS_NOT_GBZ80
},
3540 { "otdrx",0xED, 0xCB, emit_insn
, INS_EZ80
},
3541 { "oti2r",0xED, 0xB4, emit_insn
, INS_EZ80
},
3542 { "otim", 0xED, 0x83, emit_insn
, INS_Z180
|INS_EZ80
},
3543 { "otimr",0xED, 0x93, emit_insn
, INS_Z180
|INS_EZ80
},
3544 { "otir", 0xED, 0xB3, emit_insn
, INS_NOT_GBZ80
},
3545 { "otirx",0xED, 0xC3, emit_insn
, INS_EZ80
},
3546 { "out", 0x00, 0x00, emit_out
, INS_NOT_GBZ80
},
3547 { "out0", 0xED, 0x01, emit_out0
, INS_Z180
|INS_EZ80
},
3548 { "outd", 0xED, 0xAB, emit_insn
, INS_NOT_GBZ80
},
3549 { "outd2",0xED, 0xAC, emit_insn
, INS_EZ80
},
3550 { "outi", 0xED, 0xA3, emit_insn
, INS_NOT_GBZ80
},
3551 { "outi2",0xED, 0xA4, emit_insn
, INS_EZ80
},
3552 { "outinb",0xED,0x90, emit_insn
, INS_Z80N
},
3553 { "pea", 0xED, 0x65, emit_pea
, INS_EZ80
},
3554 { "pixelad",0xED,0x94,emit_insn
, INS_Z80N
},
3555 { "pixeldn",0xED,0x93,emit_insn
, INS_Z80N
},
3556 { "pop", 0x00, 0xC1, emit_pop
, INS_ALL
},
3557 { "push", 0x00, 0xC5, emit_push
, INS_ALL
},
3558 { "res", 0xCB, 0x80, emit_bit
, INS_ALL
},
3559 { "ret", 0xC9, 0xC0, emit_retcc
,INS_ALL
},
3560 { "reti", 0xED, 0x4D, emit_reti
, INS_ALL
}, /*GBZ80 has its own opcode for it*/
3561 { "retn", 0xED, 0x45, emit_insn
, INS_NOT_GBZ80
},
3562 { "rl", 0xCB, 0x10, emit_mr
, INS_ALL
},
3563 { "rla", 0x00, 0x17, emit_insn
, INS_ALL
},
3564 { "rlc", 0xCB, 0x00, emit_mr
, INS_ALL
},
3565 { "rlca", 0x00, 0x07, emit_insn
, INS_ALL
},
3566 { "rld", 0xED, 0x6F, emit_insn
, INS_NOT_GBZ80
},
3567 { "rr", 0xCB, 0x18, emit_mr
, INS_ALL
},
3568 { "rra", 0x00, 0x1F, emit_insn
, INS_ALL
},
3569 { "rrc", 0xCB, 0x08, emit_mr
, INS_ALL
},
3570 { "rrca", 0x00, 0x0F, emit_insn
, INS_ALL
},
3571 { "rrd", 0xED, 0x67, emit_insn
, INS_NOT_GBZ80
},
3572 { "rsmix",0xED, 0x7E, emit_insn
, INS_EZ80
},
3573 { "rst", 0x00, 0xC7, emit_rst
, INS_ALL
},
3574 { "sbc", 0x98, 0x42, emit_adc
, INS_ALL
},
3575 { "scf", 0x00, 0x37, emit_insn
, INS_ALL
},
3576 { "set", 0xCB, 0xC0, emit_bit
, INS_ALL
},
3577 { "setae",0xED, 0x95, emit_insn
, INS_Z80N
},
3578 { "sl1", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3579 { "sla", 0xCB, 0x20, emit_mr
, INS_ALL
},
3580 { "sli", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3581 { "sll", 0xCB, 0x30, emit_mr
, INS_SLI
|INS_Z80N
},
3582 { "slp", 0xED, 0x76, emit_insn
, INS_Z180
|INS_EZ80
},
3583 { "sra", 0xCB, 0x28, emit_mr
, INS_ALL
},
3584 { "srl", 0xCB, 0x38, emit_mr
, INS_ALL
},
3585 { "stmix",0xED, 0x7D, emit_insn
, INS_EZ80
},
3586 { "stop", 0x00, 0x10, emit_insn
, INS_GBZ80
},
3587 { "sub", 0x00, 0x90, emit_sub
, INS_ALL
},
3588 { "swap", 0xCB, 0x30, emit_swap
, INS_GBZ80
|INS_Z80N
},
3589 { "swapnib",0xED,0x23,emit_insn
, INS_Z80N
},
3590 { "test", 0xED, 0x27, emit_insn_n
, INS_Z80N
},
3591 { "tst", 0xED, 0x04, emit_tst
, INS_Z180
|INS_EZ80
|INS_Z80N
},
3592 { "tstio",0xED, 0x74, emit_insn_n
,INS_Z180
|INS_EZ80
},
3593 { "xor", 0x00, 0xA8, emit_s
, INS_ALL
},
3597 md_assemble (char *str
)
3605 inst_mode
= cpu_mode
? (INST_MODE_L
| INST_MODE_IL
) : (INST_MODE_S
| INST_MODE_IS
);
3606 old_ptr
= input_line_pointer
;
3607 p
= skip_space (str
);
3608 for (i
= 0; (i
< BUFLEN
) && (ISALPHA (*p
) || ISDIGIT (*p
));)
3609 buf
[i
++] = TOLOWER (*p
++);
3613 buf
[BUFLEN
-3] = buf
[BUFLEN
-2] = '.'; /* Mark opcode as abbreviated. */
3615 as_bad (_("Unknown instruction '%s'"), buf
);
3619 dwarf2_emit_insn (0);
3620 if ((*p
) && (!ISSPACE (*p
)))
3622 if (*p
!= '.' || !(ins_ok
& INS_EZ80
) || !assemble_suffix (&p
))
3624 as_bad (_("syntax error"));
3632 insp
= bsearch (&key
, instab
, ARRAY_SIZE (instab
),
3633 sizeof (instab
[0]), key_cmp
);
3634 if (!insp
|| (insp
->inss
&& !(insp
->inss
& ins_ok
)))
3637 as_bad (_("Unknown instruction `%s'"), buf
);
3641 p
= insp
->fp (insp
->prefix
, insp
->opcode
, p
);
3643 if ((!err_flag
) && *p
)
3644 as_bad (_("junk at end of line, "
3645 "first unrecognized character is `%c'"), *p
);
3649 input_line_pointer
= old_ptr
;
3653 is_overflow (long value
, unsigned bitsize
)
3655 long fieldmask
= (1 << bitsize
) - 1;
3656 long signmask
= ~fieldmask
;
3657 long a
= value
& fieldmask
;
3658 long ss
= a
& signmask
;
3659 if (ss
!= 0 && ss
!= (signmask
& fieldmask
))
3665 md_apply_fix (fixS
* fixP
, valueT
* valP
, segT seg
)
3668 char *p_lit
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
3670 if (fixP
->fx_addsy
== NULL
)
3672 else if (fixP
->fx_pcrel
)
3674 segT s
= S_GET_SEGMENT (fixP
->fx_addsy
);
3675 if (s
== seg
|| s
== absolute_section
)
3677 val
+= S_GET_VALUE (fixP
->fx_addsy
);
3682 switch (fixP
->fx_r_type
)
3684 case BFD_RELOC_8_PCREL
:
3685 case BFD_RELOC_Z80_DISP8
:
3690 case BFD_RELOC_Z80_16_BE
:
3691 fixP
->fx_no_overflow
= 0;
3694 fixP
->fx_no_overflow
= 1;
3698 switch (fixP
->fx_r_type
)
3700 case BFD_RELOC_8_PCREL
:
3701 case BFD_RELOC_Z80_DISP8
:
3702 if (fixP
->fx_done
&& (val
< -0x80 || val
> 0x7f))
3703 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
3704 _("8-bit signed offset out of range (%+ld)"), val
);
3708 case BFD_RELOC_Z80_BYTE0
:
3712 case BFD_RELOC_Z80_BYTE1
:
3713 *p_lit
++ = (val
>> 8);
3716 case BFD_RELOC_Z80_BYTE2
:
3717 *p_lit
++ = (val
>> 16);
3720 case BFD_RELOC_Z80_BYTE3
:
3721 *p_lit
++ = (val
>> 24);
3725 if (fixP
->fx_done
&& is_overflow(val
, 8))
3726 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3727 _("8-bit overflow (%+ld)"), val
);
3731 case BFD_RELOC_Z80_WORD1
:
3732 *p_lit
++ = (val
>> 16);
3733 *p_lit
++ = (val
>> 24);
3736 case BFD_RELOC_Z80_WORD0
:
3738 *p_lit
++ = (val
>> 8);
3742 if (fixP
->fx_done
&& is_overflow(val
, 16))
3743 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3744 _("16-bit overflow (%+ld)"), val
);
3746 *p_lit
++ = (val
>> 8);
3749 case BFD_RELOC_24
: /* Def24 may produce this. */
3750 if (fixP
->fx_done
&& is_overflow(val
, 24))
3751 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3752 _("24-bit overflow (%+ld)"), val
);
3754 *p_lit
++ = (val
>> 8);
3755 *p_lit
++ = (val
>> 16);
3758 case BFD_RELOC_32
: /* Def32 and .long may produce this. */
3759 if (fixP
->fx_done
&& is_overflow(val
, 32))
3760 as_warn_where (fixP
->fx_file
, fixP
->fx_line
,
3761 _("32-bit overflow (%+ld)"), val
);
3763 *p_lit
++ = (val
>> 8);
3764 *p_lit
++ = (val
>> 16);
3765 *p_lit
++ = (val
>> 24);
3768 case BFD_RELOC_Z80_16_BE
: /* Z80N PUSH nn instruction produce this. */
3769 *p_lit
++ = val
>> 8;
3774 printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP
->fx_r_type
);
3779 /* GAS will call this to generate a reloc. GAS will pass the
3780 resulting reloc to `bfd_install_relocation'. This currently works
3781 poorly, as `bfd_install_relocation' often does the wrong thing, and
3782 instances of `tc_gen_reloc' have been written to work around the
3783 problems, which in turns makes it difficult to fix
3784 `bfd_install_relocation'. */
3786 /* If while processing a fixup, a reloc really
3787 needs to be created then it is done here. */
3790 tc_gen_reloc (asection
*seg ATTRIBUTE_UNUSED
, fixS
*fixp
)
3794 if (fixp
->fx_subsy
!= NULL
)
3796 as_bad_where (fixp
->fx_file
, fixp
->fx_line
, _("expression too complex"));
3800 reloc
= XNEW (arelent
);
3801 reloc
->sym_ptr_ptr
= XNEW (asymbol
*);
3802 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
3803 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
3804 reloc
->addend
= fixp
->fx_offset
;
3805 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
3806 if (reloc
->howto
== NULL
)
3808 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
3809 _("reloc %d not supported by object file format"),
3810 (int) fixp
->fx_r_type
);
3814 if (fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
3815 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
3816 reloc
->address
= fixp
->fx_offset
;
3822 z80_tc_labels_without_colon (void)
3824 return colonless_labels
;
3828 z80_tc_label_is_local (const char *name
)
3832 if (local_label_prefix
== NULL
)
3834 for (p
= local_label_prefix
, n
= name
; *p
&& *n
&& *n
== *p
; p
++, n
++)
3839 /* Parse floating point number from string and compute mantissa and
3840 exponent. Mantissa is normalized.
3842 #define EXP_MIN -0x10000
3843 #define EXP_MAX 0x10000
3845 str_to_broken_float (bfd_boolean
*signP
, bfd_uint64_t
*mantissaP
, int *expP
)
3849 bfd_uint64_t mantissa
= 0;
3853 p
= (char*)skip_space (input_line_pointer
);
3856 if (sign
|| *p
== '+')
3858 if (strncasecmp (p
, "NaN", 3) == 0)
3862 input_line_pointer
= p
+ 3;
3865 if (strncasecmp (p
, "inf", 3) == 0)
3867 *mantissaP
= 1ull << 63;
3869 input_line_pointer
= p
+ 3;
3872 for (; ISDIGIT (*p
); ++p
)
3880 mantissa
= mantissa
* 10 + (*p
- '0');
3882 /* skip non-significant digits */
3883 for (; ISDIGIT (*p
); ++p
)
3889 if (!exponent
) /* If no precission overflow. */
3891 for (; ISDIGIT (*p
); ++p
, --exponent
)
3899 mantissa
= mantissa
* 10 + (*p
- '0');
3902 for (; ISDIGIT (*p
); ++p
)
3905 if (*p
== 'e' || *p
== 'E')
3911 if (es
|| *p
== '+')
3913 for (; ISDIGIT (*p
); ++p
)
3916 t
= t
* 10 + (*p
- '0');
3918 exponent
+= (es
) ? -t
: t
;
3920 if (ISALNUM (*p
) || *p
== '.')
3922 input_line_pointer
= p
;
3925 *mantissaP
= 1ull << 63;
3927 return 1; /* result is 0 */
3930 for (; mantissa
<= ~0ull/10; --exponent
)
3932 /* Now we have sign, mantissa, and signed decimal exponent
3933 need to recompute to binary exponent. */
3934 for (i
= 64; exponent
> 0; --exponent
)
3936 /* be sure that no integer overflow */
3937 while (mantissa
> ~0ull/10)
3944 for (; exponent
< 0; ++exponent
)
3946 while (!(mantissa
>> 63))
3954 for (; !(mantissa
>> 63); --i
)
3956 *mantissaP
= mantissa
;
3962 str_to_zeda32(char *litP
, int *sizeP
)
3964 bfd_uint64_t mantissa
;
3970 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
3971 return _("invalid syntax");
3972 /* I do not know why decrement is needed */
3974 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
3978 /* make 24 bit mantissa */
3980 /* check for overflow */
3987 if (exponent
< -127)
3992 else if (exponent
> 127)
3995 mantissa
= sign
? 0xc00000 : 0x400000;
3997 else if (mantissa
== 0)
4000 mantissa
= 0x200000;
4003 mantissa
&= (1ull << 23) - 1;
4004 for (i
= 0; i
< 24; i
+= 8)
4005 *litP
++ = (char)(mantissa
>> i
);
4006 *litP
= (char)(0x80 + exponent
);
4011 Math48 by Anders Hejlsberg support.
4012 Mantissa is 39 bits wide, exponent 8 bit wide.
4015 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4016 bit 7-0: exponent+128 (0 - value is null)
4017 MIN: 2.938735877e-39
4018 MAX: 1.701411835e+38
4021 str_to_float48(char *litP
, int *sizeP
)
4023 bfd_uint64_t mantissa
;
4029 if (!str_to_broken_float (&sign
, &mantissa
, &exponent
))
4030 return _("invalid syntax");
4031 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4035 /* make 40 bit mantissa */
4037 /* check for overflow */
4043 if (exponent
< -127)
4045 memset (litP
, 0, 6);
4049 return _("overflow");
4051 mantissa
&= (1ull << 39) - 1;
4052 *litP
++ = (char)(0x80 + exponent
);
4053 for (i
= 0; i
< 40; i
+= 8)
4054 *litP
++ = (char)(mantissa
>> i
);
4059 str_to_ieee754_h(char *litP
, int *sizeP
)
4061 return ieee_md_atof ('h', litP
, sizeP
, FALSE
);
4065 str_to_ieee754_s(char *litP
, int *sizeP
)
4067 return ieee_md_atof ('s', litP
, sizeP
, FALSE
);
4071 str_to_ieee754_d(char *litP
, int *sizeP
)
4073 return ieee_md_atof ('d', litP
, sizeP
, FALSE
);
4076 #ifdef TARGET_USE_CFIPOP
4077 /* Initialize the DWARF-2 unwind information for this procedure. */
4079 z80_tc_frame_initial_instructions (void)
4081 static int sp_regno
= -1;
4084 sp_regno
= z80_tc_regname_to_dw2regnum ("sp");
4086 cfi_add_CFA_def_cfa (sp_regno
, 0);
4090 z80_tc_regname_to_dw2regnum (const char *regname
)
4092 static const char *regs
[] =
4093 { /* same registers as for GDB */
4094 "af", "bc", "de", "hl",
4095 "sp", "pc", "ix", "iy",
4096 "af_", "bc_", "de_", "hl_",
4101 for (i
= 0; i
< ARRAY_SIZE(regs
); ++i
)
4102 if (!strcasecmp (regs
[i
], regname
))
4109 /* Implement DWARF2_ADDR_SIZE. */
4111 z80_dwarf2_addr_size (const bfd
*abfd
)
4113 switch (bfd_get_mach (abfd
))
4115 case bfd_mach_ez80_adl
: