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