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