The patch fixed invalid compilation of instruction LD IY,(HL) and disassemble of...
[deliverable/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 bfd_boolean
829 contains_register (symbolS *sym)
830 {
831 if (sym)
832 {
833 expressionS * ex = symbol_get_value_expression (sym);
834
835 switch (ex->X_op)
836 {
837 case O_register:
838 return TRUE;
839
840 case O_add:
841 case O_subtract:
842 if (ex->X_op_symbol && contains_register (ex->X_op_symbol))
843 return TRUE;
844 /* Fall through. */
845 case O_uminus:
846 case O_symbol:
847 if (ex->X_add_symbol && contains_register (ex->X_add_symbol))
848 return TRUE;
849 break;
850
851 default:
852 break;
853 }
854 }
855
856 return FALSE;
857 }
858
859 /* Parse general expression, not looking for indexed addressing. */
860 static const char *
861 parse_exp_not_indexed (const char *s, expressionS *op)
862 {
863 const char *p;
864 int indir;
865 int make_shift = -1;
866
867 p = skip_space (s);
868 if (sdcc_compat && (*p == '<' || *p == '>'))
869 {
870 switch (*p)
871 {
872 case '<': /* LSB request */
873 make_shift = 0;
874 break;
875 case '>': /* MSB request */
876 make_shift = cpu_mode ? 16 : 8;
877 break;
878 }
879 s = ++p;
880 p = skip_space (p);
881 }
882
883 op->X_md = indir = is_indir (p);
884 if (indir && (ins_ok & INS_GBZ80))
885 { /* check for instructions like ld a,(hl+), ld (hl-),a */
886 p = skip_space (p+1);
887 if (!strncasecmp (p, "hl", 2))
888 {
889 p = skip_space(p+2);
890 if (*skip_space(p+1) == ')' && (*p == '+' || *p == '-'))
891 {
892 op->X_op = O_md1;
893 op->X_add_symbol = NULL;
894 op->X_add_number = (*p == '+') ? REG_HL : -REG_HL;
895 input_line_pointer = (char*)skip_space(p + 1) + 1;
896 return input_line_pointer;
897 }
898 }
899 }
900 input_line_pointer = (char*) s ;
901 expression (op);
902 switch (op->X_op)
903 {
904 case O_absent:
905 error (_("missing operand"));
906 break;
907 case O_illegal:
908 error (_("bad expression syntax"));
909 break;
910 default:
911 break;
912 }
913
914 if (make_shift >= 0)
915 {
916 /* replace [op] by [op >> shift] */
917 expressionS data;
918 op->X_add_symbol = make_expr_symbol (op);
919 op->X_add_number = 0;
920 op->X_op = O_right_shift;
921 memset (&data, 0, sizeof (data));
922 data.X_op = O_constant;
923 data.X_add_number = make_shift;
924 op->X_op_symbol = make_expr_symbol (&data);
925 }
926 return input_line_pointer;
927 }
928
929 static int
930 unify_indexed (expressionS *op)
931 {
932 if (O_register != symbol_get_value_expression (op->X_add_symbol)->X_op)
933 return 0;
934
935 int rnum = symbol_get_value_expression (op->X_add_symbol)->X_add_number;
936 if ( ((REG_IX != rnum) && (REG_IY != rnum)) || contains_register (op->X_op_symbol))
937 {
938 ill_op ();
939 return 0;
940 }
941
942 /* Convert subtraction to addition of negative value. */
943 if (O_subtract == op->X_op)
944 {
945 expressionS minus;
946 minus.X_op = O_uminus;
947 minus.X_add_number = 0;
948 minus.X_add_symbol = op->X_op_symbol;
949 minus.X_op_symbol = 0;
950 op->X_op_symbol = make_expr_symbol (&minus);
951 op->X_op = O_add;
952 }
953
954 /* Clear X_add_number of the expression. */
955 if (op->X_add_number != 0)
956 {
957 expressionS add;
958 memset (&add, 0, sizeof (add));
959 add.X_op = O_symbol;
960 add.X_add_number = op->X_add_number;
961 add.X_add_symbol = op->X_op_symbol;
962 add.X_op_symbol = 0;
963 op->X_add_symbol = make_expr_symbol (&add);
964 }
965 else
966 op->X_add_symbol = op->X_op_symbol;
967
968 op->X_add_number = rnum;
969 op->X_op_symbol = 0;
970 return 1;
971 }
972
973 /* Parse expression, change operator to O_md1 for indexed addressing. */
974 static const char *
975 parse_exp (const char *s, expressionS *op)
976 {
977 const char* res = parse_exp_not_indexed (s, op);
978 switch (op->X_op)
979 {
980 case O_add:
981 case O_subtract:
982 if (unify_indexed (op) && op->X_md)
983 op->X_op = O_md1;
984 break;
985 case O_register:
986 if (op->X_md && ((REG_IX == op->X_add_number) || (REG_IY == op->X_add_number)))
987 {
988 op->X_add_symbol = zero;
989 op->X_op = O_md1;
990 }
991 break;
992 case O_constant:
993 /* parse SDCC syntax where index register offset placed before parentheses */
994 if (sdcc_compat && is_indir (res))
995 {
996 expressionS off;
997 off = *op;
998 res = parse_exp (res, op);
999 if (op->X_op != O_md1 || op->X_add_symbol != zero)
1000 ill_op ();
1001 else
1002 op->X_add_symbol = make_expr_symbol (&off);
1003 }
1004 break;
1005 default:
1006 break;
1007 }
1008 return res;
1009 }
1010
1011 /* Condition codes, including some synonyms provided by HiTech zas. */
1012 static const struct reg_entry cc_tab[] =
1013 {
1014 { "age", 6 << 3 },
1015 { "alt", 7 << 3 },
1016 { "c", 3 << 3 },
1017 { "di", 4 << 3 },
1018 { "ei", 5 << 3 },
1019 { "lge", 2 << 3 },
1020 { "llt", 3 << 3 },
1021 { "m", 7 << 3 },
1022 { "nc", 2 << 3 },
1023 { "nz", 0 << 3 },
1024 { "p", 6 << 3 },
1025 { "pe", 5 << 3 },
1026 { "po", 4 << 3 },
1027 { "z", 1 << 3 },
1028 } ;
1029
1030 /* Parse condition code. */
1031 static const char *
1032 parse_cc (const char *s, char * op)
1033 {
1034 const char *p;
1035 int i;
1036 struct reg_entry * cc_p;
1037
1038 for (i = 0; i < BUFLEN; ++i)
1039 {
1040 if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */
1041 break;
1042 buf[i] = TOLOWER (s[i]);
1043 }
1044
1045 if ((i < BUFLEN)
1046 && ((s[i] == 0) || (s[i] == ',')))
1047 {
1048 buf[i] = 0;
1049 cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
1050 sizeof (cc_tab[0]), key_cmp);
1051 }
1052 else
1053 cc_p = NULL;
1054
1055 if (cc_p)
1056 {
1057 *op = cc_p->number;
1058 p = s + i;
1059 }
1060 else
1061 p = NULL;
1062
1063 return p;
1064 }
1065
1066 static const char *
1067 emit_insn (char prefix, char opcode, const char * args)
1068 {
1069 char *p;
1070
1071 if (prefix)
1072 {
1073 p = frag_more (2);
1074 *p++ = prefix;
1075 }
1076 else
1077 p = frag_more (1);
1078 *p = opcode;
1079 return args;
1080 }
1081
1082 void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
1083 {
1084 bfd_reloc_code_real_type r[4] =
1085 {
1086 BFD_RELOC_8,
1087 BFD_RELOC_16,
1088 BFD_RELOC_24,
1089 BFD_RELOC_32
1090 };
1091
1092 if (nbytes < 1 || nbytes > 4)
1093 {
1094 as_bad (_("unsupported BFD relocation size %u"), nbytes);
1095 }
1096 else
1097 {
1098 fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
1099 }
1100 }
1101
1102 static void
1103 emit_data_val (expressionS * val, int size)
1104 {
1105 char *p;
1106 bfd_reloc_code_real_type r_type;
1107
1108 p = frag_more (size);
1109 if (val->X_op == O_constant)
1110 {
1111 int i;
1112 for (i = 0; i < size; ++i)
1113 p[i] = (char)(val->X_add_number >> (i*8));
1114 return;
1115 }
1116
1117 switch (size)
1118 {
1119 case 1: r_type = BFD_RELOC_8; break;
1120 case 2: r_type = BFD_RELOC_16; break;
1121 case 3: r_type = BFD_RELOC_24; break;
1122 case 4: r_type = BFD_RELOC_32; break;
1123 case 8: r_type = BFD_RELOC_64; break;
1124 default:
1125 as_fatal (_("invalid data size %d"), size);
1126 }
1127
1128 if ( (val->X_op == O_register)
1129 || (val->X_op == O_md1)
1130 || contains_register (val->X_add_symbol)
1131 || contains_register (val->X_op_symbol))
1132 ill_op ();
1133
1134 if (size <= 2 && val->X_op_symbol)
1135 {
1136 bfd_boolean simplify = TRUE;
1137 int shift = symbol_get_value_expression (val->X_op_symbol)->X_add_number;
1138 if (val->X_op == O_bit_and && shift == (1 << (size*8))-1)
1139 shift = 0;
1140 else if (val->X_op != O_right_shift)
1141 shift = -1;
1142
1143 if (size == 1)
1144 {
1145 switch (shift)
1146 {
1147 case 0: r_type = BFD_RELOC_Z80_BYTE0; break;
1148 case 8: r_type = BFD_RELOC_Z80_BYTE1; break;
1149 case 16: r_type = BFD_RELOC_Z80_BYTE2; break;
1150 case 24: r_type = BFD_RELOC_Z80_BYTE3; break;
1151 default: simplify = FALSE;
1152 }
1153 }
1154 else /* if (size == 2) */
1155 {
1156 switch (shift)
1157 {
1158 case 0: r_type = BFD_RELOC_Z80_WORD0; break;
1159 case 16: r_type = BFD_RELOC_Z80_WORD1; break;
1160 default: simplify = FALSE;
1161 }
1162 }
1163
1164 if (simplify)
1165 {
1166 val->X_op = O_symbol;
1167 val->X_op_symbol = NULL;
1168 val->X_add_number = 0;
1169 }
1170 }
1171
1172 fix_new_exp (frag_now, p - frag_now->fr_literal, size, val, FALSE, r_type);
1173 }
1174
1175 static void
1176 emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
1177 {
1178 char *p;
1179
1180 if (r_type == BFD_RELOC_8)
1181 {
1182 emit_data_val (val, 1);
1183 return;
1184 }
1185 p = frag_more (1);
1186 *p = val->X_add_number;
1187 if (contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol))
1188 {
1189 ill_op ();
1190 }
1191 else if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
1192 {
1193 as_bad (_("cannot make a relative jump to an absolute location"));
1194 }
1195 else if (val->X_op == O_constant)
1196 {
1197 if ((val->X_add_number < -128) || (val->X_add_number >= 128))
1198 {
1199 if (r_type == BFD_RELOC_Z80_DISP8)
1200 as_bad (_("index overflow (%+ld)"), val->X_add_number);
1201 else
1202 as_bad (_("offset overflow (%+ld)"), val->X_add_number);
1203 }
1204 }
1205 else
1206 {
1207 /* For symbols only, constants are stored at begin of function. */
1208 fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
1209 (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
1210 }
1211 }
1212
1213 static void
1214 emit_word (expressionS * val)
1215 {
1216 emit_data_val (val, (inst_mode & INST_MODE_IL) ? 3 : 2);
1217 }
1218
1219 static void
1220 emit_mx (char prefix, char opcode, int shift, expressionS * arg)
1221 /* The operand m may be r, (hl), (ix+d), (iy+d),
1222 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
1223 {
1224 char *q;
1225 int rnum;
1226
1227 rnum = arg->X_add_number;
1228 switch (arg->X_op)
1229 {
1230 case O_register:
1231 if (arg->X_md)
1232 {
1233 if (rnum != REG_HL)
1234 {
1235 ill_op ();
1236 break;
1237 }
1238 else
1239 rnum = 6;
1240 }
1241 else
1242 {
1243 if ((prefix == 0) && (rnum & R_INDEX))
1244 {
1245 prefix = (rnum & R_IX) ? 0xDD : 0xFD;
1246 if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
1247 check_mach (INS_IDX_HALF);
1248 rnum &= ~R_INDEX;
1249 }
1250 if (rnum > 7)
1251 {
1252 ill_op ();
1253 break;
1254 }
1255 }
1256 q = frag_more (prefix ? 2 : 1);
1257 if (prefix)
1258 * q ++ = prefix;
1259 * q ++ = opcode + (rnum << shift);
1260 break;
1261 case O_md1:
1262 if (ins_ok & INS_GBZ80)
1263 {
1264 ill_op ();
1265 break;
1266 }
1267 q = frag_more (2);
1268 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1269 *q = (prefix) ? prefix : (opcode + (6 << shift));
1270 {
1271 expressionS offset = *arg;
1272 offset.X_op = O_symbol;
1273 offset.X_add_number = 0;
1274 emit_byte (&offset, BFD_RELOC_Z80_DISP8);
1275 }
1276 if (prefix)
1277 {
1278 q = frag_more (1);
1279 *q = opcode+(6<<shift);
1280 }
1281 break;
1282 default:
1283 abort ();
1284 }
1285 }
1286
1287 /* The operand m may be r, (hl), (ix+d), (iy+d),
1288 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
1289 static const char *
1290 emit_m (char prefix, char opcode, const char *args)
1291 {
1292 expressionS arg_m;
1293 const char *p;
1294
1295 p = parse_exp (args, &arg_m);
1296 switch (arg_m.X_op)
1297 {
1298 case O_md1:
1299 case O_register:
1300 emit_mx (prefix, opcode, 0, &arg_m);
1301 break;
1302 default:
1303 ill_op ();
1304 }
1305 return p;
1306 }
1307
1308 /* The operand m may be as above or one of the undocumented
1309 combinations (ix+d),r and (iy+d),r (if unportable instructions
1310 are allowed). */
1311
1312 static const char *
1313 emit_mr (char prefix, char opcode, const char *args)
1314 {
1315 expressionS arg_m, arg_r;
1316 const char *p;
1317
1318 p = parse_exp (args, & arg_m);
1319
1320 switch (arg_m.X_op)
1321 {
1322 case O_md1:
1323 if (*p == ',')
1324 {
1325 p = parse_exp (p + 1, & arg_r);
1326
1327 if ((arg_r.X_md == 0)
1328 && (arg_r.X_op == O_register)
1329 && (arg_r.X_add_number < 8))
1330 opcode += arg_r.X_add_number - 6; /* Emit_mx () will add 6. */
1331 else
1332 {
1333 ill_op ();
1334 break;
1335 }
1336 if (!(ins_ok & INS_Z80N))
1337 check_mach (INS_ROT_II_LD);
1338 }
1339 /* Fall through. */
1340 case O_register:
1341 emit_mx (prefix, opcode, 0, & arg_m);
1342 break;
1343 default:
1344 ill_op ();
1345 }
1346 return p;
1347 }
1348
1349 static void
1350 emit_sx (char prefix, char opcode, expressionS * arg_p)
1351 {
1352 char *q;
1353
1354 switch (arg_p->X_op)
1355 {
1356 case O_register:
1357 case O_md1:
1358 emit_mx (prefix, opcode, 0, arg_p);
1359 break;
1360 default:
1361 if (arg_p->X_md)
1362 ill_op ();
1363 else
1364 {
1365 q = frag_more (prefix ? 2 : 1);
1366 if (prefix)
1367 *q++ = prefix;
1368 *q = opcode ^ 0x46;
1369 emit_byte (arg_p, BFD_RELOC_8);
1370 }
1371 }
1372 }
1373
1374 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
1375 static const char *
1376 emit_s (char prefix, char opcode, const char *args)
1377 {
1378 expressionS arg_s;
1379 const char *p;
1380
1381 p = parse_exp (args, & arg_s);
1382 if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
1383 { /* possible instruction in generic format op A,x */
1384 if (!(ins_ok & INS_EZ80) && !sdcc_compat)
1385 ill_op ();
1386 ++p;
1387 p = parse_exp (p, & arg_s);
1388 }
1389 emit_sx (prefix, opcode, & arg_s);
1390 return p;
1391 }
1392
1393 static const char *
1394 emit_sub (char prefix, char opcode, const char *args)
1395 {
1396 expressionS arg_s;
1397 const char *p;
1398
1399 if (!(ins_ok & INS_GBZ80))
1400 return emit_s (prefix, opcode, args);
1401 p = parse_exp (args, & arg_s);
1402 if (*p++ != ',')
1403 {
1404 error (_("bad instruction syntax"));
1405 return p;
1406 }
1407
1408 if (arg_s.X_md != 0 || arg_s.X_op != O_register || arg_s.X_add_number != REG_A)
1409 ill_op ();
1410
1411 p = parse_exp (p, & arg_s);
1412
1413 emit_sx (prefix, opcode, & arg_s);
1414 return p;
1415 }
1416
1417 static const char *
1418 emit_swap (char prefix, char opcode, const char *args)
1419 {
1420 expressionS reg;
1421 const char *p;
1422 char *q;
1423
1424 if (!(ins_ok & INS_Z80N))
1425 return emit_mr (prefix, opcode, args);
1426
1427 /* check for alias swap a for swapnib of Z80N */
1428 p = parse_exp (args, &reg);
1429 if (reg.X_md != 0 || reg.X_op != O_register || reg.X_add_number != REG_A)
1430 ill_op ();
1431
1432 q = frag_more (2);
1433 *q++ = 0xED;
1434 *q = 0x23;
1435 return p;
1436 }
1437
1438 static const char *
1439 emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1440 {
1441 expressionS addr;
1442 const char *p; char *q;
1443
1444 p = parse_exp_not_indexed (args, &addr);
1445 if (addr.X_md)
1446 ill_op ();
1447 else
1448 {
1449 q = frag_more (1);
1450 *q = opcode;
1451 emit_word (& addr);
1452 }
1453 return p;
1454 }
1455
1456 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
1457 static const char *
1458 emit_incdec (char prefix, char opcode, const char * args)
1459 {
1460 expressionS operand;
1461 int rnum;
1462 const char *p; char *q;
1463
1464 p = parse_exp (args, &operand);
1465 rnum = operand.X_add_number;
1466 if ((! operand.X_md)
1467 && (operand.X_op == O_register)
1468 && (R_ARITH&rnum))
1469 {
1470 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1471 if (rnum & R_INDEX)
1472 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1473 *q = prefix + ((rnum & 3) << 4);
1474 }
1475 else
1476 {
1477 if ((operand.X_op == O_md1) || (operand.X_op == O_register))
1478 emit_mx (0, opcode, 3, & operand);
1479 else
1480 ill_op ();
1481 }
1482 return p;
1483 }
1484
1485 static const char *
1486 emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1487 {
1488 expressionS addr;
1489 const char *p;
1490 char *q;
1491
1492 p = parse_exp_not_indexed (args, &addr);
1493 if (addr.X_md)
1494 ill_op ();
1495 else
1496 {
1497 q = frag_more (1);
1498 *q = opcode;
1499 addr.X_add_number--; /* pcrel computes after offset code */
1500 emit_byte (&addr, BFD_RELOC_8_PCREL);
1501 }
1502 return p;
1503 }
1504
1505 static const char *
1506 emit_jp (char prefix, char opcode, const char * args)
1507 {
1508 expressionS addr;
1509 const char *p;
1510 char *q;
1511 int rnum;
1512
1513 p = parse_exp_not_indexed (args, & addr);
1514 if (addr.X_md)
1515 {
1516 rnum = addr.X_add_number;
1517 if ((O_register == addr.X_op) && (REG_HL == (rnum & ~R_INDEX)))
1518 {
1519 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1520 if (rnum & R_INDEX)
1521 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1522 *q = prefix;
1523 }
1524 else if (addr.X_op == O_register && rnum == REG_C && (ins_ok & INS_Z80N))
1525 {
1526 q = frag_more (2);
1527 *q++ = 0xED;
1528 *q = 0x98;
1529 }
1530 else
1531 ill_op ();
1532 }
1533 else
1534 {
1535 q = frag_more (1);
1536 *q = opcode;
1537 emit_word (& addr);
1538 }
1539 return p;
1540 }
1541
1542 static const char *
1543 emit_im (char prefix, char opcode, const char * args)
1544 {
1545 expressionS mode;
1546 const char *p;
1547 char *q;
1548
1549 p = parse_exp (args, & mode);
1550 if (mode.X_md || (mode.X_op != O_constant))
1551 ill_op ();
1552 else
1553 switch (mode.X_add_number)
1554 {
1555 case 1:
1556 case 2:
1557 ++mode.X_add_number;
1558 /* Fall through. */
1559 case 0:
1560 q = frag_more (2);
1561 *q++ = prefix;
1562 *q = opcode + 8*mode.X_add_number;
1563 break;
1564 default:
1565 ill_op ();
1566 }
1567 return p;
1568 }
1569
1570 static const char *
1571 emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1572 {
1573 expressionS regp;
1574 const char *p;
1575 char *q;
1576
1577 p = parse_exp (args, & regp);
1578 if ((!regp.X_md)
1579 && (regp.X_op == O_register)
1580 && (regp.X_add_number & R_STACKABLE))
1581 {
1582 int rnum;
1583
1584 rnum = regp.X_add_number;
1585 if (rnum&R_INDEX)
1586 {
1587 q = frag_more (2);
1588 *q++ = (rnum&R_IX)?0xDD:0xFD;
1589 }
1590 else
1591 q = frag_more (1);
1592 *q = opcode + ((rnum & 3) << 4);
1593 }
1594 else
1595 ill_op ();
1596
1597 return p;
1598 }
1599
1600 static const char *
1601 emit_push (char prefix, char opcode, const char * args)
1602 {
1603 expressionS arg;
1604 const char *p;
1605 char *q;
1606
1607 p = parse_exp (args, & arg);
1608 if (arg.X_op == O_register)
1609 return emit_pop (prefix, opcode, args);
1610
1611 if (arg.X_md || arg.X_op == O_md1 || !(ins_ok & INS_Z80N))
1612 ill_op ();
1613
1614 q = frag_more (2);
1615 *q++ = 0xED;
1616 *q = 0x8A;
1617
1618 q = frag_more (2);
1619 fix_new_exp (frag_now, q - frag_now->fr_literal, 2, &arg, FALSE,
1620 BFD_RELOC_Z80_16_BE);
1621
1622 return p;
1623 }
1624
1625 static const char *
1626 emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1627 {
1628 char cc, *q;
1629 const char *p;
1630
1631 p = parse_cc (args, &cc);
1632 q = frag_more (1);
1633 if (p)
1634 *q = opcode + cc;
1635 else
1636 *q = prefix;
1637 return p ? p : args;
1638 }
1639
1640 static const char *
1641 emit_adc (char prefix, char opcode, const char * args)
1642 {
1643 expressionS term;
1644 int rnum;
1645 const char *p;
1646 char *q;
1647
1648 p = parse_exp (args, &term);
1649 if (*p++ != ',')
1650 {
1651 error (_("bad instruction syntax"));
1652 return p;
1653 }
1654
1655 if ((term.X_md) || (term.X_op != O_register))
1656 ill_op ();
1657 else
1658 switch (term.X_add_number)
1659 {
1660 case REG_A:
1661 p = emit_s (0, prefix, p);
1662 break;
1663 case REG_HL:
1664 p = parse_exp (p, &term);
1665 if ((!term.X_md) && (term.X_op == O_register))
1666 {
1667 rnum = term.X_add_number;
1668 if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
1669 {
1670 q = frag_more (2);
1671 *q++ = 0xED;
1672 *q = opcode + ((rnum & 3) << 4);
1673 break;
1674 }
1675 }
1676 /* Fall through. */
1677 default:
1678 ill_op ();
1679 }
1680 return p;
1681 }
1682
1683 static const char *
1684 emit_add (char prefix, char opcode, const char * args)
1685 {
1686 expressionS term;
1687 int lhs, rhs;
1688 const char *p;
1689 char *q;
1690
1691 p = parse_exp (args, &term);
1692 if (*p++ != ',')
1693 {
1694 error (_("bad instruction syntax"));
1695 return p;
1696 }
1697
1698 if ((term.X_md) || (term.X_op != O_register))
1699 ill_op ();
1700 else
1701 switch (term.X_add_number)
1702 {
1703 case REG_A:
1704 p = emit_s (0, prefix, p);
1705 break;
1706 case REG_SP:
1707 p = parse_exp (p, &term);
1708 if (!(ins_ok & INS_GBZ80) || term.X_md || term.X_op == O_register)
1709 ill_op ();
1710 q = frag_more (1);
1711 *q = 0xE8;
1712 emit_byte (&term, BFD_RELOC_Z80_DISP8);
1713 break;
1714 case REG_BC:
1715 case REG_DE:
1716 if (!(ins_ok & INS_Z80N))
1717 {
1718 ill_op ();
1719 break;
1720 }
1721 /* Fall through. */
1722 case REG_HL:
1723 case REG_IX:
1724 case REG_IY:
1725 lhs = term.X_add_number;
1726 p = parse_exp (p, &term);
1727 rhs = term.X_add_number;
1728 if (term.X_md != 0 || term.X_op == O_md1)
1729 ill_op ();
1730 else if ((term.X_op == O_register) && (rhs & R_ARITH) && (rhs == lhs || (rhs & ~R_INDEX) != REG_HL))
1731 {
1732 if (1)
1733 {
1734 q = frag_more ((lhs & R_INDEX) ? 2 : 1);
1735 if (lhs & R_INDEX)
1736 *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
1737 *q = opcode + ((rhs & 3) << 4);
1738 break;
1739 }
1740 }
1741 else if (!(lhs & R_INDEX) && (ins_ok & INS_Z80N))
1742 {
1743 if (term.X_op == O_register && rhs == REG_A)
1744 { /* ADD BC/DE/HL,A */
1745 q = frag_more (2);
1746 *q++ = 0xED;
1747 *q = 0x33 - (lhs & 3);
1748 break;
1749 }
1750 else if (term.X_op != O_register && term.X_op != O_md1)
1751 { /* ADD BC/DE/HL,nn */
1752 q = frag_more (2);
1753 *q++ = 0xED;
1754 *q = 0x36 - (lhs & 3);
1755 emit_word (&term);
1756 break;
1757 }
1758 }
1759 /* Fall through. */
1760 default:
1761 ill_op ();
1762 }
1763 return p;
1764 }
1765
1766 static const char *
1767 emit_bit (char prefix, char opcode, const char * args)
1768 {
1769 expressionS b;
1770 int bn;
1771 const char *p;
1772
1773 p = parse_exp (args, &b);
1774 if (*p++ != ',')
1775 error (_("bad instruction syntax"));
1776
1777 bn = b.X_add_number;
1778 if ((!b.X_md)
1779 && (b.X_op == O_constant)
1780 && (0 <= bn)
1781 && (bn < 8))
1782 {
1783 if (opcode == 0x40)
1784 /* Bit : no optional third operand. */
1785 p = emit_m (prefix, opcode + (bn << 3), p);
1786 else
1787 /* Set, res : resulting byte can be copied to register. */
1788 p = emit_mr (prefix, opcode + (bn << 3), p);
1789 }
1790 else
1791 ill_op ();
1792 return p;
1793 }
1794
1795 /* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
1796 static const char *
1797 emit_bshft (char prefix, char opcode, const char * args)
1798 {
1799 expressionS r1, r2;
1800 const char *p;
1801 char *q;
1802
1803 p = parse_exp (args, & r1);
1804 if (*p++ != ',')
1805 error (_("bad instruction syntax"));
1806 p = parse_exp (p, & r2);
1807 if (r1.X_md || r1.X_op != O_register || r1.X_add_number != REG_DE ||
1808 r2.X_md || r2.X_op != O_register || r2.X_add_number != REG_B)
1809 ill_op ();
1810 q = frag_more (2);
1811 *q++ = prefix;
1812 *q = opcode;
1813 return p;
1814 }
1815
1816 static const char *
1817 emit_jpcc (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 p = emit_call (0, opcode + cc, p);
1825 else
1826 p = (prefix == (char)0xC3)
1827 ? emit_jp (0xE9, prefix, args)
1828 : emit_call (0, prefix, args);
1829 return p;
1830 }
1831
1832 static const char *
1833 emit_jrcc (char prefix, char opcode, const char * args)
1834 {
1835 char cc;
1836 const char *p;
1837
1838 p = parse_cc (args, &cc);
1839 if (p && *p++ == ',')
1840 {
1841 if (cc > (3 << 3))
1842 error (_("condition code invalid for jr"));
1843 else
1844 p = emit_jr (0, opcode + cc, p);
1845 }
1846 else
1847 p = emit_jr (0, prefix, args);
1848
1849 return p;
1850 }
1851
1852 static const char *
1853 emit_ex (char prefix_in ATTRIBUTE_UNUSED,
1854 char opcode_in ATTRIBUTE_UNUSED, const char * args)
1855 {
1856 expressionS op;
1857 const char * p;
1858 char prefix, opcode;
1859
1860 p = parse_exp_not_indexed (args, &op);
1861 p = skip_space (p);
1862 if (*p++ != ',')
1863 {
1864 error (_("bad instruction syntax"));
1865 return p;
1866 }
1867
1868 prefix = opcode = 0;
1869 if (op.X_op == O_register)
1870 switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
1871 {
1872 case REG_AF:
1873 if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
1874 {
1875 /* The scrubber changes '\'' to '`' in this context. */
1876 if (*p == '`')
1877 ++p;
1878 opcode = 0x08;
1879 }
1880 break;
1881 case REG_DE:
1882 if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
1883 opcode = 0xEB;
1884 break;
1885 case REG_SP|0x8000:
1886 p = parse_exp (p, & op);
1887 if (op.X_op == O_register
1888 && op.X_md == 0
1889 && (op.X_add_number & ~R_INDEX) == REG_HL)
1890 {
1891 opcode = 0xE3;
1892 if (R_INDEX & op.X_add_number)
1893 prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
1894 }
1895 break;
1896 }
1897 if (opcode)
1898 emit_insn (prefix, opcode, p);
1899 else
1900 ill_op ();
1901
1902 return p;
1903 }
1904
1905 static const char *
1906 emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1907 const char * args)
1908 {
1909 expressionS reg, port;
1910 const char *p;
1911 char *q;
1912
1913 p = parse_exp (args, &reg);
1914 if (reg.X_md && reg.X_op == O_register && reg.X_add_number == REG_C)
1915 { /* permit instruction in (c) as alias for in f,(c) */
1916 port = reg;
1917 reg.X_md = 0;
1918 reg.X_add_number = REG_F;
1919 }
1920 else
1921 {
1922 if (*p++ != ',')
1923 {
1924 error (_("bad instruction syntax"));
1925 return p;
1926 }
1927 p = parse_exp (p, &port);
1928 }
1929 if (reg.X_md == 0
1930 && reg.X_op == O_register
1931 && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
1932 && (port.X_md))
1933 {
1934 if (port.X_op != O_md1 && port.X_op != O_register)
1935 {
1936 if (REG_A == reg.X_add_number)
1937 {
1938 q = frag_more (1);
1939 *q = 0xDB;
1940 emit_byte (&port, BFD_RELOC_8);
1941 }
1942 else
1943 ill_op ();
1944 }
1945 else
1946 {
1947 if (port.X_add_number == REG_C || port.X_add_number == REG_BC)
1948 {
1949 if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
1950 ill_op ();
1951 else if (reg.X_add_number == REG_F && !(ins_ok & (INS_R800|INS_Z80N)))
1952 check_mach (INS_IN_F_C);
1953 q = frag_more (2);
1954 *q++ = 0xED;
1955 *q = 0x40|((reg.X_add_number&7)<<3);
1956 }
1957 else
1958 ill_op ();
1959 }
1960 }
1961 else
1962 ill_op ();
1963 return p;
1964 }
1965
1966 static const char *
1967 emit_in0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1968 const char * args)
1969 {
1970 expressionS reg, port;
1971 const char *p;
1972 char *q;
1973
1974 p = parse_exp (args, &reg);
1975 if (*p++ != ',')
1976 {
1977 error (_("bad instruction syntax"));
1978 return p;
1979 }
1980
1981 p = parse_exp (p, &port);
1982 if (reg.X_md == 0
1983 && reg.X_op == O_register
1984 && reg.X_add_number <= 7
1985 && port.X_md
1986 && port.X_op != O_md1
1987 && port.X_op != O_register)
1988 {
1989 q = frag_more (2);
1990 *q++ = 0xED;
1991 *q = 0x00|(reg.X_add_number << 3);
1992 emit_byte (&port, BFD_RELOC_8);
1993 }
1994 else
1995 ill_op ();
1996 return p;
1997 }
1998
1999 static const char *
2000 emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2001 const char * args)
2002 {
2003 expressionS reg, port;
2004 const char *p;
2005 char *q;
2006
2007 p = parse_exp (args, & port);
2008 if (*p++ != ',')
2009 {
2010 error (_("bad instruction syntax"));
2011 return p;
2012 }
2013 p = parse_exp (p, &reg);
2014 if (!port.X_md)
2015 { ill_op (); return p; }
2016 /* Allow "out (c), 0" as unportable instruction. */
2017 if (reg.X_op == O_constant && reg.X_add_number == 0)
2018 {
2019 if (!(ins_ok & INS_Z80N))
2020 check_mach (INS_OUT_C_0);
2021 reg.X_op = O_register;
2022 reg.X_add_number = 6;
2023 }
2024 if (reg.X_md
2025 || reg.X_op != O_register
2026 || reg.X_add_number > 7)
2027 ill_op ();
2028 else
2029 if (port.X_op != O_register && port.X_op != O_md1)
2030 {
2031 if (REG_A == reg.X_add_number)
2032 {
2033 q = frag_more (1);
2034 *q = 0xD3;
2035 emit_byte (&port, BFD_RELOC_8);
2036 }
2037 else
2038 ill_op ();
2039 }
2040 else
2041 {
2042 if (REG_C == port.X_add_number || port.X_add_number == REG_BC)
2043 {
2044 if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
2045 ill_op ();
2046 q = frag_more (2);
2047 *q++ = 0xED;
2048 *q = 0x41 | (reg.X_add_number << 3);
2049 }
2050 else
2051 ill_op ();
2052 }
2053 return p;
2054 }
2055
2056 static const char *
2057 emit_out0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2058 const char * args)
2059 {
2060 expressionS reg, port;
2061 const char *p;
2062 char *q;
2063
2064 p = parse_exp (args, & port);
2065 if (*p++ != ',')
2066 {
2067 error (_("bad instruction syntax"));
2068 return p;
2069 }
2070 p = parse_exp (p, &reg);
2071 if (port.X_md != 0
2072 && port.X_op != O_register
2073 && port.X_op != O_md1
2074 && reg.X_md == 0
2075 && reg.X_op == O_register
2076 && reg.X_add_number <= 7)
2077 {
2078 q = frag_more (2);
2079 *q++ = 0xED;
2080 *q = 0x01 | (reg.X_add_number << 3);
2081 emit_byte (&port, BFD_RELOC_8);
2082 }
2083 else
2084 ill_op ();
2085 return p;
2086 }
2087
2088 static const char *
2089 emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
2090 {
2091 expressionS addr;
2092 const char *p;
2093 char *q;
2094
2095 p = parse_exp_not_indexed (args, &addr);
2096 if (addr.X_op != O_constant)
2097 {
2098 error ("rst needs constant address");
2099 return p;
2100 }
2101
2102 if (addr.X_add_number & ~(7 << 3))
2103 ill_op ();
2104 else
2105 {
2106 q = frag_more (1);
2107 *q = opcode + (addr.X_add_number & (7 << 3));
2108 }
2109 return p;
2110 }
2111
2112 /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n. */
2113 static void
2114 emit_ld_m_n (expressionS *dst, expressionS *src)
2115 {
2116 char *q;
2117 char prefix;
2118 expressionS dst_offset;
2119
2120 switch (dst->X_add_number)
2121 {
2122 case REG_HL: prefix = 0x00; break;
2123 case REG_IX: prefix = 0xDD; break;
2124 case REG_IY: prefix = 0xFD; break;
2125 default:
2126 ill_op ();
2127 return;
2128 }
2129
2130 q = frag_more (prefix ? 2 : 1);
2131 if (prefix)
2132 *q++ = prefix;
2133 *q = 0x36;
2134 if (prefix)
2135 {
2136 dst_offset = *dst;
2137 dst_offset.X_op = O_symbol;
2138 dst_offset.X_add_number = 0;
2139 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2140 }
2141 emit_byte (src, BFD_RELOC_8);
2142 }
2143
2144 /* For 8-bit load register to memory instructions: LD (<expression>),r. */
2145 static void
2146 emit_ld_m_r (expressionS *dst, expressionS *src)
2147 {
2148 char *q;
2149 char prefix = 0;
2150 expressionS dst_offset;
2151
2152 switch (dst->X_op)
2153 {
2154 case O_md1:
2155 if (ins_ok & INS_GBZ80)
2156 { /* LD (HL+),A or LD (HL-),A */
2157 if (src->X_op != O_register || src->X_add_number != REG_A)
2158 break;
2159 *frag_more (1) = (dst->X_add_number == REG_HL) ? 0x22 : 0x32;
2160 return;
2161 }
2162 else
2163 prefix = (dst->X_add_number == REG_IX) ? 0xDD : 0xFD;
2164 /* Fall through. */
2165 case O_register:
2166 switch (dst->X_add_number)
2167 {
2168 case REG_BC: /* LD (BC),A */
2169 case REG_DE: /* LD (DE),A */
2170 if (src->X_add_number == REG_A)
2171 {
2172 q = frag_more (1);
2173 *q = 0x02 | ((dst->X_add_number & 3) << 4);
2174 return;
2175 }
2176 break;
2177 case REG_IX:
2178 case REG_IY:
2179 case REG_HL: /* LD (HL),r or LD (ii+d),r */
2180 if (src->X_add_number <= 7)
2181 {
2182 q = frag_more (prefix ? 2 : 1);
2183 if (prefix)
2184 *q++ = prefix;
2185 *q = 0x70 | src->X_add_number;
2186 if (prefix)
2187 {
2188 dst_offset = *dst;
2189 dst_offset.X_op = O_symbol;
2190 dst_offset.X_add_number = 0;
2191 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2192 }
2193 return;
2194 }
2195 break;
2196 default:;
2197 }
2198 break;
2199 default: /* LD (nn),A */
2200 if (src->X_add_number == REG_A)
2201 {
2202 q = frag_more (1);
2203 *q = (ins_ok & INS_GBZ80) ? 0xEA : 0x32;
2204 emit_word (dst);
2205 return;
2206 }
2207 break;
2208 }
2209 ill_op ();
2210 }
2211
2212 /* For 16-bit load register to memory instructions: LD (<expression>),rr. */
2213 static void
2214 emit_ld_m_rr (expressionS *dst, expressionS *src)
2215 {
2216 char *q;
2217 int prefix = 0;
2218 int opcode = 0;
2219 expressionS dst_offset;
2220
2221 switch (dst->X_op)
2222 {
2223 case O_md1: /* eZ80 instructions LD (ii+d),rr */
2224 case O_register: /* eZ80 instructions LD (HL),rr */
2225 if (!(ins_ok & INS_EZ80)) /* 16-bit indirect load group is supported by eZ80 only */
2226 ill_op ();
2227 switch (dst->X_add_number)
2228 {
2229 case REG_IX: prefix = 0xDD; break;
2230 case REG_IY: prefix = 0xFD; break;
2231 case REG_HL: prefix = 0xED; break;
2232 default:
2233 ill_op ();
2234 }
2235 switch (src->X_add_number)
2236 {
2237 case REG_BC: opcode = 0x0F; break;
2238 case REG_DE: opcode = 0x1F; break;
2239 case REG_HL: opcode = 0x2F; break;
2240 case REG_IX: opcode = (prefix != 0xFD) ? 0x3F : 0x3E; break;
2241 case REG_IY: opcode = (prefix != 0xFD) ? 0x3E : 0x3F; break;
2242 default:
2243 ill_op ();
2244 }
2245 q = frag_more (prefix ? 2 : 1);
2246 *q++ = prefix;
2247 *q = opcode;
2248 if (prefix == 0xFD || prefix == 0xDD)
2249 {
2250 dst_offset = *dst;
2251 dst_offset.X_op = O_symbol;
2252 dst_offset.X_add_number = 0;
2253 emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
2254 }
2255 break;
2256 default: /* LD (nn),rr */
2257 if (ins_ok & INS_GBZ80)
2258 {
2259 /* GBZ80 supports only LD (nn),SP */
2260 if (src->X_add_number == REG_SP)
2261 {
2262 prefix = 0x00;
2263 opcode = 0x08;
2264 }
2265 else
2266 ill_op ();
2267 }
2268 else
2269 {
2270 switch (src->X_add_number)
2271 {
2272 case REG_BC: prefix = 0xED; opcode = 0x43; break;
2273 case REG_DE: prefix = 0xED; opcode = 0x53; break;
2274 case REG_HL: prefix = 0x00; opcode = 0x22; break;
2275 case REG_IX: prefix = 0xDD; opcode = 0x22; break;
2276 case REG_IY: prefix = 0xFD; opcode = 0x22; break;
2277 case REG_SP: prefix = 0xED; opcode = 0x73; break;
2278 default:
2279 ill_op ();
2280 }
2281 }
2282 q = frag_more (prefix ? 2 : 1);
2283 if (prefix)
2284 *q++ = prefix;
2285 *q = opcode;
2286 emit_word (dst);
2287 }
2288 }
2289
2290 static void
2291 emit_ld_r_m (expressionS *dst, expressionS *src)
2292 { /* for 8-bit memory load to register: LD r,(xxx) */
2293 char *q;
2294 char prefix = 0;
2295 char opcode = 0;
2296 expressionS src_offset;
2297
2298 if (dst->X_add_number == REG_A && src->X_op == O_register)
2299 { /* LD A,(BC) or LD A,(DE) */
2300 switch (src->X_add_number)
2301 {
2302 case REG_BC: opcode = 0x0A; break;
2303 case REG_DE: opcode = 0x1A; break;
2304 default: break;
2305 }
2306 if (opcode != 0)
2307 {
2308 q = frag_more (1);
2309 *q = opcode;
2310 return;
2311 }
2312 }
2313
2314 switch (src->X_op)
2315 {
2316 case O_md1:
2317 if (ins_ok & INS_GBZ80)
2318 { /* LD A,(HL+) or LD A,(HL-) */
2319 if (dst->X_op == O_register && dst->X_add_number == REG_A)
2320 *frag_more (1) = (src->X_add_number == REG_HL) ? 0x2A : 0x3A;
2321 else
2322 ill_op ();
2323 break;
2324 }
2325 /* Fall through. */
2326 case O_register:
2327 if (dst->X_add_number > 7)
2328 ill_op ();
2329 opcode = 0x46; /* LD B,(HL) */
2330 switch (src->X_add_number)
2331 {
2332 case REG_HL: prefix = 0x00; break;
2333 case REG_IX: prefix = 0xDD; break;
2334 case REG_IY: prefix = 0xFD; break;
2335 default:
2336 ill_op ();
2337 }
2338 q = frag_more (prefix ? 2 : 1);
2339 if (prefix)
2340 *q++ = prefix;
2341 *q = opcode | ((dst->X_add_number & 7) << 3);
2342 if (prefix)
2343 {
2344 src_offset = *src;
2345 src_offset.X_op = O_symbol;
2346 src_offset.X_add_number = 0;
2347 emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
2348 }
2349 break;
2350 default: /* LD A,(nn) */
2351 if (dst->X_add_number == REG_A)
2352 {
2353 q = frag_more (1);
2354 *q = (ins_ok & INS_GBZ80) ? 0xFA : 0x3A;
2355 emit_word (src);
2356 }
2357 }
2358 }
2359
2360 static void
2361 emit_ld_r_n (expressionS *dst, expressionS *src)
2362 { /* for 8-bit immediate value load to register: LD r,n */
2363 char *q;
2364 char prefix = 0;
2365
2366 switch (dst->X_add_number)
2367 {
2368 case REG_H|R_IX:
2369 case REG_L|R_IX:
2370 prefix = 0xDD;
2371 break;
2372 case REG_H|R_IY:
2373 case REG_L|R_IY:
2374 prefix = 0xFD;
2375 break;
2376 case REG_A:
2377 case REG_B:
2378 case REG_C:
2379 case REG_D:
2380 case REG_E:
2381 case REG_H:
2382 case REG_L:
2383 break;
2384 default:
2385 ill_op ();
2386 // return;
2387 }
2388
2389 q = frag_more (prefix ? 2 : 1);
2390 if (prefix)
2391 {
2392 if (ins_ok & INS_GBZ80)
2393 ill_op ();
2394 else if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
2395 check_mach (INS_IDX_HALF);
2396 *q++ = prefix;
2397 }
2398 *q = 0x06 | ((dst->X_add_number & 7) << 3);
2399 emit_byte (src, BFD_RELOC_8);
2400 }
2401
2402 static void
2403 emit_ld_r_r (expressionS *dst, expressionS *src)
2404 { /* mostly 8-bit load register from register instructions: LD r,r */
2405 /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
2406 char *q;
2407 int prefix = 0;
2408 int opcode = 0;
2409 int ii_halves = 0;
2410
2411 switch (dst->X_add_number)
2412 {
2413 case REG_SP:
2414 switch (src->X_add_number)
2415 {
2416 case REG_HL: prefix = 0x00; break;
2417 case REG_IX: prefix = 0xDD; break;
2418 case REG_IY: prefix = 0xFD; break;
2419 default:
2420 ill_op ();
2421 }
2422 opcode = 0xF9;
2423 break;
2424 case REG_HL:
2425 if (!(ins_ok & INS_EZ80))
2426 ill_op ();
2427 if (src->X_add_number != REG_I)
2428 ill_op ();
2429 if (cpu_mode < 1)
2430 error (_("ADL mode instruction"));
2431 /* LD HL,I */
2432 prefix = 0xED;
2433 opcode = 0xD7;
2434 break;
2435 case REG_I:
2436 if (src->X_add_number == REG_HL)
2437 {
2438 if (!(ins_ok & INS_EZ80))
2439 ill_op ();
2440 if (cpu_mode < 1)
2441 error (_("ADL mode instruction"));
2442 prefix = 0xED;
2443 opcode = 0xC7;
2444 }
2445 else if (src->X_add_number == REG_A)
2446 {
2447 prefix = 0xED;
2448 opcode = 0x47;
2449 }
2450 else
2451 ill_op ();
2452 break;
2453 case REG_MB:
2454 if (!(ins_ok & INS_EZ80) || (src->X_add_number != REG_A))
2455 ill_op ();
2456 if (cpu_mode < 1)
2457 error (_("ADL mode instruction"));
2458 prefix = 0xED;
2459 opcode = 0x6D;
2460 break;
2461 case REG_R:
2462 if (src->X_add_number == REG_A) /* LD R,A */
2463 {
2464 prefix = 0xED;
2465 opcode = 0x4F;
2466 }
2467 else
2468 ill_op ();
2469 break;
2470 case REG_A:
2471 if (src->X_add_number == REG_I) /* LD A,I */
2472 {
2473 prefix = 0xED;
2474 opcode = 0x57;
2475 break;
2476 }
2477 else if (src->X_add_number == REG_R) /* LD A,R */
2478 {
2479 prefix = 0xED;
2480 opcode = 0x5F;
2481 break;
2482 }
2483 else if (src->X_add_number == REG_MB) /* LD A,MB */
2484 {
2485 if (!(ins_ok & INS_EZ80))
2486 ill_op ();
2487 else
2488 {
2489 if (cpu_mode < 1)
2490 error (_("ADL mode instruction"));
2491 prefix = 0xED;
2492 opcode = 0x6E;
2493 }
2494 break;
2495 }
2496 /* Fall through. */
2497 case REG_B:
2498 case REG_C:
2499 case REG_D:
2500 case REG_E:
2501 case REG_H:
2502 case REG_L:
2503 prefix = 0x00;
2504 break;
2505 case REG_H|R_IX:
2506 case REG_L|R_IX:
2507 prefix = 0xDD;
2508 ii_halves = 1;
2509 break;
2510 case REG_H|R_IY:
2511 case REG_L|R_IY:
2512 prefix = 0xFD;
2513 ii_halves = 1;
2514 break;
2515 default:
2516 ill_op ();
2517 }
2518
2519 if (opcode == 0)
2520 {
2521 switch (src->X_add_number)
2522 {
2523 case REG_A:
2524 case REG_B:
2525 case REG_C:
2526 case REG_D:
2527 case REG_E:
2528 break;
2529 case REG_H:
2530 case REG_L:
2531 if (prefix != 0)
2532 ill_op (); /* LD iiH/L,H/L are not permitted */
2533 break;
2534 case REG_H|R_IX:
2535 case REG_L|R_IX:
2536 if (prefix == 0xFD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
2537 ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
2538 prefix = 0xDD;
2539 ii_halves = 1;
2540 break;
2541 case REG_H|R_IY:
2542 case REG_L|R_IY:
2543 if (prefix == 0xDD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
2544 ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
2545 prefix = 0xFD;
2546 ii_halves = 1;
2547 break;
2548 default:
2549 ill_op ();
2550 }
2551 opcode = 0x40 + ((dst->X_add_number & 7) << 3) + (src->X_add_number & 7);
2552 }
2553 if ((ins_ok & INS_GBZ80) && prefix != 0)
2554 ill_op ();
2555 if (ii_halves && !(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
2556 check_mach (INS_IDX_HALF);
2557 if (prefix == 0 && (ins_ok & INS_EZ80))
2558 {
2559 switch (opcode)
2560 {
2561 case 0x40: /* SIS prefix, in Z80 it is LD B,B */
2562 case 0x49: /* LIS prefix, in Z80 it is LD C,C */
2563 case 0x52: /* SIL prefix, in Z80 it is LD D,D */
2564 case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
2565 as_warn (_("unsupported instruction, assembled as NOP"));
2566 opcode = 0x00;
2567 break;
2568 default:;
2569 }
2570 }
2571 q = frag_more (prefix ? 2 : 1);
2572 if (prefix)
2573 *q++ = prefix;
2574 *q = opcode;
2575 }
2576
2577 static void
2578 emit_ld_rr_m (expressionS *dst, expressionS *src)
2579 { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
2580 char *q;
2581 int prefix = 0;
2582 int opcode = 0;
2583 expressionS src_offset;
2584
2585 /* GBZ80 has no support for 16-bit load from memory instructions */
2586 if (ins_ok & INS_GBZ80)
2587 ill_op ();
2588
2589 prefix = 0xED;
2590 switch (src->X_op)
2591 {
2592 case O_md1: /* LD rr,(ii+d) */
2593 prefix = (src->X_add_number == REG_IX) ? 0xDD : 0xFD;
2594 /* Fall through. */
2595 case O_register: /* LD rr,(HL) */
2596 /* currently only EZ80 has support for 16bit indirect memory load instructions */
2597 if (!(ins_ok & INS_EZ80))
2598 ill_op ();
2599 switch (dst->X_add_number)
2600 {
2601 case REG_BC: opcode = 0x07; break;
2602 case REG_DE: opcode = 0x17; break;
2603 case REG_HL: opcode = 0x27; break;
2604 case REG_IX: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x37 : 0x31; break;
2605 case REG_IY: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x31 : 0x37; break;
2606 default:
2607 ill_op ();
2608 }
2609 q = frag_more (2);
2610 *q++ = prefix;
2611 *q = opcode;
2612 if (prefix != 0xED)
2613 {
2614 src_offset = *src;
2615 src_offset.X_op = O_symbol;
2616 src_offset.X_add_number = 0;
2617 emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
2618 }
2619 break;
2620 default: /* LD rr,(nn) */
2621 switch (dst->X_add_number)
2622 {
2623 case REG_BC: prefix = 0xED; opcode = 0x4B; break;
2624 case REG_DE: prefix = 0xED; opcode = 0x5B; break;
2625 case REG_HL: prefix = 0x00; opcode = 0x2A; break;
2626 case REG_SP: prefix = 0xED; opcode = 0x7B; break;
2627 case REG_IX: prefix = 0xDD; opcode = 0x2A; break;
2628 case REG_IY: prefix = 0xFD; opcode = 0x2A; break;
2629 default:
2630 ill_op ();
2631 }
2632 q = frag_more (prefix ? 2 : 1);
2633 if (prefix)
2634 *q++ = prefix;
2635 *q = opcode;
2636 emit_word (src);
2637 }
2638 return;
2639 }
2640
2641 static void
2642 emit_ld_rr_nn (expressionS *dst, expressionS *src)
2643 { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
2644 char *q;
2645 int prefix = 0x00;
2646 int opcode = 0x21; /* LD HL,nn */
2647 switch (dst->X_add_number)
2648 {
2649 case REG_IX:
2650 prefix = 0xDD;
2651 break;
2652 case REG_IY:
2653 prefix = 0xFD;
2654 break;
2655 case REG_HL:
2656 break;
2657 case REG_BC:
2658 case REG_DE:
2659 case REG_SP:
2660 opcode = 0x01 + ((dst->X_add_number & 3) << 4);
2661 break;
2662 default:
2663 ill_op ();
2664 return;
2665 }
2666 if (prefix && (ins_ok & INS_GBZ80))
2667 ill_op ();
2668 q = frag_more (prefix ? 2 : 1);
2669 if (prefix)
2670 *q++ = prefix;
2671 *q = opcode;
2672 emit_word (src);
2673 }
2674
2675 static const char *
2676 emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
2677 const char * args)
2678 {
2679 expressionS dst, src;
2680 const char *p;
2681
2682 p = parse_exp (args, & dst);
2683 if (*p++ != ',')
2684 error (_("bad instruction syntax"));
2685 p = parse_exp (p, & src);
2686
2687 if (dst.X_md)
2688 {
2689 if (src.X_op == O_register)
2690 {
2691 if (src.X_add_number <= 7)
2692 emit_ld_m_r (& dst, & src); /* LD (xxx),r */
2693 else
2694 emit_ld_m_rr (& dst, & src); /* LD (xxx),rr */
2695 }
2696 else
2697 emit_ld_m_n (& dst, & src); /* LD (hl),n or LD (ix/y+r),n */
2698 }
2699 else if (dst.X_op == O_register)
2700 {
2701 if (src.X_md)
2702 {
2703 if (dst.X_add_number <= 7)
2704 emit_ld_r_m (& dst, & src);
2705 else
2706 emit_ld_rr_m (& dst, & src);
2707 }
2708 else if (src.X_op == O_register)
2709 emit_ld_r_r (& dst, & src);
2710 else if ((dst.X_add_number & ~R_INDEX) <= 7)
2711 emit_ld_r_n (& dst, & src);
2712 else
2713 emit_ld_rr_nn (& dst, & src);
2714 }
2715 else
2716 ill_op ();
2717
2718 return p;
2719 }
2720
2721 static const char *
2722 emit_lddldi (char prefix, char opcode, const char * args)
2723 {
2724 expressionS dst, src;
2725 const char *p;
2726 char *q;
2727
2728 if (!(ins_ok & INS_GBZ80))
2729 return emit_insn (prefix, opcode, args);
2730
2731 p = parse_exp (args, & dst);
2732 if (*p++ != ',')
2733 error (_("bad instruction syntax"));
2734 p = parse_exp (p, & src);
2735
2736 if (dst.X_op != O_register || src.X_op != O_register)
2737 ill_op ();
2738
2739 /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
2740 opcode = (opcode & 0x08) * 2 + 0x22;
2741
2742 if (dst.X_md != 0
2743 && dst.X_add_number == REG_HL
2744 && src.X_md == 0
2745 && src.X_add_number == REG_A)
2746 opcode |= 0x00; /* LDx (HL),A */
2747 else if (dst.X_md == 0
2748 && dst.X_add_number == REG_A
2749 && src.X_md != 0
2750 && src.X_add_number == REG_HL)
2751 opcode |= 0x08; /* LDx A,(HL) */
2752 else
2753 ill_op ();
2754
2755 q = frag_more (1);
2756 *q = opcode;
2757 return p;
2758 }
2759
2760 static const char *
2761 emit_ldh (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
2762 const char * args)
2763 {
2764 expressionS dst, src;
2765 const char *p;
2766 char *q;
2767
2768 p = parse_exp (args, & dst);
2769 if (*p++ != ',')
2770 {
2771 error (_("bad instruction syntax"));
2772 return p;
2773 }
2774
2775 p = parse_exp (p, & src);
2776 if (dst.X_md == 0
2777 && dst.X_op == O_register
2778 && dst.X_add_number == REG_A
2779 && src.X_md != 0
2780 && src.X_op != O_md1)
2781 {
2782 if (src.X_op != O_register)
2783 {
2784 q = frag_more (1);
2785 *q = 0xF0;
2786 emit_byte (& src, BFD_RELOC_8);
2787 }
2788 else if (src.X_add_number == REG_C)
2789 *frag_more (1) = 0xF2;
2790 else
2791 ill_op ();
2792 }
2793 else if (dst.X_md != 0
2794 && dst.X_op != O_md1
2795 && src.X_md == 0
2796 && src.X_op == O_register
2797 && src.X_add_number == REG_A)
2798 {
2799 if (dst.X_op == O_register)
2800 {
2801 if (dst.X_add_number == REG_C)
2802 {
2803 q = frag_more (1);
2804 *q = 0xE2;
2805 }
2806 else
2807 ill_op ();
2808 }
2809 else
2810 {
2811 q = frag_more (1);
2812 *q = 0xE0;
2813 emit_byte (& dst, BFD_RELOC_8);
2814 }
2815 }
2816 else
2817 ill_op ();
2818
2819 return p;
2820 }
2821
2822 static const char *
2823 emit_ldhl (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
2824 {
2825 expressionS dst, src;
2826 const char *p;
2827 char *q;
2828 p = parse_exp (args, & dst);
2829 if (*p++ != ',')
2830 {
2831 error (_("bad instruction syntax"));
2832 return p;
2833 }
2834
2835 p = parse_exp (p, & src);
2836 if (dst.X_md || dst.X_op != O_register || dst.X_add_number != REG_SP
2837 || src.X_md || src.X_op == O_register || src.X_op == O_md1)
2838 ill_op ();
2839 q = frag_more (1);
2840 *q = opcode;
2841 emit_byte (& src, BFD_RELOC_Z80_DISP8);
2842 return p;
2843 }
2844
2845 static const char *
2846 parse_lea_pea_args (const char * args, expressionS *op)
2847 {
2848 const char *p;
2849 p = parse_exp (args, op);
2850 if (sdcc_compat && *p == ',' && op->X_op == O_register)
2851 {
2852 expressionS off;
2853 p = parse_exp (p + 1, &off);
2854 op->X_op = O_add;
2855 op->X_add_symbol = make_expr_symbol (&off);
2856 }
2857 return p;
2858 }
2859
2860 static const char *
2861 emit_lea (char prefix, char opcode, const char * args)
2862 {
2863 expressionS dst, src;
2864 const char *p;
2865 char *q;
2866 int rnum;
2867
2868 p = parse_exp (args, & dst);
2869 if (dst.X_md != 0 || dst.X_op != O_register)
2870 ill_op ();
2871
2872 rnum = dst.X_add_number;
2873 switch (rnum)
2874 {
2875 case REG_BC:
2876 case REG_DE:
2877 case REG_HL:
2878 opcode = 0x02 | ((rnum & 0x03) << 4);
2879 break;
2880 case REG_IX:
2881 opcode = 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
2882 break;
2883 case REG_IY:
2884 opcode = 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
2885 break;
2886 default:
2887 ill_op ();
2888 }
2889
2890 if (*p++ != ',')
2891 error (_("bad instruction syntax"));
2892
2893 p = parse_lea_pea_args (p, & src);
2894 if (src.X_md != 0 || src.X_op != O_add /*&& src.X_op != O_register*/)
2895 ill_op ();
2896
2897 rnum = src.X_add_number;
2898 switch (src.X_op)
2899 {
2900 case O_add:
2901 break;
2902 case O_register: /* permit instructions like LEA rr,IX without displacement specified */
2903 src.X_add_symbol = zero;
2904 break;
2905 default:
2906 ill_op ();
2907 }
2908
2909 switch (rnum)
2910 {
2911 case REG_IX:
2912 opcode = (opcode == (char)0x33) ? 0x55 : (opcode|0x00);
2913 break;
2914 case REG_IY:
2915 opcode = (opcode == (char)0x32) ? 0x54 : (opcode|0x01);
2916 }
2917
2918 q = frag_more (2);
2919 *q++ = prefix;
2920 *q = opcode;
2921
2922 src.X_op = O_symbol;
2923 src.X_add_number = 0;
2924 emit_byte (& src, BFD_RELOC_Z80_DISP8);
2925
2926 return p;
2927 }
2928
2929 static const char *
2930 emit_mlt (char prefix, char opcode, const char * args)
2931 {
2932 expressionS arg;
2933 const char *p;
2934 char *q;
2935
2936 p = parse_exp (args, & arg);
2937 if (arg.X_md != 0 || arg.X_op != O_register || !(arg.X_add_number & R_ARITH))
2938 ill_op ();
2939
2940 q = frag_more (2);
2941 if (ins_ok & INS_Z80N)
2942 {
2943 if (arg.X_add_number != REG_DE)
2944 ill_op ();
2945 *q++ = 0xED;
2946 *q = 0x30;
2947 }
2948 else
2949 {
2950 *q++ = prefix;
2951 *q = opcode | ((arg.X_add_number & 3) << 4);
2952 }
2953
2954 return p;
2955 }
2956
2957 /* MUL D,E (Z80N only) */
2958 static const char *
2959 emit_mul (char prefix, char opcode, const char * args)
2960 {
2961 expressionS r1, r2;
2962 const char *p;
2963 char *q;
2964
2965 p = parse_exp (args, & r1);
2966 if (*p++ != ',')
2967 error (_("bad instruction syntax"));
2968 p = parse_exp (p, & r2);
2969
2970 if (r1.X_md != 0 || r1.X_op != O_register || r1.X_add_number != REG_D ||
2971 r2.X_md != 0 || r2.X_op != O_register || r2.X_add_number != REG_E)
2972 ill_op ();
2973
2974 q = frag_more (2);
2975 *q++ = prefix;
2976 *q = opcode;
2977
2978 return p;
2979 }
2980
2981 static const char *
2982 emit_nextreg (char prefix, char opcode ATTRIBUTE_UNUSED, const char * args)
2983 {
2984 expressionS rr, nn;
2985 const char *p;
2986 char *q;
2987
2988 p = parse_exp (args, & rr);
2989 if (*p++ != ',')
2990 error (_("bad instruction syntax"));
2991 p = parse_exp (p, & nn);
2992 if (rr.X_md != 0 || rr.X_op == O_register || rr.X_op == O_md1 ||
2993 nn.X_md != 0 || nn.X_op == O_md1)
2994 ill_op ();
2995 q = frag_more (2);
2996 *q++ = prefix;
2997 emit_byte (&rr, BFD_RELOC_8);
2998 if (nn.X_op == O_register && nn.X_add_number == REG_A)
2999 *q = 0x92;
3000 else if (nn.X_op != O_register)
3001 {
3002 *q = 0x91;
3003 emit_byte (&nn, BFD_RELOC_8);
3004 }
3005 else
3006 ill_op ();
3007 return p;
3008 }
3009
3010 static const char *
3011 emit_pea (char prefix, char opcode, const char * args)
3012 {
3013 expressionS arg;
3014 const char *p;
3015 char *q;
3016
3017 p = parse_lea_pea_args (args, & arg);
3018 if (arg.X_md != 0
3019 || (/*arg.X_op != O_register &&*/ arg.X_op != O_add)
3020 || !(arg.X_add_number & R_INDEX))
3021 ill_op ();
3022 /* PEA ii without displacement is mostly typo,
3023 because there is PUSH instruction which is shorter and faster */
3024 /*if (arg.X_op == O_register)
3025 as_warn (_("PEA is used without displacement, use PUSH instead"));*/
3026
3027 q = frag_more (2);
3028 *q++ = prefix;
3029 *q = opcode + (arg.X_add_number == REG_IY ? 1 : 0);
3030
3031 arg.X_op = O_symbol;
3032 arg.X_add_number = 0;
3033 emit_byte (& arg, BFD_RELOC_Z80_DISP8);
3034
3035 return p;
3036 }
3037
3038 static const char *
3039 emit_reti (char prefix, char opcode, const char * args)
3040 {
3041 if (ins_ok & INS_GBZ80)
3042 return emit_insn (0x00, 0xD9, args);
3043
3044 return emit_insn (prefix, opcode, args);
3045 }
3046
3047 static const char *
3048 emit_tst (char prefix, char opcode, const char *args)
3049 {
3050 expressionS arg_s;
3051 const char *p;
3052 char *q;
3053 int rnum;
3054
3055 p = parse_exp (args, & arg_s);
3056 if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
3057 {
3058 if (!(ins_ok & INS_EZ80))
3059 ill_op ();
3060 ++p;
3061 p = parse_exp (p, & arg_s);
3062 }
3063
3064 rnum = arg_s.X_add_number;
3065 switch (arg_s.X_op)
3066 {
3067 case O_md1:
3068 ill_op ();
3069 break;
3070 case O_register:
3071 rnum = arg_s.X_add_number;
3072 if (arg_s.X_md != 0)
3073 {
3074 if (rnum != REG_HL)
3075 ill_op ();
3076 else
3077 rnum = 6;
3078 }
3079 q = frag_more (2);
3080 *q++ = prefix;
3081 *q = opcode | (rnum << 3);
3082 break;
3083 default:
3084 if (arg_s.X_md)
3085 ill_op ();
3086 q = frag_more (2);
3087 if (ins_ok & INS_Z80N)
3088 {
3089 *q++ = 0xED;
3090 *q = 0x27;
3091 }
3092 else
3093 {
3094 *q++ = prefix;
3095 *q = opcode | 0x60;
3096 }
3097 emit_byte (& arg_s, BFD_RELOC_8);
3098 }
3099 return p;
3100 }
3101
3102 static const char *
3103 emit_insn_n (char prefix, char opcode, const char *args)
3104 {
3105 expressionS arg;
3106 const char *p;
3107 char *q;
3108
3109 p = parse_exp (args, & arg);
3110 if (arg.X_md || arg.X_op == O_register || arg.X_op == O_md1)
3111 ill_op ();
3112
3113 q = frag_more (2);
3114 *q++ = prefix;
3115 *q = opcode;
3116 emit_byte (& arg, BFD_RELOC_8);
3117
3118 return p;
3119 }
3120
3121 static void
3122 emit_data (int size ATTRIBUTE_UNUSED)
3123 {
3124 const char *p, *q;
3125 char *u, quote;
3126 int cnt;
3127 expressionS exp;
3128
3129 if (is_it_end_of_statement ())
3130 {
3131 demand_empty_rest_of_line ();
3132 return;
3133 }
3134 p = skip_space (input_line_pointer);
3135
3136 do
3137 {
3138 if (*p == '\"' || *p == '\'')
3139 {
3140 for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
3141 ;
3142 u = frag_more (cnt);
3143 memcpy (u, q, cnt);
3144 if (!*p)
3145 as_warn (_("unterminated string"));
3146 else
3147 p = skip_space (p+1);
3148 }
3149 else
3150 {
3151 p = parse_exp (p, &exp);
3152 if (exp.X_op == O_md1 || exp.X_op == O_register)
3153 {
3154 ill_op ();
3155 break;
3156 }
3157 if (exp.X_md)
3158 as_warn (_("parentheses ignored"));
3159 emit_byte (&exp, BFD_RELOC_8);
3160 p = skip_space (p);
3161 }
3162 }
3163 while (*p++ == ',') ;
3164 input_line_pointer = (char *)(p-1);
3165 }
3166
3167 static void
3168 z80_cons (int size)
3169 {
3170 const char *p;
3171 expressionS exp;
3172
3173 if (is_it_end_of_statement ())
3174 {
3175 demand_empty_rest_of_line ();
3176 return;
3177 }
3178 p = skip_space (input_line_pointer);
3179
3180 do
3181 {
3182 p = parse_exp (p, &exp);
3183 if (exp.X_op == O_md1 || exp.X_op == O_register)
3184 {
3185 ill_op ();
3186 break;
3187 }
3188 if (exp.X_md)
3189 as_warn (_("parentheses ignored"));
3190 emit_data_val (&exp, size);
3191 p = skip_space (p);
3192 } while (*p++ == ',') ;
3193 input_line_pointer = (char *)(p-1);
3194 }
3195
3196 /* next functions were commented out because it is difficult to mix
3197 both ADL and Z80 mode instructions within one COFF file:
3198 objdump cannot recognize point of mode switching.
3199 */
3200 static void
3201 set_cpu_mode (int mode)
3202 {
3203 if (ins_ok & INS_EZ80)
3204 cpu_mode = mode;
3205 else
3206 error (_("CPU mode is unsupported by target"));
3207 }
3208
3209 static void
3210 assume (int arg ATTRIBUTE_UNUSED)
3211 {
3212 char *name;
3213 char c;
3214 int n;
3215
3216 input_line_pointer = (char*)skip_space (input_line_pointer);
3217 c = get_symbol_name (& name);
3218 if (strncasecmp (name, "ADL", 4) != 0)
3219 {
3220 ill_op ();
3221 return;
3222 }
3223
3224 restore_line_pointer (c);
3225 input_line_pointer = (char*)skip_space (input_line_pointer);
3226 if (*input_line_pointer++ != '=')
3227 {
3228 error (_("assignment expected"));
3229 return;
3230 }
3231 input_line_pointer = (char*)skip_space (input_line_pointer);
3232 n = get_single_number ();
3233
3234 set_cpu_mode (n);
3235 }
3236
3237 static const char *
3238 emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
3239 {
3240 const char *p;
3241
3242 p = skip_space (args);
3243 if (TOLOWER (*p++) != 'a' || *p++ != ',')
3244 ill_op ();
3245 else
3246 {
3247 char *q, reg;
3248
3249 reg = TOLOWER (*p++);
3250 switch (reg)
3251 {
3252 case 'b':
3253 case 'c':
3254 case 'd':
3255 case 'e':
3256 check_mach (INS_R800);
3257 if (!*skip_space (p))
3258 {
3259 q = frag_more (2);
3260 *q++ = prefix;
3261 *q = opcode + ((reg - 'b') << 3);
3262 break;
3263 }
3264 /* Fall through. */
3265 default:
3266 ill_op ();
3267 }
3268 }
3269 return p;
3270 }
3271
3272 static const char *
3273 emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
3274 {
3275 const char *p;
3276
3277 p = skip_space (args);
3278 if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
3279 ill_op ();
3280 else
3281 {
3282 expressionS reg;
3283 char *q;
3284
3285 p = parse_exp (p, & reg);
3286
3287 if ((!reg.X_md) && reg.X_op == O_register)
3288 switch (reg.X_add_number)
3289 {
3290 case REG_BC:
3291 case REG_SP:
3292 check_mach (INS_R800);
3293 q = frag_more (2);
3294 *q++ = prefix;
3295 *q = opcode + ((reg.X_add_number & 3) << 4);
3296 break;
3297 default:
3298 ill_op ();
3299 }
3300 }
3301 return p;
3302 }
3303
3304 static int
3305 assemble_suffix (const char **suffix)
3306 {
3307 static
3308 const char sf[8][4] =
3309 {
3310 "il",
3311 "is",
3312 "l",
3313 "lil",
3314 "lis",
3315 "s",
3316 "sil",
3317 "sis"
3318 };
3319 const char *p;
3320 const char (*t)[4];
3321 char sbuf[4];
3322 int i;
3323
3324 p = *suffix;
3325 if (*p++ != '.')
3326 return 0;
3327
3328 for (i = 0; (i < 3) && (ISALPHA (*p)); i++)
3329 sbuf[i] = TOLOWER (*p++);
3330 if (*p && !ISSPACE (*p))
3331 return 0;
3332 *suffix = p;
3333 sbuf[i] = 0;
3334
3335 t = bsearch (sbuf, sf, ARRAY_SIZE (sf), sizeof (sf[0]), (int(*)(const void*, const void*)) strcmp);
3336 if (t == NULL)
3337 return 0;
3338 i = t - sf;
3339 switch (i)
3340 {
3341 case 0: /* IL */
3342 i = cpu_mode ? 0x5B : 0x52;
3343 break;
3344 case 1: /* IS */
3345 i = cpu_mode ? 0x49 : 0x40;
3346 break;
3347 case 2: /* L */
3348 i = cpu_mode ? 0x5B : 0x49;
3349 break;
3350 case 3: /* LIL */
3351 i = 0x5B;
3352 break;
3353 case 4: /* LIS */
3354 i = 0x49;
3355 break;
3356 case 5: /* S */
3357 i = cpu_mode ? 0x52 : 0x40;
3358 break;
3359 case 6: /* SIL */
3360 i = 0x52;
3361 break;
3362 case 7: /* SIS */
3363 i = 0x40;
3364 break;
3365 }
3366 *frag_more (1) = (char)i;
3367 switch (i)
3368 {
3369 case 0x40: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IS; break;
3370 case 0x49: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IS; break;
3371 case 0x52: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IL; break;
3372 case 0x5B: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IL; break;
3373 }
3374 return 1;
3375 }
3376
3377 static void
3378 psect (int arg)
3379 {
3380 #if defined(OBJ_ELF)
3381 return obj_elf_section (arg);
3382 #elif defined(OBJ_COFF)
3383 return obj_coff_section (arg);
3384 #else
3385 #error Unknown object format
3386 #endif
3387 }
3388
3389 static void
3390 set_inss (int inss)
3391 {
3392 int old_ins;
3393
3394 if (!sdcc_compat)
3395 as_fatal (_("Invalid directive"));
3396
3397 old_ins = ins_ok;
3398 ins_ok &= INS_MARCH_MASK;
3399 ins_ok |= inss;
3400 if (old_ins != ins_ok)
3401 cpu_mode = 0;
3402 }
3403
3404 static void
3405 ignore (int arg ATTRIBUTE_UNUSED)
3406 {
3407 ignore_rest_of_line ();
3408 }
3409
3410 static void
3411 area (int arg)
3412 {
3413 char *p;
3414 if (!sdcc_compat)
3415 as_fatal (_("Invalid directive"));
3416 for (p = input_line_pointer; *p && *p != '(' && *p != '\n'; p++)
3417 ;
3418 if (*p == '(')
3419 {
3420 *p = '\n';
3421 psect (arg);
3422 *p++ = '(';
3423 ignore_rest_of_line ();
3424 }
3425 else
3426 psect (arg);
3427 }
3428
3429 /* Port specific pseudo ops. */
3430 const pseudo_typeS md_pseudo_table[] =
3431 {
3432 { ".area", area, 0},
3433 { ".assume", assume, 0},
3434 { ".ez80", set_inss, INS_EZ80},
3435 { ".gbz80", set_inss, INS_GBZ80},
3436 { ".module", ignore, 0},
3437 { ".optsdcc", ignore, 0},
3438 { ".r800", set_inss, INS_R800},
3439 { ".set", s_set, 0},
3440 { ".z180", set_inss, INS_Z180},
3441 { ".z80", set_inss, INS_Z80},
3442 { ".z80n", set_inss, INS_Z80N},
3443 { "db" , emit_data, 1},
3444 { "d24", z80_cons, 3},
3445 { "d32", z80_cons, 4},
3446 { "def24", z80_cons, 3},
3447 { "def32", z80_cons, 4},
3448 { "defb", emit_data, 1},
3449 { "defm", emit_data, 1},
3450 { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
3451 { "defw", z80_cons, 2},
3452 { "ds", s_space, 1}, /* Fill with bytes rather than words. */
3453 { "dw", z80_cons, 2},
3454 { "psect", psect, 0}, /* TODO: Translate attributes. */
3455 { "set", 0, 0}, /* Real instruction on z80. */
3456 { NULL, 0, 0 }
3457 } ;
3458
3459 static table_t instab[] =
3460 {
3461 { "adc", 0x88, 0x4A, emit_adc, INS_ALL },
3462 { "add", 0x80, 0x09, emit_add, INS_ALL },
3463 { "and", 0x00, 0xA0, emit_s, INS_ALL },
3464 { "bit", 0xCB, 0x40, emit_bit, INS_ALL },
3465 { "brlc", 0xED, 0x2C, emit_bshft,INS_Z80N },
3466 { "bsla", 0xED, 0x28, emit_bshft,INS_Z80N },
3467 { "bsra", 0xED, 0x29, emit_bshft,INS_Z80N },
3468 { "bsrf", 0xED, 0x2B, emit_bshft,INS_Z80N },
3469 { "bsrl", 0xED, 0x2A, emit_bshft,INS_Z80N },
3470 { "call", 0xCD, 0xC4, emit_jpcc, INS_ALL },
3471 { "ccf", 0x00, 0x3F, emit_insn, INS_ALL },
3472 { "cp", 0x00, 0xB8, emit_s, INS_ALL },
3473 { "cpd", 0xED, 0xA9, emit_insn, INS_NOT_GBZ80 },
3474 { "cpdr", 0xED, 0xB9, emit_insn, INS_NOT_GBZ80 },
3475 { "cpi", 0xED, 0xA1, emit_insn, INS_NOT_GBZ80 },
3476 { "cpir", 0xED, 0xB1, emit_insn, INS_NOT_GBZ80 },
3477 { "cpl", 0x00, 0x2F, emit_insn, INS_ALL },
3478 { "daa", 0x00, 0x27, emit_insn, INS_ALL },
3479 { "dec", 0x0B, 0x05, emit_incdec,INS_ALL },
3480 { "di", 0x00, 0xF3, emit_insn, INS_ALL },
3481 { "djnz", 0x00, 0x10, emit_jr, INS_NOT_GBZ80 },
3482 { "ei", 0x00, 0xFB, emit_insn, INS_ALL },
3483 { "ex", 0x00, 0x00, emit_ex, INS_NOT_GBZ80 },
3484 { "exx", 0x00, 0xD9, emit_insn, INS_NOT_GBZ80 },
3485 { "halt", 0x00, 0x76, emit_insn, INS_ALL },
3486 { "im", 0xED, 0x46, emit_im, INS_NOT_GBZ80 },
3487 { "in", 0x00, 0x00, emit_in, INS_NOT_GBZ80 },
3488 { "in0", 0xED, 0x00, emit_in0, INS_Z180|INS_EZ80 },
3489 { "inc", 0x03, 0x04, emit_incdec,INS_ALL },
3490 { "ind", 0xED, 0xAA, emit_insn, INS_NOT_GBZ80 },
3491 { "ind2", 0xED, 0x8C, emit_insn, INS_EZ80 },
3492 { "ind2r",0xED, 0x9C, emit_insn, INS_EZ80 },
3493 { "indm", 0xED, 0x8A, emit_insn, INS_EZ80 },
3494 { "indmr",0xED, 0x9A, emit_insn, INS_EZ80 },
3495 { "indr", 0xED, 0xBA, emit_insn, INS_NOT_GBZ80 },
3496 { "indrx",0xED, 0xCA, emit_insn, INS_EZ80 },
3497 { "ini", 0xED, 0xA2, emit_insn, INS_NOT_GBZ80 },
3498 { "ini2", 0xED, 0x84, emit_insn, INS_EZ80 },
3499 { "ini2r",0xED, 0x94, emit_insn, INS_EZ80 },
3500 { "inim", 0xED, 0x82, emit_insn, INS_EZ80 },
3501 { "inimr",0xED, 0x92, emit_insn, INS_EZ80 },
3502 { "inir", 0xED, 0xB2, emit_insn, INS_NOT_GBZ80 },
3503 { "inirx",0xED, 0xC2, emit_insn, INS_EZ80 },
3504 { "jp", 0xC3, 0xC2, emit_jpcc, INS_ALL },
3505 { "jr", 0x18, 0x20, emit_jrcc, INS_ALL },
3506 { "ld", 0x00, 0x00, emit_ld, INS_ALL },
3507 { "ldd", 0xED, 0xA8, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
3508 { "lddr", 0xED, 0xB8, emit_insn, INS_NOT_GBZ80 },
3509 { "lddrx",0xED, 0xBC, emit_insn, INS_Z80N },
3510 { "lddx", 0xED, 0xAC, emit_insn, INS_Z80N },
3511 { "ldh", 0xE0, 0x00, emit_ldh, INS_GBZ80 },
3512 { "ldhl", 0x00, 0xF8, emit_ldhl, INS_GBZ80 },
3513 { "ldi", 0xED, 0xA0, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
3514 { "ldir", 0xED, 0xB0, emit_insn, INS_NOT_GBZ80 },
3515 { "ldirx",0xED, 0xB4, emit_insn, INS_Z80N },
3516 { "ldix", 0xED, 0xA4, emit_insn, INS_Z80N },
3517 { "ldpirx",0xED,0xB7, emit_insn, INS_Z80N },
3518 { "ldws", 0xED, 0xA5, emit_insn, INS_Z80N },
3519 { "lea", 0xED, 0x02, emit_lea, INS_EZ80 },
3520 { "mirror",0xED,0x24, emit_insn, INS_Z80N },
3521 { "mlt", 0xED, 0x4C, emit_mlt, INS_Z180|INS_EZ80|INS_Z80N },
3522 { "mul", 0xED, 0x30, emit_mul, INS_Z80N },
3523 { "mulub",0xED, 0xC5, emit_mulub,INS_R800 },
3524 { "muluw",0xED, 0xC3, emit_muluw,INS_R800 },
3525 { "neg", 0xED, 0x44, emit_insn, INS_NOT_GBZ80 },
3526 { "nextreg",0xED,0x91,emit_nextreg,INS_Z80N },
3527 { "nop", 0x00, 0x00, emit_insn, INS_ALL },
3528 { "or", 0x00, 0xB0, emit_s, INS_ALL },
3529 { "otd2r",0xED, 0xBC, emit_insn, INS_EZ80 },
3530 { "otdm", 0xED, 0x8B, emit_insn, INS_Z180|INS_EZ80 },
3531 { "otdmr",0xED, 0x9B, emit_insn, INS_Z180|INS_EZ80 },
3532 { "otdr", 0xED, 0xBB, emit_insn, INS_NOT_GBZ80 },
3533 { "otdrx",0xED, 0xCB, emit_insn, INS_EZ80 },
3534 { "oti2r",0xED, 0xB4, emit_insn, INS_EZ80 },
3535 { "otim", 0xED, 0x83, emit_insn, INS_Z180|INS_EZ80 },
3536 { "otimr",0xED, 0x93, emit_insn, INS_Z180|INS_EZ80 },
3537 { "otir", 0xED, 0xB3, emit_insn, INS_NOT_GBZ80 },
3538 { "otirx",0xED, 0xC3, emit_insn, INS_EZ80 },
3539 { "out", 0x00, 0x00, emit_out, INS_NOT_GBZ80 },
3540 { "out0", 0xED, 0x01, emit_out0, INS_Z180|INS_EZ80 },
3541 { "outd", 0xED, 0xAB, emit_insn, INS_NOT_GBZ80 },
3542 { "outd2",0xED, 0xAC, emit_insn, INS_EZ80 },
3543 { "outi", 0xED, 0xA3, emit_insn, INS_NOT_GBZ80 },
3544 { "outi2",0xED, 0xA4, emit_insn, INS_EZ80 },
3545 { "outinb",0xED,0x90, emit_insn, INS_Z80N },
3546 { "pea", 0xED, 0x65, emit_pea, INS_EZ80 },
3547 { "pixelad",0xED,0x94,emit_insn, INS_Z80N },
3548 { "pixeldn",0xED,0x93,emit_insn, INS_Z80N },
3549 { "pop", 0x00, 0xC1, emit_pop, INS_ALL },
3550 { "push", 0x00, 0xC5, emit_push, INS_ALL },
3551 { "res", 0xCB, 0x80, emit_bit, INS_ALL },
3552 { "ret", 0xC9, 0xC0, emit_retcc,INS_ALL },
3553 { "reti", 0xED, 0x4D, emit_reti, INS_ALL }, /*GBZ80 has its own opcode for it*/
3554 { "retn", 0xED, 0x45, emit_insn, INS_NOT_GBZ80 },
3555 { "rl", 0xCB, 0x10, emit_mr, INS_ALL },
3556 { "rla", 0x00, 0x17, emit_insn, INS_ALL },
3557 { "rlc", 0xCB, 0x00, emit_mr, INS_ALL },
3558 { "rlca", 0x00, 0x07, emit_insn, INS_ALL },
3559 { "rld", 0xED, 0x6F, emit_insn, INS_NOT_GBZ80 },
3560 { "rr", 0xCB, 0x18, emit_mr, INS_ALL },
3561 { "rra", 0x00, 0x1F, emit_insn, INS_ALL },
3562 { "rrc", 0xCB, 0x08, emit_mr, INS_ALL },
3563 { "rrca", 0x00, 0x0F, emit_insn, INS_ALL },
3564 { "rrd", 0xED, 0x67, emit_insn, INS_NOT_GBZ80 },
3565 { "rsmix",0xED, 0x7E, emit_insn, INS_EZ80 },
3566 { "rst", 0x00, 0xC7, emit_rst, INS_ALL },
3567 { "sbc", 0x98, 0x42, emit_adc, INS_ALL },
3568 { "scf", 0x00, 0x37, emit_insn, INS_ALL },
3569 { "set", 0xCB, 0xC0, emit_bit, INS_ALL },
3570 { "setae",0xED, 0x95, emit_insn, INS_Z80N },
3571 { "sl1", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3572 { "sla", 0xCB, 0x20, emit_mr, INS_ALL },
3573 { "sli", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3574 { "sll", 0xCB, 0x30, emit_mr, INS_SLI|INS_Z80N },
3575 { "slp", 0xED, 0x76, emit_insn, INS_Z180|INS_EZ80 },
3576 { "sra", 0xCB, 0x28, emit_mr, INS_ALL },
3577 { "srl", 0xCB, 0x38, emit_mr, INS_ALL },
3578 { "stmix",0xED, 0x7D, emit_insn, INS_EZ80 },
3579 { "stop", 0x00, 0x10, emit_insn, INS_GBZ80 },
3580 { "sub", 0x00, 0x90, emit_sub, INS_ALL },
3581 { "swap", 0xCB, 0x30, emit_swap, INS_GBZ80|INS_Z80N },
3582 { "swapnib",0xED,0x23,emit_insn, INS_Z80N },
3583 { "test", 0xED, 0x27, emit_insn_n, INS_Z80N },
3584 { "tst", 0xED, 0x04, emit_tst, INS_Z180|INS_EZ80|INS_Z80N },
3585 { "tstio",0xED, 0x74, emit_insn_n,INS_Z180|INS_EZ80 },
3586 { "xor", 0x00, 0xA8, emit_s, INS_ALL },
3587 } ;
3588
3589 void
3590 md_assemble (char *str)
3591 {
3592 const char *p;
3593 char * old_ptr;
3594 int i;
3595 table_t *insp;
3596
3597 err_flag = 0;
3598 inst_mode = cpu_mode ? (INST_MODE_L | INST_MODE_IL) : (INST_MODE_S | INST_MODE_IS);
3599 old_ptr = input_line_pointer;
3600 p = skip_space (str);
3601 for (i = 0; (i < BUFLEN) && (ISALPHA (*p) || ISDIGIT (*p));)
3602 buf[i++] = TOLOWER (*p++);
3603
3604 if (i == BUFLEN)
3605 {
3606 buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated. */
3607 buf[BUFLEN-1] = 0;
3608 as_bad (_("Unknown instruction '%s'"), buf);
3609 }
3610 else
3611 {
3612 dwarf2_emit_insn (0);
3613 if ((*p) && (!ISSPACE (*p)))
3614 {
3615 if (*p != '.' || !(ins_ok & INS_EZ80) || !assemble_suffix (&p))
3616 {
3617 as_bad (_("syntax error"));
3618 goto end;
3619 }
3620 }
3621 buf[i] = 0;
3622 p = skip_space (p);
3623 key = buf;
3624
3625 insp = bsearch (&key, instab, ARRAY_SIZE (instab),
3626 sizeof (instab[0]), key_cmp);
3627 if (!insp || (insp->inss && !(insp->inss & ins_ok)))
3628 {
3629 *frag_more (1) = 0;
3630 as_bad (_("Unknown instruction `%s'"), buf);
3631 }
3632 else
3633 {
3634 p = insp->fp (insp->prefix, insp->opcode, p);
3635 p = skip_space (p);
3636 if ((!err_flag) && *p)
3637 as_bad (_("junk at end of line, "
3638 "first unrecognized character is `%c'"), *p);
3639 }
3640 }
3641 end:
3642 input_line_pointer = old_ptr;
3643 }
3644
3645 static int
3646 is_overflow (long value, unsigned bitsize)
3647 {
3648 long fieldmask = (1 << bitsize) - 1;
3649 long signmask = ~fieldmask;
3650 long a = value & fieldmask;
3651 long ss = a & signmask;
3652 if (ss != 0 && ss != (signmask & fieldmask))
3653 return 1;
3654 return 0;
3655 }
3656
3657 void
3658 md_apply_fix (fixS * fixP, valueT* valP, segT seg)
3659 {
3660 long val = *valP;
3661 char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal;
3662
3663 if (fixP->fx_addsy == NULL)
3664 fixP->fx_done = 1;
3665 else if (fixP->fx_pcrel)
3666 {
3667 segT s = S_GET_SEGMENT (fixP->fx_addsy);
3668 if (s == seg || s == absolute_section)
3669 {
3670 val += S_GET_VALUE (fixP->fx_addsy);
3671 fixP->fx_done = 1;
3672 }
3673 }
3674
3675 switch (fixP->fx_r_type)
3676 {
3677 case BFD_RELOC_8_PCREL:
3678 case BFD_RELOC_Z80_DISP8:
3679 case BFD_RELOC_8:
3680 case BFD_RELOC_16:
3681 case BFD_RELOC_24:
3682 case BFD_RELOC_32:
3683 case BFD_RELOC_Z80_16_BE:
3684 fixP->fx_no_overflow = 0;
3685 break;
3686 default:
3687 fixP->fx_no_overflow = 1;
3688 break;
3689 }
3690
3691 switch (fixP->fx_r_type)
3692 {
3693 case BFD_RELOC_8_PCREL:
3694 case BFD_RELOC_Z80_DISP8:
3695 if (fixP->fx_done && (val < -0x80 || val > 0x7f))
3696 as_bad_where (fixP->fx_file, fixP->fx_line,
3697 _("8-bit signed offset out of range (%+ld)"), val);
3698 *p_lit++ = val;
3699 break;
3700
3701 case BFD_RELOC_Z80_BYTE0:
3702 *p_lit++ = val;
3703 break;
3704
3705 case BFD_RELOC_Z80_BYTE1:
3706 *p_lit++ = (val >> 8);
3707 break;
3708
3709 case BFD_RELOC_Z80_BYTE2:
3710 *p_lit++ = (val >> 16);
3711 break;
3712
3713 case BFD_RELOC_Z80_BYTE3:
3714 *p_lit++ = (val >> 24);
3715 break;
3716
3717 case BFD_RELOC_8:
3718 if (fixP->fx_done && is_overflow(val, 8))
3719 as_warn_where (fixP->fx_file, fixP->fx_line,
3720 _("8-bit overflow (%+ld)"), val);
3721 *p_lit++ = val;
3722 break;
3723
3724 case BFD_RELOC_Z80_WORD1:
3725 *p_lit++ = (val >> 16);
3726 *p_lit++ = (val >> 24);
3727 break;
3728
3729 case BFD_RELOC_Z80_WORD0:
3730 *p_lit++ = val;
3731 *p_lit++ = (val >> 8);
3732 break;
3733
3734 case BFD_RELOC_16:
3735 if (fixP->fx_done && is_overflow(val, 16))
3736 as_warn_where (fixP->fx_file, fixP->fx_line,
3737 _("16-bit overflow (%+ld)"), val);
3738 *p_lit++ = val;
3739 *p_lit++ = (val >> 8);
3740 break;
3741
3742 case BFD_RELOC_24: /* Def24 may produce this. */
3743 if (fixP->fx_done && is_overflow(val, 24))
3744 as_warn_where (fixP->fx_file, fixP->fx_line,
3745 _("24-bit overflow (%+ld)"), val);
3746 *p_lit++ = val;
3747 *p_lit++ = (val >> 8);
3748 *p_lit++ = (val >> 16);
3749 break;
3750
3751 case BFD_RELOC_32: /* Def32 and .long may produce this. */
3752 if (fixP->fx_done && is_overflow(val, 32))
3753 as_warn_where (fixP->fx_file, fixP->fx_line,
3754 _("32-bit overflow (%+ld)"), val);
3755 *p_lit++ = val;
3756 *p_lit++ = (val >> 8);
3757 *p_lit++ = (val >> 16);
3758 *p_lit++ = (val >> 24);
3759 break;
3760
3761 case BFD_RELOC_Z80_16_BE: /* Z80N PUSH nn instruction produce this. */
3762 *p_lit++ = val >> 8;
3763 *p_lit++ = val;
3764 break;
3765
3766 default:
3767 printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP->fx_r_type);
3768 abort ();
3769 }
3770 }
3771
3772 /* GAS will call this to generate a reloc. GAS will pass the
3773 resulting reloc to `bfd_install_relocation'. This currently works
3774 poorly, as `bfd_install_relocation' often does the wrong thing, and
3775 instances of `tc_gen_reloc' have been written to work around the
3776 problems, which in turns makes it difficult to fix
3777 `bfd_install_relocation'. */
3778
3779 /* If while processing a fixup, a reloc really
3780 needs to be created then it is done here. */
3781
3782 arelent *
3783 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
3784 {
3785 arelent *reloc;
3786
3787 if (fixp->fx_subsy != NULL)
3788 {
3789 as_bad_where (fixp->fx_file, fixp->fx_line, _("expression too complex"));
3790 return NULL;
3791 }
3792
3793 reloc = XNEW (arelent);
3794 reloc->sym_ptr_ptr = XNEW (asymbol *);
3795 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
3796 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
3797 reloc->addend = fixp->fx_offset;
3798 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
3799 if (reloc->howto == NULL)
3800 {
3801 as_bad_where (fixp->fx_file, fixp->fx_line,
3802 _("reloc %d not supported by object file format"),
3803 (int) fixp->fx_r_type);
3804 return NULL;
3805 }
3806
3807 if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
3808 || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
3809 reloc->address = fixp->fx_offset;
3810
3811 return reloc;
3812 }
3813
3814 int
3815 z80_tc_label_is_local (const char *name)
3816 {
3817 const char *n;
3818 const char *p;
3819 if (local_label_prefix == NULL)
3820 return 0;
3821 for (p = local_label_prefix, n = name; *p && *n && *n == *p; p++, n++)
3822 ;
3823 return *p == '\0';
3824 }
3825
3826 /* Parse floating point number from string and compute mantissa and
3827 exponent. Mantissa is normalized.
3828 */
3829 #define EXP_MIN -0x10000
3830 #define EXP_MAX 0x10000
3831 static int
3832 str_to_broken_float (bfd_boolean *signP, bfd_uint64_t *mantissaP, int *expP)
3833 {
3834 char *p;
3835 bfd_boolean sign;
3836 bfd_uint64_t mantissa = 0;
3837 int exponent = 0;
3838 int i;
3839
3840 p = (char*)skip_space (input_line_pointer);
3841 sign = (*p == '-');
3842 *signP = sign;
3843 if (sign || *p == '+')
3844 ++p;
3845 if (strncasecmp (p, "NaN", 3) == 0)
3846 {
3847 *mantissaP = 0;
3848 *expP = 0;
3849 input_line_pointer = p + 3;
3850 return 1;
3851 }
3852 if (strncasecmp (p, "inf", 3) == 0)
3853 {
3854 *mantissaP = 1ull << 63;
3855 *expP = EXP_MAX;
3856 input_line_pointer = p + 3;
3857 return 1;
3858 }
3859 for (; ISDIGIT (*p); ++p)
3860 {
3861 if (mantissa >> 60)
3862 {
3863 if (*p >= '5')
3864 mantissa++;
3865 break;
3866 }
3867 mantissa = mantissa * 10 + (*p - '0');
3868 }
3869 /* skip non-significant digits */
3870 for (; ISDIGIT (*p); ++p)
3871 exponent++;
3872
3873 if (*p == '.')
3874 {
3875 p++;
3876 if (!exponent) /* If no precission overflow. */
3877 {
3878 for (; ISDIGIT (*p); ++p, --exponent)
3879 {
3880 if (mantissa >> 60)
3881 {
3882 if (*p >= '5')
3883 mantissa++;
3884 break;
3885 }
3886 mantissa = mantissa * 10 + (*p - '0');
3887 }
3888 }
3889 for (; ISDIGIT (*p); ++p)
3890 ;
3891 }
3892 if (*p == 'e' || *p == 'E')
3893 {
3894 int es;
3895 int t = 0;
3896 ++p;
3897 es = (*p == '-');
3898 if (es || *p == '+')
3899 p++;
3900 for (; ISDIGIT (*p); ++p)
3901 {
3902 if (t < 100)
3903 t = t * 10 + (*p - '0');
3904 }
3905 exponent += (es) ? -t : t;
3906 }
3907 if (ISALNUM (*p) || *p == '.')
3908 return 0;
3909 input_line_pointer = p;
3910 if (mantissa == 0)
3911 {
3912 *mantissaP = 1ull << 63;
3913 *expP = EXP_MIN;
3914 return 1; /* result is 0 */
3915 }
3916 /* normalization */
3917 for (; mantissa <= ~0ull/10; --exponent)
3918 mantissa *= 10;
3919 /* Now we have sign, mantissa, and signed decimal exponent
3920 need to recompute to binary exponent. */
3921 for (i = 64; exponent > 0; --exponent)
3922 {
3923 /* be sure that no integer overflow */
3924 while (mantissa > ~0ull/10)
3925 {
3926 mantissa >>= 1;
3927 i += 1;
3928 }
3929 mantissa *= 10;
3930 }
3931 for (; exponent < 0; ++exponent)
3932 {
3933 while (!(mantissa >> 63))
3934 {
3935 mantissa <<= 1;
3936 i -= 1;
3937 }
3938 mantissa /= 10;
3939 }
3940 /* normalization */
3941 for (; !(mantissa >> 63); --i)
3942 mantissa <<= 1;
3943 *mantissaP = mantissa;
3944 *expP = i;
3945 return 1;
3946 }
3947
3948 static const char *
3949 str_to_zeda32(char *litP, int *sizeP)
3950 {
3951 bfd_uint64_t mantissa;
3952 bfd_boolean sign;
3953 int exponent;
3954 unsigned i;
3955
3956 *sizeP = 4;
3957 if (!str_to_broken_float (&sign, &mantissa, &exponent))
3958 return _("invalid syntax");
3959 /* I do not know why decrement is needed */
3960 --exponent;
3961 /* shift by 39 bits right keeping 25 bit mantissa for rounding */
3962 mantissa >>= 39;
3963 /* do rounding */
3964 ++mantissa;
3965 /* make 24 bit mantissa */
3966 mantissa >>= 1;
3967 /* check for overflow */
3968 if (mantissa >> 24)
3969 {
3970 mantissa >>= 1;
3971 ++exponent;
3972 }
3973 /* check for 0 */
3974 if (exponent < -127)
3975 {
3976 exponent = -128;
3977 mantissa = 0;
3978 }
3979 else if (exponent > 127)
3980 {
3981 exponent = -128;
3982 mantissa = sign ? 0xc00000 : 0x400000;
3983 }
3984 else if (mantissa == 0)
3985 {
3986 exponent = -128;
3987 mantissa = 0x200000;
3988 }
3989 else if (!sign)
3990 mantissa &= (1ull << 23) - 1;
3991 for (i = 0; i < 24; i += 8)
3992 *litP++ = (char)(mantissa >> i);
3993 *litP = (char)(0x80 + exponent);
3994 return NULL;
3995 }
3996
3997 /*
3998 Math48 by Anders Hejlsberg support.
3999 Mantissa is 39 bits wide, exponent 8 bit wide.
4000 Format is:
4001 bit 47: sign
4002 bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
4003 bit 7-0: exponent+128 (0 - value is null)
4004 MIN: 2.938735877e-39
4005 MAX: 1.701411835e+38
4006 */
4007 static const char *
4008 str_to_float48(char *litP, int *sizeP)
4009 {
4010 bfd_uint64_t mantissa;
4011 bfd_boolean sign;
4012 int exponent;
4013 unsigned i;
4014
4015 *sizeP = 6;
4016 if (!str_to_broken_float (&sign, &mantissa, &exponent))
4017 return _("invalid syntax");
4018 /* shift by 23 bits right keeping 41 bit mantissa for rounding */
4019 mantissa >>= 23;
4020 /* do rounding */
4021 ++mantissa;
4022 /* make 40 bit mantissa */
4023 mantissa >>= 1;
4024 /* check for overflow */
4025 if (mantissa >> 40)
4026 {
4027 mantissa >>= 1;
4028 ++exponent;
4029 }
4030 if (exponent < -127)
4031 {
4032 memset (litP, 0, 6);
4033 return NULL;
4034 }
4035 if (exponent > 127)
4036 return _("overflow");
4037 if (!sign)
4038 mantissa &= (1ull << 39) - 1;
4039 *litP++ = (char)(0x80 + exponent);
4040 for (i = 0; i < 40; i += 8)
4041 *litP++ = (char)(mantissa >> i);
4042 return NULL;
4043 }
4044
4045 static const char *
4046 str_to_ieee754_h(char *litP, int *sizeP)
4047 {
4048 return ieee_md_atof ('h', litP, sizeP, FALSE);
4049 }
4050
4051 static const char *
4052 str_to_ieee754_s(char *litP, int *sizeP)
4053 {
4054 return ieee_md_atof ('s', litP, sizeP, FALSE);
4055 }
4056
4057 static const char *
4058 str_to_ieee754_d(char *litP, int *sizeP)
4059 {
4060 return ieee_md_atof ('d', litP, sizeP, FALSE);
4061 }
4062
4063 #ifdef TARGET_USE_CFIPOP
4064 /* Initialize the DWARF-2 unwind information for this procedure. */
4065 void
4066 z80_tc_frame_initial_instructions (void)
4067 {
4068 static int sp_regno = -1;
4069
4070 if (sp_regno < 0)
4071 sp_regno = z80_tc_regname_to_dw2regnum ("sp");
4072
4073 cfi_add_CFA_def_cfa (sp_regno, 0);
4074 }
4075
4076 int
4077 z80_tc_regname_to_dw2regnum (const char *regname)
4078 {
4079 static const char *regs[] =
4080 { /* same registers as for GDB */
4081 "af", "bc", "de", "hl",
4082 "sp", "pc", "ix", "iy",
4083 "af_", "bc_", "de_", "hl_",
4084 "ir"
4085 };
4086 unsigned i;
4087
4088 for (i = 0; i < ARRAY_SIZE(regs); ++i)
4089 if (!strcasecmp (regs[i], regname))
4090 return i;
4091
4092 return -1;
4093 }
4094 #endif
4095
4096 /* Implement DWARF2_ADDR_SIZE. */
4097 int
4098 z80_dwarf2_addr_size (const bfd *abfd)
4099 {
4100 switch (bfd_get_mach (abfd))
4101 {
4102 case bfd_mach_ez80_adl:
4103 return 3;
4104 default:
4105 return 2;
4106 }
4107 }
This page took 0.174244 seconds and 4 git commands to generate.