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