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