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