gas/ acinclude.m4 aclocal.m4 app.c app.o as.c as.h as.h.cvs asintl.h as-new as.o...
[deliverable/binutils-gdb.git] / gas / config / tc-z80.c
1 /* tc-z80.c -- Assemble code for the Zilog Z80 and ASCII R800
2 Copyright 2005 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 2, 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 "listing.h"
24 #include "bfd.h"
25 #include "safe-ctype.h"
26 #include "subsegs.h"
27 #include "symbols.h"
28 #include "libiberty.h"
29
30 /* Exported constants. */
31 const char comment_chars[] = ";\0";
32 const char line_comment_chars[] = "#;\0";
33 const char line_separator_chars[] = "\0";
34 const char EXP_CHARS[] = "eE\0";
35 const char FLT_CHARS[] = "RrFf\0";
36
37 /* For machine specific options. */
38 const char * md_shortopts = ""; /* None yet. */
39
40 enum options
41 {
42 OPTION_MACH_Z80 = OPTION_MD_BASE,
43 OPTION_MACH_R800,
44 OPTION_MACH_IUD,
45 OPTION_MACH_WUD,
46 OPTION_MACH_FUD,
47 OPTION_MACH_IUP,
48 OPTION_MACH_WUP,
49 OPTION_MACH_FUP
50 };
51
52 #define INS_Z80 1
53 #define INS_UNDOC 2
54 #define INS_UNPORT 4
55 #define INS_R800 8
56
57 struct option md_longopts[] =
58 {
59 { "z80", no_argument, NULL, OPTION_MACH_Z80},
60 { "r800", no_argument, NULL, OPTION_MACH_R800},
61 { "ignore-undocumented-instructions", no_argument, NULL, OPTION_MACH_IUD },
62 { "Wnud", no_argument, NULL, OPTION_MACH_IUD },
63 { "warn-undocumented-instructions", no_argument, NULL, OPTION_MACH_WUD },
64 { "Wud", no_argument, NULL, OPTION_MACH_WUD },
65 { "forbid-undocumented-instructions", no_argument, NULL, OPTION_MACH_FUD },
66 { "Fud", no_argument, NULL, OPTION_MACH_FUD },
67 { "ignore-unportable-instructions", no_argument, NULL, OPTION_MACH_IUP },
68 { "Wnup", no_argument, NULL, OPTION_MACH_IUP },
69 { "warn-unportable-instructions", no_argument, NULL, OPTION_MACH_WUP },
70 { "Wup", no_argument, NULL, OPTION_MACH_WUP },
71 { "forbid-unportable-instructions", no_argument, NULL, OPTION_MACH_FUP },
72 { "Fup", no_argument, NULL, OPTION_MACH_FUP },
73
74 { NULL, no_argument, NULL, 0 }
75 } ;
76
77 size_t md_longopts_size = sizeof (md_longopts);
78
79 extern int coff_flags;
80 /* Instruction classes that silently assembled. */
81 static int ins_ok = INS_Z80 | INS_UNDOC;
82 /* Instruction classes that generate errors. */
83 static int ins_err = INS_R800;
84 /* Instruction classes actually used, determines machine type. */
85 static int ins_used = INS_Z80;
86
87 int
88 md_parse_option (int c, char* arg ATTRIBUTE_UNUSED)
89 {
90 switch (c)
91 {
92 default:
93 return 0;
94 case OPTION_MACH_Z80:
95 ins_ok &= ~INS_R800;
96 ins_err |= INS_R800;
97 break;
98 case OPTION_MACH_R800:
99 ins_ok = INS_Z80 | INS_UNDOC | INS_R800;
100 ins_err = INS_UNPORT;
101 break;
102 case OPTION_MACH_IUD:
103 ins_ok |= INS_UNDOC;
104 ins_err &= ~INS_UNDOC;
105 break;
106 case OPTION_MACH_IUP:
107 ins_ok |= INS_UNDOC | INS_UNPORT;
108 ins_err &= ~(INS_UNDOC | INS_UNPORT);
109 break;
110 case OPTION_MACH_WUD:
111 if ((ins_ok & INS_R800) == 0)
112 {
113 ins_ok &= ~(INS_UNDOC|INS_UNPORT);
114 ins_err &= ~INS_UNDOC;
115 }
116 break;
117 case OPTION_MACH_WUP:
118 ins_ok &= ~INS_UNPORT;
119 ins_err &= ~(INS_UNDOC|INS_UNPORT);
120 break;
121 case OPTION_MACH_FUD:
122 if ((ins_ok & INS_R800) == 0)
123 {
124 ins_ok &= (INS_UNDOC | INS_UNPORT);
125 ins_err |= INS_UNDOC | INS_UNPORT;
126 }
127 break;
128 case OPTION_MACH_FUP:
129 ins_ok &= ~INS_UNPORT;
130 ins_err |= INS_UNPORT;
131 break;
132 }
133
134 return 1;
135 }
136
137 void
138 md_show_usage (FILE * f)
139 {
140 fprintf (f, "\n\
141 CPU model/instruction set options:\n\
142 \n\
143 -z80\t\t assemble for Z80\n\
144 -ignore-undocumented-instructions\n\
145 -Wnud\n\
146 \tsilently assemble undocumented Z80-instructions that work on R800\n\
147 -ignore-unportable-instructions\n\
148 -Wnup\n\
149 \tsilently assemble all undocumented Z80-instructions\n\
150 -warn-undocumented-instructions\n\
151 -Wud\n\
152 \tissue warnings for undocumented Z80-instructions that work on R800\n\
153 -warn-unportable-instructions\n\
154 -Wup\n\
155 \tissue warnings for other undocumented Z80-instructions\n\
156 -forbid-undocumented-instructions\n\
157 -Fud\n\
158 \ttreat all undocumented z80-instructions as errors\n\
159 -forbid-unportable-instructions\n\
160 -Fup\n\
161 \ttreat undocumented z80-instructions that do not work on R800 as errors\n\
162 -r800\t assemble for R800\n\n\
163 Default: -z80 -ignore-undocument-instructions -warn-unportable-instructions.\n");
164 }
165
166 static symbolS * zero;
167
168 void
169 md_begin (void)
170 {
171 expressionS nul;
172 char * p;
173
174 p = input_line_pointer;
175 input_line_pointer = "0";
176 nul.X_md=0;
177 expression (& nul);
178 input_line_pointer = p;
179 zero = make_expr_symbol (& nul);
180 /* We do not use relaxation (yet). */
181 linkrelax = 0;
182 }
183
184 void
185 z80_md_end (void)
186 {
187 int mach_type;
188
189 if (ins_used & (INS_UNPORT | INS_R800))
190 ins_used |= INS_UNDOC;
191
192 switch (ins_used)
193 {
194 case INS_Z80:
195 mach_type = bfd_mach_z80strict;
196 break;
197 case INS_Z80|INS_UNDOC:
198 mach_type = bfd_mach_z80;
199 break;
200 case INS_Z80|INS_UNDOC|INS_UNPORT:
201 mach_type = bfd_mach_z80full;
202 break;
203 case INS_Z80|INS_UNDOC|INS_R800:
204 mach_type = bfd_mach_r800;
205 break;
206 default:
207 mach_type = 0;
208 }
209
210 bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
211 }
212
213 /* Port specific features. */
214 const pseudo_typeS md_pseudo_table[] =
215 {
216 { "defs", s_space, 1}, /* Synonym for ds on some assemblers. */
217 { "ds", s_space, 1}, /* Fill with bytes rather than words. */
218 { "psect", obj_coff_section, 0}, /* TODO: Translate attributes. */
219 { "set", 0, 0}, /* Real instruction on z80. */
220 { NULL, 0, 0 }
221 } ;
222
223 static const char *
224 skip_space (const char *s)
225 {
226 while (*s == ' ' || *s == '\t')
227 ++s;
228 return s;
229 }
230
231 /* A non-zero return-value causes a continue in the
232 function read_a_source_file () in ../read.c. */
233 int
234 z80_start_line_hook (void)
235 {
236 char *p, quote;
237 char buf[4];
238
239 /* Convert one character constants. */
240 for (p = input_line_pointer; *p && *p != '\n'; ++p)
241 {
242 switch (*p)
243 {
244 case '\'':
245 if (p[1] != 0 && p[1] != '\'' && p[2] == '\'')
246 {
247 snprintf (buf, 4, "%3d", (unsigned char)p[1]);
248 *p++ = buf[0];
249 *p++ = buf[1];
250 *p++ = buf[2];
251 break;
252 }
253 case '"':
254 for (quote = *p++; quote != *p && '\n' != *p; ++p)
255 /* No escapes. */ ;
256 if (quote != *p)
257 {
258 as_bad (_("-- unterminated string"));
259 ignore_rest_of_line ();
260 return 1;
261 }
262 break;
263 }
264 }
265 /* Check for <label>[:] (EQU|DEFL) <value>. */
266 if (is_name_beginner (*input_line_pointer))
267 {
268 char c, *rest, *line_start;
269 int len;
270 symbolS * symbolP;
271
272 line_start = input_line_pointer;
273 LISTING_NEWLINE ();
274 if (ignore_input ())
275 return 0;
276
277 c = get_symbol_end ();
278 rest = input_line_pointer + 1;
279
280 if (*rest == ':')
281 ++rest;
282 if (*rest == ' ' || *rest == '\t')
283 ++rest;
284 if (strncasecmp (rest, "EQU", 3) == 0)
285 len = 3;
286 else if (strncasecmp (rest, "DEFL", 4) == 0)
287 len = 4;
288 else
289 len = 0;
290 if (len && (rest[len] == ' ' || rest[len] == '\t'))
291 {
292 /* Handle assignment here. */
293 input_line_pointer = rest + len;
294 if (line_start[-1] == '\n')
295 bump_line_counters ();
296 /* Most Z80 assemblers require the first definition of a
297 label to use "EQU" and redefinitions to have "DEFL". */
298 if (len == 3 && (symbolP = symbol_find (line_start)) != NULL)
299 {
300 if (S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
301 as_bad (_("symbol `%s' is already defined"), line_start);
302 }
303 /* All symbols may be redefined. */
304 equals (line_start, 1);
305 return 1;
306 }
307 else
308 {
309 /* Restore line and pointer. */
310 *input_line_pointer = c;
311 input_line_pointer = line_start;
312 }
313 }
314 return 0;
315 }
316
317 symbolS *
318 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
319 {
320 return NULL;
321 }
322
323 char *
324 md_atof (int type ATTRIBUTE_UNUSED, char *litP ATTRIBUTE_UNUSED,
325 int *sizeP ATTRIBUTE_UNUSED)
326 {
327 return _("floating point numbers are not implemented");
328 }
329
330 valueT
331 md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size)
332 {
333 return size;
334 }
335
336 long
337 md_pcrel_from (fixS * fixp)
338 {
339 return fixp->fx_where +
340 fixp->fx_frag->fr_address + 1;
341 }
342
343 typedef const char * (asfunc)(char, char, const char*);
344
345 typedef struct _table_t
346 {
347 char* name;
348 char prefix;
349 char opcode;
350 asfunc * fp;
351 } table_t;
352
353 /* Compares the key for structs that start with a char * to the key. */
354 static int
355 key_cmp (const void * a, const void * b)
356 {
357 const char *str_a, *str_b;
358
359 str_a = *((const char**)a);
360 str_b = *((const char**)b);
361 return strcmp (str_a, str_b);
362 }
363
364 #define BUFLEN 8 /* Large enough for any keyword. */
365
366 char buf[BUFLEN];
367 const char *key = buf;
368
369 #define R_STACKABLE (0x80)
370 #define R_ARITH (0x40)
371 #define R_IX (0x20)
372 #define R_IY (0x10)
373 #define R_INDEX (R_IX | R_IY)
374
375 #define REG_A (7)
376 #define REG_B (0)
377 #define REG_C (1)
378 #define REG_D (2)
379 #define REG_E (3)
380 #define REG_H (4)
381 #define REG_L (5)
382 #define REG_F (6 | 8)
383 #define REG_I (9)
384 #define REG_R (10)
385
386 #define REG_AF (3 | R_STACKABLE)
387 #define REG_BC (0 | R_STACKABLE | R_ARITH)
388 #define REG_DE (1 | R_STACKABLE | R_ARITH)
389 #define REG_HL (2 | R_STACKABLE | R_ARITH)
390 #define REG_SP (3 | R_ARITH)
391
392 static const struct reg_entry
393 {
394 char* name;
395 int number;
396 } regtable[] =
397 {
398 {"a", REG_A },
399 {"af", REG_AF },
400 {"b", REG_B },
401 {"bc", REG_BC },
402 {"c", REG_C },
403 {"d", REG_D },
404 {"de", REG_DE },
405 {"e", REG_E },
406 {"f", REG_F },
407 {"h", REG_H },
408 {"hl", REG_HL },
409 {"i", REG_I },
410 {"ix", REG_HL | R_IX },
411 {"ixh",REG_H | R_IX },
412 {"ixl",REG_L | R_IX },
413 {"iy", REG_HL | R_IY },
414 {"iyh",REG_H | R_IY },
415 {"iyl",REG_L | R_IY },
416 {"l", REG_L },
417 {"r", REG_R },
418 {"sp", REG_SP },
419 } ;
420
421 /* Prevent an error on a line from also generating
422 a "junk at end of line" error message. */
423 static char err_flag;
424
425 static void
426 error (const char * message)
427 {
428 as_bad (message);
429 err_flag = 1;
430 }
431
432 static void
433 ill_op (void)
434 {
435 error (_("illegal operand"));
436 }
437
438 static void
439 wrong_mach (int ins_type)
440 {
441 const char *p;
442
443 switch (ins_type)
444 {
445 case INS_UNDOC:
446 p = "undocumented instruction";
447 break;
448 case INS_UNPORT:
449 p = "instruction does not work on R800";
450 break;
451 case INS_R800:
452 p = "instruction only works R800";
453 break;
454 default:
455 p = 0; /* Not reachables. */
456 }
457
458 if (ins_type & ins_err)
459 error (_(p));
460 else
461 as_warn (_(p));
462 }
463
464 static void
465 check_mach (int ins_type)
466 {
467 if ((ins_type & ins_ok) == 0)
468 wrong_mach (ins_type);
469 ins_used |= ins_type;
470 }
471
472 /* This function tries to subtract two symbols, the generic code does
473 that too, but this function tries harder.
474 The behaviour of this function is not altered by extra
475 fragmentations caused by the code to produce listings. */
476 int
477 z80_optimize_expr (expressionS *resultP, operatorT left_op,
478 expressionS *right)
479 {
480 int res, swap, som;
481 fragS *lfrag, *rfrag, *cur;
482
483 res = 0;
484 if (left_op == O_subtract
485 && right->X_op == O_symbol
486 && resultP->X_op == O_symbol)
487 {
488 lfrag = symbol_get_frag (resultP->X_add_symbol);
489 rfrag = symbol_get_frag (right->X_add_symbol);
490
491 if (S_GET_SEGMENT (right->X_add_symbol) != undefined_section
492 && (S_GET_SEGMENT (right->X_add_symbol)
493 == S_GET_SEGMENT (resultP->X_add_symbol)))
494 {
495 for (swap = 0; (res == 0) && (swap < 2); ++swap)
496 {
497 if (swap)
498 {
499 cur = lfrag;
500 lfrag = rfrag;
501 rfrag = cur;
502 }
503 else
504 cur = rfrag;
505
506 /* Now som == cur->fr_address - rfrag->address, except
507 the latter may not have been computed yet. */
508 for (som = 0; cur && cur != lfrag; cur = cur->fr_next)
509 {
510 if (cur->fr_type == rs_fill) /* Is the size fized? */
511 som += cur->fr_fix+cur->fr_offset*cur->fr_var;
512 else
513 break;
514 }
515
516 if (cur == lfrag)
517 {
518 resultP->X_add_number -= right->X_add_number;
519 resultP->X_add_number
520 += (S_GET_VALUE (resultP->X_add_symbol)
521 - S_GET_VALUE (right->X_add_symbol));
522 som -= lfrag->fr_address - rfrag->fr_address;
523 /* Correct the result if the fr_address
524 fields are not computed yet. */
525 resultP->X_add_number += (swap ? -som : som);
526 resultP->X_op = O_constant;
527 resultP->X_add_symbol = 0;
528 res = 1;
529 }
530 }
531 }
532 }
533 return res;
534 }
535
536 /* Check whether an expression is indirect. */
537 static int
538 is_indir (const char *s)
539 {
540 char quote;
541 const char *p;
542 int indir, depth;
543
544 /* Indirection is indicated with parentheses. */
545 indir = (*s == '(');
546
547 for (p = s, depth = 0; *p && *p != ','; ++p)
548 {
549 switch (*p)
550 {
551 case '"':
552 case '\'':
553 for (quote = *p++; quote != *p && *p != '\n'; ++p)
554 if (*p == '\\' && p[1])
555 ++p;
556 break;
557 case '(':
558 ++ depth;
559 break;
560 case ')':
561 -- depth;
562 if (depth == 0)
563 {
564 p = skip_space (p + 1);
565 if (*p && *p != ',')
566 indir = 0;
567 --p;
568 }
569 if (depth < 0)
570 error (_("mismatched parentheses"));
571 break;
572 }
573 }
574
575 if (depth != 0)
576 error (_("mismatched parentheses"));
577
578 return indir;
579 }
580
581 /* Parse general expression. */
582 static const char *
583 parse_exp2 (const char *s, expressionS *op, segT *pseg)
584 {
585 const char *p;
586 int indir;
587 int i;
588 const struct reg_entry * regp;
589 expressionS offset;
590
591 p = skip_space (s);
592 op->X_md = indir = is_indir (p);
593 if (indir)
594 p = skip_space (p + 1);
595
596 for (i = 0; i < BUFLEN; ++i)
597 {
598 if (!ISALPHA (p[i])) /* Register names consist of letters only. */
599 break;
600 buf[i] = TOLOWER (p[i]);
601 }
602
603 if ((i < BUFLEN) && ((p[i] == 0) || (strchr (")+-, \t", p[i]))))
604 {
605 buf[i] = 0;
606 regp = bsearch (& key, regtable, ARRAY_SIZE (regtable),
607 sizeof (regtable[0]), key_cmp);
608 if (regp)
609 {
610 *pseg = reg_section;
611 op->X_add_symbol = op->X_op_symbol = 0;
612 op->X_add_number = regp->number;
613 op->X_op = O_register;
614 p += strlen (regp->name);
615 p = skip_space (p);
616 if (indir)
617 {
618 if (*p == ')')
619 ++p;
620 if ((regp->number & R_INDEX) && (regp->number & R_ARITH))
621 {
622 op->X_op = O_md1;
623
624 if ((*p == '+') || (*p == '-'))
625 {
626 input_line_pointer = (char*) p;
627 expression (& offset);
628 p = skip_space (input_line_pointer);
629 if (*p != ')')
630 error (_("bad offset expression syntax"));
631 else
632 ++ p;
633 op->X_add_symbol = make_expr_symbol (& offset);
634 return p;
635 }
636
637 /* We treat (i[xy]) as (i[xy]+0), which is how it will
638 end up anyway, unless we're processing jp (i[xy]). */
639 op->X_add_symbol = zero;
640 }
641 }
642 p = skip_space (p);
643
644 if ((*p == 0) || (*p == ','))
645 return p;
646 }
647 }
648 /* Not an argument involving a register; use the generic parser. */
649 input_line_pointer = (char*) s ;
650 *pseg = expression (op);
651 if (op->X_op == O_absent)
652 error (_("missing operand"));
653 if (op->X_op == O_illegal)
654 error (_("bad expression syntax"));
655 return input_line_pointer;
656 }
657
658 static const char *
659 parse_exp (const char *s, expressionS *op)
660 {
661 segT dummy;
662 return parse_exp2 (s, op, & dummy);
663 }
664
665 /* Condition codes, including some synonyms provided by HiTech zas. */
666 static const struct reg_entry cc_tab[] =
667 {
668 { "age", 6 << 3 },
669 { "alt", 7 << 3 },
670 { "c", 3 << 3 },
671 { "di", 4 << 3 },
672 { "ei", 5 << 3 },
673 { "lge", 2 << 3 },
674 { "llt", 3 << 3 },
675 { "m", 7 << 3 },
676 { "nc", 2 << 3 },
677 { "nz", 0 << 3 },
678 { "p", 6 << 3 },
679 { "pe", 5 << 3 },
680 { "po", 4 << 3 },
681 { "z", 1 << 3 },
682 } ;
683
684 /* Parse condition code. */
685 static const char *
686 parse_cc (const char *s, char * op)
687 {
688 const char *p;
689 int i;
690 struct reg_entry * cc_p;
691
692 for (i = 0; i < BUFLEN; ++i)
693 {
694 if (!ISALPHA (s[i])) /* Condition codes consist of letters only. */
695 break;
696 buf[i] = TOLOWER (s[i]);
697 }
698
699 if ((i < BUFLEN)
700 && ((s[i] == 0) || (s[i] == ',')))
701 {
702 buf[i] = 0;
703 cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
704 sizeof (cc_tab[0]), key_cmp);
705 }
706 else
707 cc_p = NULL;
708
709 if (cc_p)
710 {
711 *op = cc_p->number;
712 p = s + i;
713 }
714 else
715 p = NULL;
716
717 return p;
718 }
719
720 static const char *
721 emit_insn (char prefix, char opcode, const char * args)
722 {
723 char *p;
724
725 if (prefix)
726 {
727 p = frag_more (2);
728 *p++ = prefix;
729 }
730 else
731 p = frag_more (1);
732 *p = opcode;
733 return args;
734 }
735
736 static void
737 emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
738 {
739 char *p;
740 int lo, hi;
741 fixS * fixp;
742
743 p = frag_more (1);
744 *p = val->X_add_number;
745 if ((r_type != BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
746 {
747 lo = -128;
748 hi = (BFD_RELOC_8 == r_type) ? 255 : 127;
749
750 if ((val->X_add_number < lo) || (val->X_add_number > hi))
751 {
752 if (r_type == BFD_RELOC_Z80_DISP8)
753 as_bad (_("offset too large"));
754 else
755 as_warn (_("overflow"));
756 }
757 }
758 else
759 {
760 fixp = fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
761 (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
762 /* FIXME : Process constant offsets immediately. */
763 }
764 }
765
766 static void
767 emit_word (expressionS * val)
768 {
769 char *p;
770
771 p = frag_more (2);
772 if ( (val->X_op == O_register)
773 || (val->X_op == O_md1))
774 ill_op ();
775 else
776 {
777 *p = val->X_add_number;
778 p[1] = (val->X_add_number>>8);
779 if (val->X_op != O_constant)
780 fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
781 val, FALSE, BFD_RELOC_16);
782 }
783 }
784
785 static void
786 emit_mx (char prefix, char opcode, int shift, expressionS * arg)
787 /* The operand m may be r, (hl), (ix+d), (iy+d),
788 if 0 == prefix m may also be ixl, ixh, iyl, iyh. */
789 {
790 char *q;
791 int rnum;
792
793 rnum = arg->X_add_number;
794 switch (arg->X_op)
795 {
796 case O_register:
797 if (arg->X_md)
798 {
799 if (rnum != REG_HL)
800 {
801 ill_op ();
802 break;
803 }
804 else
805 rnum = 6;
806 }
807 else
808 {
809 if ((prefix == 0) && (rnum & R_INDEX))
810 {
811 prefix = (rnum & R_IX) ? 0xDD : 0xFD;
812 check_mach (INS_UNDOC);
813 rnum &= ~R_INDEX;
814 }
815 if (rnum > 7)
816 {
817 ill_op ();
818 break;
819 }
820 }
821 q = frag_more (prefix ? 2 : 1);
822 if (prefix)
823 * q ++ = prefix;
824 * q ++ = opcode + (rnum << shift);
825 break;
826 case O_md1:
827 q = frag_more (2);
828 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
829 *q = (prefix) ? prefix : (opcode + (6 << shift));
830 emit_byte (symbol_get_value_expression (arg->X_add_symbol),
831 BFD_RELOC_Z80_DISP8);
832 if (prefix)
833 {
834 q = frag_more (1);
835 *q = opcode+(6<<shift);
836 }
837 break;
838 default:
839 abort ();
840 }
841 }
842
843 /* The operand m may be r, (hl), (ix+d), (iy+d),
844 if 0 = prefix m may also be ixl, ixh, iyl, iyh. */
845 static const char *
846 emit_m (char prefix, char opcode, const char *args)
847 {
848 expressionS arg_m;
849 const char *p;
850
851 p = parse_exp (args, &arg_m);
852 switch (arg_m.X_op)
853 {
854 case O_md1:
855 case O_register:
856 emit_mx (prefix, opcode, 0, &arg_m);
857 break;
858 default:
859 ill_op ();
860 }
861 return p;
862 }
863
864 /* The operand m may be as above or one of the undocumented
865 combinations (ix+d),r and (iy+d),r (if unportable instructions
866 are allowed). */
867 static const char *
868 emit_mr (char prefix, char opcode, const char *args)
869 {
870 expressionS arg_m, arg_r;
871 const char *p;
872
873 p = parse_exp (args, & arg_m);
874
875 switch (arg_m.X_op)
876 {
877 case O_md1:
878 if (*p == ',')
879 {
880 p = parse_exp (p + 1, & arg_r);
881
882 if ((arg_r.X_md == 0)
883 && (arg_r.X_op == O_register)
884 && (arg_r.X_add_number < 8))
885 opcode += arg_r.X_add_number-6; /* Emit_mx () will add 6. */
886 else
887 {
888 ill_op ();
889 break;
890 }
891 check_mach (INS_UNPORT);
892 }
893 case O_register:
894 emit_mx (prefix, opcode, 0, & arg_m);
895 break;
896 default:
897 ill_op ();
898 }
899 return p;
900 }
901
902 static void
903 emit_sx (char prefix, char opcode, expressionS * arg_p)
904 {
905 char *q;
906
907 switch (arg_p->X_op)
908 {
909 case O_register:
910 case O_md1:
911 emit_mx (prefix, opcode, 0, arg_p);
912 break;
913 default:
914 if (arg_p->X_md)
915 ill_op ();
916 else
917 {
918 q = frag_more (prefix ? 2 : 1);
919 if (prefix)
920 *q++ = prefix;
921 *q = opcode ^ 0x46;
922 emit_byte (arg_p, BFD_RELOC_8);
923 }
924 }
925 }
926
927 /* The operand s may be r, (hl), (ix+d), (iy+d), n. */
928 static const char *
929 emit_s (char prefix, char opcode, const char *args)
930 {
931 expressionS arg_s;
932 const char *p;
933
934 p = parse_exp (args, & arg_s);
935 emit_sx (prefix, opcode, & arg_s);
936 return p;
937 }
938
939 static const char *
940 emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
941 {
942 expressionS addr;
943 const char *p; char *q;
944
945 p = parse_exp (args, &addr);
946 if (addr.X_md)
947 ill_op ();
948 else
949 {
950 q = frag_more (1);
951 *q = opcode;
952 emit_word (& addr);
953 }
954 return p;
955 }
956
957 /* Operand may be rr, r, (hl), (ix+d), (iy+d). */
958 static const char *
959 emit_incdec (char prefix, char opcode, const char * args)
960 {
961 expressionS operand;
962 int rnum;
963 const char *p; char *q;
964
965 p = parse_exp (args, &operand);
966 rnum = operand.X_add_number;
967 if ((! operand.X_md)
968 && (operand.X_op == O_register)
969 && (R_ARITH&rnum))
970 {
971 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
972 if (rnum & R_INDEX)
973 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
974 *q = prefix + ((rnum & 3) << 4);
975 }
976 else
977 {
978 if ((operand.X_op == O_md1) || (operand.X_op == O_register))
979 emit_mx (0, opcode, 3, & operand);
980 else
981 ill_op ();
982 }
983 return p;
984 }
985
986 static const char *
987 emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
988 {
989 expressionS addr;
990 const char *p;
991 char *q;
992
993 p = parse_exp (args, &addr);
994 if (addr.X_md)
995 ill_op ();
996 else
997 {
998 q = frag_more (1);
999 *q = opcode;
1000 emit_byte (&addr, BFD_RELOC_8_PCREL);
1001 }
1002 return p;
1003 }
1004
1005 static const char *
1006 emit_jp (char prefix, char opcode, const char * args)
1007 {
1008 expressionS addr;
1009 const char *p;
1010 char *q;
1011 int rnum;
1012
1013 p = parse_exp (args, & addr);
1014 if (addr.X_md)
1015 {
1016 rnum = addr.X_add_number;
1017 if ((addr.X_op == O_register && (rnum & ~R_INDEX) == REG_HL)
1018 /* An operand (i[xy]) would have been rewritten to (i[xy]+0)
1019 in parse_exp (). */
1020 || (addr.X_op == O_md1 && addr.X_add_symbol == zero))
1021 {
1022 q = frag_more ((rnum & R_INDEX) ? 2 : 1);
1023 if (rnum & R_INDEX)
1024 *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
1025 *q = prefix;
1026 }
1027 else
1028 ill_op ();
1029 }
1030 else
1031 {
1032 q = frag_more (1);
1033 *q = opcode;
1034 emit_word (& addr);
1035 }
1036 return p;
1037 }
1038
1039 static const char *
1040 emit_im (char prefix, char opcode, const char * args)
1041 {
1042 expressionS mode;
1043 const char *p;
1044 char *q;
1045
1046 p = parse_exp (args, & mode);
1047 if (mode.X_md || (mode.X_op != O_constant))
1048 ill_op ();
1049 else
1050 switch (mode.X_add_number)
1051 {
1052 case 1:
1053 case 2:
1054 ++mode.X_add_number;
1055 /* Fall through. */
1056 case 0:
1057 q = frag_more (2);
1058 *q++ = prefix;
1059 *q = opcode + 8*mode.X_add_number;
1060 break;
1061 default:
1062 ill_op ();
1063 }
1064 return p;
1065 }
1066
1067 static const char *
1068 emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1069 {
1070 expressionS regp;
1071 const char *p;
1072 char *q;
1073
1074 p = parse_exp (args, & regp);
1075 if ((!regp.X_md)
1076 && (regp.X_op == O_register)
1077 && (regp.X_add_number & R_STACKABLE))
1078 {
1079 int rnum;
1080
1081 rnum = regp.X_add_number;
1082 if (rnum&R_INDEX)
1083 {
1084 q = frag_more (2);
1085 *q++ = (rnum&R_IX)?0xDD:0xFD;
1086 }
1087 else
1088 q = frag_more (1);
1089 *q = opcode + ((rnum & 3) << 4);
1090 }
1091 else
1092 ill_op ();
1093
1094 return p;
1095 }
1096
1097 static const char *
1098 emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1099 {
1100 char cc, *q;
1101 const char *p;
1102
1103 p = parse_cc (args, &cc);
1104 q = frag_more (1);
1105 if (p)
1106 *q = opcode + cc;
1107 else
1108 *q = prefix;
1109 return p ? p : args;
1110 }
1111
1112 static const char *
1113 emit_adc (char prefix, char opcode, const char * args)
1114 {
1115 expressionS term;
1116 int rnum;
1117 const char *p;
1118 char *q;
1119
1120 p = parse_exp (args, &term);
1121 if (*p++ != ',')
1122 {
1123 error (_("bad intruction syntax"));
1124 return p;
1125 }
1126
1127 if ((term.X_md) || (term.X_op != O_register))
1128 ill_op ();
1129 else
1130 switch (term.X_add_number)
1131 {
1132 case REG_A:
1133 p = emit_s (0, prefix, p);
1134 break;
1135 case REG_HL:
1136 p = parse_exp (p, &term);
1137 if ((!term.X_md) && (term.X_op == O_register))
1138 {
1139 rnum = term.X_add_number;
1140 if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
1141 {
1142 q = frag_more (2);
1143 *q++ = 0xED;
1144 *q = opcode + ((rnum & 3) << 4);
1145 break;
1146 }
1147 }
1148 /* Fall through. */
1149 default:
1150 ill_op ();
1151 }
1152 return p;
1153 }
1154
1155 static const char *
1156 emit_add (char prefix, char opcode, const char * args)
1157 {
1158 expressionS term;
1159 int lhs, rhs;
1160 const char *p;
1161 char *q;
1162
1163 p = parse_exp (args, &term);
1164 if (*p++ != ',')
1165 {
1166 error (_("bad intruction syntax"));
1167 return p;
1168 }
1169
1170 if ((term.X_md) || (term.X_op != O_register))
1171 ill_op ();
1172 else
1173 switch (term.X_add_number & ~R_INDEX)
1174 {
1175 case REG_A:
1176 p = emit_s (0, prefix, p);
1177 break;
1178 case REG_HL:
1179 lhs = term.X_add_number;
1180 p = parse_exp (p, &term);
1181 if ((!term.X_md) && (term.X_op == O_register))
1182 {
1183 rhs = term.X_add_number;
1184 if ((rhs & R_ARITH)
1185 && ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL)))
1186 {
1187 q = frag_more ((lhs & R_INDEX) ? 2 : 1);
1188 if (lhs & R_INDEX)
1189 *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
1190 *q = opcode + ((rhs & 3) << 4);
1191 break;
1192 }
1193 }
1194 /* Fall through. */
1195 default:
1196 ill_op ();
1197 }
1198 return p;
1199 }
1200
1201 static const char *
1202 emit_bit (char prefix, char opcode, const char * args)
1203 {
1204 expressionS b;
1205 int bn;
1206 const char *p;
1207
1208 p = parse_exp (args, &b);
1209 if (*p++ != ',')
1210 error (_("bad intruction syntax"));
1211
1212 bn = b.X_add_number;
1213 if ((!b.X_md)
1214 && (b.X_op == O_constant)
1215 && (0 <= bn)
1216 && (bn < 8))
1217 {
1218 if (opcode == 0x40)
1219 /* Bit : no optional third operand. */
1220 p = emit_m (prefix, opcode + (bn << 3), p);
1221 else
1222 /* Set, res : resulting byte can be copied to register. */
1223 p = emit_mr (prefix, opcode + (bn << 3), p);
1224 }
1225 else
1226 ill_op ();
1227 return p;
1228 }
1229
1230 static const char *
1231 emit_jpcc (char prefix, char opcode, const char * args)
1232 {
1233 char cc;
1234 const char *p;
1235
1236 p = parse_cc (args, & cc);
1237 if (p && *p++ == ',')
1238 p = emit_call (0, opcode + cc, p);
1239 else
1240 p = (prefix == (char)0xC3)
1241 ? emit_jp (0xE9, prefix, args)
1242 : emit_call (0, prefix, args);
1243 return p;
1244 }
1245
1246 static const char *
1247 emit_jrcc (char prefix, char opcode, const char * args)
1248 {
1249 char cc;
1250 const char *p;
1251
1252 p = parse_cc (args, &cc);
1253 if (p && *p++ == ',')
1254 {
1255 if (cc > (3 << 3))
1256 error (_("condition code invalid for jr"));
1257 else
1258 p = emit_jr (0, opcode + cc, p);
1259 }
1260 else
1261 p = emit_jr (0, prefix, args);
1262
1263 return p;
1264 }
1265
1266 static const char *
1267 emit_ex (char prefix_in ATTRIBUTE_UNUSED,
1268 char opcode_in ATTRIBUTE_UNUSED, const char * args)
1269 {
1270 expressionS op;
1271 const char * p;
1272 char prefix, opcode;
1273
1274 p = parse_exp (args, &op);
1275 p = skip_space (p);
1276 if (*p++ != ',')
1277 {
1278 error (_("bad instruction syntax"));
1279 return p;
1280 }
1281
1282 prefix = opcode = 0;
1283 if (op.X_op == O_register)
1284 switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
1285 {
1286 case REG_AF:
1287 if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
1288 {
1289 /* The scrubber changes '\'' to '`' in this context. */
1290 if (*p == '`')
1291 ++p;
1292 opcode = 0x08;
1293 }
1294 break;
1295 case REG_DE:
1296 if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
1297 opcode = 0xEB;
1298 break;
1299 case REG_SP|0x8000:
1300 p = parse_exp (p, & op);
1301 if (op.X_op == O_register
1302 && op.X_md == 0
1303 && (op.X_add_number & ~R_INDEX) == REG_HL)
1304 {
1305 opcode = 0xE3;
1306 if (R_INDEX & op.X_add_number)
1307 prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
1308 }
1309 break;
1310 }
1311 if (opcode)
1312 emit_insn (prefix, opcode, p);
1313 else
1314 ill_op ();
1315
1316 return p;
1317 }
1318
1319 static const char *
1320 emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1321 const char * args)
1322 {
1323 expressionS reg, port;
1324 const char *p;
1325 char *q;
1326
1327 p = parse_exp (args, &reg);
1328 if (*p++ != ',')
1329 {
1330 error (_("bad intruction syntax"));
1331 return p;
1332 }
1333
1334 p = parse_exp (p, &port);
1335 if (reg.X_md == 0
1336 && reg.X_op == O_register
1337 && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
1338 && (port.X_md))
1339 {
1340 if (port.X_op != O_md1 && port.X_op != O_register)
1341 {
1342 if (REG_A == reg.X_add_number)
1343 {
1344 q = frag_more (1);
1345 *q = 0xDB;
1346 emit_byte (&port, BFD_RELOC_8);
1347 }
1348 else
1349 ill_op ();
1350 }
1351 else
1352 {
1353 if (port.X_add_number == REG_C)
1354 {
1355 if (reg.X_add_number == REG_F)
1356 check_mach (INS_UNDOC);
1357 else
1358 {
1359 q = frag_more (2);
1360 *q++ = 0xED;
1361 *q = 0x40|((reg.X_add_number&7)<<3);
1362 }
1363 }
1364 else
1365 ill_op ();
1366 }
1367 }
1368 else
1369 ill_op ();
1370 return p;
1371 }
1372
1373 static const char *
1374 emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
1375 const char * args)
1376 {
1377 expressionS reg, port;
1378 const char *p;
1379 char *q;
1380
1381 p = parse_exp (args, & port);
1382 if (*p++ != ',')
1383 {
1384 error (_("bad intruction syntax"));
1385 return p;
1386 }
1387 p = parse_exp (p, &reg);
1388 if (!port.X_md)
1389 { ill_op (); return p; }
1390 /* Allow "out (c), 0" as unportable instruction. */
1391 if (reg.X_op == O_constant && reg.X_add_number == 0)
1392 {
1393 check_mach (INS_UNPORT);
1394 reg.X_op = O_register;
1395 reg.X_add_number = 6;
1396 }
1397 if (reg.X_md
1398 || reg.X_op != O_register
1399 || reg.X_add_number > 7)
1400 ill_op ();
1401 else
1402 if (port.X_op != O_register && port.X_op != O_md1)
1403 {
1404 if (REG_A == reg.X_add_number)
1405 {
1406 q = frag_more (1);
1407 *q = 0xD3;
1408 emit_byte (&port, BFD_RELOC_8);
1409 }
1410 else
1411 ill_op ();
1412 }
1413 else
1414 {
1415 if (REG_C == port.X_add_number)
1416 {
1417 q = frag_more (2);
1418 *q++ = 0xED;
1419 *q = 0x41 | (reg.X_add_number << 3);
1420 }
1421 else
1422 ill_op ();
1423 }
1424 return p;
1425 }
1426
1427 static const char *
1428 emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1429 {
1430 expressionS addr;
1431 const char *p;
1432 char *q;
1433
1434 p = parse_exp (args, &addr);
1435 if (addr.X_op != O_constant)
1436 {
1437 error ("rst needs constant address");
1438 return p;
1439 }
1440
1441 if (addr.X_add_number & ~(7 << 3))
1442 ill_op ();
1443 else
1444 {
1445 q = frag_more (1);
1446 *q = opcode + (addr.X_add_number & (7 << 3));
1447 }
1448 return p;
1449 }
1450
1451 static void
1452 emit_ldxhl (char prefix, char opcode, expressionS *src, expressionS *d)
1453 {
1454 char *q;
1455
1456 if (src->X_md)
1457 ill_op ();
1458 else
1459 {
1460 if (src->X_op == O_register)
1461 {
1462 if (src->X_add_number>7)
1463 ill_op ();
1464 if (prefix)
1465 {
1466 q = frag_more (2);
1467 *q++ = prefix;
1468 }
1469 else
1470 q = frag_more (1);
1471 *q = opcode + src->X_add_number;
1472 if (d)
1473 emit_byte (d, BFD_RELOC_Z80_DISP8);
1474 }
1475 else
1476 {
1477 if (prefix)
1478 {
1479 q = frag_more (2);
1480 *q++ = prefix;
1481 }
1482 else
1483 q = frag_more (1);
1484 *q = opcode^0x46;
1485 if (d)
1486 emit_byte (d, BFD_RELOC_Z80_DISP8);
1487 emit_byte (src, BFD_RELOC_8);
1488 }
1489 }
1490 }
1491
1492 static void
1493 emit_ldreg (int dest, expressionS * src)
1494 {
1495 char *q;
1496 int rnum;
1497
1498 switch (dest)
1499 {
1500 /* 8 Bit ld group: */
1501 case REG_I:
1502 case REG_R:
1503 if (src->X_md == 0 && src->X_op == O_register && src->X_add_number == REG_A)
1504 {
1505 q = frag_more (2);
1506 *q++ = 0xED;
1507 *q = (dest == REG_I) ? 0x47 : 0x4F;
1508 }
1509 else
1510 ill_op ();
1511 break;
1512
1513 case REG_A:
1514 if ((src->X_md) && src->X_op != O_register && src->X_op != O_md1)
1515 {
1516 q = frag_more (1);
1517 *q = 0x3A;
1518 emit_word (src);
1519 break;
1520 }
1521
1522 if ((src->X_md)
1523 && src->X_op == O_register
1524 && (src->X_add_number == REG_BC || src->X_add_number == REG_DE))
1525 {
1526 q = frag_more (1);
1527 *q = 0x0A + ((dest & 1) << 4);
1528 break;
1529 }
1530
1531 if ((!src->X_md)
1532 && src->X_op == O_register
1533 && (src->X_add_number == REG_R || src->X_add_number == REG_I))
1534 {
1535 q = frag_more (2);
1536 *q++ = 0xED;
1537 *q = (src->X_add_number == REG_I) ? 0x57 : 0x5F;
1538 break;
1539 }
1540 /* Fall through. */
1541 case REG_B:
1542 case REG_C:
1543 case REG_D:
1544 case REG_E:
1545 emit_sx (0, 0x40 + (dest << 3), src);
1546 break;
1547
1548 case REG_H:
1549 case REG_L:
1550 if ((src->X_md == 0)
1551 && (src->X_op == O_register)
1552 && (src->X_add_number & R_INDEX))
1553 ill_op ();
1554 else
1555 emit_sx (0, 0x40 + (dest << 3), src);
1556 break;
1557
1558 case R_IX | REG_H:
1559 case R_IX | REG_L:
1560 case R_IY | REG_H:
1561 case R_IY | REG_L:
1562 if (src->X_md)
1563 {
1564 ill_op ();
1565 break;
1566 }
1567 check_mach (INS_UNDOC);
1568 if (src-> X_op == O_register)
1569 {
1570 rnum = src->X_add_number;
1571 if ((rnum & ~R_INDEX) < 8
1572 && ((rnum & R_INDEX) == (dest & R_INDEX)
1573 || ( (rnum & ~R_INDEX) != REG_H
1574 && (rnum & ~R_INDEX) != REG_L)))
1575 {
1576 q = frag_more (2);
1577 *q++ = (dest & R_IX) ? 0xDD : 0xFD;
1578 *q = 0x40 + ((dest & 0x07) << 3) + (rnum & 7);
1579 }
1580 else
1581 ill_op ();
1582 }
1583 else
1584 {
1585 q = frag_more (2);
1586 *q++ = (dest & R_IX) ? 0xDD : 0xFD;
1587 *q = 0x06 + ((dest & 0x07) << 3);
1588 emit_byte (src, BFD_RELOC_8);
1589 }
1590 break;
1591
1592 /* 16 Bit ld group: */
1593 case REG_SP:
1594 if (src->X_md == 0
1595 && src->X_op == O_register
1596 && REG_HL == (src->X_add_number &~ R_INDEX))
1597 {
1598 q = frag_more ((src->X_add_number & R_INDEX) ? 2 : 1);
1599 if (src->X_add_number & R_INDEX)
1600 *q++ = (src->X_add_number & R_IX) ? 0xDD : 0xFD;
1601 *q = 0xF9;
1602 break;
1603 }
1604 /* Fall through. */
1605 case REG_BC:
1606 case REG_DE:
1607 if (src->X_op == O_register || src->X_op != O_md1)
1608 ill_op ();
1609 q = frag_more (src->X_md ? 2 : 1);
1610 if (src->X_md)
1611 {
1612 *q++ = 0xED;
1613 *q = 0x4B + ((dest & 3) << 4);
1614 }
1615 else
1616 *q = 0x01 + ((dest & 3) << 4);
1617 emit_word (src);
1618 break;
1619
1620 case REG_HL:
1621 case REG_HL | R_IX:
1622 case REG_HL | R_IY:
1623 if (src->X_op == O_register || src->X_op == O_md1)
1624 ill_op ();
1625 q = frag_more ((dest & R_INDEX) ? 2 : 1);
1626 if (dest & R_INDEX)
1627 * q ++ = (dest & R_IX) ? 0xDD : 0xFD;
1628 *q = (src->X_md) ? 0x2A : 0x21;
1629 emit_word (src);
1630 break;
1631
1632 case REG_AF:
1633 case REG_F:
1634 ill_op ();
1635 break;
1636
1637 default:
1638 abort ();
1639 }
1640 }
1641
1642 static const char *
1643 emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
1644 const char * args)
1645 {
1646 expressionS dst, src;
1647 const char *p;
1648 char *q;
1649 char prefix, opcode;
1650
1651 p = parse_exp (args, &dst);
1652 if (*p++ != ',')
1653 error (_("bad intruction syntax"));
1654 p = parse_exp (p, &src);
1655
1656 switch (dst.X_op)
1657 {
1658 case O_md1:
1659 emit_ldxhl ((dst.X_add_number & R_IX) ? 0xDD : 0xFD, 0x70,
1660 &src, symbol_get_value_expression (dst.X_add_symbol));
1661 break;
1662
1663 case O_register:
1664 if (dst.X_md)
1665 {
1666 switch (dst.X_add_number)
1667 {
1668 case REG_BC:
1669 case REG_DE:
1670 if (src.X_md == 0 && src.X_op == O_register && src.X_add_number == REG_A)
1671 {
1672 q = frag_more (1);
1673 *q = 0x02 + ( (dst.X_add_number & 1) << 4);
1674 }
1675 else
1676 ill_op ();
1677 break;
1678 case REG_HL:
1679 emit_ldxhl (0, 0x70, &src, NULL);
1680 break;
1681 default:
1682 ill_op ();
1683 }
1684 }
1685 else
1686 emit_ldreg (dst.X_add_number, &src);
1687 break;
1688
1689 default:
1690 if (src.X_md != 0 || src.X_op != O_register)
1691 ill_op ();
1692 prefix = opcode = 0;
1693 switch (src.X_add_number)
1694 {
1695 case REG_A:
1696 opcode = 0x32; break;
1697 case REG_BC: case REG_DE: case REG_SP:
1698 prefix = 0xED; opcode = 0x43 + ((src.X_add_number&3)<<4); break;
1699 case REG_HL:
1700 opcode = 0x22; break;
1701 case REG_HL|R_IX:
1702 prefix = 0xDD; opcode = 0x22; break;
1703 case REG_HL|R_IY:
1704 prefix = 0xFD; opcode = 0x22; break;
1705 }
1706 if (opcode)
1707 {
1708 q = frag_more (prefix?2:1);
1709 if (prefix)
1710 *q++ = prefix;
1711 *q = opcode;
1712 emit_word (&dst);
1713 }
1714 else
1715 ill_op ();
1716 }
1717 return p;
1718 }
1719
1720 static const char *
1721 emit_data (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1722 {
1723 const char *p, *q;
1724 char *u, quote;
1725 int cnt;
1726 expressionS exp;
1727
1728 p = skip_space (args);
1729 if (!*p)
1730 error (_("missing operand"));
1731
1732 while (*p)
1733 {
1734 if (*p == '\"' || *p == '\'')
1735 {
1736 if (opcode == 1)
1737 {
1738 for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
1739 ;
1740 u = frag_more (cnt);
1741 memcpy (u, q, cnt);
1742 if (!*p)
1743 as_warn (_("unterminated string"));
1744 else
1745 p = skip_space (p+1);
1746 }
1747 else
1748 {
1749 ill_op ();
1750 break;
1751 }
1752 }
1753 else
1754 {
1755 p = parse_exp (p, &exp);
1756 if (exp.X_op == O_md1 || exp.X_op == O_register)
1757 {
1758 ill_op ();
1759 break;
1760 }
1761 if (exp.X_md)
1762 as_warn (_("parentheses ignored"));
1763 if (opcode == 1)
1764 emit_byte (&exp, BFD_RELOC_8);
1765 else
1766 emit_word (&exp);
1767 p = skip_space (p);
1768 }
1769 if (*p)
1770 {
1771 if (*p != ',')
1772 as_warn (_("missing ','"));
1773 else
1774 ++p;
1775 }
1776 }
1777 return p;
1778 }
1779
1780 static const char *
1781 emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1782 {
1783 const char *p;
1784
1785 p = skip_space (args);
1786 if (TOLOWER (*p++) != 'a' || *p++ != ',')
1787 ill_op ();
1788 else
1789 {
1790 char *q, reg;
1791
1792 reg = TOLOWER (*p++);
1793 switch (reg)
1794 {
1795 case 'b':
1796 case 'c':
1797 case 'd':
1798 case 'e':
1799 check_mach (INS_R800);
1800 if (!*skip_space (p))
1801 {
1802 q = frag_more (2);
1803 *q++ = prefix;
1804 *q = opcode + ((reg - 'b') << 3);
1805 break;
1806 }
1807 default:
1808 ill_op ();
1809 }
1810 }
1811 return p;
1812 }
1813
1814 static const char *
1815 emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
1816 {
1817 const char *p;
1818
1819 p = skip_space (args);
1820 if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
1821 ill_op ();
1822 else
1823 {
1824 expressionS reg;
1825 char *q;
1826
1827 p = parse_exp (p, & reg);
1828
1829 if ((!reg.X_md) && reg.X_op == O_register)
1830 switch (reg.X_add_number)
1831 {
1832 case REG_BC:
1833 case REG_SP:
1834 check_mach (INS_R800);
1835 q = frag_more (2);
1836 *q++ = prefix;
1837 *q = opcode + ((reg.X_add_number & 3) << 4);
1838 break;
1839 default:
1840 ill_op ();
1841 }
1842 }
1843 return p;
1844 }
1845
1846 static table_t instab[] =
1847 {
1848 { "adc", 0x88, 0x4A, emit_adc },
1849 { "add", 0x80, 0x09, emit_add },
1850 { "and", 0x00, 0xA0, emit_s },
1851 { "bit", 0xCB, 0x40, emit_bit },
1852 { "call", 0xCD, 0xC4, emit_jpcc },
1853 { "ccf", 0x00, 0x3F, emit_insn },
1854 { "cp", 0x00, 0xB8, emit_s },
1855 { "cpd", 0xED, 0xA9, emit_insn },
1856 { "cpdr", 0xED, 0xB9, emit_insn },
1857 { "cpi", 0xED, 0xA1, emit_insn },
1858 { "cpir", 0xED, 0xB1, emit_insn },
1859 { "cpl", 0x00, 0x2F, emit_insn },
1860 { "daa", 0x00, 0x27, emit_insn },
1861 { "db", 0x00, 0x01, emit_data },
1862 { "dec", 0x0B, 0x05, emit_incdec },
1863 { "defb", 0x00, 0x01, emit_data },
1864 { "defw", 0x00, 0x02, emit_data },
1865 { "di", 0x00, 0xF3, emit_insn },
1866 { "djnz", 0x00, 0x10, emit_jr },
1867 { "dw", 0x00, 0x02, emit_data },
1868 { "ei", 0x00, 0xFB, emit_insn },
1869 { "ex", 0x00, 0x00, emit_ex},
1870 { "exx", 0x00, 0xD9, emit_insn },
1871 { "halt", 0x00, 0x76, emit_insn },
1872 { "im", 0xED, 0x46, emit_im },
1873 { "in", 0x00, 0x00, emit_in },
1874 { "inc", 0x03, 0x04, emit_incdec },
1875 { "ind", 0xED, 0xAA, emit_insn },
1876 { "indr", 0xED, 0xBA, emit_insn },
1877 { "ini", 0xED, 0xA2, emit_insn },
1878 { "inir", 0xED, 0xB2, emit_insn },
1879 { "jp", 0xC3, 0xC2, emit_jpcc },
1880 { "jr", 0x18, 0x20, emit_jrcc },
1881 { "ld", 0x00, 0x00, emit_ld },
1882 { "ldd", 0xED, 0xA8, emit_insn },
1883 { "lddr", 0xED, 0xB8, emit_insn },
1884 { "ldi", 0xED, 0xA0, emit_insn },
1885 { "ldir", 0xED, 0xB0, emit_insn },
1886 { "mulub", 0xED, 0xC5, emit_mulub }, /* R800 only. */
1887 { "muluw", 0xED, 0xC3, emit_muluw }, /* R800 only. */
1888 { "neg", 0xed, 0x44, emit_insn },
1889 { "nop", 0x00, 0x00, emit_insn },
1890 { "or", 0x00, 0xB0, emit_s },
1891 { "otdr", 0xED, 0xBB, emit_insn },
1892 { "otir", 0xED, 0xB3, emit_insn },
1893 { "out", 0x00, 0x00, emit_out },
1894 { "outd", 0xED, 0xAB, emit_insn },
1895 { "outi", 0xED, 0xA3, emit_insn },
1896 { "pop", 0x00, 0xC1, emit_pop },
1897 { "push", 0x00, 0xC5, emit_pop },
1898 { "res", 0xCB, 0x80, emit_bit },
1899 { "ret", 0xC9, 0xC0, emit_retcc },
1900 { "reti", 0xED, 0x4D, emit_insn },
1901 { "retn", 0xED, 0x45, emit_insn },
1902 { "rl", 0xCB, 0x10, emit_mr },
1903 { "rla", 0x00, 0x17, emit_insn },
1904 { "rlc", 0xCB, 0x00, emit_mr },
1905 { "rlca", 0x00, 0x07, emit_insn },
1906 { "rld", 0xED, 0x6F, emit_insn },
1907 { "rr", 0xCB, 0x18, emit_mr },
1908 { "rra", 0x00, 0x1F, emit_insn },
1909 { "rrc", 0xCB, 0x08, emit_mr },
1910 { "rrca", 0x00, 0x0F, emit_insn },
1911 { "rrd", 0xED, 0x67, emit_insn },
1912 { "rst", 0x00, 0xC7, emit_rst},
1913 { "sbc", 0x98, 0x42, emit_adc },
1914 { "scf", 0x00, 0x37, emit_insn },
1915 { "set", 0xCB, 0xC0, emit_bit },
1916 { "sla", 0xCB, 0x20, emit_mr },
1917 { "sli", 0xCB, 0x30, emit_mr },
1918 { "sll", 0xCB, 0x30, emit_mr },
1919 { "sra", 0xCB, 0x28, emit_mr },
1920 { "srl", 0xCB, 0x38, emit_mr },
1921 { "sub", 0x00, 0x90, emit_s },
1922 { "xor", 0x00, 0xA8, emit_s },
1923 } ;
1924
1925 void
1926 md_assemble (char* str)
1927 {
1928 const char *p;
1929 char * old_ptr;
1930 int i;
1931 table_t *insp;
1932
1933 err_flag = 0;
1934 old_ptr = input_line_pointer;
1935 p = skip_space (str);
1936 for (i = 0; (i < BUFLEN) && (ISALPHA (*p));)
1937 buf[i++] = TOLOWER (*p++);
1938
1939 if ((i == BUFLEN)
1940 || ((*p) && (!ISSPACE (*p))))
1941 as_bad (_("illegal instruction '%s'"), buf);
1942
1943 buf[i] = 0;
1944 p = skip_space (p);
1945 key = buf;
1946
1947 insp = bsearch (&key, instab, ARRAY_SIZE (instab),
1948 sizeof (instab[0]), key_cmp);
1949 if (!insp)
1950 as_bad (_("illegal instruction '%s'"), buf);
1951 else
1952 {
1953 p = insp->fp (insp->prefix, insp->opcode, p);
1954 p = skip_space (p);
1955 if ((!err_flag) && *p)
1956 as_bad (_("junk at end of line, first unrecognized character is `%c'"),
1957 *p);
1958 }
1959 input_line_pointer = old_ptr;
1960 }
1961
1962 void
1963 md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
1964 {
1965 long val = * (long *) valP;
1966 char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1967
1968 switch (fixP->fx_r_type)
1969 {
1970 case BFD_RELOC_8_PCREL:
1971 if (fixP->fx_addsy)
1972 {
1973 fixP->fx_no_overflow = 1;
1974 fixP->fx_done = 0;
1975 }
1976 else
1977 {
1978 fixP->fx_no_overflow = (-128 <= val && val < 128);
1979 if (!fixP->fx_no_overflow)
1980 as_bad_where (fixP->fx_file, fixP->fx_line,
1981 _("relative jump out of range"));
1982 *buf++ = val;
1983 fixP->fx_done = 1;
1984 }
1985 break;
1986
1987 case BFD_RELOC_Z80_DISP8:
1988 if (fixP->fx_addsy)
1989 {
1990 fixP->fx_no_overflow = 1;
1991 fixP->fx_done = 0;
1992 }
1993 else
1994 {
1995 fixP->fx_no_overflow = (-128 <= val && val < 128);
1996 if (!fixP->fx_no_overflow)
1997 as_bad_where (fixP->fx_file, fixP->fx_line,
1998 _("index offset out of range"));
1999 *buf++ = val;
2000 fixP->fx_done = 1;
2001 }
2002 break;
2003
2004 case BFD_RELOC_8:
2005 if (val > 255 || val < -128)
2006 as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow"));
2007 *buf++ = val;
2008 if (fixP->fx_addsy == NULL)
2009 fixP->fx_done = 1;
2010 break;
2011
2012 case BFD_RELOC_16:
2013 *buf++ = val;
2014 *buf++ = (val >> 8);
2015 if (fixP->fx_addsy == NULL)
2016 fixP->fx_done = 1;
2017 break;
2018
2019 case BFD_RELOC_32: /* .Long may produce this. */
2020 *buf++ = val;
2021 *buf++ = (val >> 8);
2022 *buf++ = (val >> 16);
2023 *buf++ = (val >> 24);
2024 if (fixP->fx_addsy == NULL)
2025 fixP->fx_done = 1;
2026 break;
2027
2028 default:
2029 printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
2030 abort ();
2031 }
2032 }
2033
2034 /* GAS will call this to generate a reloc. GAS will pass the
2035 resulting reloc to `bfd_install_relocation'. This currently works
2036 poorly, as `bfd_install_relocation' often does the wrong thing, and
2037 instances of `tc_gen_reloc' have been written to work around the
2038 problems, which in turns makes it difficult to fix
2039 `bfd_install_relocation'. */
2040
2041 /* If while processing a fixup, a reloc really
2042 needs to be created then it is done here. */
2043
2044 arelent *
2045 tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
2046 {
2047 arelent *reloc;
2048
2049 if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type))
2050 {
2051 as_bad_where (fixp->fx_file, fixp->fx_line,
2052 _("reloc %d not supported by object file format"),
2053 (int) fixp->fx_r_type);
2054 return NULL;
2055 }
2056
2057 reloc = xmalloc (sizeof (arelent));
2058 reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
2059 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2060 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2061 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2062 reloc->addend = fixp->fx_offset;
2063
2064 return reloc;
2065 }
2066
This page took 0.071562 seconds and 5 git commands to generate.