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