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