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