[binutils][arm] PR25376 Change MVE into a CORE_HIGH feature
[deliverable/binutils-gdb.git] / gas / config / tc-z80.c
CommitLineData
6655dba2 1/* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800
b3adc24a 2 Copyright (C) 2005-2020 Free Software Foundation, Inc.
3c9b82ba
NC
3 Contributed by Arnold Metselaar <arnold_m@operamail.com>
4
5 This file is part of GAS, the GNU Assembler.
6
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
ec2655a6 9 the Free Software Foundation; either version 3, or (at your option)
3c9b82ba
NC
10 any later version.
11
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.
16
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
20 02110-1301, USA. */
21
22#include "as.h"
3c9b82ba
NC
23#include "safe-ctype.h"
24#include "subsegs.h"
6655dba2 25#include "elf/z80.h"
7a6bf3be 26#include "dwarf2dbg.h"
3c9b82ba
NC
27
28/* Exported constants. */
29const char comment_chars[] = ";\0";
30const char line_comment_chars[] = "#;\0";
31const char line_separator_chars[] = "\0";
32const char EXP_CHARS[] = "eE\0";
7a6bf3be 33const char FLT_CHARS[] = "RrDdFfSsHh\0";
3c9b82ba
NC
34
35/* For machine specific options. */
36const char * md_shortopts = ""; /* None yet. */
37
38enum options
39{
40 OPTION_MACH_Z80 = OPTION_MD_BASE,
41 OPTION_MACH_R800,
6655dba2
SB
42 OPTION_MACH_Z180,
43 OPTION_MACH_EZ80_Z80,
44 OPTION_MACH_EZ80_ADL,
45 OPTION_MACH_GBZ80,
46 OPTION_MACH_INST,
47 OPTION_MACH_NO_INST,
3c9b82ba
NC
48 OPTION_MACH_IUD,
49 OPTION_MACH_WUD,
50 OPTION_MACH_FUD,
51 OPTION_MACH_IUP,
52 OPTION_MACH_WUP,
6655dba2 53 OPTION_MACH_FUP,
7a6bf3be
SB
54 OPTION_FP_SINGLE_FORMAT,
55 OPTION_FP_DOUBLE_FORMAT,
6655dba2
SB
56 OPTION_COMPAT_LL_PREFIX,
57 OPTION_COMPAT_COLONLESS,
58 OPTION_COMPAT_SDCC
3c9b82ba
NC
59};
60
6655dba2
SB
61#define INS_Z80 (1 << 0)
62#define INS_R800 (1 << 1)
63#define INS_GBZ80 (1 << 2)
64#define INS_Z180 (1 << 3)
65#define INS_EZ80 (1 << 4)
66#define INS_MARCH_MASK 0xffff
67
68#define INS_IDX_HALF (1 << 16)
69#define INS_IN_F_C (1 << 17)
70#define INS_OUT_C_0 (1 << 18)
71#define INS_SLI (1 << 19)
72#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 */
73#define INS_TUNE_MASK 0xffff0000
74
75#define INS_NOT_GBZ80 (INS_Z80 | INS_Z180 | INS_R800 | INS_EZ80)
76
77#define INS_ALL 0
78#define INS_UNDOC (INS_IDX_HALF | INS_IN_F_C)
79#define INS_UNPORT (INS_OUT_C_0 | INS_SLI | INS_ROT_II_LD)
3c9b82ba
NC
80
81struct option md_longopts[] =
82{
83 { "z80", no_argument, NULL, OPTION_MACH_Z80},
84 { "r800", no_argument, NULL, OPTION_MACH_R800},
6655dba2
SB
85 { "z180", no_argument, NULL, OPTION_MACH_Z180},
86 { "ez80", no_argument, NULL, OPTION_MACH_EZ80_Z80},
87 { "ez80-adl", no_argument, NULL, OPTION_MACH_EZ80_ADL},
7a6bf3be
SB
88 { "fp-s", required_argument, NULL, OPTION_FP_SINGLE_FORMAT},
89 { "fp-d", required_argument, NULL, OPTION_FP_DOUBLE_FORMAT},
6655dba2
SB
90 { "strict", no_argument, NULL, OPTION_MACH_FUD},
91 { "full", no_argument, NULL, OPTION_MACH_IUP},
92 { "with-inst", required_argument, NULL, OPTION_MACH_INST},
93 { "Wnins", required_argument, NULL, OPTION_MACH_INST},
94 { "without-inst", required_argument, NULL, OPTION_MACH_NO_INST},
95 { "local-prefix", required_argument, NULL, OPTION_COMPAT_LL_PREFIX},
96 { "colonless", no_argument, NULL, OPTION_COMPAT_COLONLESS},
97 { "sdcc", no_argument, NULL, OPTION_COMPAT_SDCC},
98 { "Fins", required_argument, NULL, OPTION_MACH_NO_INST},
3c9b82ba
NC
99 { "ignore-undocumented-instructions", no_argument, NULL, OPTION_MACH_IUD },
100 { "Wnud", no_argument, NULL, OPTION_MACH_IUD },
101 { "warn-undocumented-instructions", no_argument, NULL, OPTION_MACH_WUD },
102 { "Wud", no_argument, NULL, OPTION_MACH_WUD },
103 { "forbid-undocumented-instructions", no_argument, NULL, OPTION_MACH_FUD },
104 { "Fud", no_argument, NULL, OPTION_MACH_FUD },
105 { "ignore-unportable-instructions", no_argument, NULL, OPTION_MACH_IUP },
106 { "Wnup", no_argument, NULL, OPTION_MACH_IUP },
107 { "warn-unportable-instructions", no_argument, NULL, OPTION_MACH_WUP },
108 { "Wup", no_argument, NULL, OPTION_MACH_WUP },
109 { "forbid-unportable-instructions", no_argument, NULL, OPTION_MACH_FUP },
110 { "Fup", no_argument, NULL, OPTION_MACH_FUP },
111
112 { NULL, no_argument, NULL, 0 }
113} ;
114
115size_t md_longopts_size = sizeof (md_longopts);
116
117extern int coff_flags;
118/* Instruction classes that silently assembled. */
119static int ins_ok = INS_Z80 | INS_UNDOC;
120/* Instruction classes that generate errors. */
6655dba2
SB
121static int ins_err = ~(INS_Z80 | INS_UNDOC);
122/* eZ80 CPU mode (ADL or Z80) */
123static int cpu_mode = 0; /* 0 - Z80, 1 - ADL */
124/* accept SDCC specific instruction encoding */
125static int sdcc_compat = 0;
126/* accept colonless labels */
127static int colonless_labels = 0;
128/* local label prefix (NULL - default) */
129static const char *local_label_prefix = NULL;
130/* floating point support */
131typedef const char *(*str_to_float_t)(char *litP, int *sizeP);
132static str_to_float_t str_to_float;
133static str_to_float_t str_to_double;
134
135/* mode of current instruction */
136#define INST_MODE_S 0 /* short data mode */
137#define INST_MODE_IS 0 /* short instruction mode */
138#define INST_MODE_L 2 /* long data mode */
139#define INST_MODE_IL 1 /* long instruction mode */
140#define INST_MODE_FORCED 4 /* CPU mode changed by instruction suffix*/
141static char inst_mode;
142
143static int
144setup_instruction (const char *inst, int *add, int *sub)
145{
146 int n;
147 if (!strcmp (inst, "idx-reg-halves"))
148 n = INS_IDX_HALF;
149 else if (!strcmp (inst, "sli"))
150 n = INS_SLI;
151 else if (!strcmp (inst, "op-ii-ld"))
152 n = INS_ROT_II_LD;
153 else if (!strcmp (inst, "in-f-c"))
154 n = INS_IN_F_C;
155 else if (!strcmp (inst, "out-c-0"))
156 n = INS_OUT_C_0;
157 else
158 return 0;
159 *add |= n;
160 *sub &= ~n;
161 return 1;
162}
163
164static const char *
165str_to_zeda32 (char *litP, int *sizeP);
166static const char *
167str_to_float48 (char *litP, int *sizeP);
7a6bf3be
SB
168static const char *
169str_to_ieee754_h (char *litP, int *sizeP);
170static const char *
171str_to_ieee754_s (char *litP, int *sizeP);
172static const char *
173str_to_ieee754_d (char *litP, int *sizeP);
6655dba2
SB
174
175static str_to_float_t
176get_str_to_float (const char *arg)
177{
40c75bc8 178 if (strcasecmp (arg, "zeda32") == 0)
6655dba2
SB
179 return str_to_zeda32;
180
40c75bc8 181 if (strcasecmp (arg, "math48") == 0)
6655dba2
SB
182 return str_to_float48;
183
7a6bf3be
SB
184 if (strcasecmp (arg, "half") != 0)
185 return str_to_ieee754_h;
186
187 if (strcasecmp (arg, "single") != 0)
188 return str_to_ieee754_s;
189
190 if (strcasecmp (arg, "double") != 0)
191 return str_to_ieee754_d;
192
193 if (strcasecmp (arg, "ieee754") == 0)
6655dba2
SB
194 as_fatal (_("invalid floating point numbers type `%s'"), arg);
195 return NULL;
196}
197
198static int
199setup_instruction_list (const char *list, int *add, int *sub)
200{
201 char buf[16];
202 const char *b;
203 const char *e;
204 int sz;
205 int res = 0;
206 for (b = list; *b != '\0';)
207 {
208 e = strchr (b, ',');
209 if (e == NULL)
210 sz = strlen (b);
211 else
212 sz = e - b;
213 if (sz == 0 || sz >= (int)sizeof (buf))
214 {
215 as_bad (_("invalid INST in command line: %s"), b);
216 return 0;
217 }
218 memcpy (buf, b, sz);
219 buf[sz] = '\0';
220 if (setup_instruction (buf, add, sub))
221 res++;
222 else
223 {
224 as_bad (_("invalid INST in command line: %s"), buf);
225 return 0;
226 }
227 b = &b[sz];
228 if (*b == ',')
229 ++b;
230 }
231 return res;
232}
3c9b82ba
NC
233
234int
6655dba2 235md_parse_option (int c, const char* arg)
3c9b82ba
NC
236{
237 switch (c)
238 {
239 default:
240 return 0;
241 case OPTION_MACH_Z80:
6655dba2
SB
242 ins_ok = (ins_ok & INS_TUNE_MASK) | INS_Z80;
243 ins_err = (ins_err & INS_MARCH_MASK) | (~INS_Z80 & INS_MARCH_MASK);
3c9b82ba
NC
244 break;
245 case OPTION_MACH_R800:
6655dba2 246 ins_ok = INS_R800 | INS_IDX_HALF;
3c9b82ba
NC
247 ins_err = INS_UNPORT;
248 break;
6655dba2
SB
249 case OPTION_MACH_Z180:
250 ins_ok = INS_Z180;
251 ins_err = INS_UNDOC | INS_UNPORT;
3c9b82ba 252 break;
6655dba2
SB
253 case OPTION_MACH_EZ80_Z80:
254 ins_ok = INS_EZ80;
255 ins_err = (INS_UNDOC | INS_UNPORT) & ~INS_IDX_HALF;
256 cpu_mode = 0;
257 break;
258 case OPTION_MACH_EZ80_ADL:
259 ins_ok = INS_EZ80;
260 ins_err = (INS_UNDOC | INS_UNPORT) & ~INS_IDX_HALF;
261 cpu_mode = 1;
262 break;
263 case OPTION_MACH_GBZ80:
264 ins_ok = INS_GBZ80;
265 ins_err = INS_UNDOC | INS_UNPORT;
266 break;
7a6bf3be 267 case OPTION_FP_SINGLE_FORMAT:
6655dba2
SB
268 str_to_float = get_str_to_float (arg);
269 break;
7a6bf3be 270 case OPTION_FP_DOUBLE_FORMAT:
6655dba2
SB
271 str_to_double = get_str_to_float (arg);
272 break;
273 case OPTION_MACH_INST:
274 if ((ins_ok & INS_GBZ80) == 0)
40c75bc8 275 return setup_instruction_list (arg, & ins_ok, & ins_err);
6655dba2
SB
276 break;
277 case OPTION_MACH_NO_INST:
278 if ((ins_ok & INS_GBZ80) == 0)
40c75bc8 279 return setup_instruction_list (arg, & ins_err, & ins_ok);
3c9b82ba
NC
280 break;
281 case OPTION_MACH_WUD:
6655dba2
SB
282 case OPTION_MACH_IUD:
283 if ((ins_ok & INS_GBZ80) == 0)
284 {
285 ins_ok |= INS_UNDOC;
286 ins_err &= ~INS_UNDOC;
287 }
3c9b82ba
NC
288 break;
289 case OPTION_MACH_WUP:
6655dba2
SB
290 case OPTION_MACH_IUP:
291 if ((ins_ok & INS_GBZ80) == 0)
292 {
293 ins_ok |= INS_UNDOC | INS_UNPORT;
294 ins_err &= ~(INS_UNDOC | INS_UNPORT);
295 }
3c9b82ba
NC
296 break;
297 case OPTION_MACH_FUD:
6655dba2 298 if ((ins_ok & (INS_R800 | INS_GBZ80)) == 0)
3c9b82ba
NC
299 {
300 ins_ok &= (INS_UNDOC | INS_UNPORT);
301 ins_err |= INS_UNDOC | INS_UNPORT;
302 }
303 break;
304 case OPTION_MACH_FUP:
305 ins_ok &= ~INS_UNPORT;
306 ins_err |= INS_UNPORT;
307 break;
6655dba2
SB
308 case OPTION_COMPAT_LL_PREFIX:
309 local_label_prefix = (arg && *arg) ? arg : NULL;
310 break;
311 case OPTION_COMPAT_SDCC:
312 sdcc_compat = 1;
313 local_label_prefix = "_";
314 break;
315 case OPTION_COMPAT_COLONLESS:
316 colonless_labels = 1;
317 break;
3c9b82ba
NC
318 }
319
320 return 1;
321}
322
323void
324md_show_usage (FILE * f)
325{
326 fprintf (f, "\n\
6655dba2
SB
327CPU model options:\n\
328 -z80\t\t\t assemble for Z80\n\
329 -r800\t\t\t assemble for R800\n\
330 -z180\t\t\t assemble for Z180\n\
331 -ez80\t\t\t assemble for eZ80 in Z80 mode by default\n\
332 -ez80-adl\t\t assemble for eZ80 in ADL mode by default\n\
333\n\
334Compatibility options:\n\
335 -local-prefix=TEXT\t treat labels prefixed by TEXT as local\n\
336 -colonless\t\t permit colonless labels\n\
337 -sdcc\t\t\t accept SDCC specific instruction syntax\n\
7a6bf3be
SB
338 -fp-s=FORMAT\t\t set single precission FP numbers format\n\
339 -fp-d=FORMAT\t\t set double precission FP numbers format\n\
6655dba2
SB
340Where FORMAT one of:\n\
341 ieee754\t\t IEEE754 compatible\n\
7a6bf3be
SB
342 half\t\t\t IEEE754 half precision (16 bit)\n\
343 single\t\t IEEE754 single precision (32 bit)\n\
344 double\t\t IEEE754 double precision (64 bit)\n\
345 zeda32\t\t Zeda z80float library 32 bit format\n\
6655dba2
SB
346 math48\t\t 48 bit format from Math48 library\n\
347\n\
348Support for known undocumented instructions:\n\
349 -strict\t\t assemble only documented instructions\n\
350 -full\t\t\t assemble all undocumented instructions\n\
351 -with-inst=INST[,...]\n\
352 -Wnins INST[,...]\t assemble specified instruction(s)\n\
353 -without-inst=INST[,...]\n\
354 -Fins INST[,...]\t do not assemble specified instruction(s)\n\
355Where INST is one of:\n\
356 idx-reg-halves\t instructions with halves of index registers\n\
357 sli\t\t\t instruction SLI/SLL\n\
358 op-ii-ld\t\t instructions like SLA (II+dd),R (opcodes DD/FD CB dd xx)\n\
359 in-f-c\t\t instruction IN F,(C)\n\
360 out-c-0\t\t instruction OUT (C),0\n\
3c9b82ba 361\n\
6655dba2 362Obsolete options:\n\
3c9b82ba 363 -ignore-undocumented-instructions\n\
6655dba2 364 -Wnud\t\t\t silently assemble undocumented Z80-instructions that work on R800\n\
3c9b82ba 365 -ignore-unportable-instructions\n\
6655dba2 366 -Wnup\t\t\t silently assemble all undocumented Z80-instructions\n\
3c9b82ba 367 -warn-undocumented-instructions\n\
6655dba2 368 -Wud\t\t\t issue warnings for undocumented Z80-instructions that work on R800\n\
3c9b82ba 369 -warn-unportable-instructions\n\
6655dba2 370 -Wup\t\t\t issue warnings for other undocumented Z80-instructions\n\
3c9b82ba 371 -forbid-undocumented-instructions\n\
6655dba2 372 -Fud\t\t\t treat all undocumented Z80-instructions as errors\n\
3c9b82ba 373 -forbid-unportable-instructions\n\
6655dba2
SB
374 -Fup\t\t\t treat undocumented Z80-instructions that do not work on R800 as errors\n\
375\n\
33eaf5de 376Default: -z80 -ignore-undocumented-instructions -warn-unportable-instructions.\n");
3c9b82ba
NC
377}
378
379static symbolS * zero;
380
25045f79
AM
381struct reg_entry
382{
f86f5863 383 const char* name;
25045f79
AM
384 int number;
385};
386#define R_STACKABLE (0x80)
387#define R_ARITH (0x40)
388#define R_IX (0x20)
389#define R_IY (0x10)
390#define R_INDEX (R_IX | R_IY)
391
392#define REG_A (7)
393#define REG_B (0)
394#define REG_C (1)
395#define REG_D (2)
396#define REG_E (3)
397#define REG_H (4)
398#define REG_L (5)
399#define REG_F (6 | 8)
400#define REG_I (9)
401#define REG_R (10)
6655dba2 402#define REG_MB (11)
25045f79
AM
403
404#define REG_AF (3 | R_STACKABLE)
405#define REG_BC (0 | R_STACKABLE | R_ARITH)
406#define REG_DE (1 | R_STACKABLE | R_ARITH)
407#define REG_HL (2 | R_STACKABLE | R_ARITH)
408#define REG_IX (REG_HL | R_IX)
409#define REG_IY (REG_HL | R_IY)
410#define REG_SP (3 | R_ARITH)
411
412static const struct reg_entry regtable[] =
413{
414 {"a", REG_A },
415 {"af", REG_AF },
416 {"b", REG_B },
417 {"bc", REG_BC },
418 {"c", REG_C },
419 {"d", REG_D },
420 {"de", REG_DE },
421 {"e", REG_E },
422 {"f", REG_F },
423 {"h", REG_H },
424 {"hl", REG_HL },
425 {"i", REG_I },
426 {"ix", REG_IX },
427 {"ixh",REG_H | R_IX },
428 {"ixl",REG_L | R_IX },
429 {"iy", REG_IY },
430 {"iyh",REG_H | R_IY },
431 {"iyl",REG_L | R_IY },
432 {"l", REG_L },
6655dba2 433 {"mb", REG_MB },
25045f79
AM
434 {"r", REG_R },
435 {"sp", REG_SP },
436} ;
437
438#define BUFLEN 8 /* Large enough for any keyword. */
439
3c9b82ba
NC
440void
441md_begin (void)
442{
25045f79 443 expressionS nul, reg;
3c9b82ba 444 char * p;
25045f79
AM
445 unsigned int i, j, k;
446 char buf[BUFLEN];
3c9b82ba 447
6655dba2
SB
448 if (ins_ok & INS_EZ80) /* if select EZ80 cpu then */
449 listing_lhs_width = 6; /* use 6 bytes per line in the listing */
450
25045f79
AM
451 reg.X_op = O_register;
452 reg.X_md = 0;
453 reg.X_add_symbol = reg.X_op_symbol = 0;
454 for ( i = 0 ; i < ARRAY_SIZE ( regtable ) ; ++i )
455 {
456 reg.X_add_number = regtable[i].number;
457 k = strlen ( regtable[i].name );
458 buf[k] = 0;
459 if ( k+1 < BUFLEN )
460 {
461 for ( j = ( 1<<k ) ; j ; --j )
462 {
463 for ( k = 0 ; regtable[i].name[k] ; ++k )
464 {
40c75bc8 465 buf[k] = ( j & ( 1<<k ) ) ? TOUPPER (regtable[i].name[k]) : regtable[i].name[k];
25045f79 466 }
40c75bc8
SB
467 symbolS * psym = symbol_find_or_make (buf);
468 S_SET_SEGMENT (psym, reg_section);
469 symbol_set_value_expression (psym, &reg);
25045f79
AM
470 }
471 }
472 }
3c9b82ba 473 p = input_line_pointer;
47990a6a 474 input_line_pointer = (char *) "0";
3c9b82ba
NC
475 nul.X_md=0;
476 expression (& nul);
477 input_line_pointer = p;
478 zero = make_expr_symbol (& nul);
479 /* We do not use relaxation (yet). */
480 linkrelax = 0;
481}
482
483void
484z80_md_end (void)
485{
486 int mach_type;
487
6655dba2 488 switch (ins_ok & INS_MARCH_MASK)
3c9b82ba
NC
489 {
490 case INS_Z80:
6655dba2
SB
491 if (ins_ok & INS_UNPORT)
492 mach_type = bfd_mach_z80full;
493 else if (ins_ok & INS_UNDOC)
494 mach_type = bfd_mach_z80;
495 else
496 mach_type = bfd_mach_z80strict;
3c9b82ba 497 break;
6655dba2
SB
498 case INS_R800:
499 mach_type = bfd_mach_r800;
3c9b82ba 500 break;
6655dba2
SB
501 case INS_Z180:
502 mach_type = bfd_mach_z180;
3c9b82ba 503 break;
6655dba2
SB
504 case INS_GBZ80:
505 mach_type = bfd_mach_gbz80;
506 break;
507 case INS_EZ80:
508 mach_type = cpu_mode ? bfd_mach_ez80_adl : bfd_mach_ez80_z80;
3c9b82ba
NC
509 break;
510 default:
511 mach_type = 0;
512 }
513
514 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
515}
516
6655dba2
SB
517#if defined (OBJ_ELF) || defined (OBJ_MAYBE_ELF)
518void
519z80_elf_final_processing (void)
520{
521 unsigned elf_flags;
522 switch (ins_ok & INS_MARCH_MASK)
523 {
524 case INS_Z80:
525 elf_flags = EF_Z80_MACH_Z80;
526 break;
527 case INS_R800:
528 elf_flags = EF_Z80_MACH_R800;
529 break;
530 case INS_Z180:
531 elf_flags = EF_Z80_MACH_Z180;
532 break;
533 case INS_GBZ80:
534 elf_flags = EF_Z80_MACH_GBZ80;
535 break;
536 case INS_EZ80:
537 elf_flags = cpu_mode ? EF_Z80_MACH_EZ80_ADL : EF_Z80_MACH_EZ80_Z80;
538 break;
539 default:
540 elf_flags = 0;
541 }
542
543 elf_elfheader (stdoutput)->e_flags = elf_flags;
544}
545#endif
546
3c9b82ba
NC
547static const char *
548skip_space (const char *s)
549{
550 while (*s == ' ' || *s == '\t')
551 ++s;
552 return s;
553}
554
555/* A non-zero return-value causes a continue in the
556 function read_a_source_file () in ../read.c. */
557int
558z80_start_line_hook (void)
559{
560 char *p, quote;
561 char buf[4];
562
563 /* Convert one character constants. */
564 for (p = input_line_pointer; *p && *p != '\n'; ++p)
565 {
566 switch (*p)
567 {
568 case '\'':
569 if (p[1] != 0 && p[1] != '\'' && p[2] == '\'')
570 {
571 snprintf (buf, 4, "%3d", (unsigned char)p[1]);
572 *p++ = buf[0];
573 *p++ = buf[1];
574 *p++ = buf[2];
575 break;
576 }
1a0670f3 577 /* Fall through. */
3c9b82ba
NC
578 case '"':
579 for (quote = *p++; quote != *p && '\n' != *p; ++p)
580 /* No escapes. */ ;
581 if (quote != *p)
582 {
583 as_bad (_("-- unterminated string"));
584 ignore_rest_of_line ();
585 return 1;
586 }
587 break;
6655dba2
SB
588 case '#':
589 if (sdcc_compat)
590 *p = (*skip_space (p + 1) == '(') ? '+' : ' ';
591 break;
3c9b82ba
NC
592 }
593 }
134dcee5 594 /* Check for <label>[:] [.](EQU|DEFL) <value>. */
3c9b82ba
NC
595 if (is_name_beginner (*input_line_pointer))
596 {
d02603dc 597 char *name;
3c9b82ba
NC
598 char c, *rest, *line_start;
599 int len;
600
601 line_start = input_line_pointer;
3c9b82ba
NC
602 if (ignore_input ())
603 return 0;
604
d02603dc 605 c = get_symbol_name (&name);
3c9b82ba
NC
606 rest = input_line_pointer + 1;
607
40c75bc8 608 if (ISSPACE (c) && colonless_labels)
6655dba2
SB
609 {
610 if (c == '\n')
611 {
612 bump_line_counters ();
613 LISTING_NEWLINE ();
614 }
615 c = ':';
616 }
617 if (c == ':' && sdcc_compat && rest[-2] != '$')
618 dollar_label_clear ();
3c9b82ba 619 if (*rest == ':')
6655dba2
SB
620 {
621 /* remove second colon if SDCC compatibility enabled */
622 if (sdcc_compat)
623 *rest = ' ';
624 ++rest;
625 }
626 rest = (char*)skip_space (rest);
134dcee5
AM
627 if (*rest == '.')
628 ++rest;
3c9b82ba
NC
629 if (strncasecmp (rest, "EQU", 3) == 0)
630 len = 3;
631 else if (strncasecmp (rest, "DEFL", 4) == 0)
632 len = 4;
633 else
634 len = 0;
40c75bc8 635 if (len && (!ISALPHA (rest[len])))
3c9b82ba
NC
636 {
637 /* Handle assignment here. */
3c9b82ba 638 if (line_start[-1] == '\n')
f9eb6721 639 {
3c45a255
AM
640 bump_line_counters ();
641 LISTING_NEWLINE ();
f9eb6721 642 }
3c45a255
AM
643 input_line_pointer = rest + len - 1;
644 /* Allow redefining with "DEFL" (len == 4), but not with "EQU". */
d02603dc 645 equals (name, len == 4);
3c9b82ba
NC
646 return 1;
647 }
648 else
649 {
650 /* Restore line and pointer. */
d02603dc 651 (void) restore_line_pointer (c);
3c9b82ba
NC
652 input_line_pointer = line_start;
653 }
654 }
655 return 0;
656}
657
658symbolS *
659md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
660{
661 return NULL;
662}
663
6d4af3c2 664const char *
6655dba2 665md_atof (int type, char *litP, int *sizeP)
3c9b82ba 666{
6655dba2
SB
667 switch (type)
668 {
669 case 'f':
670 case 'F':
7a6bf3be
SB
671 case 's':
672 case 'S':
6655dba2 673 if (str_to_float)
7a6bf3be 674 return str_to_float (litP, sizeP);
6655dba2
SB
675 break;
676 case 'd':
677 case 'D':
7a6bf3be
SB
678 case 'r':
679 case 'R':
6655dba2 680 if (str_to_double)
7a6bf3be 681 return str_to_double (litP, sizeP);
6655dba2
SB
682 break;
683 }
684 return ieee_md_atof (type, litP, sizeP, FALSE);
3c9b82ba
NC
685}
686
687valueT
688md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size)
689{
690 return size;
691}
692
693long
694md_pcrel_from (fixS * fixp)
695{
6655dba2 696 return fixp->fx_where + fixp->fx_frag->fr_address;
3c9b82ba
NC
697}
698
699typedef const char * (asfunc)(char, char, const char*);
700
701typedef struct _table_t
702{
f86f5863 703 const char* name;
d9235011
TS
704 unsigned char prefix;
705 unsigned char opcode;
3c9b82ba 706 asfunc * fp;
6655dba2 707 unsigned inss; /*0 - all CPU types or list of supported INS_* */
3c9b82ba
NC
708} table_t;
709
710/* Compares the key for structs that start with a char * to the key. */
711static int
712key_cmp (const void * a, const void * b)
713{
714 const char *str_a, *str_b;
715
716 str_a = *((const char**)a);
717 str_b = *((const char**)b);
718 return strcmp (str_a, str_b);
719}
720
3c9b82ba
NC
721char buf[BUFLEN];
722const char *key = buf;
723
3c9b82ba
NC
724/* Prevent an error on a line from also generating
725 a "junk at end of line" error message. */
726static char err_flag;
727
728static void
729error (const char * message)
730{
6655dba2
SB
731 if (err_flag)
732 return;
733
20203fb9 734 as_bad ("%s", message);
3c9b82ba
NC
735 err_flag = 1;
736}
737
738static void
739ill_op (void)
740{
741 error (_("illegal operand"));
742}
743
744static void
745wrong_mach (int ins_type)
746{
3c9b82ba 747 if (ins_type & ins_err)
40c75bc8 748 ill_op ();
3c9b82ba 749 else
6655dba2 750 as_warn (_("undocumented instruction"));
3c9b82ba
NC
751}
752
753static void
754check_mach (int ins_type)
755{
756 if ((ins_type & ins_ok) == 0)
757 wrong_mach (ins_type);
3c9b82ba
NC
758}
759
3c9b82ba
NC
760/* Check whether an expression is indirect. */
761static int
762is_indir (const char *s)
763{
764 char quote;
765 const char *p;
766 int indir, depth;
767
768 /* Indirection is indicated with parentheses. */
769 indir = (*s == '(');
770
771 for (p = s, depth = 0; *p && *p != ','; ++p)
772 {
773 switch (*p)
774 {
775 case '"':
776 case '\'':
777 for (quote = *p++; quote != *p && *p != '\n'; ++p)
778 if (*p == '\\' && p[1])
779 ++p;
780 break;
781 case '(':
782 ++ depth;
783 break;
784 case ')':
785 -- depth;
786 if (depth == 0)
787 {
788 p = skip_space (p + 1);
789 if (*p && *p != ',')
790 indir = 0;
791 --p;
792 }
793 if (depth < 0)
794 error (_("mismatched parentheses"));
795 break;
796 }
797 }
798
799 if (depth != 0)
800 error (_("mismatched parentheses"));
801
802 return indir;
803}
804
25045f79 805/* Check whether a symbol involves a register. */
3739860c 806static int
40c75bc8 807contains_register (symbolS *sym)
25045f79
AM
808{
809 if (sym)
40c75bc8
SB
810 {
811 expressionS * ex = symbol_get_value_expression(sym);
812
813 return (O_register == ex->X_op)
814 || (ex->X_add_symbol && contains_register(ex->X_add_symbol))
815 || (ex->X_op_symbol && contains_register(ex->X_op_symbol));
816 }
817
818 return 0;
25045f79
AM
819}
820
33eaf5de 821/* Parse general expression, not looking for indexed addressing. */
3c9b82ba 822static const char *
25045f79 823parse_exp_not_indexed (const char *s, expressionS *op)
3c9b82ba
NC
824{
825 const char *p;
826 int indir;
6655dba2 827 int make_shift = -1;
3c9b82ba
NC
828
829 p = skip_space (s);
6655dba2
SB
830 if (sdcc_compat && (*p == '<' || *p == '>'))
831 {
832 switch (*p)
833 {
834 case '<': /* LSB request */
835 make_shift = 0;
836 break;
837 case '>': /* MSB request */
838 make_shift = cpu_mode ? 16 : 8;
839 break;
840 }
841 s = ++p;
842 p = skip_space (p);
843 }
844
3c9b82ba 845 op->X_md = indir = is_indir (p);
25045f79 846 input_line_pointer = (char*) s ;
73812f59 847 expression (op);
25045f79 848 switch (op->X_op)
3c9b82ba 849 {
25045f79
AM
850 case O_absent:
851 error (_("missing operand"));
852 break;
853 case O_illegal:
854 error (_("bad expression syntax"));
855 break;
abd58633
AM
856 default:
857 break;
3c9b82ba 858 }
6655dba2
SB
859
860 if (make_shift >= 0)
861 {
862 /* replace [op] by [op >> shift] */
863 expressionS data;
864 op->X_add_symbol = make_expr_symbol (op);
865 op->X_add_number = 0;
866 op->X_op = O_right_shift;
867 memset (&data, 0, sizeof (data));
868 data.X_op = O_constant;
869 data.X_add_number = make_shift;
870 op->X_op_symbol = make_expr_symbol (&data);
871 }
3c9b82ba
NC
872 return input_line_pointer;
873}
874
6655dba2
SB
875static int
876unify_indexed (expressionS *op)
877{
40c75bc8 878 if (O_register != symbol_get_value_expression (op->X_add_symbol)->X_op)
6655dba2
SB
879 return 0;
880
40c75bc8
SB
881 int rnum = symbol_get_value_expression (op->X_add_symbol)->X_add_number;
882 if ( ((REG_IX != rnum) && (REG_IY != rnum)) || contains_register (op->X_op_symbol))
6655dba2 883 {
40c75bc8 884 ill_op ();
6655dba2
SB
885 return 0;
886 }
887
40c75bc8 888 /* Convert subtraction to addition of negative value. */
6655dba2
SB
889 if (O_subtract == op->X_op)
890 {
891 expressionS minus;
892 minus.X_op = O_uminus;
893 minus.X_add_number = 0;
894 minus.X_add_symbol = op->X_op_symbol;
895 minus.X_op_symbol = 0;
40c75bc8 896 op->X_op_symbol = make_expr_symbol (&minus);
6655dba2
SB
897 op->X_op = O_add;
898 }
40c75bc8
SB
899
900 /* Clear X_add_number of the expression. */
6655dba2
SB
901 if (op->X_add_number != 0)
902 {
903 expressionS add;
904 memset (&add, 0, sizeof (add));
905 add.X_op = O_symbol;
906 add.X_add_number = op->X_add_number;
907 add.X_add_symbol = op->X_op_symbol;
908 add.X_op_symbol = 0;
40c75bc8 909 op->X_add_symbol = make_expr_symbol (&add);
6655dba2
SB
910 }
911 else
912 op->X_add_symbol = op->X_op_symbol;
913
914 op->X_add_number = rnum;
915 op->X_op_symbol = 0;
916 return 1;
917}
918
40c75bc8 919/* Parse expression, change operator to O_md1 for indexed addressing. */
3c9b82ba
NC
920static const char *
921parse_exp (const char *s, expressionS *op)
922{
25045f79
AM
923 const char* res = parse_exp_not_indexed (s, op);
924 switch (op->X_op)
925 {
926 case O_add:
927 case O_subtract:
40c75bc8 928 if (unify_indexed (op) && op->X_md)
6655dba2 929 op->X_op = O_md1;
25045f79
AM
930 break;
931 case O_register:
40c75bc8 932 if (op->X_md && ((REG_IX == op->X_add_number) || (REG_IY == op->X_add_number)))
25045f79
AM
933 {
934 op->X_add_symbol = zero;
935 op->X_op = O_md1;
936 }
937 break;
6655dba2
SB
938 case O_constant:
939 /* parse SDCC syntax where index register offset placed before parentheses */
940 if (sdcc_compat && is_indir (res))
941 {
942 expressionS off;
943 off = *op;
944 res = parse_exp (res, op);
945 if (op->X_op != O_md1 || op->X_add_symbol != zero)
946 ill_op ();
947 else
948 op->X_add_symbol = make_expr_symbol (&off);
949 }
950 break;
abd58633
AM
951 default:
952 break;
25045f79
AM
953 }
954 return res;
3c9b82ba
NC
955}
956
957/* Condition codes, including some synonyms provided by HiTech zas. */
958static const struct reg_entry cc_tab[] =
959{
960 { "age", 6 << 3 },
961 { "alt", 7 << 3 },
962 { "c", 3 << 3 },
963 { "di", 4 << 3 },
964 { "ei", 5 << 3 },
965 { "lge", 2 << 3 },
966 { "llt", 3 << 3 },
967 { "m", 7 << 3 },
968 { "nc", 2 << 3 },
969 { "nz", 0 << 3 },
970 { "p", 6 << 3 },
971 { "pe", 5 << 3 },
972 { "po", 4 << 3 },
973 { "z", 1 << 3 },
974} ;
975
976/* Parse condition code. */
977static const char *
978parse_cc (const char *s, char * op)
979{
980 const char *p;
981 int i;
982 struct reg_entry * cc_p;
983
984 for (i = 0; i < BUFLEN; ++i)
985 {
986 if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */
987 break;
988 buf[i] = TOLOWER (s[i]);
989 }
990
991 if ((i < BUFLEN)
992 && ((s[i] == 0) || (s[i] == ',')))
993 {
994 buf[i] = 0;
995 cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
996 sizeof (cc_tab[0]), key_cmp);
997 }
998 else
999 cc_p = NULL;
1000
1001 if (cc_p)
1002 {
1003 *op = cc_p->number;
1004 p = s + i;
1005 }
1006 else
1007 p = NULL;
1008
1009 return p;
1010}
1011
1012static const char *
1013emit_insn (char prefix, char opcode, const char * args)
1014{
1015 char *p;
1016
1017 if (prefix)
1018 {
1019 p = frag_more (2);
1020 *p++ = prefix;
1021 }
1022 else
1023 p = frag_more (1);
1024 *p = opcode;
1025 return args;
1026}
1027
134dcee5
AM
1028void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
1029{
1030 bfd_reloc_code_real_type r[4] =
1031 {
1032 BFD_RELOC_8,
1033 BFD_RELOC_16,
1034 BFD_RELOC_24,
1035 BFD_RELOC_32
1036 };
1037
3739860c 1038 if (nbytes < 1 || nbytes > 4)
134dcee5
AM
1039 {
1040 as_bad (_("unsupported BFD relocation size %u"), nbytes);
1041 }
1042 else
1043 {
1044 fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
1045 }
1046}
1047
6655dba2
SB
1048static void
1049emit_data_val (expressionS * val, int size)
1050{
1051 char *p;
1052 bfd_reloc_code_real_type r_type;
1053
1054 p = frag_more (size);
1055 if (val->X_op == O_constant)
1056 {
1057 int i;
1058 for (i = 0; i < size; ++i)
1059 p[i] = (char)(val->X_add_number >> (i*8));
1060 return;
1061 }
1062
1063 switch (size)
1064 {
1065 case 1: r_type = BFD_RELOC_8; break;
1066 case 2: r_type = BFD_RELOC_16; break;
1067 case 3: r_type = BFD_RELOC_24; break;
1068 case 4: r_type = BFD_RELOC_32; break;
1069 case 8: r_type = BFD_RELOC_64; break;
1070 default:
1071 as_fatal (_("invalid data size %d"), size);
1072 }
1073
1074 if ( (val->X_op == O_register)
1075 || (val->X_op == O_md1)
40c75bc8
SB
1076 || contains_register (val->X_add_symbol)
1077 || contains_register (val->X_op_symbol))
6655dba2
SB
1078 ill_op ();
1079
1080 if (size <= 2 && val->X_op_symbol)
1081 {
1082 bfd_boolean simplify = TRUE;
40c75bc8 1083 int shift = symbol_get_value_expression (val->X_op_symbol)->X_add_number;
6655dba2
SB
1084 if (val->X_op == O_bit_and && shift == (1 << (size*8))-1)
1085 shift = 0;
1086 else if (val->X_op != O_right_shift)
1087 shift = -1;
1088
1089 if (size == 1)
1090 {
1091 switch (shift)
1092 {
1093 case 0: r_type = BFD_RELOC_Z80_BYTE0; break;
1094 case 8: r_type = BFD_RELOC_Z80_BYTE1; break;
1095 case 16: r_type = BFD_RELOC_Z80_BYTE2; break;
1096 case 24: r_type = BFD_RELOC_Z80_BYTE3; break;
1097 default: simplify = FALSE;
1098 }
1099 }
1100 else /* if (size == 2) */
1101 {
1102 switch (shift)
1103 {
1104 case 0: r_type = BFD_RELOC_Z80_WORD0; break;
1105 case 16: r_type = BFD_RELOC_Z80_WORD1; break;
1106 default: simplify = FALSE;
1107 }
1108 }
1109
1110 if (simplify)
1111 {
1112 val->X_op = O_symbol;
1113 val->X_op_symbol = NULL;
1114 val->X_add_number = 0;
1115 }
1116 }
1117
1118 fix_new_exp (frag_now, p - frag_now->fr_literal, size, val, FALSE, r_type);
1119}
1120
3c9b82ba
NC
1121static void
1122emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
1123{
1124 char *p;
1125 int lo, hi;
3c9b82ba 1126
6655dba2
SB
1127 if (r_type == BFD_RELOC_8)
1128 {
1129 emit_data_val (val, 1);
1130 return;
1131 }
3c9b82ba
NC
1132 p = frag_more (1);
1133 *p = val->X_add_number;
40c75bc8 1134 if ( contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol) )
25045f79 1135 {
40c75bc8 1136 ill_op ();
25045f79
AM
1137 }
1138 else if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
134dcee5 1139 {
20203fb9 1140 as_bad (_("cannot make a relative jump to an absolute location"));
134dcee5
AM
1141 }
1142 else if (val->X_op == O_constant)
3c9b82ba
NC
1143 {
1144 lo = -128;
1145 hi = (BFD_RELOC_8 == r_type) ? 255 : 127;
1146
1147 if ((val->X_add_number < lo) || (val->X_add_number > hi))
1148 {
1149 if (r_type == BFD_RELOC_Z80_DISP8)
1150 as_bad (_("offset too large"));
1151 else
1152 as_warn (_("overflow"));
1153 }
1154 }
1155 else
1156 {
6655dba2 1157 /* For symbols only, constants are stored at begin of function */
73812f59
NC
1158 fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
1159 (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
3c9b82ba
NC
1160 }
1161}
1162
1163static void
1164emit_word (expressionS * val)
1165{
6655dba2 1166 emit_data_val (val, (inst_mode & INST_MODE_IL) ? 3 : 2);
3c9b82ba
NC
1167}
1168
1169static void
1170emit_mx (char prefix, char opcode, int shift, expressionS * arg)
1171 /* The operand m may be r, (hl), (ix+d), (iy+d),
1172 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1173{
1174 char *q;
1175 int rnum;
1176
1177 rnum = arg->X_add_number;
1178 switch (arg->X_op)
1179 {
1180 case O_register:
1181 if (arg->X_md)
1182 {
1183 if (rnum != REG_HL)
1184 {
1185 ill_op ();
1186 break;
1187 }
1188 else
1189 rnum = 6;
1190 }
1191 else
1192 {
1193 if ((prefix == 0) && (rnum & R_INDEX))
1194 {
1195 prefix = (rnum & R_IX) ? 0xDD : 0xFD;
6655dba2
SB
1196 if (!(ins_ok & INS_EZ80))
1197 check_mach (INS_IDX_HALF);
3c9b82ba
NC
1198 rnum &= ~R_INDEX;
1199 }
1200 if (rnum > 7)
1201 {
1202 ill_op ();
1203 break;
1204 }
1205 }
1206 q = frag_more (prefix ? 2 : 1);
1207 if (prefix)
1208 * q ++ = prefix;
1209 * q ++ = opcode + (rnum << shift);
1210 break;
1211 case O_md1:
6655dba2
SB
1212 if (ins_ok & INS_GBZ80)
1213 {
1214 ill_op ();
1215 break;
1216 }
3c9b82ba
NC
1217 q = frag_more (2);
1218 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1219 *q = (prefix) ? prefix : (opcode + (6 << shift));
761025be
AM
1220 {
1221 expressionS offset = *arg;
1222 offset.X_op = O_symbol;
1223 offset.X_add_number = 0;
1224 emit_byte (&offset, BFD_RELOC_Z80_DISP8);
1225 }
3c9b82ba
NC
1226 if (prefix)
1227 {
1228 q = frag_more (1);
1229 *q = opcode+(6<<shift);
1230 }
1231 break;
1232 default:
1233 abort ();
1234 }
1235}
1236
1237/* The operand m may be r, (hl), (ix+d), (iy+d),
1238 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1239static const char *
1240emit_m (char prefix, char opcode, const char *args)
1241{
1242 expressionS arg_m;
1243 const char *p;
1244
1245 p = parse_exp (args, &arg_m);
1246 switch (arg_m.X_op)
1247 {
1248 case O_md1:
1249 case O_register:
1250 emit_mx (prefix, opcode, 0, &arg_m);
1251 break;
1252 default:
1253 ill_op ();
1254 }
1255 return p;
1256}
1257
1258/* The operand m may be as above or one of the undocumented
1259 combinations (ix+d),r and (iy+d),r (if unportable instructions
1260 are allowed). */
6efa941c 1261
3c9b82ba 1262static const char *
6655dba2 1263emit_mr (char prefix, char opcode, const char *args)
3c9b82ba
NC
1264{
1265 expressionS arg_m, arg_r;
1266 const char *p;
1267
1268 p = parse_exp (args, & arg_m);
1269
1270 switch (arg_m.X_op)
1271 {
1272 case O_md1:
1273 if (*p == ',')
1274 {
1275 p = parse_exp (p + 1, & arg_r);
1276
1277 if ((arg_r.X_md == 0)
1278 && (arg_r.X_op == O_register)
1279 && (arg_r.X_add_number < 8))
6efa941c 1280 opcode += arg_r.X_add_number - 6; /* Emit_mx () will add 6. */
3c9b82ba
NC
1281 else
1282 {
1283 ill_op ();
1284 break;
1285 }
6655dba2 1286 check_mach (INS_ROT_II_LD);
3c9b82ba 1287 }
1a0670f3 1288 /* Fall through. */
3c9b82ba
NC
1289 case O_register:
1290 emit_mx (prefix, opcode, 0, & arg_m);
1291 break;
1292 default:
1293 ill_op ();
1294 }
1295 return p;
1296}
1297
1298static void
1299emit_sx (char prefix, char opcode, expressionS * arg_p)
1300{
1301 char *q;
1302
1303 switch (arg_p->X_op)
1304 {
1305 case O_register:
1306 case O_md1:
1307 emit_mx (prefix, opcode, 0, arg_p);
1308 break;
1309 default:
1310 if (arg_p->X_md)
1311 ill_op ();
1312 else
1313 {
1314 q = frag_more (prefix ? 2 : 1);
1315 if (prefix)
1316 *q++ = prefix;
1317 *q = opcode ^ 0x46;
1318 emit_byte (arg_p, BFD_RELOC_8);
1319 }
1320 }
1321}
1322
1323/* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1324static const char *
1325emit_s (char prefix, char opcode, const char *args)
1326{
1327 expressionS arg_s;
1328 const char *p;
1329
1330 p = parse_exp (args, & arg_s);
6655dba2
SB
1331 if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
1332 { /* possible instruction in generic format op A,x */
1333 if (!(ins_ok & INS_EZ80) && !sdcc_compat)
40c75bc8 1334 ill_op ();
6655dba2
SB
1335 ++p;
1336 p = parse_exp (p, & arg_s);
1337 }
3c9b82ba
NC
1338 emit_sx (prefix, opcode, & arg_s);
1339 return p;
1340}
1341
1342static const char *
1343emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1344{
1345 expressionS addr;
1346 const char *p; char *q;
1347
25045f79 1348 p = parse_exp_not_indexed (args, &addr);
3c9b82ba
NC
1349 if (addr.X_md)
1350 ill_op ();
1351 else
1352 {
1353 q = frag_more (1);
1354 *q = opcode;
1355 emit_word (& addr);
1356 }
1357 return p;
1358}
1359
1360/* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1361static const char *
1362emit_incdec (char prefix, char opcode, const char * args)
1363{
1364 expressionS operand;
1365 int rnum;
1366 const char *p; char *q;
1367
1368 p = parse_exp (args, &operand);
1369 rnum = operand.X_add_number;
1370 if ((! operand.X_md)
1371 && (operand.X_op == O_register)
1372 && (R_ARITH&rnum))
1373 {
1374 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1375 if (rnum & R_INDEX)
1376 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1377 *q = prefix + ((rnum & 3) << 4);
1378 }
1379 else
1380 {
1381 if ((operand.X_op == O_md1) || (operand.X_op == O_register))
1382 emit_mx (0, opcode, 3, & operand);
1383 else
1384 ill_op ();
1385 }
1386 return p;
1387}
1388
1389static const char *
1390emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1391{
1392 expressionS addr;
1393 const char *p;
1394 char *q;
1395
25045f79 1396 p = parse_exp_not_indexed (args, &addr);
3c9b82ba
NC
1397 if (addr.X_md)
1398 ill_op ();
1399 else
1400 {
1401 q = frag_more (1);
1402 *q = opcode;
6655dba2 1403 addr.X_add_number--; /* pcrel computes after offset code */
3c9b82ba
NC
1404 emit_byte (&addr, BFD_RELOC_8_PCREL);
1405 }
1406 return p;
1407}
1408
1409static const char *
1410emit_jp (char prefix, char opcode, const char * args)
1411{
1412 expressionS addr;
1413 const char *p;
1414 char *q;
1415 int rnum;
1416
25045f79 1417 p = parse_exp_not_indexed (args, & addr);
3c9b82ba
NC
1418 if (addr.X_md)
1419 {
1420 rnum = addr.X_add_number;
25045f79 1421 if ((O_register == addr.X_op) && (REG_HL == (rnum & ~R_INDEX)))
3c9b82ba
NC
1422 {
1423 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1424 if (rnum & R_INDEX)
1425 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1426 *q = prefix;
1427 }
1428 else
1429 ill_op ();
1430 }
1431 else
1432 {
1433 q = frag_more (1);
1434 *q = opcode;
1435 emit_word (& addr);
1436 }
1437 return p;
1438}
1439
1440static const char *
1441emit_im (char prefix, char opcode, const char * args)
1442{
1443 expressionS mode;
1444 const char *p;
1445 char *q;
1446
1447 p = parse_exp (args, & mode);
1448 if (mode.X_md || (mode.X_op != O_constant))
1449 ill_op ();
1450 else
1451 switch (mode.X_add_number)
1452 {
1453 case 1:
1454 case 2:
1455 ++mode.X_add_number;
1456 /* Fall through. */
1457 case 0:
1458 q = frag_more (2);
1459 *q++ = prefix;
1460 *q = opcode + 8*mode.X_add_number;
1461 break;
1462 default:
1463 ill_op ();
1464 }
1465 return p;
1466}
1467
1468static const char *
1469emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1470{
1471 expressionS regp;
1472 const char *p;
1473 char *q;
1474
1475 p = parse_exp (args, & regp);
1476 if ((!regp.X_md)
1477 && (regp.X_op == O_register)
1478 && (regp.X_add_number & R_STACKABLE))
1479 {
1480 int rnum;
1481
1482 rnum = regp.X_add_number;
1483 if (rnum&R_INDEX)
1484 {
1485 q = frag_more (2);
1486 *q++ = (rnum&R_IX)?0xDD:0xFD;
1487 }
1488 else
1489 q = frag_more (1);
1490 *q = opcode + ((rnum & 3) << 4);
1491 }
1492 else
1493 ill_op ();
1494
1495 return p;
1496}
1497
1498static const char *
1499emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1500{
1501 char cc, *q;
1502 const char *p;
1503
1504 p = parse_cc (args, &cc);
1505 q = frag_more (1);
1506 if (p)
1507 *q = opcode + cc;
1508 else
1509 *q = prefix;
1510 return p ? p : args;
1511}
1512
1513static const char *
1514emit_adc (char prefix, char opcode, const char * args)
1515{
1516 expressionS term;
1517 int rnum;
1518 const char *p;
1519 char *q;
1520
1521 p = parse_exp (args, &term);
1522 if (*p++ != ',')
1523 {
9aff4b7a 1524 error (_("bad instruction syntax"));
3c9b82ba
NC
1525 return p;
1526 }
1527
1528 if ((term.X_md) || (term.X_op != O_register))
1529 ill_op ();
1530 else
1531 switch (term.X_add_number)
1532 {
1533 case REG_A:
1534 p = emit_s (0, prefix, p);
1535 break;
1536 case REG_HL:
1537 p = parse_exp (p, &term);
1538 if ((!term.X_md) && (term.X_op == O_register))
1539 {
1540 rnum = term.X_add_number;
1541 if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
1542 {
1543 q = frag_more (2);
1544 *q++ = 0xED;
1545 *q = opcode + ((rnum & 3) << 4);
1546 break;
1547 }
1548 }
1549 /* Fall through. */
1550 default:
1551 ill_op ();
1552 }
1553 return p;
1554}
1555
1556static const char *
1557emit_add (char prefix, char opcode, const char * args)
1558{
1559 expressionS term;
1560 int lhs, rhs;
1561 const char *p;
1562 char *q;
1563
1564 p = parse_exp (args, &term);
1565 if (*p++ != ',')
1566 {
9aff4b7a 1567 error (_("bad instruction syntax"));
3c9b82ba
NC
1568 return p;
1569 }
1570
1571 if ((term.X_md) || (term.X_op != O_register))
1572 ill_op ();
1573 else
1574 switch (term.X_add_number & ~R_INDEX)
1575 {
1576 case REG_A:
1577 p = emit_s (0, prefix, p);
1578 break;
1579 case REG_HL:
1580 lhs = term.X_add_number;
1581 p = parse_exp (p, &term);
1582 if ((!term.X_md) && (term.X_op == O_register))
1583 {
1584 rhs = term.X_add_number;
1585 if ((rhs & R_ARITH)
1586 && ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL)))
1587 {
1588 q = frag_more ((lhs & R_INDEX) ? 2 : 1);
1589 if (lhs & R_INDEX)
1590 *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
1591 *q = opcode + ((rhs & 3) << 4);
1592 break;
1593 }
1594 }
1595 /* Fall through. */
1596 default:
1597 ill_op ();
1598 }
1599 return p;
1600}
1601
1602static const char *
1603emit_bit (char prefix, char opcode, const char * args)
1604{
1605 expressionS b;
1606 int bn;
1607 const char *p;
1608
1609 p = parse_exp (args, &b);
1610 if (*p++ != ',')
9aff4b7a 1611 error (_("bad instruction syntax"));
3c9b82ba
NC
1612
1613 bn = b.X_add_number;
1614 if ((!b.X_md)
1615 && (b.X_op == O_constant)
1616 && (0 <= bn)
1617 && (bn < 8))
1618 {
1619 if (opcode == 0x40)
1620 /* Bit : no optional third operand. */
1621 p = emit_m (prefix, opcode + (bn << 3), p);
1622 else
1623 /* Set, res : resulting byte can be copied to register. */
6655dba2 1624 p = emit_mr (prefix, opcode + (bn << 3), p);
3c9b82ba
NC
1625 }
1626 else
1627 ill_op ();
1628 return p;
1629}
1630
1631static const char *
1632emit_jpcc (char prefix, char opcode, const char * args)
1633{
1634 char cc;
1635 const char *p;
1636
1637 p = parse_cc (args, & cc);
1638 if (p && *p++ == ',')
1639 p = emit_call (0, opcode + cc, p);
1640 else
1641 p = (prefix == (char)0xC3)
1642 ? emit_jp (0xE9, prefix, args)
1643 : emit_call (0, prefix, args);
1644 return p;
1645}
1646
1647static const char *
1648emit_jrcc (char prefix, char opcode, const char * args)
1649{
1650 char cc;
1651 const char *p;
1652
1653 p = parse_cc (args, &cc);
1654 if (p && *p++ == ',')
1655 {
1656 if (cc > (3 << 3))
1657 error (_("condition code invalid for jr"));
1658 else
1659 p = emit_jr (0, opcode + cc, p);
1660 }
1661 else
1662 p = emit_jr (0, prefix, args);
1663
1664 return p;
1665}
1666
1667static const char *
1668emit_ex (char prefix_in ATTRIBUTE_UNUSED,
1669 char opcode_in ATTRIBUTE_UNUSED, const char * args)
1670{
1671 expressionS op;
1672 const char * p;
1673 char prefix, opcode;
1674
25045f79 1675 p = parse_exp_not_indexed (args, &op);
3c9b82ba
NC
1676 p = skip_space (p);
1677 if (*p++ != ',')
1678 {
1679 error (_("bad instruction syntax"));
1680 return p;
1681 }
1682
1683 prefix = opcode = 0;
1684 if (op.X_op == O_register)
1685 switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
1686 {
1687 case REG_AF:
1688 if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
1689 {
1690 /* The scrubber changes '\'' to '`' in this context. */
1691 if (*p == '`')
1692 ++p;
1693 opcode = 0x08;
1694 }
1695 break;
1696 case REG_DE:
1697 if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
1698 opcode = 0xEB;
1699 break;
1700 case REG_SP|0x8000:
1701 p = parse_exp (p, & op);
1702 if (op.X_op == O_register
1703 && op.X_md == 0
1704 && (op.X_add_number & ~R_INDEX) == REG_HL)
1705 {
1706 opcode = 0xE3;
1707 if (R_INDEX & op.X_add_number)
1708 prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
1709 }
1710 break;
1711 }
1712 if (opcode)
1713 emit_insn (prefix, opcode, p);
1714 else
1715 ill_op ();
1716
1717 return p;
1718}
1719
1720static const char *
1721emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1722 const char * args)
1723{
1724 expressionS reg, port;
1725 const char *p;
1726 char *q;
1727
1728 p = parse_exp (args, &reg);
1729 if (*p++ != ',')
1730 {
9aff4b7a 1731 error (_("bad instruction syntax"));
3c9b82ba
NC
1732 return p;
1733 }
1734
1735 p = parse_exp (p, &port);
1736 if (reg.X_md == 0
1737 && reg.X_op == O_register
1738 && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
1739 && (port.X_md))
1740 {
1741 if (port.X_op != O_md1 && port.X_op != O_register)
1742 {
1743 if (REG_A == reg.X_add_number)
1744 {
1745 q = frag_more (1);
1746 *q = 0xDB;
1747 emit_byte (&port, BFD_RELOC_8);
1748 }
1749 else
1750 ill_op ();
1751 }
1752 else
1753 {
6655dba2 1754 if (port.X_add_number == REG_C || port.X_add_number == REG_BC)
3c9b82ba 1755 {
6655dba2
SB
1756 if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
1757 ill_op ();
1758 else if (reg.X_add_number == REG_F && !(ins_ok & INS_R800))
1759 check_mach (INS_IN_F_C);
1760 q = frag_more (2);
1761 *q++ = 0xED;
1762 *q = 0x40|((reg.X_add_number&7)<<3);
3c9b82ba
NC
1763 }
1764 else
1765 ill_op ();
1766 }
1767 }
1768 else
1769 ill_op ();
1770 return p;
1771}
1772
6655dba2
SB
1773static const char *
1774emit_in0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1775 const char * args)
1776{
1777 expressionS reg, port;
1778 const char *p;
1779 char *q;
1780
1781 p = parse_exp (args, &reg);
1782 if (*p++ != ',')
1783 {
1784 error (_("bad instruction syntax"));
1785 return p;
1786 }
1787
1788 p = parse_exp (p, &port);
1789 if (reg.X_md == 0
1790 && reg.X_op == O_register
1791 && reg.X_add_number <= 7
1792 && port.X_md
1793 && port.X_op != O_md1
1794 && port.X_op != O_register)
1795 {
1796 q = frag_more (2);
1797 *q++ = 0xED;
1798 *q = 0x00|(reg.X_add_number << 3);
1799 emit_byte (&port, BFD_RELOC_8);
1800 }
1801 else
1802 ill_op ();
1803 return p;
1804}
1805
3c9b82ba
NC
1806static const char *
1807emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1808 const char * args)
1809{
1810 expressionS reg, port;
1811 const char *p;
1812 char *q;
1813
1814 p = parse_exp (args, & port);
1815 if (*p++ != ',')
1816 {
9aff4b7a 1817 error (_("bad instruction syntax"));
3c9b82ba
NC
1818 return p;
1819 }
1820 p = parse_exp (p, &reg);
1821 if (!port.X_md)
1822 { ill_op (); return p; }
1823 /* Allow "out (c), 0" as unportable instruction. */
1824 if (reg.X_op == O_constant && reg.X_add_number == 0)
1825 {
6655dba2 1826 check_mach (INS_OUT_C_0);
3c9b82ba
NC
1827 reg.X_op = O_register;
1828 reg.X_add_number = 6;
1829 }
1830 if (reg.X_md
1831 || reg.X_op != O_register
1832 || reg.X_add_number > 7)
1833 ill_op ();
1834 else
1835 if (port.X_op != O_register && port.X_op != O_md1)
1836 {
1837 if (REG_A == reg.X_add_number)
1838 {
1839 q = frag_more (1);
1840 *q = 0xD3;
1841 emit_byte (&port, BFD_RELOC_8);
1842 }
1843 else
1844 ill_op ();
1845 }
1846 else
1847 {
6655dba2 1848 if (REG_C == port.X_add_number || port.X_add_number == REG_BC)
3c9b82ba 1849 {
6655dba2
SB
1850 if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
1851 ill_op ();
3c9b82ba
NC
1852 q = frag_more (2);
1853 *q++ = 0xED;
1854 *q = 0x41 | (reg.X_add_number << 3);
1855 }
1856 else
1857 ill_op ();
1858 }
1859 return p;
1860}
1861
6655dba2
SB
1862static const char *
1863emit_out0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1864 const char * args)
1865{
1866 expressionS reg, port;
1867 const char *p;
1868 char *q;
1869
1870 p = parse_exp (args, & port);
1871 if (*p++ != ',')
1872 {
1873 error (_("bad instruction syntax"));
1874 return p;
1875 }
1876 p = parse_exp (p, &reg);
1877 if (port.X_md != 0
1878 && port.X_op != O_register
1879 && port.X_op != O_md1
1880 && reg.X_md == 0
1881 && reg.X_op == O_register
1882 && reg.X_add_number <= 7)
1883 {
1884 q = frag_more (2);
1885 *q++ = 0xED;
1886 *q = 0x01 | (reg.X_add_number << 3);
1887 emit_byte (&port, BFD_RELOC_8);
1888 }
1889 else
1890 ill_op ();
1891 return p;
1892}
1893
3c9b82ba
NC
1894static const char *
1895emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1896{
1897 expressionS addr;
1898 const char *p;
1899 char *q;
1900
25045f79 1901 p = parse_exp_not_indexed (args, &addr);
3c9b82ba
NC
1902 if (addr.X_op != O_constant)
1903 {
1904 error ("rst needs constant address");
1905 return p;
1906 }
1907
1908 if (addr.X_add_number & ~(7 << 3))
1909 ill_op ();
1910 else
1911 {
1912 q = frag_more (1);
1913 *q = opcode + (addr.X_add_number & (7 << 3));
1914 }
1915 return p;
1916}
1917
40c75bc8 1918/* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
3c9b82ba 1919static void
40c75bc8
SB
1920emit_ld_m_n (expressionS *dst, expressionS *src)
1921{
3c9b82ba 1922 char *q;
6655dba2
SB
1923 char prefix;
1924 expressionS dst_offset;
3c9b82ba 1925
6655dba2 1926 switch (dst->X_add_number)
3c9b82ba 1927 {
6655dba2
SB
1928 case REG_HL: prefix = 0x00; break;
1929 case REG_IX: prefix = 0xDD; break;
1930 case REG_IY: prefix = 0xFD; break;
1931 default:
1932 ill_op ();
1933 return;
1934 }
1935
1936 q = frag_more (prefix ? 2 : 1);
1937 if (prefix)
1938 *q++ = prefix;
1939 *q = 0x36;
1940 if (prefix)
1941 {
1942 dst_offset = *dst;
1943 dst_offset.X_op = O_symbol;
1944 dst_offset.X_add_number = 0;
1945 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
3c9b82ba 1946 }
6655dba2 1947 emit_byte (src, BFD_RELOC_8);
3c9b82ba
NC
1948}
1949
40c75bc8 1950/* For 8-bit load register to memory instructions: LD (<expression>),r. */
3c9b82ba 1951static void
40c75bc8
SB
1952emit_ld_m_r (expressionS *dst, expressionS *src)
1953{
3c9b82ba 1954 char *q;
6655dba2
SB
1955 char prefix = 0;
1956 expressionS dst_offset;
3c9b82ba 1957
6655dba2 1958 switch (dst->X_op)
3c9b82ba 1959 {
6655dba2
SB
1960 case O_md1:
1961 prefix = (dst->X_add_number == REG_IX) ? 0xDD : 0xFD;
1962 /* Fall through. */
1963 case O_register:
1964 switch (dst->X_add_number)
1965 {
1966 case REG_BC: /* LD (BC),A */
1967 case REG_DE: /* LD (DE),A */
1968 if (src->X_add_number == REG_A)
1969 {
1970 q = frag_more (1);
1971 *q = 0x02 | ((dst->X_add_number & 3) << 4);
1972 return;
1973 }
1974 break;
1975 case REG_IX:
1976 case REG_IY:
1977 case REG_HL: /* LD (HL),r or LD (ii+d),r */
1978 if (src->X_add_number <= 7)
1979 {
1980 q = frag_more (prefix ? 2 : 1);
1981 if (prefix)
1982 *q++ = prefix;
1983 *q = 0x70 | src->X_add_number;
1984 if (prefix)
1985 {
1986 dst_offset = *dst;
1987 dst_offset.X_op = O_symbol;
1988 dst_offset.X_add_number = 0;
1989 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
1990 }
1991 return;
1992 }
1993 break;
1994 default:;
1995 }
1996 break;
1997 default: /* LD (nn),A */
1998 if (src->X_add_number == REG_A)
1999 {
2000 q = frag_more (1);
2001 *q = 0x32;
2002 emit_word (dst);
2003 return;
2004 }
3c9b82ba 2005 break;
6655dba2
SB
2006 }
2007 ill_op ();
2008}
3c9b82ba 2009
40c75bc8 2010/* For 16-bit load register to memory instructions: LD (<expression>),rr. */
6655dba2 2011static void
40c75bc8
SB
2012emit_ld_m_rr (expressionS *dst, expressionS *src)
2013{
6655dba2 2014 char *q;
40c75bc8
SB
2015 int prefix = 0;
2016 int opcode = 0;
6655dba2 2017 expressionS dst_offset;
3c9b82ba 2018
6655dba2
SB
2019 switch (dst->X_op)
2020 {
2021 case O_md1: /* eZ80 instructions LD (ii+d),rr */
2022 case O_register: /* eZ80 instructions LD (HL),rr */
2023 if (!(ins_ok & INS_EZ80)) /* 16-bit indirect load group is supported by eZ80 only */
2024 ill_op ();
2025 switch (dst->X_add_number)
2026 {
2027 case REG_IX: prefix = 0xDD; break;
2028 case REG_IY: prefix = 0xFD; break;
2029 case REG_HL: prefix = 0xED; break;
2030 default:
2031 ill_op ();
2032 }
2033 switch (src->X_add_number)
2034 {
2035 case REG_BC: opcode = 0x0F; break;
2036 case REG_DE: opcode = 0x1F; break;
2037 case REG_HL: opcode = 0x2F; break;
40c75bc8
SB
2038 case REG_IX: opcode = (prefix != 0xFD) ? 0x3F : 0x3E; break;
2039 case REG_IY: opcode = (prefix != 0xFD) ? 0x3E : 0x3F; break;
6655dba2
SB
2040 default:
2041 ill_op ();
2042 }
2043 q = frag_more (prefix ? 2 : 1);
2044 *q++ = prefix;
2045 *q = opcode;
40c75bc8 2046 if (prefix == 0xFD || prefix == 0xDD)
6655dba2
SB
2047 {
2048 dst_offset = *dst;
2049 dst_offset.X_op = O_symbol;
2050 dst_offset.X_add_number = 0;
2051 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2052 }
2053 break;
2054 default: /* LD (nn),rr */
2055 if (ins_ok & INS_GBZ80)
2056 {
2057 /* GBZ80 supports only LD (nn),SP */
2058 if (src->X_add_number == REG_SP)
2059 {
2060 prefix = 0x00;
2061 opcode = 0x08;
2062 }
2063 else
2064 ill_op ();
2065 }
2066 else
2067 {
2068 switch (src->X_add_number)
2069 {
2070 case REG_BC: prefix = 0xED; opcode = 0x43; break;
2071 case REG_DE: prefix = 0xED; opcode = 0x53; break;
2072 case REG_HL: prefix = 0x00; opcode = 0x22; break;
2073 case REG_IX: prefix = 0xDD; opcode = 0x22; break;
2074 case REG_IY: prefix = 0xFD; opcode = 0x22; break;
2075 case REG_SP: prefix = 0xED; opcode = 0x73; break;
2076 default:
2077 ill_op ();
2078 }
2079 }
2080 q = frag_more (prefix ? 2 : 1);
2081 if (prefix)
2082 *q++ = prefix;
2083 *q = opcode;
2084 emit_word (dst);
2085 }
2086}
3c9b82ba 2087
6655dba2
SB
2088static void
2089emit_ld_r_m (expressionS *dst, expressionS *src)
2090{ /* for 8-bit memory load to register: LD r,(xxx) */
2091 char *q;
2092 char prefix = 0;
2093 char opcode = 0;
2094 expressionS src_offset;
2095
2096 if (dst->X_add_number == REG_A && src->X_op == O_register)
2097 { /* LD A,(BC) or LD A,(DE) */
2098 switch (src->X_add_number)
2099 {
2100 case REG_BC: opcode = 0x0A; break;
2101 case REG_DE: opcode = 0x1A; break;
2102 default: break;
2103 }
2104 if (opcode != 0)
2105 {
2106 q = frag_more (1);
2107 *q = opcode;
2108 return;
2109 }
2110 }
2111
2112 switch (src->X_op)
2113 {
2114 case O_md1:
2115 case O_register:
2116 if (dst->X_add_number > 7)
2117 ill_op ();
2118 opcode = 0x46; /* LD B,(HL) */
2119 switch (src->X_add_number)
2120 {
2121 case REG_HL: prefix = 0x00; break;
2122 case REG_IX: prefix = 0xDD; break;
2123 case REG_IY: prefix = 0xFD; break;
2124 default:
2125 ill_op ();
2126 }
2127 q = frag_more (prefix ? 2 : 1);
2128 if (prefix)
2129 *q++ = prefix;
2130 *q = opcode | ((dst->X_add_number & 7) << 3);
2131 if (prefix)
2132 {
2133 src_offset = *src;
2134 src_offset.X_op = O_symbol;
2135 src_offset.X_add_number = 0;
2136 emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
2137 }
2138 break;
2139 default: /* LD A,(nn) */
2140 if (dst->X_add_number == REG_A)
2141 {
2142 q = frag_more (1);
2143 *q = 0x3A;
2144 emit_word (src);
2145 }
2146 }
2147}
2148
2149static void
2150emit_ld_r_n (expressionS *dst, expressionS *src)
2151{ /* for 8-bit immediate value load to register: LD r,n */
2152 char *q;
2153 char prefix = 0;
2154
2155 switch (dst->X_add_number)
2156 {
2157 case REG_H|R_IX:
2158 case REG_L|R_IX:
2159 prefix = 0xDD;
2160 break;
2161 case REG_H|R_IY:
2162 case REG_L|R_IY:
2163 prefix = 0xFD;
2164 break;
2165 case REG_A:
3c9b82ba
NC
2166 case REG_B:
2167 case REG_C:
2168 case REG_D:
2169 case REG_E:
3c9b82ba
NC
2170 case REG_H:
2171 case REG_L:
3c9b82ba 2172 break;
6655dba2
SB
2173 default:
2174 ill_op ();
2175// return;
2176 }
3c9b82ba 2177
6655dba2
SB
2178 q = frag_more (prefix ? 2 : 1);
2179 if (prefix)
2180 {
2181 if (ins_ok & INS_GBZ80)
2182 ill_op ();
2183 else if (!(ins_ok & INS_EZ80))
2184 check_mach (INS_IDX_HALF);
2185 *q++ = prefix;
2186 }
2187 *q = 0x06 | ((dst->X_add_number & 7) << 3);
2188 emit_byte (src, BFD_RELOC_8);
2189}
2190
2191static void
2192emit_ld_r_r (expressionS *dst, expressionS *src)
2193{ /* mostly 8-bit load register from register instructions: LD r,r */
2194 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2195 char *q;
40c75bc8
SB
2196 int prefix = 0;
2197 int opcode = 0;
6655dba2
SB
2198 int ii_halves = 0;
2199
2200 switch (dst->X_add_number)
2201 {
2202 case REG_SP:
2203 switch (src->X_add_number)
2204 {
2205 case REG_HL: prefix = 0x00; break;
2206 case REG_IX: prefix = 0xDD; break;
2207 case REG_IY: prefix = 0xFD; break;
2208 default:
2209 ill_op ();
2210 }
2211 if (ins_ok & INS_GBZ80)
2212 ill_op ();
2213 opcode = 0xF9;
2214 break;
2215 case REG_HL:
2216 if (!(ins_ok & INS_EZ80))
2217 ill_op ();
2218 if (src->X_add_number != REG_I)
2219 ill_op ();
2220 if (cpu_mode < 1)
2221 error (_("ADL mode instruction"));
2222 /* LD HL,I */
2223 prefix = 0xED;
2224 opcode = 0xD7;
2225 break;
2226 case REG_I:
2227 if (src->X_add_number == REG_HL)
2228 {
2229 if (!(ins_ok & INS_EZ80))
2230 ill_op ();
2231 if (cpu_mode < 1)
2232 error (_("ADL mode instruction"));
2233 prefix = 0xED;
2234 opcode = 0xC7;
2235 }
2236 else if (src->X_add_number == REG_A)
2237 {
2238 prefix = 0xED;
2239 opcode = 0x47;
2240 }
3c9b82ba 2241 else
6655dba2
SB
2242 ill_op ();
2243 break;
2244 case REG_MB:
2245 if (!(ins_ok & INS_EZ80) || (src->X_add_number != REG_A))
2246 ill_op ();
2247 if (cpu_mode < 1)
2248 error (_("ADL mode instruction"));
2249 prefix = 0xED;
2250 opcode = 0x6D;
2251 break;
2252 case REG_R:
2253 if (src->X_add_number == REG_A) /* LD R,A */
2254 {
2255 prefix = 0xED;
2256 opcode = 0x4F;
2257 }
2258 else
2259 ill_op ();
2260 break;
2261 case REG_A:
2262 if (src->X_add_number == REG_I) /* LD A,I */
2263 {
2264 prefix = 0xED;
2265 opcode = 0x57;
2266 break;
2267 }
2268 else if (src->X_add_number == REG_R) /* LD A,R */
2269 {
2270 prefix = 0xED;
2271 opcode = 0x5F;
2272 break;
2273 }
2274 else if (src->X_add_number == REG_MB) /* LD A,MB */
2275 {
2276 if (!(ins_ok & INS_EZ80))
2277 ill_op ();
2278 else
2279 {
2280 if (cpu_mode < 1)
2281 error (_("ADL mode instruction"));
2282 prefix = 0xED;
2283 opcode = 0x6E;
2284 }
2285 break;
2286 }
2287 /* Fall through. */
2288 case REG_B:
2289 case REG_C:
2290 case REG_D:
2291 case REG_E:
2292 case REG_H:
2293 case REG_L:
2294 prefix = 0x00;
2295 break;
2296 case REG_H|R_IX:
2297 case REG_L|R_IX:
2298 prefix = 0xDD;
2299 ii_halves = 1;
2300 break;
2301 case REG_H|R_IY:
2302 case REG_L|R_IY:
2303 prefix = 0xFD;
2304 ii_halves = 1;
3c9b82ba 2305 break;
6655dba2
SB
2306 default:
2307 ill_op ();
2308 }
3c9b82ba 2309
6655dba2
SB
2310 if (opcode == 0)
2311 {
2312 switch (src->X_add_number)
2313 {
2314 case REG_A:
2315 case REG_B:
2316 case REG_C:
2317 case REG_D:
2318 case REG_E:
2319 break;
2320 case REG_H:
2321 case REG_L:
2322 if (prefix != 0)
2323 ill_op (); /* LD iiH/L,H/L are not permitted */
2324 break;
2325 case REG_H|R_IX:
2326 case REG_L|R_IX:
40c75bc8 2327 if (prefix == 0xFD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
6655dba2
SB
2328 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2329 prefix = 0xDD;
2330 ii_halves = 1;
2331 break;
2332 case REG_H|R_IY:
2333 case REG_L|R_IY:
40c75bc8 2334 if (prefix == 0xDD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
6655dba2
SB
2335 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2336 prefix = 0xFD;
2337 ii_halves = 1;
2338 break;
2339 default:
2340 ill_op ();
2341 }
2342 opcode = 0x40 + ((dst->X_add_number & 7) << 3) + (src->X_add_number & 7);
2343 }
2344 if ((ins_ok & INS_GBZ80) && prefix != 0)
2345 ill_op ();
2346 if (ii_halves && !(ins_ok & INS_EZ80))
2347 check_mach (INS_IDX_HALF);
2348 if (prefix == 0 && (ins_ok & INS_EZ80))
2349 {
2350 switch (opcode)
2351 {
2352 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2353 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2354 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2355 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
40c75bc8 2356 as_warn (_("unsupported instruction, assembled as NOP"));
6655dba2
SB
2357 opcode = 0x00;
2358 break;
2359 default:;
2360 }
2361 }
2362 q = frag_more (prefix ? 2 : 1);
2363 if (prefix)
2364 *q++ = prefix;
2365 *q = opcode;
2366}
2367
2368static void
2369emit_ld_rr_m (expressionS *dst, expressionS *src)
2370{ /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2371 char *q;
40c75bc8
SB
2372 int prefix = 0;
2373 int opcode = 0;
6655dba2
SB
2374 expressionS src_offset;
2375
2376 /* GBZ80 has no support for 16-bit load from memory instructions */
2377 if (ins_ok & INS_GBZ80)
2378 ill_op ();
2379
2380 prefix = 0xED;
2381 switch (src->X_op)
2382 {
2383 case O_md1: /* LD rr,(ii+d) */
2384 prefix = (src->X_add_number == REG_IX) ? 0xDD : 0xFD;
3c9b82ba 2385 /* Fall through. */
6655dba2
SB
2386 case O_register: /* LD rr,(HL) */
2387 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2388 if (!(ins_ok & INS_EZ80))
2389 ill_op ();
2390 switch (dst->X_add_number)
2391 {
2392 case REG_BC: opcode = 0x07; break;
2393 case REG_DE: opcode = 0x17; break;
2394 case REG_HL: opcode = 0x27; break;
40c75bc8
SB
2395 case REG_IX: opcode = (!prefix || prefix == 0xDD) ? 0x37 : 0x31; break;
2396 case REG_IY: opcode = prefix ? ((prefix == 0xDD) ? 0x31 : 0x37) : 0x36; break;
6655dba2
SB
2397 default:
2398 ill_op ();
2399 }
2400 q = frag_more (2);
2401 *q++ = prefix;
2402 *q = opcode;
40c75bc8 2403 if (prefix != 0xED)
6655dba2
SB
2404 {
2405 src_offset = *src;
2406 src_offset.X_op = O_symbol;
2407 src_offset.X_add_number = 0;
2408 emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
2409 }
2410 break;
2411 default: /* LD rr,(nn) */
2412 switch (dst->X_add_number)
2413 {
2414 case REG_BC: prefix = 0xED; opcode = 0x4B; break;
2415 case REG_DE: prefix = 0xED; opcode = 0x5B; break;
2416 case REG_HL: prefix = 0x00; opcode = 0x2A; break;
2417 case REG_SP: prefix = 0xED; opcode = 0x7B; break;
2418 case REG_IX: prefix = 0xDD; opcode = 0x2A; break;
2419 case REG_IY: prefix = 0xFD; opcode = 0x2A; break;
2420 default:
2421 ill_op ();
2422 }
2423 q = frag_more (prefix ? 2 : 1);
2424 if (prefix)
2425 *q++ = prefix;
2426 *q = opcode;
2427 emit_word (src);
2428 }
2429 return;
2430}
2431
2432static void
2433emit_ld_rr_nn (expressionS *dst, expressionS *src)
2434{ /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2435 char *q;
40c75bc8
SB
2436 int prefix = 0x00;
2437 int opcode = 0x21; /* LD HL,nn */
6655dba2
SB
2438 switch (dst->X_add_number)
2439 {
2440 case REG_IX:
2441 prefix = 0xDD;
2442 break;
2443 case REG_IY:
2444 prefix = 0xFD;
2445 break;
2446 case REG_HL:
2447 break;
3c9b82ba
NC
2448 case REG_BC:
2449 case REG_DE:
6655dba2
SB
2450 case REG_SP:
2451 opcode = 0x01 + ((dst->X_add_number & 3) << 4);
2452 break;
2453 default:
2454 ill_op ();
2455 return;
2456 }
2457 if (prefix && (ins_ok & INS_GBZ80))
2458 ill_op ();
2459 q = frag_more (prefix ? 2 : 1);
2460 if (prefix)
2461 *q++ = prefix;
2462 *q = opcode;
2463 emit_word (src);
2464}
2465
2466static const char *
2467emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
2468 const char * args)
2469{
2470 expressionS dst, src;
2471 const char *p;
2472
2473 p = parse_exp (args, & dst);
2474 if (*p++ != ',')
2475 error (_("bad instruction syntax"));
2476 p = parse_exp (p, & src);
2477
2478 if (dst.X_md)
2479 {
2480 if (src.X_op == O_register)
2481 {
2482 if (src.X_add_number <= 7)
2483 emit_ld_m_r (& dst, & src); /* LD (xxx),r */
2484 else
2485 emit_ld_m_rr (& dst, & src); /* LD (xxx),rr */
2486 }
3c9b82ba 2487 else
6655dba2
SB
2488 emit_ld_m_n (& dst, & src); /* LD (hl),n or LD (ix/y+r),n */
2489 }
2490 else if (dst.X_op == O_register)
2491 {
2492 if (src.X_md)
2493 {
2494 if (dst.X_add_number <= 7)
2495 emit_ld_r_m (& dst, & src);
2496 else
2497 emit_ld_rr_m (& dst, & src);
2498 }
2499 else if (src.X_op == O_register)
2500 emit_ld_r_r (& dst, & src);
2501 else if ((dst.X_add_number & ~R_INDEX) <= 7)
2502 emit_ld_r_n (& dst, & src);
2503 else
2504 emit_ld_rr_nn (& dst, & src);
2505 }
2506 else
2507 ill_op ();
2508
2509 return p;
2510}
2511
2512static const char *
2513emit_lddldi (char prefix, char opcode, const char * args)
2514{
2515 expressionS dst, src;
2516 const char *p;
2517 char *q;
2518
2519 if (!(ins_ok & INS_GBZ80))
40c75bc8 2520 return emit_insn (prefix, opcode, args);
6655dba2
SB
2521
2522 p = parse_exp (args, & dst);
2523 if (*p++ != ',')
2524 error (_("bad instruction syntax"));
2525 p = parse_exp (args, & src);
2526
2527 if (dst.X_op != O_register || src.X_op != O_register)
2528 ill_op ();
2529
2530 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2531 opcode = (opcode & 0x08) * 2 + 0x22;
2532
2533 if (dst.X_md != 0
2534 && dst.X_add_number == REG_HL
2535 && src.X_md == 0
2536 && src.X_add_number == REG_A)
2537 opcode |= 0x00; /* LDx (HL),A */
2538 else if (dst.X_md == 0
2539 && dst.X_add_number == REG_A
2540 && src.X_md != 0
2541 && src.X_add_number == REG_HL)
2542 opcode |= 0x08; /* LDx A,(HL) */
2543 else
2544 ill_op ();
2545
2546 q = frag_more (1);
2547 *q = opcode;
2548 return p;
2549}
2550
2551static const char *
2552emit_ldh (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2553 const char * args)
2554{
2555 expressionS dst, src;
2556 const char *p;
2557 char *q;
2558
2559 p = parse_exp (args, & dst);
2560 if (*p++ != ',')
2561 {
2562 error (_("bad instruction syntax"));
2563 return p;
2564 }
2565
2566 p = parse_exp (p, & src);
2567 if (dst.X_md == 0
2568 && dst.X_op == O_register
2569 && dst.X_add_number == REG_A
2570 && src.X_md != 0
2571 && src.X_op != O_md1
2572 && src.X_op != O_register)
2573 {
2574 q = frag_more (1);
2575 *q = 0xF0;
2576 emit_byte (& src, BFD_RELOC_8);
2577 }
2578 else if (dst.X_md != 0
2579 && dst.X_op != O_md1
2580 && src.X_md == 0
2581 && src.X_op == O_register
2582 && src.X_add_number == REG_A)
2583 {
2584 if (dst.X_op == O_register)
2585 {
2586 if (dst.X_add_number == REG_C)
2587 {
2588 q = frag_more (1);
2589 *q = 0xE2;
2590 }
2591 else
40c75bc8 2592 ill_op ();
6655dba2
SB
2593 }
2594 else
2595 {
2596 q = frag_more (1);
2597 *q = 0xE0;
2598 emit_byte (& dst, BFD_RELOC_8);
2599 }
2600 }
2601 else
2602 ill_op ();
2603
2604 return p;
2605}
2606
2607static const char *
2608parse_lea_pea_args (const char * args, expressionS *op)
2609{
2610 const char *p;
2611 p = parse_exp (args, op);
2612 if (sdcc_compat && *p == ',' && op->X_op == O_register)
2613 {
2614 expressionS off;
2615 p = parse_exp (p + 1, &off);
2616 op->X_op = O_add;
2617 op->X_add_symbol = make_expr_symbol (&off);
2618 }
2619 return p;
2620}
2621
2622static const char *
2623emit_lea (char prefix, char opcode, const char * args)
2624{
2625 expressionS dst, src;
2626 const char *p;
2627 char *q;
2628 int rnum;
2629
2630 p = parse_exp (args, & dst);
2631 if (dst.X_md != 0 || dst.X_op != O_register)
2632 ill_op ();
2633
2634 rnum = dst.X_add_number;
2635 switch (rnum)
2636 {
2637 case REG_BC:
2638 case REG_DE:
2639 case REG_HL:
2640 opcode = 0x02 | ((rnum & 0x03) << 4);
2641 break;
2642 case REG_IX:
2643 opcode = 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2644 break;
2645 case REG_IY:
2646 opcode = 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2647 break;
2648 default:
2649 ill_op ();
2650 }
2651
2652 if (*p++ != ',')
2653 error (_("bad instruction syntax"));
2654
2655 p = parse_lea_pea_args (p, & src);
2656 if (src.X_md != 0 || src.X_op != O_add /*&& src.X_op != O_register*/)
2657 ill_op ();
2658
2659 rnum = src.X_add_number;
2660 switch (src.X_op)
2661 {
2662 case O_add:
2663 break;
2664 case O_register: /* permit instructions like LEA rr,IX without displacement specified */
2665 src.X_add_symbol = zero;
2666 break;
2667 default:
2668 ill_op ();
2669 }
2670
2671 switch (rnum)
2672 {
2673 case REG_IX:
40c75bc8 2674 opcode = (opcode == (char)0x33) ? 0x55 : (opcode|0x00);
3c9b82ba 2675 break;
6655dba2 2676 case REG_IY:
40c75bc8 2677 opcode = (opcode == (char)0x32) ? 0x54 : (opcode|0x01);
6655dba2
SB
2678 }
2679
2680 q = frag_more (2);
2681 *q++ = prefix;
2682 *q = opcode;
2683
2684 src.X_op = O_symbol;
2685 src.X_add_number = 0;
2686 emit_byte (& src, BFD_RELOC_Z80_DISP8);
2687
2688 return p;
2689}
2690
2691static const char *
2692emit_mlt (char prefix, char opcode, const char * args)
2693{
2694 expressionS arg;
2695 const char *p;
2696 char *q;
2697
2698 p = parse_exp (args, & arg);
2699 if (arg.X_md != 0 || arg.X_op != O_register || !(arg.X_add_number & R_ARITH))
2700 ill_op ();
2701
2702 q = frag_more (2);
2703 *q++ = prefix;
2704 *q = opcode | ((arg.X_add_number & 3) << 4);
2705
2706 return p;
2707}
3c9b82ba 2708
6655dba2
SB
2709static const char *
2710emit_pea (char prefix, char opcode, const char * args)
2711{
2712 expressionS arg;
2713 const char *p;
2714 char *q;
3c9b82ba 2715
6655dba2
SB
2716 p = parse_lea_pea_args (args, & arg);
2717 if (arg.X_md != 0
2718 || (/*arg.X_op != O_register &&*/ arg.X_op != O_add)
2719 || !(arg.X_add_number & R_INDEX))
2720 ill_op ();
2721 /* PEA ii without displacement is mostly typo,
2722 because there is PUSH instruction which is shorter and faster */
2723 /*if (arg.X_op == O_register)
40c75bc8 2724 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3c9b82ba 2725
6655dba2
SB
2726 q = frag_more (2);
2727 *q++ = prefix;
2728 *q = opcode + (arg.X_add_number == REG_IY ? 1 : 0);
2729
2730 arg.X_op = O_symbol;
2731 arg.X_add_number = 0;
2732 emit_byte (& arg, BFD_RELOC_Z80_DISP8);
2733
2734 return p;
3c9b82ba
NC
2735}
2736
2737static const char *
6655dba2 2738emit_reti (char prefix, char opcode, const char * args)
3c9b82ba 2739{
6655dba2 2740 if (ins_ok & INS_GBZ80)
40c75bc8 2741 return emit_insn (0x00, 0xD9, args);
6655dba2 2742
40c75bc8 2743 return emit_insn (prefix, opcode, args);
6655dba2
SB
2744}
2745
2746static const char *
2747emit_tst (char prefix, char opcode, const char *args)
2748{
2749 expressionS arg_s;
3c9b82ba
NC
2750 const char *p;
2751 char *q;
6655dba2 2752 int rnum;
3c9b82ba 2753
6655dba2
SB
2754 p = parse_exp (args, & arg_s);
2755 if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
2756 {
2757 if (!(ins_ok & INS_EZ80))
40c75bc8 2758 ill_op ();
6655dba2
SB
2759 ++p;
2760 p = parse_exp (p, & arg_s);
2761 }
3c9b82ba 2762
6655dba2
SB
2763 rnum = arg_s.X_add_number;
2764 switch (arg_s.X_op)
3c9b82ba
NC
2765 {
2766 case O_md1:
6655dba2 2767 ill_op ();
3c9b82ba 2768 break;
3c9b82ba 2769 case O_register:
6655dba2
SB
2770 rnum = arg_s.X_add_number;
2771 if (arg_s.X_md != 0)
2772 {
2773 if (rnum != REG_HL)
2774 ill_op ();
2775 else
2776 rnum = 6;
2777 }
2778 q = frag_more (2);
2779 *q++ = prefix;
2780 *q = opcode | (rnum << 3);
3c9b82ba 2781 break;
3c9b82ba 2782 default:
6655dba2
SB
2783 if (arg_s.X_md)
2784 ill_op ();
2785 q = frag_more (2);
2786 *q++ = prefix;
2787 *q = opcode | 0x60;
2788 emit_byte (& arg_s, BFD_RELOC_8);
3c9b82ba
NC
2789 }
2790 return p;
2791}
2792
6655dba2
SB
2793static const char *
2794emit_tstio (char prefix, char opcode, const char *args)
2795{
2796 expressionS arg;
2797 const char *p;
2798 char *q;
2799
2800 p = parse_exp (args, & arg);
2801 if (arg.X_md || arg.X_op == O_register || arg.X_op == O_md1)
2802 ill_op ();
2803
2804 q = frag_more (2);
2805 *q++ = prefix;
2806 *q = opcode;
40c75bc8 2807 emit_byte (& arg, BFD_RELOC_8);
6655dba2
SB
2808
2809 return p;
2810}
2811
134dcee5
AM
2812static void
2813emit_data (int size ATTRIBUTE_UNUSED)
3c9b82ba
NC
2814{
2815 const char *p, *q;
2816 char *u, quote;
2817 int cnt;
2818 expressionS exp;
2819
134dcee5
AM
2820 if (is_it_end_of_statement ())
2821 {
2822 demand_empty_rest_of_line ();
2823 return;
2824 }
2825 p = skip_space (input_line_pointer);
3c9b82ba 2826
134dcee5 2827 do
3c9b82ba
NC
2828 {
2829 if (*p == '\"' || *p == '\'')
2830 {
134dcee5
AM
2831 for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
2832 ;
2833 u = frag_more (cnt);
2834 memcpy (u, q, cnt);
2835 if (!*p)
2836 as_warn (_("unterminated string"));
2837 else
2838 p = skip_space (p+1);
3c9b82ba
NC
2839 }
2840 else
2841 {
2842 p = parse_exp (p, &exp);
2843 if (exp.X_op == O_md1 || exp.X_op == O_register)
2844 {
2845 ill_op ();
2846 break;
2847 }
2848 if (exp.X_md)
2849 as_warn (_("parentheses ignored"));
134dcee5 2850 emit_byte (&exp, BFD_RELOC_8);
3c9b82ba
NC
2851 p = skip_space (p);
2852 }
3c9b82ba 2853 }
134dcee5
AM
2854 while (*p++ == ',') ;
2855 input_line_pointer = (char *)(p-1);
3c9b82ba
NC
2856}
2857
6655dba2
SB
2858static void
2859z80_cons (int size)
2860{
2861 const char *p;
2862 expressionS exp;
2863
2864 if (is_it_end_of_statement ())
2865 {
2866 demand_empty_rest_of_line ();
2867 return;
2868 }
2869 p = skip_space (input_line_pointer);
2870
2871 do
2872 {
2873 p = parse_exp (p, &exp);
2874 if (exp.X_op == O_md1 || exp.X_op == O_register)
2875 {
2876 ill_op ();
2877 break;
2878 }
2879 if (exp.X_md)
2880 as_warn (_("parentheses ignored"));
2881 emit_data_val (&exp, size);
2882 p = skip_space (p);
2883 } while (*p++ == ',') ;
2884 input_line_pointer = (char *)(p-1);
2885}
2886
2887/* next functions were commented out because it is difficult to mix
2888 both ADL and Z80 mode instructions within one COFF file:
2889 objdump cannot recognize point of mode switching.
2890*/
2891static void
2892set_cpu_mode (int mode)
2893{
2894 if (ins_ok & INS_EZ80)
2895 cpu_mode = mode;
2896 else
2897 error (_("CPU mode is unsupported by target"));
2898}
2899
2900static void
2901assume (int arg ATTRIBUTE_UNUSED)
2902{
2903 char *name;
2904 char c;
2905 int n;
2906
2907 input_line_pointer = (char*)skip_space (input_line_pointer);
2908 c = get_symbol_name (& name);
40c75bc8 2909 if (strncasecmp (name, "ADL", 4) != 0)
6655dba2
SB
2910 {
2911 ill_op ();
2912 return;
2913 }
2914
2915 restore_line_pointer (c);
2916 input_line_pointer = (char*)skip_space (input_line_pointer);
2917 if (*input_line_pointer++ != '=')
2918 {
2919 error (_("assignment expected"));
2920 return;
2921 }
2922 input_line_pointer = (char*)skip_space (input_line_pointer);
2923 n = get_single_number ();
2924
2925 set_cpu_mode (n);
2926}
2927
3c9b82ba
NC
2928static const char *
2929emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
2930{
2931 const char *p;
2932
2933 p = skip_space (args);
2934 if (TOLOWER (*p++) != 'a' || *p++ != ',')
2935 ill_op ();
2936 else
2937 {
2938 char *q, reg;
2939
2940 reg = TOLOWER (*p++);
2941 switch (reg)
2942 {
2943 case 'b':
2944 case 'c':
2945 case 'd':
2946 case 'e':
2947 check_mach (INS_R800);
2948 if (!*skip_space (p))
2949 {
2950 q = frag_more (2);
2951 *q++ = prefix;
2952 *q = opcode + ((reg - 'b') << 3);
2953 break;
2954 }
1a0670f3 2955 /* Fall through. */
3c9b82ba
NC
2956 default:
2957 ill_op ();
2958 }
2959 }
2960 return p;
2961}
2962
2963static const char *
2964emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
2965{
2966 const char *p;
2967
2968 p = skip_space (args);
2969 if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
2970 ill_op ();
2971 else
2972 {
2973 expressionS reg;
2974 char *q;
2975
2976 p = parse_exp (p, & reg);
2977
2978 if ((!reg.X_md) && reg.X_op == O_register)
2979 switch (reg.X_add_number)
2980 {
2981 case REG_BC:
2982 case REG_SP:
2983 check_mach (INS_R800);
2984 q = frag_more (2);
2985 *q++ = prefix;
2986 *q = opcode + ((reg.X_add_number & 3) << 4);
2987 break;
2988 default:
2989 ill_op ();
2990 }
2991 }
2992 return p;
2993}
2994
6655dba2
SB
2995static int
2996assemble_suffix (const char **suffix)
2997{
2998 static
2999 const char sf[8][4] =
3000 {
3001 "il",
3002 "is",
3003 "l",
3004 "lil",
3005 "lis",
3006 "s",
3007 "sil",
3008 "sis"
3009 };
3010 const char *p;
3011 const char (*t)[4];
3012 char sbuf[4];
3013 int i;
3014
3015 p = *suffix;
3016 if (*p++ != '.')
3017 return 0;
3018
3019 for (i = 0; (i < 3) && (ISALPHA (*p)); i++)
3020 sbuf[i] = TOLOWER (*p++);
40c75bc8 3021 if (*p && !ISSPACE (*p))
6655dba2
SB
3022 return 0;
3023 *suffix = p;
3024 sbuf[i] = 0;
3025
40c75bc8 3026 t = bsearch (sbuf, sf, ARRAY_SIZE (sf), sizeof (sf[0]), (int(*)(const void*, const void*)) strcmp);
6655dba2
SB
3027 if (t == NULL)
3028 return 0;
3029 i = t - sf;
3030 switch (i)
3031 {
3032 case 0: /* IL */
3033 i = cpu_mode ? 0x5B : 0x52;
3034 break;
3035 case 1: /* IS */
3036 i = cpu_mode ? 0x49 : 0x40;
3037 break;
3038 case 2: /* L */
3039 i = cpu_mode ? 0x5B : 0x49;
3040 break;
3041 case 3: /* LIL */
3042 i = 0x5B;
3043 break;
3044 case 4: /* LIS */
3045 i = 0x49;
3046 break;
3047 case 5: /* S */
3048 i = cpu_mode ? 0x52 : 0x40;
3049 break;
3050 case 6: /* SIL */
3051 i = 0x52;
3052 break;
3053 case 7: /* SIS */
3054 i = 0x40;
3055 break;
3056 }
40c75bc8 3057 *frag_more (1) = (char)i;
6655dba2
SB
3058 switch (i)
3059 {
3060 case 0x40: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IS; break;
3061 case 0x49: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IS; break;
3062 case 0x52: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IL; break;
3063 case 0x5B: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IL; break;
3064 }
3065 return 1;
3066}
3067
3068static void
3069psect (int arg)
3070{
3071#if defined(OBJ_ELF)
3072 return obj_elf_section (arg);
3073#elif defined(OBJ_COFF)
3074 return obj_coff_section (arg);
3075#else
3076#error Unknown object format
3077#endif
3078}
3079
3080static void
3081set_inss (int inss)
3082{
3083 int old_ins;
3084
3085 if (!sdcc_compat)
3086 as_fatal (_("Invalid directive"));
3087
3088 old_ins = ins_ok;
3089 ins_ok &= INS_MARCH_MASK;
3090 ins_ok |= inss;
3091 if (old_ins != ins_ok)
3092 cpu_mode = 0;
3093}
3094
3095static void
3096ignore (int arg ATTRIBUTE_UNUSED)
3097{
3098 ignore_rest_of_line ();
3099}
3100
3101static void
3102area (int arg)
3103{
3104 char *p;
3105 if (!sdcc_compat)
3106 as_fatal (_("Invalid directive"));
3107 for (p = input_line_pointer; *p && *p != '(' && *p != '\n'; p++)
3108 ;
3109 if (*p == '(')
3110 {
3111 *p = '\n';
3112 psect (arg);
3113 *p++ = '(';
3114 ignore_rest_of_line ();
3115 }
3116 else
3117 psect (arg);
3118}
3119
134dcee5
AM
3120/* Port specific pseudo ops. */
3121const pseudo_typeS md_pseudo_table[] =
3122{
6655dba2
SB
3123 { ".area", area, 0},
3124 { ".assume", assume, 0},
3125 { ".ez80", set_inss, INS_EZ80},
3126 { ".gbz80", set_inss, INS_GBZ80},
3127 { ".module", ignore, 0},
3128 { ".optsdcc", ignore, 0},
3129 { ".r800", set_inss, INS_R800},
3130 { ".set", s_set, 0},
3131 { ".z180", set_inss, INS_Z180},
3132 { ".z80", set_inss, INS_Z80},
134dcee5 3133 { "db" , emit_data, 1},
6655dba2
SB
3134 { "d24", z80_cons, 3},
3135 { "d32", z80_cons, 4},
3136 { "def24", z80_cons, 3},
3137 { "def32", z80_cons, 4},
3739860c 3138 { "defb", emit_data, 1},
6655dba2 3139 { "defm", emit_data, 1},
134dcee5 3140 { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
6655dba2 3141 { "defw", z80_cons, 2},
134dcee5 3142 { "ds", s_space, 1}, /* Fill with bytes rather than words. */
6655dba2
SB
3143 { "dw", z80_cons, 2},
3144 { "psect", psect, 0}, /* TODO: Translate attributes. */
134dcee5
AM
3145 { "set", 0, 0}, /* Real instruction on z80. */
3146 { NULL, 0, 0 }
3147} ;
3148
3c9b82ba
NC
3149static table_t instab[] =
3150{
6655dba2
SB
3151 { "adc", 0x88, 0x4A, emit_adc, INS_ALL },
3152 { "add", 0x80, 0x09, emit_add, INS_ALL },
3153 { "and", 0x00, 0xA0, emit_s, INS_ALL },
3154 { "bit", 0xCB, 0x40, emit_bit, INS_ALL },
3155 { "call", 0xCD, 0xC4, emit_jpcc, INS_ALL },
3156 { "ccf", 0x00, 0x3F, emit_insn, INS_ALL },
3157 { "cp", 0x00, 0xB8, emit_s, INS_ALL },
3158 { "cpd", 0xED, 0xA9, emit_insn, INS_NOT_GBZ80 },
3159 { "cpdr", 0xED, 0xB9, emit_insn, INS_NOT_GBZ80 },
3160 { "cpi", 0xED, 0xA1, emit_insn, INS_NOT_GBZ80 },
3161 { "cpir", 0xED, 0xB1, emit_insn, INS_NOT_GBZ80 },
3162 { "cpl", 0x00, 0x2F, emit_insn, INS_ALL },
3163 { "daa", 0x00, 0x27, emit_insn, INS_ALL },
3164 { "dec", 0x0B, 0x05, emit_incdec,INS_ALL },
3165 { "di", 0x00, 0xF3, emit_insn, INS_ALL },
3166 { "djnz", 0x00, 0x10, emit_jr, INS_NOT_GBZ80 },
3167 { "ei", 0x00, 0xFB, emit_insn, INS_ALL },
3168 { "ex", 0x00, 0x00, emit_ex, INS_NOT_GBZ80 },
3169 { "exx", 0x00, 0xD9, emit_insn, INS_NOT_GBZ80 },
3170 { "halt", 0x00, 0x76, emit_insn, INS_ALL },
3171 { "im", 0xED, 0x46, emit_im, INS_NOT_GBZ80 },
3172 { "in", 0x00, 0x00, emit_in, INS_NOT_GBZ80 },
3173 { "in0", 0xED, 0x00, emit_in0, INS_Z180|INS_EZ80 },
3174 { "inc", 0x03, 0x04, emit_incdec,INS_ALL },
3175 { "ind", 0xED, 0xAA, emit_insn, INS_NOT_GBZ80 },
3176 { "ind2", 0xED, 0x8C, emit_insn, INS_EZ80 },
3177 { "ind2r",0xED, 0x9C, emit_insn, INS_EZ80 },
3178 { "indm", 0xED, 0x8A, emit_insn, INS_EZ80 },
3179 { "indmr",0xED, 0x9A, emit_insn, INS_EZ80 },
3180 { "indr", 0xED, 0xBA, emit_insn, INS_NOT_GBZ80 },
3181 { "indrx",0xED, 0xCA, emit_insn, INS_EZ80 },
3182 { "ini", 0xED, 0xA2, emit_insn, INS_NOT_GBZ80 },
3183 { "ini2", 0xED, 0x84, emit_insn, INS_EZ80 },
3184 { "ini2r",0xED, 0x94, emit_insn, INS_EZ80 },
3185 { "inim", 0xED, 0x82, emit_insn, INS_EZ80 },
3186 { "inimr",0xED, 0x92, emit_insn, INS_EZ80 },
3187 { "inir", 0xED, 0xB2, emit_insn, INS_NOT_GBZ80 },
3188 { "inirx",0xED, 0xC2, emit_insn, INS_EZ80 },
3189 { "jp", 0xC3, 0xC2, emit_jpcc, INS_ALL },
3190 { "jr", 0x18, 0x20, emit_jrcc, INS_ALL },
3191 { "ld", 0x00, 0x00, emit_ld, INS_ALL },
3192 { "ldd", 0xED, 0xA8, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
3193 { "lddr", 0xED, 0xB8, emit_insn, INS_NOT_GBZ80 },
3194 { "ldh", 0xE0, 0x00, emit_ldh, INS_GBZ80 },
3195 { "ldhl", 0xE0, 0x00, emit_ldh, INS_GBZ80 },
3196 { "ldi", 0xED, 0xA0, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
3197 { "ldir", 0xED, 0xB0, emit_insn, INS_NOT_GBZ80 },
3198 { "lea", 0xED, 0x02, emit_lea, INS_EZ80 },
3199 { "mlt", 0xED, 0x4C, emit_mlt, INS_Z180|INS_EZ80 },
3200 { "mulub",0xED, 0xC5, emit_mulub,INS_R800 },
3201 { "muluw",0xED, 0xC3, emit_muluw,INS_R800 },
3202 { "neg", 0xed, 0x44, emit_insn, INS_NOT_GBZ80 },
3203 { "nop", 0x00, 0x00, emit_insn, INS_ALL },
3204 { "or", 0x00, 0xB0, emit_s, INS_ALL },
3205 { "otd2r",0xED, 0xBC, emit_insn, INS_EZ80 },
3206 { "otdm", 0xED, 0x8B, emit_insn, INS_Z180|INS_EZ80 },
3207 { "otdmr",0xED, 0x9B, emit_insn, INS_Z180|INS_EZ80 },
3208 { "otdr", 0xED, 0xBB, emit_insn, INS_NOT_GBZ80 },
3209 { "otdrx",0xED, 0xCB, emit_insn, INS_EZ80 },
3210 { "oti2r",0xED, 0xB4, emit_insn, INS_EZ80 },
3211 { "otim", 0xED, 0x83, emit_insn, INS_Z180|INS_EZ80 },
3212 { "otimr",0xED, 0x93, emit_insn, INS_Z180|INS_EZ80 },
3213 { "otir", 0xED, 0xB3, emit_insn, INS_NOT_GBZ80 },
3214 { "otirx",0xED, 0xC3, emit_insn, INS_EZ80 },
3215 { "out", 0x00, 0x00, emit_out, INS_NOT_GBZ80 },
3216 { "out0", 0xED, 0x01, emit_out0, INS_Z180|INS_EZ80 },
3217 { "outd", 0xED, 0xAB, emit_insn, INS_NOT_GBZ80 },
3218 { "outd2",0xED, 0xAC, emit_insn, INS_EZ80 },
3219 { "outi", 0xED, 0xA3, emit_insn, INS_NOT_GBZ80 },
3220 { "outi2",0xED, 0xA4, emit_insn, INS_EZ80 },
3221 { "pea", 0xED, 0x65, emit_pea, INS_EZ80 },
3222 { "pop", 0x00, 0xC1, emit_pop, INS_ALL },
3223 { "push", 0x00, 0xC5, emit_pop, INS_ALL },
3224 { "res", 0xCB, 0x80, emit_bit, INS_ALL },
3225 { "ret", 0xC9, 0xC0, emit_retcc,INS_ALL },
3226 { "reti", 0xED, 0x4D, emit_reti, INS_ALL }, /*GBZ80 has its own opcode for it*/
3227 { "retn", 0xED, 0x45, emit_insn, INS_NOT_GBZ80 },
3228 { "rl", 0xCB, 0x10, emit_mr, INS_ALL },
3229 { "rla", 0x00, 0x17, emit_insn, INS_ALL },
3230 { "rlc", 0xCB, 0x00, emit_mr, INS_ALL },
3231 { "rlca", 0x00, 0x07, emit_insn, INS_ALL },
3232 { "rld", 0xED, 0x6F, emit_insn, INS_NOT_GBZ80 },
3233 { "rr", 0xCB, 0x18, emit_mr, INS_ALL },
3234 { "rra", 0x00, 0x1F, emit_insn, INS_ALL },
3235 { "rrc", 0xCB, 0x08, emit_mr, INS_ALL },
3236 { "rrca", 0x00, 0x0F, emit_insn, INS_ALL },
3237 { "rrd", 0xED, 0x67, emit_insn, INS_NOT_GBZ80 },
3238 { "rsmix",0xED, 0x7E, emit_insn, INS_EZ80 },
3239 { "rst", 0x00, 0xC7, emit_rst, INS_ALL },
3240 { "sbc", 0x98, 0x42, emit_adc, INS_ALL },
3241 { "scf", 0x00, 0x37, emit_insn, INS_ALL },
3242 { "set", 0xCB, 0xC0, emit_bit, INS_ALL },
3243 { "sla", 0xCB, 0x20, emit_mr, INS_ALL },
3244 { "sli", 0xCB, 0x30, emit_mr, INS_SLI },
3245 { "sll", 0xCB, 0x30, emit_mr, INS_SLI },
3246 { "slp", 0xED, 0x76, emit_insn, INS_Z180|INS_EZ80 },
3247 { "sra", 0xCB, 0x28, emit_mr, INS_ALL },
3248 { "srl", 0xCB, 0x38, emit_mr, INS_ALL },
3249 { "stmix",0xED, 0x7D, emit_insn, INS_EZ80 },
3250 { "stop", 0x00, 0x10, emit_insn, INS_GBZ80 },
3251 { "sub", 0x00, 0x90, emit_s, INS_ALL },
3252 { "swap", 0xCB, 0x30, emit_mr, INS_GBZ80 },
3253 { "tst", 0xED, 0x04, emit_tst, INS_Z180|INS_EZ80 },
3254 { "tstio",0xED, 0x74, emit_tstio,INS_Z180|INS_EZ80 },
3255 { "xor", 0x00, 0xA8, emit_s, INS_ALL },
3c9b82ba
NC
3256} ;
3257
3258void
6efa941c 3259md_assemble (char *str)
3c9b82ba
NC
3260{
3261 const char *p;
3262 char * old_ptr;
3263 int i;
3264 table_t *insp;
3265
3266 err_flag = 0;
6655dba2 3267 inst_mode = cpu_mode ? (INST_MODE_L | INST_MODE_IL) : (INST_MODE_S | INST_MODE_IS);
3c9b82ba
NC
3268 old_ptr = input_line_pointer;
3269 p = skip_space (str);
6655dba2 3270 for (i = 0; (i < BUFLEN) && (ISALPHA (*p) || ISDIGIT (*p));)
3c9b82ba
NC
3271 buf[i++] = TOLOWER (*p++);
3272
134dcee5
AM
3273 if (i == BUFLEN)
3274 {
3275 buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated. */
3276 buf[BUFLEN-1] = 0;
3277 as_bad (_("Unknown instruction '%s'"), buf);
3278 }
3739860c 3279 else
3c9b82ba 3280 {
7a6bf3be 3281 dwarf2_emit_insn (0);
6655dba2
SB
3282 if ((*p) && (!ISSPACE (*p)))
3283 {
40c75bc8 3284 if (*p != '.' || !(ins_ok & INS_EZ80) || !assemble_suffix (&p))
6655dba2
SB
3285 {
3286 as_bad (_("syntax error"));
3287 goto end;
3288 }
3289 }
134dcee5 3290 buf[i] = 0;
3c9b82ba 3291 p = skip_space (p);
134dcee5 3292 key = buf;
3739860c 3293
134dcee5
AM
3294 insp = bsearch (&key, instab, ARRAY_SIZE (instab),
3295 sizeof (instab[0]), key_cmp);
6655dba2
SB
3296 if (!insp || (insp->inss && !(insp->inss & ins_ok)))
3297 {
3298 as_bad (_("Unknown instruction '%s'"), buf);
40c75bc8 3299 *frag_more (1) = 0;
6655dba2 3300 }
134dcee5
AM
3301 else
3302 {
3303 p = insp->fp (insp->prefix, insp->opcode, p);
3304 p = skip_space (p);
3305 if ((!err_flag) && *p)
3306 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
3307 *p);
3308 }
3c9b82ba 3309 }
6655dba2 3310end:
3c9b82ba
NC
3311 input_line_pointer = old_ptr;
3312}
3313
3314void
3315md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
3316{
3317 long val = * (long *) valP;
de6d4f05 3318 char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal;
3c9b82ba
NC
3319
3320 switch (fixP->fx_r_type)
3321 {
3322 case BFD_RELOC_8_PCREL:
3323 if (fixP->fx_addsy)
3324 {
3325 fixP->fx_no_overflow = 1;
3326 fixP->fx_done = 0;
3327 }
3328 else
3329 {
3330 fixP->fx_no_overflow = (-128 <= val && val < 128);
3331 if (!fixP->fx_no_overflow)
3332 as_bad_where (fixP->fx_file, fixP->fx_line,
3333 _("relative jump out of range"));
de6d4f05 3334 *p_lit++ = val;
3c9b82ba
NC
3335 fixP->fx_done = 1;
3336 }
3337 break;
3338
3339 case BFD_RELOC_Z80_DISP8:
3340 if (fixP->fx_addsy)
3341 {
3342 fixP->fx_no_overflow = 1;
3343 fixP->fx_done = 0;
3344 }
3345 else
3346 {
3347 fixP->fx_no_overflow = (-128 <= val && val < 128);
3348 if (!fixP->fx_no_overflow)
3349 as_bad_where (fixP->fx_file, fixP->fx_line,
33eaf5de 3350 _("index offset out of range"));
de6d4f05 3351 *p_lit++ = val;
3c9b82ba
NC
3352 fixP->fx_done = 1;
3353 }
3354 break;
3355
6655dba2
SB
3356 case BFD_RELOC_Z80_BYTE0:
3357 *p_lit++ = val;
3358 fixP->fx_no_overflow = 1;
3359 if (fixP->fx_addsy == NULL)
3360 fixP->fx_done = 1;
3361 break;
3362
3363 case BFD_RELOC_Z80_BYTE1:
3364 *p_lit++ = (val >> 8);
3365 fixP->fx_no_overflow = 1;
3366 if (fixP->fx_addsy == NULL)
3367 fixP->fx_done = 1;
3368 break;
3369
3370 case BFD_RELOC_Z80_BYTE2:
3371 *p_lit++ = (val >> 16);
3372 fixP->fx_no_overflow = 1;
3373 if (fixP->fx_addsy == NULL)
3374 fixP->fx_done = 1;
3375 break;
3376
3377 case BFD_RELOC_Z80_BYTE3:
3378 *p_lit++ = (val >> 24);
3379 fixP->fx_no_overflow = 1;
3380 if (fixP->fx_addsy == NULL)
3381 fixP->fx_done = 1;
3382 break;
3383
3c9b82ba
NC
3384 case BFD_RELOC_8:
3385 if (val > 255 || val < -128)
3386 as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow"));
de6d4f05 3387 *p_lit++ = val;
3739860c 3388 fixP->fx_no_overflow = 1;
3c9b82ba
NC
3389 if (fixP->fx_addsy == NULL)
3390 fixP->fx_done = 1;
3391 break;
3392
6655dba2
SB
3393 case BFD_RELOC_Z80_WORD1:
3394 *p_lit++ = (val >> 16);
3395 *p_lit++ = (val >> 24);
3396 fixP->fx_no_overflow = 1;
3397 if (fixP->fx_addsy == NULL)
3398 fixP->fx_done = 1;
3399 break;
3400
3401 case BFD_RELOC_Z80_WORD0:
3c9b82ba 3402 case BFD_RELOC_16:
de6d4f05
AM
3403 *p_lit++ = val;
3404 *p_lit++ = (val >> 8);
3739860c 3405 fixP->fx_no_overflow = 1;
134dcee5
AM
3406 if (fixP->fx_addsy == NULL)
3407 fixP->fx_done = 1;
3408 break;
3409
3410 case BFD_RELOC_24: /* Def24 may produce this. */
de6d4f05
AM
3411 *p_lit++ = val;
3412 *p_lit++ = (val >> 8);
3413 *p_lit++ = (val >> 16);
3739860c 3414 fixP->fx_no_overflow = 1;
3c9b82ba
NC
3415 if (fixP->fx_addsy == NULL)
3416 fixP->fx_done = 1;
3417 break;
3418
134dcee5 3419 case BFD_RELOC_32: /* Def32 and .long may produce this. */
de6d4f05
AM
3420 *p_lit++ = val;
3421 *p_lit++ = (val >> 8);
3422 *p_lit++ = (val >> 16);
3423 *p_lit++ = (val >> 24);
3c9b82ba
NC
3424 if (fixP->fx_addsy == NULL)
3425 fixP->fx_done = 1;
3426 break;
3427
3428 default:
3429 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
3430 abort ();
3431 }
3432}
3433
3434/* GAS will call this to generate a reloc. GAS will pass the
3435 resulting reloc to `bfd_install_relocation'. This currently works
3436 poorly, as `bfd_install_relocation' often does the wrong thing, and
3437 instances of `tc_gen_reloc' have been written to work around the
3438 problems, which in turns makes it difficult to fix
3439 `bfd_install_relocation'. */
3440
3441/* If while processing a fixup, a reloc really
3442 needs to be created then it is done here. */
3443
3444arelent *
3445tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
3446{
3447 arelent *reloc;
3448
3449 if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type))
3450 {
3451 as_bad_where (fixp->fx_file, fixp->fx_line,
3452 _("reloc %d not supported by object file format"),
3453 (int) fixp->fx_r_type);
3454 return NULL;
3455 }
3456
325801bd
TS
3457 reloc = XNEW (arelent);
3458 reloc->sym_ptr_ptr = XNEW (asymbol *);
3c9b82ba
NC
3459 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3460 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3461 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3462 reloc->addend = fixp->fx_offset;
3463
3464 return reloc;
3465}
6655dba2
SB
3466
3467int
3468z80_tc_label_is_local (const char *name)
3469{
3470 const char *n;
3471 const char *p;
3472 if (local_label_prefix == NULL)
3473 return 0;
3474 for (p = local_label_prefix, n = name; *p && *n && *n == *p; p++, n++)
3475 ;
3476 return *p == '\0';
3477}
3478
3479/* Parse floating point number from string and compute mantissa and
3480 exponent. Mantissa is normalized.
3481*/
3482#define EXP_MIN -0x10000
3483#define EXP_MAX 0x10000
3484static int
3485str_to_broken_float (bfd_boolean *signP, bfd_uint64_t *mantissaP, int *expP)
3486{
3487 char *p;
3488 bfd_boolean sign;
3489 bfd_uint64_t mantissa = 0;
3490 int exponent = 0;
3491 int i;
3492
3493 p = (char*)skip_space (input_line_pointer);
3494 sign = (*p == '-');
3495 *signP = sign;
3496 if (sign || *p == '+')
3497 ++p;
40c75bc8 3498 if (strncasecmp (p, "NaN", 3) == 0)
6655dba2
SB
3499 {
3500 *mantissaP = 0;
3501 *expP = 0;
3502 input_line_pointer = p + 3;
3503 return 1;
3504 }
40c75bc8 3505 if (strncasecmp (p, "inf", 3) == 0)
6655dba2
SB
3506 {
3507 *mantissaP = 1ull << 63;
3508 *expP = EXP_MAX;
3509 input_line_pointer = p + 3;
3510 return 1;
3511 }
40c75bc8 3512 for (; ISDIGIT (*p); ++p)
6655dba2
SB
3513 {
3514 if (mantissa >> 60)
3515 {
3516 if (*p >= '5')
3517 mantissa++;
3518 break;
3519 }
3520 mantissa = mantissa * 10 + (*p - '0');
3521 }
3522 /* skip non-significant digits */
40c75bc8 3523 for (; ISDIGIT (*p); ++p)
6655dba2
SB
3524 exponent++;
3525
3526 if (*p == '.')
3527 {
3528 p++;
40c75bc8 3529 if (!exponent) /* If no precission overflow. */
6655dba2 3530 {
40c75bc8 3531 for (; ISDIGIT (*p); ++p, --exponent)
6655dba2
SB
3532 {
3533 if (mantissa >> 60)
3534 {
3535 if (*p >= '5')
3536 mantissa++;
3537 break;
3538 }
3539 mantissa = mantissa * 10 + (*p - '0');
3540 }
3541 }
40c75bc8 3542 for (; ISDIGIT (*p); ++p)
6655dba2
SB
3543 ;
3544 }
3545 if (*p == 'e' || *p == 'E')
3546 {
3547 int es;
3548 int t = 0;
3549 ++p;
3550 es = (*p == '-');
3551 if (es || *p == '+')
3552 p++;
40c75bc8 3553 for (; ISDIGIT (*p); ++p)
6655dba2
SB
3554 {
3555 if (t < 100)
3556 t = t * 10 + (*p - '0');
3557 }
3558 exponent += (es) ? -t : t;
3559 }
40c75bc8 3560 if (ISALNUM (*p) || *p == '.')
6655dba2
SB
3561 return 0;
3562 input_line_pointer = p;
3563 if (mantissa == 0)
3564 {
3565 *mantissaP = 1ull << 63;
3566 *expP = EXP_MIN;
3567 return 1; /* result is 0 */
3568 }
3569 /* normalization */
3570 for (; mantissa <= ~0ull/10; --exponent)
3571 mantissa *= 10;
40c75bc8
SB
3572 /* Now we have sign, mantissa, and signed decimal exponent
3573 need to recompute to binary exponent. */
6655dba2
SB
3574 for (i = 64; exponent > 0; --exponent)
3575 {
3576 /* be sure that no integer overflow */
3577 while (mantissa > ~0ull/10)
3578 {
3579 mantissa >>= 1;
3580 i += 1;
3581 }
3582 mantissa *= 10;
3583 }
3584 for (; exponent < 0; ++exponent)
3585 {
3586 while (!(mantissa >> 63))
3587 {
3588 mantissa <<= 1;
3589 i -= 1;
3590 }
3591 mantissa /= 10;
3592 }
3593 /* normalization */
3594 for (; !(mantissa >> 63); --i)
3595 mantissa <<= 1;
3596 *mantissaP = mantissa;
3597 *expP = i;
3598 return 1;
3599}
3600
3601static const char *
3602str_to_zeda32(char *litP, int *sizeP)
3603{
3604 bfd_uint64_t mantissa;
3605 bfd_boolean sign;
3606 int exponent;
3607 unsigned i;
3608
3609 *sizeP = 4;
3610 if (!str_to_broken_float (&sign, &mantissa, &exponent))
3611 return _("invalid syntax");
3612 /* I do not know why decrement is needed */
3613 --exponent;
3614 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
3615 mantissa >>= 39;
3616 /* do rounding */
3617 ++mantissa;
3618 /* make 24 bit mantissa */
3619 mantissa >>= 1;
3620 /* check for overflow */
3621 if (mantissa >> 24)
3622 {
3623 mantissa >>= 1;
3624 ++exponent;
3625 }
3626 /* check for 0 */
3627 if (exponent < -127)
3628 {
3629 exponent = -128;
3630 mantissa = 0;
3631 }
3632 else if (exponent > 127)
3633 {
3634 exponent = -128;
3635 mantissa = sign ? 0xc00000 : 0x400000;
3636 }
3637 else if (mantissa == 0)
3638 {
3639 exponent = -128;
3640 mantissa = 0x200000;
3641 }
3642 else if (!sign)
3643 mantissa &= (1ull << 23) - 1;
3644 for (i = 0; i < 24; i += 8)
3645 *litP++ = (char)(mantissa >> i);
3646 *litP = (char)(0x80 + exponent);
3647 return NULL;
3648}
3649
3650/*
3651 Math48 by Anders Hejlsberg support.
3652 Mantissa is 39 bits wide, exponent 8 bit wide.
3653 Format is:
3654 bit 47: sign
3655 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
3656 bit 7-0: exponent+128 (0 - value is null)
3657 MIN: 2.938735877e-39
3658 MAX: 1.701411835e+38
3659*/
3660static const char *
3661str_to_float48(char *litP, int *sizeP)
3662{
3663 bfd_uint64_t mantissa;
3664 bfd_boolean sign;
3665 int exponent;
3666 unsigned i;
3667
3668 *sizeP = 6;
3669 if (!str_to_broken_float (&sign, &mantissa, &exponent))
3670 return _("invalid syntax");
3671 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
3672 mantissa >>= 23;
3673 /* do rounding */
3674 ++mantissa;
3675 /* make 40 bit mantissa */
3676 mantissa >>= 1;
3677 /* check for overflow */
3678 if (mantissa >> 40)
3679 {
3680 mantissa >>= 1;
3681 ++exponent;
3682 }
3683 if (exponent < -127)
3684 {
3685 memset (litP, 0, 6);
3686 return NULL;
3687 }
3688 if (exponent > 127)
3689 return _("overflow");
3690 if (!sign)
3691 mantissa &= (1ull << 39) - 1;
3692 *litP++ = (char)(0x80 + exponent);
3693 for (i = 0; i < 40; i += 8)
3694 *litP++ = (char)(mantissa >> i);
3695 return NULL;
3696}
7a6bf3be
SB
3697
3698static const char *
3699str_to_ieee754_h(char *litP, int *sizeP)
3700{
3701 return ieee_md_atof ('h', litP, sizeP, FALSE);
3702}
3703
3704static const char *
3705str_to_ieee754_s(char *litP, int *sizeP)
3706{
3707 return ieee_md_atof ('s', litP, sizeP, FALSE);
3708}
3709
3710static const char *
3711str_to_ieee754_d(char *litP, int *sizeP)
3712{
3713 return ieee_md_atof ('d', litP, sizeP, FALSE);
3714}
This page took 0.877301 seconds and 4 git commands to generate.