Home | History | Annotate | Line # | Download | only in config
tc-z80.c revision 1.9
      1  1.7  christos /* tc-z80.c -- Assemble code for the Zilog Z80, Z180, EZ80 and ASCII R800
      2  1.9  christos    Copyright (C) 2005-2024 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.9  christos z80_md_finish (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.9  christos   resolve_register (op);
    930  1.1  christos   switch (op->X_op)
    931  1.1  christos     {
    932  1.1  christos     case O_absent:
    933  1.1  christos       error (_("missing operand"));
    934  1.1  christos       break;
    935  1.1  christos     case O_illegal:
    936  1.1  christos       error (_("bad expression syntax"));
    937  1.1  christos       break;
    938  1.3  christos     default:
    939  1.3  christos       break;
    940  1.1  christos     }
    941  1.7  christos 
    942  1.7  christos   if (make_shift >= 0)
    943  1.7  christos     {
    944  1.7  christos       /* replace [op] by [op >> shift] */
    945  1.7  christos       expressionS data;
    946  1.7  christos       op->X_add_symbol = make_expr_symbol (op);
    947  1.7  christos       op->X_add_number = 0;
    948  1.7  christos       op->X_op = O_right_shift;
    949  1.7  christos       memset (&data, 0, sizeof (data));
    950  1.7  christos       data.X_op = O_constant;
    951  1.7  christos       data.X_add_number = make_shift;
    952  1.7  christos       op->X_op_symbol = make_expr_symbol (&data);
    953  1.7  christos     }
    954  1.1  christos   return input_line_pointer;
    955  1.1  christos }
    956  1.1  christos 
    957  1.7  christos static int
    958  1.7  christos unify_indexed (expressionS *op)
    959  1.7  christos {
    960  1.7  christos   if (O_register != symbol_get_value_expression (op->X_add_symbol)->X_op)
    961  1.7  christos     return 0;
    962  1.7  christos 
    963  1.7  christos   int rnum = symbol_get_value_expression (op->X_add_symbol)->X_add_number;
    964  1.7  christos   if ( ((REG_IX != rnum) && (REG_IY != rnum)) || contains_register (op->X_op_symbol))
    965  1.7  christos     {
    966  1.7  christos       ill_op ();
    967  1.7  christos       return 0;
    968  1.7  christos     }
    969  1.7  christos 
    970  1.7  christos   /* Convert subtraction to addition of negative value.  */
    971  1.7  christos   if (O_subtract == op->X_op)
    972  1.7  christos     {
    973  1.7  christos       expressionS minus;
    974  1.8  christos       memset (&minus, 0, sizeof (minus));
    975  1.7  christos       minus.X_op = O_uminus;
    976  1.7  christos       minus.X_add_symbol = op->X_op_symbol;
    977  1.7  christos       op->X_op_symbol = make_expr_symbol (&minus);
    978  1.7  christos       op->X_op = O_add;
    979  1.7  christos     }
    980  1.7  christos 
    981  1.7  christos   /* Clear X_add_number of the expression.  */
    982  1.7  christos   if (op->X_add_number != 0)
    983  1.7  christos     {
    984  1.7  christos       expressionS add;
    985  1.7  christos       memset (&add, 0, sizeof (add));
    986  1.7  christos       add.X_op = O_symbol;
    987  1.7  christos       add.X_add_number = op->X_add_number;
    988  1.7  christos       add.X_add_symbol = op->X_op_symbol;
    989  1.7  christos       op->X_add_symbol = make_expr_symbol (&add);
    990  1.7  christos     }
    991  1.7  christos   else
    992  1.7  christos     op->X_add_symbol = op->X_op_symbol;
    993  1.7  christos 
    994  1.7  christos   op->X_add_number = rnum;
    995  1.7  christos   op->X_op_symbol = 0;
    996  1.7  christos   return 1;
    997  1.7  christos }
    998  1.7  christos 
    999  1.7  christos /* Parse expression, change operator to O_md1 for indexed addressing.  */
   1000  1.1  christos static const char *
   1001  1.1  christos parse_exp (const char *s, expressionS *op)
   1002  1.1  christos {
   1003  1.1  christos   const char* res = parse_exp_not_indexed (s, op);
   1004  1.1  christos   switch (op->X_op)
   1005  1.1  christos     {
   1006  1.1  christos     case O_add:
   1007  1.1  christos     case O_subtract:
   1008  1.7  christos       if (unify_indexed (op) && op->X_md)
   1009  1.7  christos         op->X_op = O_md1;
   1010  1.1  christos       break;
   1011  1.1  christos     case O_register:
   1012  1.7  christos       if (op->X_md && ((REG_IX == op->X_add_number) || (REG_IY == op->X_add_number)))
   1013  1.1  christos         {
   1014  1.1  christos 	  op->X_add_symbol = zero;
   1015  1.1  christos 	  op->X_op = O_md1;
   1016  1.1  christos 	}
   1017  1.1  christos 	break;
   1018  1.7  christos     case O_constant:
   1019  1.7  christos       /* parse SDCC syntax where index register offset placed before parentheses */
   1020  1.7  christos       if (sdcc_compat && is_indir (res))
   1021  1.7  christos         {
   1022  1.7  christos           expressionS off;
   1023  1.7  christos           off = *op;
   1024  1.7  christos           res = parse_exp (res, op);
   1025  1.7  christos           if (op->X_op != O_md1 || op->X_add_symbol != zero)
   1026  1.7  christos             ill_op ();
   1027  1.7  christos           else
   1028  1.7  christos               op->X_add_symbol = make_expr_symbol (&off);
   1029  1.7  christos         }
   1030  1.7  christos       break;
   1031  1.3  christos     default:
   1032  1.3  christos       break;
   1033  1.1  christos     }
   1034  1.1  christos   return res;
   1035  1.1  christos }
   1036  1.1  christos 
   1037  1.1  christos /* Condition codes, including some synonyms provided by HiTech zas.  */
   1038  1.1  christos static const struct reg_entry cc_tab[] =
   1039  1.1  christos {
   1040  1.8  christos   { "age", 6 << 3, INS_ALL },
   1041  1.8  christos   { "alt", 7 << 3, INS_ALL },
   1042  1.8  christos   { "c",   3 << 3, INS_ALL },
   1043  1.8  christos   { "di",  4 << 3, INS_ALL },
   1044  1.8  christos   { "ei",  5 << 3, INS_ALL },
   1045  1.8  christos   { "lge", 2 << 3, INS_ALL },
   1046  1.8  christos   { "llt", 3 << 3, INS_ALL },
   1047  1.8  christos   { "m",   7 << 3, INS_ALL },
   1048  1.8  christos   { "nc",  2 << 3, INS_ALL },
   1049  1.8  christos   { "nz",  0 << 3, INS_ALL },
   1050  1.8  christos   { "p",   6 << 3, INS_ALL },
   1051  1.8  christos   { "pe",  5 << 3, INS_ALL },
   1052  1.8  christos   { "po",  4 << 3, INS_ALL },
   1053  1.8  christos   { "z",   1 << 3, INS_ALL },
   1054  1.1  christos } ;
   1055  1.1  christos 
   1056  1.1  christos /* Parse condition code.  */
   1057  1.1  christos static const char *
   1058  1.1  christos parse_cc (const char *s, char * op)
   1059  1.1  christos {
   1060  1.1  christos   const char *p;
   1061  1.1  christos   int i;
   1062  1.1  christos   struct reg_entry * cc_p;
   1063  1.1  christos 
   1064  1.1  christos   for (i = 0; i < BUFLEN; ++i)
   1065  1.1  christos     {
   1066  1.1  christos       if (!ISALPHA (s[i])) /* Condition codes consist of letters only.  */
   1067  1.1  christos 	break;
   1068  1.1  christos       buf[i] = TOLOWER (s[i]);
   1069  1.1  christos     }
   1070  1.1  christos 
   1071  1.1  christos   if ((i < BUFLEN)
   1072  1.1  christos       && ((s[i] == 0) || (s[i] == ',')))
   1073  1.1  christos     {
   1074  1.1  christos       buf[i] = 0;
   1075  1.1  christos       cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
   1076  1.1  christos 		      sizeof (cc_tab[0]), key_cmp);
   1077  1.1  christos     }
   1078  1.1  christos   else
   1079  1.1  christos     cc_p = NULL;
   1080  1.1  christos 
   1081  1.1  christos   if (cc_p)
   1082  1.1  christos     {
   1083  1.1  christos       *op = cc_p->number;
   1084  1.1  christos       p = s + i;
   1085  1.1  christos     }
   1086  1.1  christos   else
   1087  1.1  christos     p = NULL;
   1088  1.1  christos 
   1089  1.1  christos   return p;
   1090  1.1  christos }
   1091  1.1  christos 
   1092  1.1  christos static const char *
   1093  1.1  christos emit_insn (char prefix, char opcode, const char * args)
   1094  1.1  christos {
   1095  1.1  christos   char *p;
   1096  1.1  christos 
   1097  1.1  christos   if (prefix)
   1098  1.1  christos     {
   1099  1.1  christos       p = frag_more (2);
   1100  1.1  christos       *p++ = prefix;
   1101  1.1  christos     }
   1102  1.1  christos   else
   1103  1.1  christos     p = frag_more (1);
   1104  1.1  christos   *p = opcode;
   1105  1.1  christos   return args;
   1106  1.1  christos }
   1107  1.1  christos 
   1108  1.1  christos void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
   1109  1.1  christos {
   1110  1.1  christos   bfd_reloc_code_real_type r[4] =
   1111  1.1  christos     {
   1112  1.1  christos       BFD_RELOC_8,
   1113  1.1  christos       BFD_RELOC_16,
   1114  1.1  christos       BFD_RELOC_24,
   1115  1.1  christos       BFD_RELOC_32
   1116  1.1  christos     };
   1117  1.1  christos 
   1118  1.3  christos   if (nbytes < 1 || nbytes > 4)
   1119  1.1  christos     {
   1120  1.1  christos       as_bad (_("unsupported BFD relocation size %u"), nbytes);
   1121  1.1  christos     }
   1122  1.1  christos   else
   1123  1.1  christos     {
   1124  1.1  christos       fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
   1125  1.1  christos     }
   1126  1.1  christos }
   1127  1.1  christos 
   1128  1.1  christos static void
   1129  1.7  christos emit_data_val (expressionS * val, int size)
   1130  1.7  christos {
   1131  1.7  christos   char *p;
   1132  1.7  christos   bfd_reloc_code_real_type r_type;
   1133  1.7  christos 
   1134  1.7  christos   p = frag_more (size);
   1135  1.7  christos   if (val->X_op == O_constant)
   1136  1.7  christos     {
   1137  1.7  christos       int i;
   1138  1.8  christos 
   1139  1.8  christos        /* PR 28791:
   1140  1.8  christos 	  Check for overflow, but ignore values that were generated by bit
   1141  1.8  christos 	  manipulation operators (eg ~0xe6 and -7).  This does mean that
   1142  1.8  christos 	  manipluated overlarge values will not be reported (eg ~0x1234),
   1143  1.8  christos 	  but it does help to maintain compatibility with earlier versions
   1144  1.8  christos 	  of the assembler.  */
   1145  1.8  christos       if (! val->X_extrabit
   1146  1.9  christos 	  && is_overflow (val->X_add_number, size * 8))
   1147  1.9  christos 	as_warn ( _("%d-bit overflow (%+" PRId64 ")"), size * 8,
   1148  1.9  christos 		  (int64_t) val->X_add_number);
   1149  1.7  christos       for (i = 0; i < size; ++i)
   1150  1.9  christos 	p[i] = (val->X_add_number >> (i * 8)) & 0xff;
   1151  1.7  christos       return;
   1152  1.7  christos     }
   1153  1.7  christos 
   1154  1.7  christos   switch (size)
   1155  1.7  christos     {
   1156  1.7  christos     case 1: r_type = BFD_RELOC_8; break;
   1157  1.7  christos     case 2: r_type = BFD_RELOC_16; break;
   1158  1.7  christos     case 3: r_type = BFD_RELOC_24; break;
   1159  1.7  christos     case 4: r_type = BFD_RELOC_32; break;
   1160  1.7  christos     case 8: r_type = BFD_RELOC_64; break;
   1161  1.7  christos     default:
   1162  1.7  christos       as_fatal (_("invalid data size %d"), size);
   1163  1.7  christos     }
   1164  1.7  christos 
   1165  1.7  christos   if (   (val->X_op == O_register)
   1166  1.7  christos       || (val->X_op == O_md1)
   1167  1.7  christos       || contains_register (val->X_add_symbol)
   1168  1.7  christos       || contains_register (val->X_op_symbol))
   1169  1.7  christos     ill_op ();
   1170  1.7  christos 
   1171  1.7  christos   if (size <= 2 && val->X_op_symbol)
   1172  1.7  christos     {
   1173  1.8  christos       bool simplify = true;
   1174  1.7  christos       int shift = symbol_get_value_expression (val->X_op_symbol)->X_add_number;
   1175  1.7  christos       if (val->X_op == O_bit_and && shift == (1 << (size*8))-1)
   1176  1.7  christos 	shift = 0;
   1177  1.7  christos       else if (val->X_op != O_right_shift)
   1178  1.7  christos 	shift = -1;
   1179  1.7  christos 
   1180  1.7  christos       if (size == 1)
   1181  1.7  christos 	{
   1182  1.7  christos 	  switch (shift)
   1183  1.7  christos 	    {
   1184  1.7  christos 	    case 0: r_type = BFD_RELOC_Z80_BYTE0; break;
   1185  1.7  christos 	    case 8: r_type = BFD_RELOC_Z80_BYTE1; break;
   1186  1.7  christos 	    case 16: r_type = BFD_RELOC_Z80_BYTE2; break;
   1187  1.7  christos 	    case 24: r_type = BFD_RELOC_Z80_BYTE3; break;
   1188  1.8  christos 	    default: simplify = false;
   1189  1.7  christos 	    }
   1190  1.7  christos 	}
   1191  1.7  christos       else /* if (size == 2) */
   1192  1.7  christos 	{
   1193  1.7  christos 	  switch (shift)
   1194  1.7  christos 	    {
   1195  1.7  christos 	    case 0: r_type = BFD_RELOC_Z80_WORD0; break;
   1196  1.7  christos 	    case 16: r_type = BFD_RELOC_Z80_WORD1; break;
   1197  1.8  christos 	    case 8:
   1198  1.8  christos 	    case 24: /* add two byte fixups */
   1199  1.8  christos 	      val->X_op = O_symbol;
   1200  1.8  christos 	      val->X_op_symbol = NULL;
   1201  1.8  christos 	      val->X_add_number = 0;
   1202  1.8  christos 	      if (shift == 8)
   1203  1.8  christos 		{
   1204  1.8  christos 		  fix_new_exp (frag_now, p++ - frag_now->fr_literal, 1, val, false,
   1205  1.8  christos 			       BFD_RELOC_Z80_BYTE1);
   1206  1.8  christos 		  /* prepare to next byte */
   1207  1.8  christos 		  r_type = BFD_RELOC_Z80_BYTE2;
   1208  1.8  christos 		}
   1209  1.8  christos 	      else
   1210  1.8  christos 		r_type = BFD_RELOC_Z80_BYTE3; /* high byte will be 0 */
   1211  1.8  christos 	      size = 1;
   1212  1.8  christos 	      simplify = false;
   1213  1.8  christos 	      break;
   1214  1.8  christos 	    default: simplify = false;
   1215  1.7  christos 	    }
   1216  1.7  christos 	}
   1217  1.7  christos 
   1218  1.7  christos       if (simplify)
   1219  1.7  christos 	{
   1220  1.7  christos 	  val->X_op = O_symbol;
   1221  1.7  christos 	  val->X_op_symbol = NULL;
   1222  1.7  christos 	  val->X_add_number = 0;
   1223  1.7  christos 	}
   1224  1.7  christos     }
   1225  1.7  christos 
   1226  1.8  christos   fix_new_exp (frag_now, p - frag_now->fr_literal, size, val, false, r_type);
   1227  1.7  christos }
   1228  1.7  christos 
   1229  1.7  christos static void
   1230  1.1  christos emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
   1231  1.1  christos {
   1232  1.1  christos   char *p;
   1233  1.1  christos 
   1234  1.7  christos   if (r_type == BFD_RELOC_8)
   1235  1.7  christos     {
   1236  1.7  christos       emit_data_val (val, 1);
   1237  1.7  christos       return;
   1238  1.7  christos     }
   1239  1.1  christos   p = frag_more (1);
   1240  1.1  christos   *p = val->X_add_number;
   1241  1.8  christos   if (contains_register (val->X_add_symbol) || contains_register (val->X_op_symbol))
   1242  1.1  christos     {
   1243  1.7  christos       ill_op ();
   1244  1.1  christos     }
   1245  1.1  christos   else if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
   1246  1.1  christos     {
   1247  1.1  christos       as_bad (_("cannot make a relative jump to an absolute location"));
   1248  1.1  christos     }
   1249  1.1  christos   else if (val->X_op == O_constant)
   1250  1.1  christos     {
   1251  1.8  christos       if ((val->X_add_number < -128) || (val->X_add_number >= 128))
   1252  1.1  christos 	{
   1253  1.1  christos 	  if (r_type == BFD_RELOC_Z80_DISP8)
   1254  1.9  christos 	    as_bad (_("index overflow (%+" PRId64 ")"),
   1255  1.9  christos 		    (int64_t) val->X_add_number);
   1256  1.1  christos 	  else
   1257  1.9  christos 	    as_bad (_("offset overflow (%+" PRId64 ")"),
   1258  1.9  christos 		    (int64_t) val->X_add_number);
   1259  1.1  christos 	}
   1260  1.1  christos     }
   1261  1.1  christos   else
   1262  1.1  christos     {
   1263  1.8  christos       /* For symbols only, constants are stored at begin of function.  */
   1264  1.3  christos       fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
   1265  1.8  christos 		   r_type == BFD_RELOC_8_PCREL, r_type);
   1266  1.1  christos     }
   1267  1.1  christos }
   1268  1.1  christos 
   1269  1.1  christos static void
   1270  1.1  christos emit_word (expressionS * val)
   1271  1.1  christos {
   1272  1.7  christos   emit_data_val (val, (inst_mode & INST_MODE_IL) ? 3 : 2);
   1273  1.1  christos }
   1274  1.1  christos 
   1275  1.1  christos static void
   1276  1.1  christos emit_mx (char prefix, char opcode, int shift, expressionS * arg)
   1277  1.1  christos      /* The operand m may be r, (hl), (ix+d), (iy+d),
   1278  1.1  christos 	if 0 == prefix m may also be ixl, ixh, iyl, iyh.  */
   1279  1.1  christos {
   1280  1.1  christos   char *q;
   1281  1.1  christos   int rnum;
   1282  1.1  christos 
   1283  1.1  christos   rnum = arg->X_add_number;
   1284  1.1  christos   switch (arg->X_op)
   1285  1.1  christos     {
   1286  1.1  christos     case O_register:
   1287  1.1  christos       if (arg->X_md)
   1288  1.1  christos 	{
   1289  1.1  christos 	  if (rnum != REG_HL)
   1290  1.1  christos 	    {
   1291  1.1  christos 	      ill_op ();
   1292  1.1  christos 	      break;
   1293  1.1  christos 	    }
   1294  1.1  christos 	  else
   1295  1.1  christos 	    rnum = 6;
   1296  1.1  christos 	}
   1297  1.1  christos       else
   1298  1.1  christos 	{
   1299  1.1  christos 	  if ((prefix == 0) && (rnum & R_INDEX))
   1300  1.1  christos 	    {
   1301  1.1  christos 	      prefix = (rnum & R_IX) ? 0xDD : 0xFD;
   1302  1.8  christos 	      if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
   1303  1.7  christos                 check_mach (INS_IDX_HALF);
   1304  1.1  christos 	      rnum &= ~R_INDEX;
   1305  1.1  christos 	    }
   1306  1.1  christos 	  if (rnum > 7)
   1307  1.1  christos 	    {
   1308  1.1  christos 	      ill_op ();
   1309  1.1  christos 	      break;
   1310  1.1  christos 	    }
   1311  1.1  christos 	}
   1312  1.1  christos       q = frag_more (prefix ? 2 : 1);
   1313  1.1  christos       if (prefix)
   1314  1.1  christos 	* q ++ = prefix;
   1315  1.1  christos       * q ++ = opcode + (rnum << shift);
   1316  1.1  christos       break;
   1317  1.1  christos     case O_md1:
   1318  1.7  christos       if (ins_ok & INS_GBZ80)
   1319  1.7  christos         {
   1320  1.7  christos           ill_op ();
   1321  1.7  christos           break;
   1322  1.7  christos         }
   1323  1.1  christos       q = frag_more (2);
   1324  1.1  christos       *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
   1325  1.1  christos       *q = (prefix) ? prefix : (opcode + (6 << shift));
   1326  1.1  christos       {
   1327  1.1  christos 	expressionS offset = *arg;
   1328  1.1  christos 	offset.X_op = O_symbol;
   1329  1.1  christos 	offset.X_add_number = 0;
   1330  1.1  christos 	emit_byte (&offset, BFD_RELOC_Z80_DISP8);
   1331  1.1  christos       }
   1332  1.1  christos       if (prefix)
   1333  1.1  christos 	{
   1334  1.1  christos 	  q = frag_more (1);
   1335  1.1  christos 	  *q = opcode+(6<<shift);
   1336  1.1  christos 	}
   1337  1.1  christos       break;
   1338  1.1  christos     default:
   1339  1.1  christos       abort ();
   1340  1.1  christos     }
   1341  1.1  christos }
   1342  1.1  christos 
   1343  1.1  christos /* The operand m may be r, (hl), (ix+d), (iy+d),
   1344  1.1  christos    if 0 = prefix m may also be ixl, ixh, iyl, iyh.  */
   1345  1.1  christos static const char *
   1346  1.1  christos emit_m (char prefix, char opcode, const char *args)
   1347  1.1  christos {
   1348  1.1  christos   expressionS arg_m;
   1349  1.1  christos   const char *p;
   1350  1.1  christos 
   1351  1.1  christos   p = parse_exp (args, &arg_m);
   1352  1.1  christos   switch (arg_m.X_op)
   1353  1.1  christos     {
   1354  1.1  christos     case O_md1:
   1355  1.1  christos     case O_register:
   1356  1.1  christos       emit_mx (prefix, opcode, 0, &arg_m);
   1357  1.1  christos       break;
   1358  1.1  christos     default:
   1359  1.1  christos       ill_op ();
   1360  1.1  christos     }
   1361  1.1  christos   return p;
   1362  1.1  christos }
   1363  1.1  christos 
   1364  1.1  christos /* The operand m may be as above or one of the undocumented
   1365  1.1  christos    combinations (ix+d),r and (iy+d),r (if unportable instructions
   1366  1.1  christos    are allowed).  */
   1367  1.7  christos 
   1368  1.1  christos static const char *
   1369  1.1  christos emit_mr (char prefix, char opcode, const char *args)
   1370  1.1  christos {
   1371  1.1  christos   expressionS arg_m, arg_r;
   1372  1.1  christos   const char *p;
   1373  1.1  christos 
   1374  1.1  christos   p = parse_exp (args, & arg_m);
   1375  1.1  christos 
   1376  1.1  christos   switch (arg_m.X_op)
   1377  1.1  christos     {
   1378  1.1  christos     case O_md1:
   1379  1.1  christos       if (*p == ',')
   1380  1.1  christos 	{
   1381  1.1  christos 	  p = parse_exp (p + 1, & arg_r);
   1382  1.1  christos 
   1383  1.1  christos 	  if ((arg_r.X_md == 0)
   1384  1.1  christos 	      && (arg_r.X_op == O_register)
   1385  1.1  christos 	      && (arg_r.X_add_number < 8))
   1386  1.7  christos 	    opcode += arg_r.X_add_number - 6; /* Emit_mx () will add 6.  */
   1387  1.1  christos 	  else
   1388  1.1  christos 	    {
   1389  1.1  christos 	      ill_op ();
   1390  1.1  christos 	      break;
   1391  1.1  christos 	    }
   1392  1.8  christos 	  if (!(ins_ok & INS_Z80N))
   1393  1.8  christos 	    check_mach (INS_ROT_II_LD);
   1394  1.1  christos 	}
   1395  1.6  christos       /* Fall through.  */
   1396  1.1  christos     case O_register:
   1397  1.1  christos       emit_mx (prefix, opcode, 0, & arg_m);
   1398  1.1  christos       break;
   1399  1.1  christos     default:
   1400  1.1  christos       ill_op ();
   1401  1.1  christos     }
   1402  1.1  christos   return p;
   1403  1.1  christos }
   1404  1.1  christos 
   1405  1.1  christos static void
   1406  1.1  christos emit_sx (char prefix, char opcode, expressionS * arg_p)
   1407  1.1  christos {
   1408  1.1  christos   char *q;
   1409  1.1  christos 
   1410  1.1  christos   switch (arg_p->X_op)
   1411  1.1  christos     {
   1412  1.1  christos     case O_register:
   1413  1.1  christos     case O_md1:
   1414  1.1  christos       emit_mx (prefix, opcode, 0, arg_p);
   1415  1.1  christos       break;
   1416  1.1  christos     default:
   1417  1.1  christos       if (arg_p->X_md)
   1418  1.1  christos 	ill_op ();
   1419  1.1  christos       else
   1420  1.1  christos 	{
   1421  1.1  christos 	  q = frag_more (prefix ? 2 : 1);
   1422  1.1  christos 	  if (prefix)
   1423  1.1  christos 	    *q++ = prefix;
   1424  1.1  christos 	  *q = opcode ^ 0x46;
   1425  1.1  christos 	  emit_byte (arg_p, BFD_RELOC_8);
   1426  1.1  christos 	}
   1427  1.1  christos     }
   1428  1.1  christos }
   1429  1.1  christos 
   1430  1.1  christos /* The operand s may be r, (hl), (ix+d), (iy+d), n.  */
   1431  1.1  christos static const char *
   1432  1.1  christos emit_s (char prefix, char opcode, const char *args)
   1433  1.1  christos {
   1434  1.1  christos   expressionS arg_s;
   1435  1.1  christos   const char *p;
   1436  1.1  christos 
   1437  1.1  christos   p = parse_exp (args, & arg_s);
   1438  1.7  christos   if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
   1439  1.7  christos     { /* possible instruction in generic format op A,x */
   1440  1.7  christos       if (!(ins_ok & INS_EZ80) && !sdcc_compat)
   1441  1.7  christos         ill_op ();
   1442  1.7  christos       ++p;
   1443  1.7  christos       p = parse_exp (p, & arg_s);
   1444  1.7  christos     }
   1445  1.1  christos   emit_sx (prefix, opcode, & arg_s);
   1446  1.1  christos   return p;
   1447  1.1  christos }
   1448  1.1  christos 
   1449  1.1  christos static const char *
   1450  1.8  christos emit_sub (char prefix, char opcode, const char *args)
   1451  1.8  christos {
   1452  1.8  christos   expressionS arg_s;
   1453  1.8  christos   const char *p;
   1454  1.8  christos 
   1455  1.8  christos   if (!(ins_ok & INS_GBZ80))
   1456  1.8  christos     return emit_s (prefix, opcode, args);
   1457  1.8  christos   p = parse_exp (args, & arg_s);
   1458  1.8  christos   if (*p++ != ',')
   1459  1.8  christos     {
   1460  1.8  christos       error (_("bad instruction syntax"));
   1461  1.8  christos       return p;
   1462  1.8  christos     }
   1463  1.8  christos 
   1464  1.8  christos   if (arg_s.X_md != 0 || arg_s.X_op != O_register || arg_s.X_add_number != REG_A)
   1465  1.8  christos     ill_op ();
   1466  1.8  christos 
   1467  1.8  christos   p = parse_exp (p, & arg_s);
   1468  1.8  christos 
   1469  1.8  christos   emit_sx (prefix, opcode, & arg_s);
   1470  1.8  christos   return p;
   1471  1.8  christos }
   1472  1.8  christos 
   1473  1.8  christos static const char *
   1474  1.8  christos emit_swap (char prefix, char opcode, const char *args)
   1475  1.8  christos {
   1476  1.8  christos   expressionS reg;
   1477  1.8  christos   const char *p;
   1478  1.8  christos   char *q;
   1479  1.8  christos 
   1480  1.8  christos   if (!(ins_ok & INS_Z80N))
   1481  1.8  christos     return emit_mr (prefix, opcode, args);
   1482  1.8  christos 
   1483  1.8  christos   /* check for alias swap a for swapnib of Z80N */
   1484  1.8  christos   p = parse_exp (args, &reg);
   1485  1.8  christos   if (reg.X_md != 0 || reg.X_op != O_register || reg.X_add_number != REG_A)
   1486  1.8  christos     ill_op ();
   1487  1.8  christos 
   1488  1.8  christos   q = frag_more (2);
   1489  1.8  christos   *q++ = 0xED;
   1490  1.8  christos   *q = 0x23;
   1491  1.8  christos   return p;
   1492  1.8  christos }
   1493  1.8  christos 
   1494  1.8  christos static const char *
   1495  1.1  christos emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1496  1.1  christos {
   1497  1.1  christos   expressionS addr;
   1498  1.1  christos   const char *p;  char *q;
   1499  1.1  christos 
   1500  1.1  christos   p = parse_exp_not_indexed (args, &addr);
   1501  1.1  christos   if (addr.X_md)
   1502  1.1  christos     ill_op ();
   1503  1.1  christos   else
   1504  1.1  christos     {
   1505  1.1  christos       q = frag_more (1);
   1506  1.1  christos       *q = opcode;
   1507  1.1  christos       emit_word (& addr);
   1508  1.1  christos     }
   1509  1.1  christos   return p;
   1510  1.1  christos }
   1511  1.1  christos 
   1512  1.1  christos /* Operand may be rr, r, (hl), (ix+d), (iy+d).  */
   1513  1.1  christos static const char *
   1514  1.1  christos emit_incdec (char prefix, char opcode, const char * args)
   1515  1.1  christos {
   1516  1.1  christos   expressionS operand;
   1517  1.1  christos   int rnum;
   1518  1.1  christos   const char *p;  char *q;
   1519  1.1  christos 
   1520  1.1  christos   p = parse_exp (args, &operand);
   1521  1.1  christos   rnum = operand.X_add_number;
   1522  1.1  christos   if ((! operand.X_md)
   1523  1.1  christos       && (operand.X_op == O_register)
   1524  1.1  christos       && (R_ARITH&rnum))
   1525  1.1  christos     {
   1526  1.1  christos       q = frag_more ((rnum & R_INDEX) ? 2 : 1);
   1527  1.1  christos       if (rnum & R_INDEX)
   1528  1.1  christos 	*q++ = (rnum & R_IX) ? 0xDD : 0xFD;
   1529  1.1  christos       *q = prefix + ((rnum & 3) << 4);
   1530  1.1  christos     }
   1531  1.1  christos   else
   1532  1.1  christos     {
   1533  1.1  christos       if ((operand.X_op == O_md1) || (operand.X_op == O_register))
   1534  1.1  christos 	emit_mx (0, opcode, 3, & operand);
   1535  1.1  christos       else
   1536  1.1  christos 	ill_op ();
   1537  1.1  christos     }
   1538  1.1  christos   return p;
   1539  1.1  christos }
   1540  1.1  christos 
   1541  1.1  christos static const char *
   1542  1.1  christos emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1543  1.1  christos {
   1544  1.1  christos   expressionS addr;
   1545  1.1  christos   const char *p;
   1546  1.1  christos   char *q;
   1547  1.1  christos 
   1548  1.1  christos   p = parse_exp_not_indexed (args, &addr);
   1549  1.1  christos   if (addr.X_md)
   1550  1.1  christos     ill_op ();
   1551  1.1  christos   else
   1552  1.1  christos     {
   1553  1.1  christos       q = frag_more (1);
   1554  1.1  christos       *q = opcode;
   1555  1.7  christos       addr.X_add_number--; /* pcrel computes after offset code */
   1556  1.1  christos       emit_byte (&addr, BFD_RELOC_8_PCREL);
   1557  1.1  christos     }
   1558  1.1  christos   return p;
   1559  1.1  christos }
   1560  1.1  christos 
   1561  1.1  christos static const char *
   1562  1.1  christos emit_jp (char prefix, char opcode, const char * args)
   1563  1.1  christos {
   1564  1.1  christos   expressionS addr;
   1565  1.1  christos   const char *p;
   1566  1.1  christos   char *q;
   1567  1.1  christos   int rnum;
   1568  1.1  christos 
   1569  1.1  christos   p = parse_exp_not_indexed (args, & addr);
   1570  1.1  christos   if (addr.X_md)
   1571  1.1  christos     {
   1572  1.1  christos       rnum = addr.X_add_number;
   1573  1.1  christos       if ((O_register == addr.X_op) && (REG_HL == (rnum & ~R_INDEX)))
   1574  1.1  christos 	{
   1575  1.1  christos 	  q = frag_more ((rnum & R_INDEX) ? 2 : 1);
   1576  1.1  christos 	  if (rnum & R_INDEX)
   1577  1.1  christos 	    *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
   1578  1.1  christos 	  *q = prefix;
   1579  1.1  christos 	}
   1580  1.8  christos       else if (addr.X_op == O_register && rnum == REG_C && (ins_ok & INS_Z80N))
   1581  1.8  christos 	{
   1582  1.8  christos 	  q = frag_more (2);
   1583  1.8  christos 	  *q++ = 0xED;
   1584  1.8  christos 	  *q = 0x98;
   1585  1.8  christos 	}
   1586  1.1  christos       else
   1587  1.1  christos 	ill_op ();
   1588  1.1  christos     }
   1589  1.1  christos   else
   1590  1.1  christos     {
   1591  1.1  christos       q = frag_more (1);
   1592  1.1  christos       *q = opcode;
   1593  1.1  christos       emit_word (& addr);
   1594  1.1  christos     }
   1595  1.1  christos   return p;
   1596  1.1  christos }
   1597  1.1  christos 
   1598  1.1  christos static const char *
   1599  1.1  christos emit_im (char prefix, char opcode, const char * args)
   1600  1.1  christos {
   1601  1.1  christos   expressionS mode;
   1602  1.1  christos   const char *p;
   1603  1.1  christos   char *q;
   1604  1.1  christos 
   1605  1.1  christos   p = parse_exp (args, & mode);
   1606  1.1  christos   if (mode.X_md || (mode.X_op != O_constant))
   1607  1.1  christos     ill_op ();
   1608  1.1  christos   else
   1609  1.1  christos     switch (mode.X_add_number)
   1610  1.1  christos       {
   1611  1.1  christos       case 1:
   1612  1.1  christos       case 2:
   1613  1.1  christos 	++mode.X_add_number;
   1614  1.1  christos 	/* Fall through.  */
   1615  1.1  christos       case 0:
   1616  1.1  christos 	q = frag_more (2);
   1617  1.1  christos 	*q++ = prefix;
   1618  1.1  christos 	*q = opcode + 8*mode.X_add_number;
   1619  1.1  christos 	break;
   1620  1.1  christos       default:
   1621  1.1  christos 	ill_op ();
   1622  1.1  christos       }
   1623  1.1  christos   return p;
   1624  1.1  christos }
   1625  1.1  christos 
   1626  1.1  christos static const char *
   1627  1.1  christos emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1628  1.1  christos {
   1629  1.1  christos   expressionS regp;
   1630  1.1  christos   const char *p;
   1631  1.1  christos   char *q;
   1632  1.1  christos 
   1633  1.1  christos   p = parse_exp (args, & regp);
   1634  1.1  christos   if ((!regp.X_md)
   1635  1.1  christos       && (regp.X_op == O_register)
   1636  1.1  christos       && (regp.X_add_number & R_STACKABLE))
   1637  1.1  christos     {
   1638  1.1  christos       int rnum;
   1639  1.1  christos 
   1640  1.1  christos       rnum = regp.X_add_number;
   1641  1.1  christos       if (rnum&R_INDEX)
   1642  1.1  christos 	{
   1643  1.1  christos 	  q = frag_more (2);
   1644  1.1  christos 	  *q++ = (rnum&R_IX)?0xDD:0xFD;
   1645  1.1  christos 	}
   1646  1.1  christos       else
   1647  1.1  christos 	q = frag_more (1);
   1648  1.1  christos       *q = opcode + ((rnum & 3) << 4);
   1649  1.1  christos     }
   1650  1.1  christos   else
   1651  1.1  christos     ill_op ();
   1652  1.1  christos 
   1653  1.1  christos   return p;
   1654  1.1  christos }
   1655  1.1  christos 
   1656  1.1  christos static const char *
   1657  1.8  christos emit_push (char prefix, char opcode, const char * args)
   1658  1.8  christos {
   1659  1.8  christos   expressionS arg;
   1660  1.8  christos   const char *p;
   1661  1.8  christos   char *q;
   1662  1.8  christos 
   1663  1.8  christos   p = parse_exp (args, & arg);
   1664  1.8  christos   if (arg.X_op == O_register)
   1665  1.8  christos     return emit_pop (prefix, opcode, args);
   1666  1.8  christos 
   1667  1.8  christos   if (arg.X_md || arg.X_op == O_md1 || !(ins_ok & INS_Z80N))
   1668  1.8  christos     ill_op ();
   1669  1.8  christos 
   1670  1.8  christos   q = frag_more (2);
   1671  1.8  christos   *q++ = 0xED;
   1672  1.8  christos   *q = 0x8A;
   1673  1.8  christos 
   1674  1.8  christos   q = frag_more (2);
   1675  1.8  christos   fix_new_exp (frag_now, q - frag_now->fr_literal, 2, &arg, false,
   1676  1.8  christos                BFD_RELOC_Z80_16_BE);
   1677  1.8  christos 
   1678  1.8  christos   return p;
   1679  1.8  christos }
   1680  1.8  christos 
   1681  1.8  christos static const char *
   1682  1.1  christos emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1683  1.1  christos {
   1684  1.1  christos   char cc, *q;
   1685  1.1  christos   const char *p;
   1686  1.1  christos 
   1687  1.1  christos   p = parse_cc (args, &cc);
   1688  1.1  christos   q = frag_more (1);
   1689  1.1  christos   if (p)
   1690  1.1  christos     *q = opcode + cc;
   1691  1.1  christos   else
   1692  1.1  christos     *q = prefix;
   1693  1.1  christos   return p ? p : args;
   1694  1.1  christos }
   1695  1.1  christos 
   1696  1.1  christos static const char *
   1697  1.1  christos emit_adc (char prefix, char opcode, const char * args)
   1698  1.1  christos {
   1699  1.1  christos   expressionS term;
   1700  1.1  christos   int rnum;
   1701  1.1  christos   const char *p;
   1702  1.1  christos   char *q;
   1703  1.1  christos 
   1704  1.1  christos   p = parse_exp (args, &term);
   1705  1.1  christos   if (*p++ != ',')
   1706  1.1  christos     {
   1707  1.3  christos       error (_("bad instruction syntax"));
   1708  1.1  christos       return p;
   1709  1.1  christos     }
   1710  1.1  christos 
   1711  1.1  christos   if ((term.X_md) || (term.X_op != O_register))
   1712  1.1  christos     ill_op ();
   1713  1.1  christos   else
   1714  1.1  christos     switch (term.X_add_number)
   1715  1.1  christos       {
   1716  1.1  christos       case REG_A:
   1717  1.1  christos 	p = emit_s (0, prefix, p);
   1718  1.1  christos 	break;
   1719  1.1  christos       case REG_HL:
   1720  1.1  christos 	p = parse_exp (p, &term);
   1721  1.1  christos 	if ((!term.X_md) && (term.X_op == O_register))
   1722  1.1  christos 	  {
   1723  1.1  christos 	    rnum = term.X_add_number;
   1724  1.1  christos 	    if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
   1725  1.1  christos 	      {
   1726  1.1  christos 		q = frag_more (2);
   1727  1.1  christos 		*q++ = 0xED;
   1728  1.1  christos 		*q = opcode + ((rnum & 3) << 4);
   1729  1.1  christos 		break;
   1730  1.1  christos 	      }
   1731  1.1  christos 	  }
   1732  1.1  christos 	/* Fall through.  */
   1733  1.1  christos       default:
   1734  1.1  christos 	ill_op ();
   1735  1.1  christos       }
   1736  1.1  christos   return p;
   1737  1.1  christos }
   1738  1.1  christos 
   1739  1.1  christos static const char *
   1740  1.1  christos emit_add (char prefix, char opcode, const char * args)
   1741  1.1  christos {
   1742  1.1  christos   expressionS term;
   1743  1.1  christos   int lhs, rhs;
   1744  1.1  christos   const char *p;
   1745  1.1  christos   char *q;
   1746  1.1  christos 
   1747  1.1  christos   p = parse_exp (args, &term);
   1748  1.1  christos   if (*p++ != ',')
   1749  1.1  christos     {
   1750  1.3  christos       error (_("bad instruction syntax"));
   1751  1.1  christos       return p;
   1752  1.1  christos     }
   1753  1.1  christos 
   1754  1.1  christos   if ((term.X_md) || (term.X_op != O_register))
   1755  1.1  christos     ill_op ();
   1756  1.1  christos   else
   1757  1.8  christos     switch (term.X_add_number)
   1758  1.1  christos       {
   1759  1.1  christos       case REG_A:
   1760  1.1  christos 	p = emit_s (0, prefix, p);
   1761  1.1  christos 	break;
   1762  1.8  christos       case REG_SP:
   1763  1.8  christos 	p = parse_exp (p, &term);
   1764  1.8  christos 	if (!(ins_ok & INS_GBZ80) || term.X_md || term.X_op == O_register)
   1765  1.8  christos 	  ill_op ();
   1766  1.8  christos 	q = frag_more (1);
   1767  1.8  christos 	*q = 0xE8;
   1768  1.8  christos 	emit_byte (&term, BFD_RELOC_Z80_DISP8);
   1769  1.8  christos 	break;
   1770  1.8  christos       case REG_BC:
   1771  1.8  christos       case REG_DE:
   1772  1.8  christos 	if (!(ins_ok & INS_Z80N))
   1773  1.8  christos 	  {
   1774  1.8  christos 	    ill_op ();
   1775  1.8  christos 	    break;
   1776  1.8  christos 	  }
   1777  1.8  christos 	/* Fall through.  */
   1778  1.1  christos       case REG_HL:
   1779  1.8  christos       case REG_IX:
   1780  1.8  christos       case REG_IY:
   1781  1.1  christos 	lhs = term.X_add_number;
   1782  1.1  christos 	p = parse_exp (p, &term);
   1783  1.8  christos 	rhs = term.X_add_number;
   1784  1.8  christos 	if (term.X_md != 0 || term.X_op == O_md1)
   1785  1.8  christos 	  ill_op ();
   1786  1.8  christos 	else if ((term.X_op == O_register) && (rhs & R_ARITH) && (rhs == lhs || (rhs & ~R_INDEX) != REG_HL))
   1787  1.1  christos 	  {
   1788  1.8  christos 	    if (1)
   1789  1.1  christos 	      {
   1790  1.1  christos 		q = frag_more ((lhs & R_INDEX) ? 2 : 1);
   1791  1.1  christos 		if (lhs & R_INDEX)
   1792  1.1  christos 		  *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
   1793  1.1  christos 		*q = opcode + ((rhs & 3) << 4);
   1794  1.1  christos 		break;
   1795  1.1  christos 	      }
   1796  1.1  christos 	  }
   1797  1.8  christos 	else if (!(lhs & R_INDEX) && (ins_ok & INS_Z80N))
   1798  1.8  christos 	  {
   1799  1.8  christos 	    if (term.X_op == O_register && rhs == REG_A)
   1800  1.8  christos 	      { /* ADD BC/DE/HL,A */
   1801  1.8  christos 		q = frag_more (2);
   1802  1.8  christos 		*q++ = 0xED;
   1803  1.8  christos 		*q = 0x33 - (lhs & 3);
   1804  1.8  christos 		break;
   1805  1.8  christos 	      }
   1806  1.8  christos 	    else if (term.X_op != O_register && term.X_op != O_md1)
   1807  1.8  christos 	      { /* ADD BC/DE/HL,nn */
   1808  1.8  christos 		q = frag_more (2);
   1809  1.8  christos 		*q++ = 0xED;
   1810  1.8  christos 		*q = 0x36 - (lhs & 3);
   1811  1.8  christos 		emit_word (&term);
   1812  1.8  christos 		break;
   1813  1.8  christos 	      }
   1814  1.8  christos 	  }
   1815  1.1  christos 	/* Fall through.  */
   1816  1.1  christos       default:
   1817  1.1  christos 	ill_op ();
   1818  1.1  christos       }
   1819  1.1  christos   return p;
   1820  1.1  christos }
   1821  1.1  christos 
   1822  1.1  christos static const char *
   1823  1.1  christos emit_bit (char prefix, char opcode, const char * args)
   1824  1.1  christos {
   1825  1.1  christos   expressionS b;
   1826  1.1  christos   int bn;
   1827  1.1  christos   const char *p;
   1828  1.1  christos 
   1829  1.1  christos   p = parse_exp (args, &b);
   1830  1.1  christos   if (*p++ != ',')
   1831  1.3  christos     error (_("bad instruction syntax"));
   1832  1.1  christos 
   1833  1.1  christos   bn = b.X_add_number;
   1834  1.1  christos   if ((!b.X_md)
   1835  1.1  christos       && (b.X_op == O_constant)
   1836  1.1  christos       && (0 <= bn)
   1837  1.1  christos       && (bn < 8))
   1838  1.1  christos     {
   1839  1.1  christos       if (opcode == 0x40)
   1840  1.1  christos 	/* Bit : no optional third operand.  */
   1841  1.1  christos 	p = emit_m (prefix, opcode + (bn << 3), p);
   1842  1.1  christos       else
   1843  1.1  christos 	/* Set, res : resulting byte can be copied to register.  */
   1844  1.7  christos         p = emit_mr (prefix, opcode + (bn << 3), p);
   1845  1.1  christos     }
   1846  1.1  christos   else
   1847  1.1  christos     ill_op ();
   1848  1.1  christos   return p;
   1849  1.1  christos }
   1850  1.1  christos 
   1851  1.8  christos /* BSLA DE,B; BSRA DE,B; BSRL DE,B; BSRF DE,B; BRLC DE,B (Z80N only) */
   1852  1.8  christos static const char *
   1853  1.8  christos emit_bshft (char prefix, char opcode, const char * args)
   1854  1.8  christos {
   1855  1.8  christos   expressionS r1, r2;
   1856  1.8  christos   const char *p;
   1857  1.8  christos   char *q;
   1858  1.8  christos 
   1859  1.8  christos   p = parse_exp (args, & r1);
   1860  1.8  christos   if (*p++ != ',')
   1861  1.8  christos     error (_("bad instruction syntax"));
   1862  1.8  christos   p = parse_exp (p, & r2);
   1863  1.8  christos   if (r1.X_md || r1.X_op != O_register || r1.X_add_number != REG_DE ||
   1864  1.8  christos       r2.X_md || r2.X_op != O_register || r2.X_add_number != REG_B)
   1865  1.8  christos     ill_op ();
   1866  1.8  christos   q = frag_more (2);
   1867  1.8  christos   *q++ = prefix;
   1868  1.8  christos   *q = opcode;
   1869  1.8  christos   return p;
   1870  1.8  christos }
   1871  1.8  christos 
   1872  1.1  christos static const char *
   1873  1.1  christos emit_jpcc (char prefix, char opcode, const char * args)
   1874  1.1  christos {
   1875  1.1  christos   char cc;
   1876  1.1  christos   const char *p;
   1877  1.1  christos 
   1878  1.1  christos   p = parse_cc (args, & cc);
   1879  1.1  christos   if (p && *p++ == ',')
   1880  1.1  christos     p = emit_call (0, opcode + cc, p);
   1881  1.1  christos   else
   1882  1.1  christos     p = (prefix == (char)0xC3)
   1883  1.1  christos       ? emit_jp (0xE9, prefix, args)
   1884  1.1  christos       : emit_call (0, prefix, args);
   1885  1.1  christos   return p;
   1886  1.1  christos }
   1887  1.1  christos 
   1888  1.1  christos static const char *
   1889  1.1  christos emit_jrcc (char prefix, char opcode, const char * args)
   1890  1.1  christos {
   1891  1.1  christos   char cc;
   1892  1.1  christos   const char *p;
   1893  1.1  christos 
   1894  1.1  christos   p = parse_cc (args, &cc);
   1895  1.1  christos   if (p && *p++ == ',')
   1896  1.1  christos     {
   1897  1.1  christos       if (cc > (3 << 3))
   1898  1.1  christos 	error (_("condition code invalid for jr"));
   1899  1.1  christos       else
   1900  1.1  christos 	p = emit_jr (0, opcode + cc, p);
   1901  1.1  christos     }
   1902  1.1  christos   else
   1903  1.1  christos     p = emit_jr (0, prefix, args);
   1904  1.1  christos 
   1905  1.1  christos   return p;
   1906  1.1  christos }
   1907  1.1  christos 
   1908  1.1  christos static const char *
   1909  1.1  christos emit_ex (char prefix_in ATTRIBUTE_UNUSED,
   1910  1.1  christos 	 char opcode_in ATTRIBUTE_UNUSED, const char * args)
   1911  1.1  christos {
   1912  1.1  christos   expressionS op;
   1913  1.1  christos   const char * p;
   1914  1.1  christos   char prefix, opcode;
   1915  1.1  christos 
   1916  1.1  christos   p = parse_exp_not_indexed (args, &op);
   1917  1.1  christos   p = skip_space (p);
   1918  1.1  christos   if (*p++ != ',')
   1919  1.1  christos     {
   1920  1.1  christos       error (_("bad instruction syntax"));
   1921  1.1  christos       return p;
   1922  1.1  christos     }
   1923  1.1  christos 
   1924  1.1  christos   prefix = opcode = 0;
   1925  1.1  christos   if (op.X_op == O_register)
   1926  1.1  christos     switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
   1927  1.1  christos       {
   1928  1.1  christos       case REG_AF:
   1929  1.1  christos 	if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
   1930  1.1  christos 	  {
   1931  1.1  christos 	    /* The scrubber changes '\'' to '`' in this context.  */
   1932  1.1  christos 	    if (*p == '`')
   1933  1.1  christos 	      ++p;
   1934  1.1  christos 	    opcode = 0x08;
   1935  1.1  christos 	  }
   1936  1.1  christos 	break;
   1937  1.1  christos       case REG_DE:
   1938  1.1  christos 	if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
   1939  1.1  christos 	  opcode = 0xEB;
   1940  1.1  christos 	break;
   1941  1.1  christos       case REG_SP|0x8000:
   1942  1.1  christos 	p = parse_exp (p, & op);
   1943  1.1  christos 	if (op.X_op == O_register
   1944  1.1  christos 	    && op.X_md == 0
   1945  1.1  christos 	    && (op.X_add_number & ~R_INDEX) == REG_HL)
   1946  1.1  christos 	  {
   1947  1.1  christos 	    opcode = 0xE3;
   1948  1.1  christos 	    if (R_INDEX & op.X_add_number)
   1949  1.1  christos 	      prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
   1950  1.1  christos 	  }
   1951  1.1  christos 	break;
   1952  1.1  christos       }
   1953  1.1  christos   if (opcode)
   1954  1.1  christos     emit_insn (prefix, opcode, p);
   1955  1.1  christos   else
   1956  1.1  christos     ill_op ();
   1957  1.1  christos 
   1958  1.1  christos   return p;
   1959  1.1  christos }
   1960  1.1  christos 
   1961  1.1  christos static const char *
   1962  1.1  christos emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
   1963  1.1  christos 	const char * args)
   1964  1.1  christos {
   1965  1.1  christos   expressionS reg, port;
   1966  1.1  christos   const char *p;
   1967  1.1  christos   char *q;
   1968  1.1  christos 
   1969  1.1  christos   p = parse_exp (args, &reg);
   1970  1.8  christos   if (reg.X_md && reg.X_op == O_register && reg.X_add_number == REG_C)
   1971  1.8  christos     { /* permit instruction in (c) as alias for in f,(c) */
   1972  1.8  christos       port = reg;
   1973  1.8  christos       reg.X_md = 0;
   1974  1.8  christos       reg.X_add_number = REG_F;
   1975  1.8  christos     }
   1976  1.8  christos   else
   1977  1.1  christos     {
   1978  1.8  christos       if (*p++ != ',')
   1979  1.8  christos 	{
   1980  1.8  christos 	  error (_("bad instruction syntax"));
   1981  1.8  christos 	  return p;
   1982  1.8  christos 	}
   1983  1.8  christos       p = parse_exp (p, &port);
   1984  1.1  christos     }
   1985  1.1  christos   if (reg.X_md == 0
   1986  1.1  christos       && reg.X_op == O_register
   1987  1.1  christos       && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
   1988  1.1  christos       && (port.X_md))
   1989  1.1  christos     {
   1990  1.1  christos       if (port.X_op != O_md1 && port.X_op != O_register)
   1991  1.1  christos 	{
   1992  1.1  christos 	  if (REG_A == reg.X_add_number)
   1993  1.1  christos 	    {
   1994  1.1  christos 	      q = frag_more (1);
   1995  1.1  christos 	      *q = 0xDB;
   1996  1.1  christos 	      emit_byte (&port, BFD_RELOC_8);
   1997  1.1  christos 	    }
   1998  1.1  christos 	  else
   1999  1.1  christos 	    ill_op ();
   2000  1.1  christos 	}
   2001  1.1  christos       else
   2002  1.1  christos 	{
   2003  1.7  christos           if (port.X_add_number == REG_C || port.X_add_number == REG_BC)
   2004  1.1  christos 	    {
   2005  1.7  christos               if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
   2006  1.7  christos                 ill_op ();
   2007  1.8  christos 	      else if (reg.X_add_number == REG_F && !(ins_ok & (INS_R800|INS_Z80N)))
   2008  1.7  christos                 check_mach (INS_IN_F_C);
   2009  1.7  christos           q = frag_more (2);
   2010  1.7  christos           *q++ = 0xED;
   2011  1.7  christos           *q = 0x40|((reg.X_add_number&7)<<3);
   2012  1.1  christos 	    }
   2013  1.1  christos 	  else
   2014  1.1  christos 	    ill_op ();
   2015  1.1  christos 	}
   2016  1.1  christos     }
   2017  1.1  christos   else
   2018  1.1  christos     ill_op ();
   2019  1.1  christos   return p;
   2020  1.1  christos }
   2021  1.1  christos 
   2022  1.1  christos static const char *
   2023  1.7  christos emit_in0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
   2024  1.7  christos         const char * args)
   2025  1.7  christos {
   2026  1.7  christos   expressionS reg, port;
   2027  1.7  christos   const char *p;
   2028  1.7  christos   char *q;
   2029  1.7  christos 
   2030  1.7  christos   p = parse_exp (args, &reg);
   2031  1.7  christos   if (*p++ != ',')
   2032  1.7  christos     {
   2033  1.7  christos       error (_("bad instruction syntax"));
   2034  1.7  christos       return p;
   2035  1.7  christos     }
   2036  1.7  christos 
   2037  1.7  christos   p = parse_exp (p, &port);
   2038  1.7  christos   if (reg.X_md == 0
   2039  1.7  christos       && reg.X_op == O_register
   2040  1.7  christos       && reg.X_add_number <= 7
   2041  1.7  christos       && port.X_md
   2042  1.7  christos       && port.X_op != O_md1
   2043  1.7  christos       && port.X_op != O_register)
   2044  1.7  christos     {
   2045  1.7  christos       q = frag_more (2);
   2046  1.7  christos       *q++ = 0xED;
   2047  1.7  christos       *q = 0x00|(reg.X_add_number << 3);
   2048  1.7  christos       emit_byte (&port, BFD_RELOC_8);
   2049  1.7  christos     }
   2050  1.7  christos   else
   2051  1.7  christos     ill_op ();
   2052  1.7  christos   return p;
   2053  1.7  christos }
   2054  1.7  christos 
   2055  1.7  christos static const char *
   2056  1.1  christos emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
   2057  1.1  christos 	 const char * args)
   2058  1.1  christos {
   2059  1.1  christos   expressionS reg, port;
   2060  1.1  christos   const char *p;
   2061  1.1  christos   char *q;
   2062  1.1  christos 
   2063  1.1  christos   p = parse_exp (args, & port);
   2064  1.1  christos   if (*p++ != ',')
   2065  1.1  christos     {
   2066  1.3  christos       error (_("bad instruction syntax"));
   2067  1.1  christos       return p;
   2068  1.1  christos     }
   2069  1.1  christos   p = parse_exp (p, &reg);
   2070  1.1  christos   if (!port.X_md)
   2071  1.1  christos     { ill_op (); return p; }
   2072  1.1  christos   /* Allow "out (c), 0" as unportable instruction.  */
   2073  1.1  christos   if (reg.X_op == O_constant && reg.X_add_number == 0)
   2074  1.1  christos     {
   2075  1.8  christos       if (!(ins_ok & INS_Z80N))
   2076  1.8  christos 	check_mach (INS_OUT_C_0);
   2077  1.1  christos       reg.X_op = O_register;
   2078  1.1  christos       reg.X_add_number = 6;
   2079  1.1  christos     }
   2080  1.1  christos   if (reg.X_md
   2081  1.1  christos       || reg.X_op != O_register
   2082  1.1  christos       || reg.X_add_number > 7)
   2083  1.1  christos     ill_op ();
   2084  1.1  christos   else
   2085  1.1  christos     if (port.X_op != O_register && port.X_op != O_md1)
   2086  1.1  christos       {
   2087  1.1  christos 	if (REG_A == reg.X_add_number)
   2088  1.1  christos 	  {
   2089  1.1  christos 	    q = frag_more (1);
   2090  1.1  christos 	    *q = 0xD3;
   2091  1.1  christos 	    emit_byte (&port, BFD_RELOC_8);
   2092  1.1  christos 	  }
   2093  1.1  christos 	else
   2094  1.1  christos 	  ill_op ();
   2095  1.1  christos       }
   2096  1.1  christos     else
   2097  1.1  christos       {
   2098  1.7  christos         if (REG_C == port.X_add_number || port.X_add_number == REG_BC)
   2099  1.1  christos 	  {
   2100  1.7  christos             if (port.X_add_number == REG_BC && !(ins_ok & INS_EZ80))
   2101  1.7  christos               ill_op ();
   2102  1.1  christos 	    q = frag_more (2);
   2103  1.1  christos 	    *q++ = 0xED;
   2104  1.1  christos 	    *q = 0x41 | (reg.X_add_number << 3);
   2105  1.1  christos 	  }
   2106  1.1  christos 	else
   2107  1.1  christos 	  ill_op ();
   2108  1.1  christos       }
   2109  1.1  christos   return p;
   2110  1.1  christos }
   2111  1.1  christos 
   2112  1.1  christos static const char *
   2113  1.7  christos emit_out0 (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
   2114  1.7  christos          const char * args)
   2115  1.7  christos {
   2116  1.7  christos   expressionS reg, port;
   2117  1.7  christos   const char *p;
   2118  1.7  christos   char *q;
   2119  1.7  christos 
   2120  1.7  christos   p = parse_exp (args, & port);
   2121  1.7  christos   if (*p++ != ',')
   2122  1.7  christos     {
   2123  1.7  christos       error (_("bad instruction syntax"));
   2124  1.7  christos       return p;
   2125  1.7  christos     }
   2126  1.7  christos   p = parse_exp (p, &reg);
   2127  1.7  christos   if (port.X_md != 0
   2128  1.7  christos       && port.X_op != O_register
   2129  1.7  christos       && port.X_op != O_md1
   2130  1.7  christos       && reg.X_md == 0
   2131  1.7  christos       && reg.X_op == O_register
   2132  1.7  christos       && reg.X_add_number <= 7)
   2133  1.7  christos     {
   2134  1.7  christos       q = frag_more (2);
   2135  1.7  christos       *q++ = 0xED;
   2136  1.7  christos       *q = 0x01 | (reg.X_add_number << 3);
   2137  1.7  christos       emit_byte (&port, BFD_RELOC_8);
   2138  1.7  christos     }
   2139  1.7  christos   else
   2140  1.7  christos     ill_op ();
   2141  1.7  christos   return p;
   2142  1.7  christos }
   2143  1.7  christos 
   2144  1.7  christos static const char *
   2145  1.1  christos emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   2146  1.1  christos {
   2147  1.1  christos   expressionS addr;
   2148  1.1  christos   const char *p;
   2149  1.1  christos   char *q;
   2150  1.1  christos 
   2151  1.1  christos   p = parse_exp_not_indexed (args, &addr);
   2152  1.1  christos   if (addr.X_op != O_constant)
   2153  1.1  christos     {
   2154  1.1  christos       error ("rst needs constant address");
   2155  1.1  christos       return p;
   2156  1.1  christos     }
   2157  1.1  christos 
   2158  1.1  christos   if (addr.X_add_number & ~(7 << 3))
   2159  1.1  christos     ill_op ();
   2160  1.1  christos   else
   2161  1.1  christos     {
   2162  1.1  christos       q = frag_more (1);
   2163  1.1  christos       *q = opcode + (addr.X_add_number & (7 << 3));
   2164  1.1  christos     }
   2165  1.1  christos   return p;
   2166  1.1  christos }
   2167  1.1  christos 
   2168  1.7  christos /* For 8-bit indirect load to memory instructions like: LD (HL),n or LD (ii+d),n.  */
   2169  1.1  christos static void
   2170  1.7  christos emit_ld_m_n (expressionS *dst, expressionS *src)
   2171  1.1  christos {
   2172  1.1  christos   char *q;
   2173  1.7  christos   char prefix;
   2174  1.7  christos   expressionS dst_offset;
   2175  1.1  christos 
   2176  1.7  christos   switch (dst->X_add_number)
   2177  1.7  christos     {
   2178  1.7  christos     case REG_HL: prefix = 0x00; break;
   2179  1.7  christos     case REG_IX: prefix = 0xDD; break;
   2180  1.7  christos     case REG_IY: prefix = 0xFD; break;
   2181  1.7  christos     default:
   2182  1.7  christos       ill_op ();
   2183  1.7  christos       return;
   2184  1.7  christos     }
   2185  1.7  christos 
   2186  1.7  christos   q = frag_more (prefix ? 2 : 1);
   2187  1.7  christos   if (prefix)
   2188  1.7  christos     *q++ = prefix;
   2189  1.7  christos   *q = 0x36;
   2190  1.7  christos   if (prefix)
   2191  1.1  christos     {
   2192  1.7  christos       dst_offset = *dst;
   2193  1.7  christos       dst_offset.X_op = O_symbol;
   2194  1.7  christos       dst_offset.X_add_number = 0;
   2195  1.7  christos       emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
   2196  1.7  christos     }
   2197  1.7  christos   emit_byte (src, BFD_RELOC_8);
   2198  1.7  christos }
   2199  1.7  christos 
   2200  1.7  christos /* For 8-bit load register to memory instructions: LD (<expression>),r.  */
   2201  1.7  christos static void
   2202  1.7  christos emit_ld_m_r (expressionS *dst, expressionS *src)
   2203  1.7  christos {
   2204  1.7  christos   char *q;
   2205  1.7  christos   char prefix = 0;
   2206  1.7  christos   expressionS dst_offset;
   2207  1.7  christos 
   2208  1.7  christos   switch (dst->X_op)
   2209  1.7  christos     {
   2210  1.7  christos     case O_md1:
   2211  1.8  christos       if (ins_ok & INS_GBZ80)
   2212  1.8  christos 	{ /* LD (HL+),A or LD (HL-),A */
   2213  1.8  christos 	  if (src->X_op != O_register || src->X_add_number != REG_A)
   2214  1.8  christos 	    break;
   2215  1.8  christos 	  *frag_more (1) = (dst->X_add_number == REG_HL) ? 0x22 : 0x32;
   2216  1.8  christos 	  return;
   2217  1.8  christos 	}
   2218  1.8  christos       else
   2219  1.8  christos 	prefix = (dst->X_add_number == REG_IX) ? 0xDD : 0xFD;
   2220  1.7  christos       /* Fall through.  */
   2221  1.7  christos     case O_register:
   2222  1.7  christos       switch (dst->X_add_number)
   2223  1.7  christos         {
   2224  1.7  christos         case REG_BC: /* LD (BC),A */
   2225  1.7  christos         case REG_DE: /* LD (DE),A */
   2226  1.7  christos           if (src->X_add_number == REG_A)
   2227  1.7  christos             {
   2228  1.7  christos               q = frag_more (1);
   2229  1.7  christos               *q = 0x02 | ((dst->X_add_number & 3) << 4);
   2230  1.7  christos               return;
   2231  1.7  christos             }
   2232  1.7  christos           break;
   2233  1.7  christos         case REG_IX:
   2234  1.7  christos         case REG_IY:
   2235  1.7  christos         case REG_HL: /* LD (HL),r or LD (ii+d),r */
   2236  1.7  christos           if (src->X_add_number <= 7)
   2237  1.7  christos             {
   2238  1.7  christos               q = frag_more (prefix ? 2 : 1);
   2239  1.7  christos               if (prefix)
   2240  1.7  christos                 *q++ = prefix;
   2241  1.7  christos               *q = 0x70 | src->X_add_number;
   2242  1.7  christos               if (prefix)
   2243  1.7  christos                 {
   2244  1.7  christos                   dst_offset = *dst;
   2245  1.7  christos                   dst_offset.X_op = O_symbol;
   2246  1.7  christos                   dst_offset.X_add_number = 0;
   2247  1.7  christos                   emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
   2248  1.7  christos                 }
   2249  1.7  christos               return;
   2250  1.7  christos             }
   2251  1.7  christos           break;
   2252  1.7  christos         default:;
   2253  1.7  christos         }
   2254  1.7  christos         break;
   2255  1.7  christos     default: /* LD (nn),A */
   2256  1.7  christos       if (src->X_add_number == REG_A)
   2257  1.7  christos         {
   2258  1.7  christos           q = frag_more (1);
   2259  1.8  christos 	  *q = (ins_ok & INS_GBZ80) ? 0xEA : 0x32;
   2260  1.7  christos           emit_word (dst);
   2261  1.7  christos           return;
   2262  1.7  christos         }
   2263  1.7  christos       break;
   2264  1.7  christos     }
   2265  1.7  christos     ill_op ();
   2266  1.7  christos }
   2267  1.7  christos 
   2268  1.7  christos /* For 16-bit load register to memory instructions: LD (<expression>),rr.  */
   2269  1.7  christos static void
   2270  1.7  christos emit_ld_m_rr (expressionS *dst, expressionS *src)
   2271  1.7  christos {
   2272  1.7  christos   char *q;
   2273  1.7  christos   int prefix = 0;
   2274  1.7  christos   int opcode = 0;
   2275  1.7  christos   expressionS dst_offset;
   2276  1.7  christos 
   2277  1.7  christos   switch (dst->X_op)
   2278  1.7  christos     {
   2279  1.7  christos     case O_md1:      /* eZ80 instructions LD (ii+d),rr */
   2280  1.7  christos     case O_register: /* eZ80 instructions LD (HL),rr */
   2281  1.7  christos       if (!(ins_ok & INS_EZ80)) /* 16-bit indirect load group is supported by eZ80 only */
   2282  1.7  christos           ill_op ();
   2283  1.7  christos       switch (dst->X_add_number)
   2284  1.7  christos         {
   2285  1.7  christos         case REG_IX: prefix = 0xDD; break;
   2286  1.7  christos         case REG_IY: prefix = 0xFD; break;
   2287  1.7  christos         case REG_HL: prefix = 0xED; break;
   2288  1.7  christos         default:
   2289  1.7  christos           ill_op ();
   2290  1.7  christos         }
   2291  1.7  christos       switch (src->X_add_number)
   2292  1.7  christos         {
   2293  1.7  christos         case REG_BC: opcode = 0x0F; break;
   2294  1.7  christos         case REG_DE: opcode = 0x1F; break;
   2295  1.7  christos         case REG_HL: opcode = 0x2F; break;
   2296  1.7  christos 	case REG_IX: opcode = (prefix != 0xFD) ? 0x3F : 0x3E; break;
   2297  1.7  christos 	case REG_IY: opcode = (prefix != 0xFD) ? 0x3E : 0x3F; break;
   2298  1.7  christos         default:
   2299  1.7  christos           ill_op ();
   2300  1.7  christos         }
   2301  1.7  christos         q = frag_more (prefix ? 2 : 1);
   2302  1.7  christos         *q++ = prefix;
   2303  1.7  christos         *q = opcode;
   2304  1.7  christos 	if (prefix == 0xFD || prefix == 0xDD)
   2305  1.7  christos           {
   2306  1.7  christos             dst_offset = *dst;
   2307  1.7  christos             dst_offset.X_op = O_symbol;
   2308  1.7  christos             dst_offset.X_add_number = 0;
   2309  1.7  christos             emit_byte (& dst_offset, BFD_RELOC_Z80_DISP8);
   2310  1.7  christos           }
   2311  1.7  christos         break;
   2312  1.7  christos     default: /* LD (nn),rr */
   2313  1.7  christos       if (ins_ok & INS_GBZ80)
   2314  1.7  christos         {
   2315  1.7  christos           /* GBZ80 supports only LD (nn),SP */
   2316  1.7  christos           if (src->X_add_number == REG_SP)
   2317  1.7  christos             {
   2318  1.7  christos               prefix = 0x00;
   2319  1.7  christos               opcode = 0x08;
   2320  1.7  christos             }
   2321  1.7  christos           else
   2322  1.7  christos             ill_op ();
   2323  1.7  christos         }
   2324  1.1  christos       else
   2325  1.7  christos         {
   2326  1.7  christos           switch (src->X_add_number)
   2327  1.7  christos             {
   2328  1.7  christos             case REG_BC: prefix = 0xED; opcode = 0x43; break;
   2329  1.7  christos             case REG_DE: prefix = 0xED; opcode = 0x53; break;
   2330  1.7  christos             case REG_HL: prefix = 0x00; opcode = 0x22; break;
   2331  1.7  christos             case REG_IX: prefix = 0xDD; opcode = 0x22; break;
   2332  1.7  christos             case REG_IY: prefix = 0xFD; opcode = 0x22; break;
   2333  1.7  christos             case REG_SP: prefix = 0xED; opcode = 0x73; break;
   2334  1.7  christos             default:
   2335  1.7  christos               ill_op ();
   2336  1.7  christos             }
   2337  1.7  christos         }
   2338  1.7  christos       q = frag_more (prefix ? 2 : 1);
   2339  1.7  christos       if (prefix)
   2340  1.7  christos         *q++ = prefix;
   2341  1.7  christos       *q = opcode;
   2342  1.7  christos       emit_word (dst);
   2343  1.7  christos     }
   2344  1.7  christos }
   2345  1.7  christos 
   2346  1.7  christos static void
   2347  1.7  christos emit_ld_r_m (expressionS *dst, expressionS *src)
   2348  1.7  christos { /* for 8-bit memory load to register: LD r,(xxx) */
   2349  1.7  christos   char *q;
   2350  1.7  christos   char prefix = 0;
   2351  1.7  christos   char opcode = 0;
   2352  1.7  christos   expressionS src_offset;
   2353  1.7  christos 
   2354  1.7  christos   if (dst->X_add_number == REG_A && src->X_op == O_register)
   2355  1.7  christos     { /* LD A,(BC) or LD A,(DE) */
   2356  1.7  christos       switch (src->X_add_number)
   2357  1.7  christos         {
   2358  1.7  christos         case REG_BC: opcode = 0x0A; break;
   2359  1.7  christos         case REG_DE: opcode = 0x1A; break;
   2360  1.7  christos         default: break;
   2361  1.7  christos         }
   2362  1.7  christos       if (opcode != 0)
   2363  1.7  christos         {
   2364  1.7  christos           q = frag_more (1);
   2365  1.7  christos           *q = opcode;
   2366  1.7  christos           return;
   2367  1.7  christos         }
   2368  1.7  christos     }
   2369  1.7  christos 
   2370  1.7  christos   switch (src->X_op)
   2371  1.7  christos     {
   2372  1.7  christos     case O_md1:
   2373  1.8  christos       if (ins_ok & INS_GBZ80)
   2374  1.8  christos 	{ /* LD A,(HL+) or LD A,(HL-) */
   2375  1.8  christos 	  if (dst->X_op == O_register && dst->X_add_number == REG_A)
   2376  1.8  christos 	    *frag_more (1) = (src->X_add_number == REG_HL) ? 0x2A : 0x3A;
   2377  1.8  christos 	  else
   2378  1.8  christos 	    ill_op ();
   2379  1.8  christos 	  break;
   2380  1.8  christos 	}
   2381  1.8  christos       /* Fall through. */
   2382  1.7  christos     case O_register:
   2383  1.7  christos       if (dst->X_add_number > 7)
   2384  1.7  christos         ill_op ();
   2385  1.7  christos       opcode = 0x46; /* LD B,(HL) */
   2386  1.7  christos       switch (src->X_add_number)
   2387  1.7  christos         {
   2388  1.7  christos         case REG_HL: prefix = 0x00; break;
   2389  1.7  christos         case REG_IX: prefix = 0xDD; break;
   2390  1.7  christos         case REG_IY: prefix = 0xFD; break;
   2391  1.7  christos         default:
   2392  1.7  christos           ill_op ();
   2393  1.7  christos         }
   2394  1.7  christos       q = frag_more (prefix ? 2 : 1);
   2395  1.7  christos       if (prefix)
   2396  1.7  christos         *q++ = prefix;
   2397  1.7  christos       *q = opcode | ((dst->X_add_number & 7) << 3);
   2398  1.7  christos       if (prefix)
   2399  1.7  christos         {
   2400  1.7  christos           src_offset = *src;
   2401  1.7  christos           src_offset.X_op = O_symbol;
   2402  1.7  christos           src_offset.X_add_number = 0;
   2403  1.7  christos           emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
   2404  1.7  christos         }
   2405  1.7  christos       break;
   2406  1.7  christos     default: /* LD A,(nn) */
   2407  1.7  christos       if (dst->X_add_number == REG_A)
   2408  1.7  christos         {
   2409  1.7  christos           q = frag_more (1);
   2410  1.8  christos 	  *q = (ins_ok & INS_GBZ80) ? 0xFA : 0x3A;
   2411  1.7  christos           emit_word (src);
   2412  1.7  christos         }
   2413  1.8  christos       else
   2414  1.8  christos 	ill_op ();
   2415  1.7  christos     }
   2416  1.7  christos }
   2417  1.7  christos 
   2418  1.7  christos static void
   2419  1.7  christos emit_ld_r_n (expressionS *dst, expressionS *src)
   2420  1.7  christos { /* for 8-bit immediate value load to register: LD r,n */
   2421  1.7  christos   char *q;
   2422  1.7  christos   char prefix = 0;
   2423  1.7  christos 
   2424  1.7  christos   switch (dst->X_add_number)
   2425  1.7  christos     {
   2426  1.7  christos     case REG_H|R_IX:
   2427  1.7  christos     case REG_L|R_IX:
   2428  1.7  christos       prefix = 0xDD;
   2429  1.7  christos       break;
   2430  1.7  christos     case REG_H|R_IY:
   2431  1.7  christos     case REG_L|R_IY:
   2432  1.7  christos       prefix = 0xFD;
   2433  1.7  christos       break;
   2434  1.7  christos     case REG_A:
   2435  1.7  christos     case REG_B:
   2436  1.7  christos     case REG_C:
   2437  1.7  christos     case REG_D:
   2438  1.7  christos     case REG_E:
   2439  1.7  christos     case REG_H:
   2440  1.7  christos     case REG_L:
   2441  1.7  christos       break;
   2442  1.7  christos     default:
   2443  1.7  christos       ill_op ();
   2444  1.7  christos     }
   2445  1.7  christos 
   2446  1.7  christos   q = frag_more (prefix ? 2 : 1);
   2447  1.7  christos   if (prefix)
   2448  1.7  christos     {
   2449  1.7  christos       if (ins_ok & INS_GBZ80)
   2450  1.7  christos         ill_op ();
   2451  1.8  christos       else if (!(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
   2452  1.7  christos         check_mach (INS_IDX_HALF);
   2453  1.7  christos       *q++ = prefix;
   2454  1.1  christos     }
   2455  1.7  christos   *q = 0x06 | ((dst->X_add_number & 7) << 3);
   2456  1.7  christos   emit_byte (src, BFD_RELOC_8);
   2457  1.1  christos }
   2458  1.1  christos 
   2459  1.1  christos static void
   2460  1.7  christos emit_ld_r_r (expressionS *dst, expressionS *src)
   2461  1.7  christos { /* mostly 8-bit load register from register instructions: LD r,r */
   2462  1.7  christos   /* there are some exceptions: LD SP,HL/IX/IY; LD I,HL and LD HL,I */
   2463  1.1  christos   char *q;
   2464  1.7  christos   int prefix = 0;
   2465  1.7  christos   int opcode = 0;
   2466  1.7  christos   int ii_halves = 0;
   2467  1.1  christos 
   2468  1.7  christos   switch (dst->X_add_number)
   2469  1.1  christos     {
   2470  1.7  christos     case REG_SP:
   2471  1.7  christos       switch (src->X_add_number)
   2472  1.7  christos         {
   2473  1.7  christos         case REG_HL: prefix = 0x00; break;
   2474  1.7  christos         case REG_IX: prefix = 0xDD; break;
   2475  1.7  christos         case REG_IY: prefix = 0xFD; break;
   2476  1.7  christos         default:
   2477  1.7  christos           ill_op ();
   2478  1.7  christos         }
   2479  1.7  christos       opcode = 0xF9;
   2480  1.7  christos       break;
   2481  1.7  christos     case REG_HL:
   2482  1.7  christos       if (!(ins_ok & INS_EZ80))
   2483  1.7  christos         ill_op ();
   2484  1.7  christos       if (src->X_add_number != REG_I)
   2485  1.7  christos         ill_op ();
   2486  1.7  christos       if (cpu_mode < 1)
   2487  1.7  christos         error (_("ADL mode instruction"));
   2488  1.7  christos       /* LD HL,I */
   2489  1.7  christos       prefix = 0xED;
   2490  1.7  christos       opcode = 0xD7;
   2491  1.7  christos       break;
   2492  1.1  christos     case REG_I:
   2493  1.7  christos       if (src->X_add_number == REG_HL)
   2494  1.7  christos         {
   2495  1.7  christos           if (!(ins_ok & INS_EZ80))
   2496  1.7  christos             ill_op ();
   2497  1.7  christos           if (cpu_mode < 1)
   2498  1.7  christos             error (_("ADL mode instruction"));
   2499  1.7  christos           prefix = 0xED;
   2500  1.7  christos           opcode = 0xC7;
   2501  1.7  christos         }
   2502  1.7  christos       else if (src->X_add_number == REG_A)
   2503  1.7  christos         {
   2504  1.7  christos           prefix = 0xED;
   2505  1.7  christos           opcode = 0x47;
   2506  1.7  christos         }
   2507  1.7  christos       else
   2508  1.7  christos         ill_op ();
   2509  1.7  christos       break;
   2510  1.7  christos     case REG_MB:
   2511  1.7  christos       if (!(ins_ok & INS_EZ80) || (src->X_add_number != REG_A))
   2512  1.7  christos         ill_op ();
   2513  1.7  christos       if (cpu_mode < 1)
   2514  1.7  christos         error (_("ADL mode instruction"));
   2515  1.7  christos       prefix = 0xED;
   2516  1.7  christos       opcode = 0x6D;
   2517  1.7  christos       break;
   2518  1.1  christos     case REG_R:
   2519  1.7  christos       if (src->X_add_number == REG_A) /* LD R,A */
   2520  1.7  christos         {
   2521  1.7  christos           prefix = 0xED;
   2522  1.7  christos           opcode = 0x4F;
   2523  1.7  christos         }
   2524  1.1  christos       else
   2525  1.7  christos         ill_op ();
   2526  1.1  christos       break;
   2527  1.1  christos     case REG_A:
   2528  1.7  christos       if (src->X_add_number == REG_I) /* LD A,I */
   2529  1.7  christos         {
   2530  1.7  christos           prefix = 0xED;
   2531  1.7  christos           opcode = 0x57;
   2532  1.7  christos           break;
   2533  1.7  christos         }
   2534  1.7  christos       else if (src->X_add_number == REG_R) /* LD A,R */
   2535  1.7  christos         {
   2536  1.7  christos           prefix = 0xED;
   2537  1.7  christos           opcode = 0x5F;
   2538  1.7  christos           break;
   2539  1.7  christos         }
   2540  1.7  christos       else if (src->X_add_number == REG_MB) /* LD A,MB */
   2541  1.7  christos         {
   2542  1.7  christos           if (!(ins_ok & INS_EZ80))
   2543  1.7  christos             ill_op ();
   2544  1.7  christos           else
   2545  1.7  christos             {
   2546  1.7  christos               if (cpu_mode < 1)
   2547  1.7  christos                 error (_("ADL mode instruction"));
   2548  1.7  christos               prefix = 0xED;
   2549  1.7  christos               opcode = 0x6E;
   2550  1.7  christos             }
   2551  1.7  christos           break;
   2552  1.7  christos         }
   2553  1.7  christos       /* Fall through. */
   2554  1.1  christos     case REG_B:
   2555  1.1  christos     case REG_C:
   2556  1.1  christos     case REG_D:
   2557  1.1  christos     case REG_E:
   2558  1.7  christos     case REG_H:
   2559  1.7  christos     case REG_L:
   2560  1.7  christos       prefix = 0x00;
   2561  1.7  christos       break;
   2562  1.7  christos     case REG_H|R_IX:
   2563  1.7  christos     case REG_L|R_IX:
   2564  1.7  christos       prefix = 0xDD;
   2565  1.7  christos       ii_halves = 1;
   2566  1.7  christos       break;
   2567  1.7  christos     case REG_H|R_IY:
   2568  1.7  christos     case REG_L|R_IY:
   2569  1.7  christos       prefix = 0xFD;
   2570  1.7  christos       ii_halves = 1;
   2571  1.7  christos       break;
   2572  1.7  christos     default:
   2573  1.7  christos       ill_op ();
   2574  1.7  christos     }
   2575  1.7  christos 
   2576  1.7  christos   if (opcode == 0)
   2577  1.7  christos     {
   2578  1.7  christos       switch (src->X_add_number)
   2579  1.7  christos         {
   2580  1.7  christos           case REG_A:
   2581  1.7  christos           case REG_B:
   2582  1.7  christos           case REG_C:
   2583  1.7  christos           case REG_D:
   2584  1.7  christos           case REG_E:
   2585  1.7  christos             break;
   2586  1.7  christos           case REG_H:
   2587  1.7  christos           case REG_L:
   2588  1.7  christos             if (prefix != 0)
   2589  1.7  christos               ill_op (); /* LD iiH/L,H/L are not permitted */
   2590  1.7  christos             break;
   2591  1.7  christos           case REG_H|R_IX:
   2592  1.7  christos           case REG_L|R_IX:
   2593  1.7  christos 	    if (prefix == 0xFD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
   2594  1.7  christos               ill_op (); /* LD IYL,IXL and LD H,IXH are not permitted */
   2595  1.7  christos             prefix = 0xDD;
   2596  1.7  christos             ii_halves = 1;
   2597  1.7  christos             break;
   2598  1.7  christos           case REG_H|R_IY:
   2599  1.7  christos           case REG_L|R_IY:
   2600  1.7  christos 	    if (prefix == 0xDD || dst->X_add_number == REG_H || dst->X_add_number == REG_L)
   2601  1.7  christos               ill_op (); /* LD IXH,IYH and LD L,IYL are not permitted */
   2602  1.7  christos             prefix = 0xFD;
   2603  1.7  christos             ii_halves = 1;
   2604  1.7  christos             break;
   2605  1.7  christos           default:
   2606  1.7  christos             ill_op ();
   2607  1.7  christos         }
   2608  1.7  christos       opcode = 0x40 + ((dst->X_add_number & 7) << 3) + (src->X_add_number & 7);
   2609  1.7  christos     }
   2610  1.7  christos   if ((ins_ok & INS_GBZ80) && prefix != 0)
   2611  1.7  christos     ill_op ();
   2612  1.8  christos   if (ii_halves && !(ins_ok & (INS_EZ80|INS_R800|INS_Z80N)))
   2613  1.7  christos     check_mach (INS_IDX_HALF);
   2614  1.7  christos   if (prefix == 0 && (ins_ok & INS_EZ80))
   2615  1.7  christos     {
   2616  1.7  christos       switch (opcode)
   2617  1.7  christos         {
   2618  1.7  christos         case 0x40: /* SIS prefix, in Z80 it is LD B,B */
   2619  1.7  christos         case 0x49: /* LIS prefix, in Z80 it is LD C,C */
   2620  1.7  christos         case 0x52: /* SIL prefix, in Z80 it is LD D,D */
   2621  1.7  christos         case 0x5B: /* LIL prefix, in Z80 it is LD E,E */
   2622  1.7  christos           as_warn (_("unsupported instruction, assembled as NOP"));
   2623  1.7  christos           opcode = 0x00;
   2624  1.7  christos           break;
   2625  1.7  christos         default:;
   2626  1.7  christos         }
   2627  1.7  christos     }
   2628  1.7  christos   q = frag_more (prefix ? 2 : 1);
   2629  1.7  christos   if (prefix)
   2630  1.7  christos     *q++ = prefix;
   2631  1.7  christos   *q = opcode;
   2632  1.7  christos }
   2633  1.7  christos 
   2634  1.7  christos static void
   2635  1.7  christos emit_ld_rr_m (expressionS *dst, expressionS *src)
   2636  1.7  christos { /* for 16-bit indirect load from memory to register: LD rr,(xxx) */
   2637  1.7  christos   char *q;
   2638  1.7  christos   int prefix = 0;
   2639  1.7  christos   int opcode = 0;
   2640  1.7  christos   expressionS src_offset;
   2641  1.7  christos 
   2642  1.7  christos   /* GBZ80 has no support for 16-bit load from memory instructions */
   2643  1.7  christos   if (ins_ok & INS_GBZ80)
   2644  1.7  christos     ill_op ();
   2645  1.7  christos 
   2646  1.7  christos   prefix = 0xED;
   2647  1.7  christos   switch (src->X_op)
   2648  1.7  christos     {
   2649  1.7  christos     case O_md1: /* LD rr,(ii+d) */
   2650  1.7  christos       prefix = (src->X_add_number == REG_IX) ? 0xDD : 0xFD;
   2651  1.7  christos       /* Fall through.  */
   2652  1.7  christos     case O_register: /* LD rr,(HL) */
   2653  1.7  christos       /* currently only EZ80 has support for 16bit indirect memory load instructions */
   2654  1.7  christos       if (!(ins_ok & INS_EZ80))
   2655  1.7  christos         ill_op ();
   2656  1.7  christos       switch (dst->X_add_number)
   2657  1.7  christos         {
   2658  1.7  christos         case REG_BC: opcode = 0x07; break;
   2659  1.7  christos         case REG_DE: opcode = 0x17; break;
   2660  1.7  christos         case REG_HL: opcode = 0x27; break;
   2661  1.8  christos 	case REG_IX: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x37 : 0x31; break;
   2662  1.8  christos 	case REG_IY: opcode = (prefix == 0xED || prefix == 0xDD) ? 0x31 : 0x37; break;
   2663  1.7  christos         default:
   2664  1.7  christos           ill_op ();
   2665  1.7  christos         }
   2666  1.7  christos       q = frag_more (2);
   2667  1.7  christos       *q++ = prefix;
   2668  1.7  christos       *q = opcode;
   2669  1.7  christos       if (prefix != 0xED)
   2670  1.7  christos         {
   2671  1.7  christos           src_offset = *src;
   2672  1.7  christos           src_offset.X_op = O_symbol;
   2673  1.7  christos           src_offset.X_add_number = 0;
   2674  1.7  christos           emit_byte (& src_offset, BFD_RELOC_Z80_DISP8);
   2675  1.7  christos         }
   2676  1.7  christos       break;
   2677  1.7  christos     default: /* LD rr,(nn) */
   2678  1.7  christos       switch (dst->X_add_number)
   2679  1.7  christos         {
   2680  1.7  christos         case REG_BC: prefix = 0xED; opcode = 0x4B; break;
   2681  1.7  christos         case REG_DE: prefix = 0xED; opcode = 0x5B; break;
   2682  1.7  christos         case REG_HL: prefix = 0x00; opcode = 0x2A; break;
   2683  1.7  christos         case REG_SP: prefix = 0xED; opcode = 0x7B; break;
   2684  1.7  christos         case REG_IX: prefix = 0xDD; opcode = 0x2A; break;
   2685  1.7  christos         case REG_IY: prefix = 0xFD; opcode = 0x2A; break;
   2686  1.7  christos         default:
   2687  1.7  christos           ill_op ();
   2688  1.7  christos         }
   2689  1.7  christos       q = frag_more (prefix ? 2 : 1);
   2690  1.7  christos       if (prefix)
   2691  1.7  christos         *q++ = prefix;
   2692  1.7  christos       *q = opcode;
   2693  1.7  christos       emit_word (src);
   2694  1.7  christos     }
   2695  1.7  christos     return;
   2696  1.7  christos }
   2697  1.7  christos 
   2698  1.7  christos static void
   2699  1.7  christos emit_ld_rr_nn (expressionS *dst, expressionS *src)
   2700  1.7  christos { /* mostly load imediate value to multibyte register instructions: LD rr,nn */
   2701  1.7  christos   char *q;
   2702  1.7  christos   int prefix = 0x00;
   2703  1.7  christos   int opcode = 0x21; /* LD HL,nn */
   2704  1.7  christos   switch (dst->X_add_number)
   2705  1.7  christos     {
   2706  1.7  christos     case REG_IX:
   2707  1.7  christos       prefix = 0xDD;
   2708  1.7  christos       break;
   2709  1.7  christos     case REG_IY:
   2710  1.7  christos       prefix = 0xFD;
   2711  1.1  christos       break;
   2712  1.7  christos     case REG_HL:
   2713  1.7  christos       break;
   2714  1.7  christos     case REG_BC:
   2715  1.7  christos     case REG_DE:
   2716  1.7  christos     case REG_SP:
   2717  1.7  christos       opcode = 0x01 + ((dst->X_add_number & 3) << 4);
   2718  1.7  christos       break;
   2719  1.7  christos     default:
   2720  1.7  christos       ill_op ();
   2721  1.7  christos       return;
   2722  1.7  christos     }
   2723  1.7  christos   if (prefix && (ins_ok & INS_GBZ80))
   2724  1.7  christos     ill_op ();
   2725  1.7  christos   q = frag_more (prefix ? 2 : 1);
   2726  1.7  christos   if (prefix)
   2727  1.7  christos     *q++ = prefix;
   2728  1.7  christos   *q = opcode;
   2729  1.7  christos   emit_word (src);
   2730  1.7  christos }
   2731  1.7  christos 
   2732  1.7  christos static const char *
   2733  1.7  christos emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
   2734  1.7  christos 	const char * args)
   2735  1.7  christos {
   2736  1.7  christos   expressionS dst, src;
   2737  1.7  christos   const char *p;
   2738  1.7  christos 
   2739  1.7  christos   p = parse_exp (args, & dst);
   2740  1.7  christos   if (*p++ != ',')
   2741  1.7  christos     error (_("bad instruction syntax"));
   2742  1.7  christos   p = parse_exp (p, & src);
   2743  1.7  christos 
   2744  1.7  christos   if (dst.X_md)
   2745  1.7  christos     {
   2746  1.7  christos       if (src.X_op == O_register)
   2747  1.7  christos         {
   2748  1.7  christos           if (src.X_add_number <= 7)
   2749  1.7  christos             emit_ld_m_r (& dst, & src); /* LD (xxx),r */
   2750  1.7  christos           else
   2751  1.7  christos             emit_ld_m_rr (& dst, & src); /* LD (xxx),rr */
   2752  1.7  christos         }
   2753  1.7  christos       else
   2754  1.7  christos         emit_ld_m_n (& dst, & src); /* LD (hl),n or LD (ix/y+r),n */
   2755  1.7  christos     }
   2756  1.7  christos   else if (dst.X_op == O_register)
   2757  1.7  christos     {
   2758  1.7  christos       if (src.X_md)
   2759  1.7  christos         {
   2760  1.7  christos           if (dst.X_add_number <= 7)
   2761  1.7  christos             emit_ld_r_m (& dst, & src);
   2762  1.7  christos           else
   2763  1.7  christos             emit_ld_rr_m (& dst, & src);
   2764  1.7  christos         }
   2765  1.7  christos       else if (src.X_op == O_register)
   2766  1.7  christos         emit_ld_r_r (& dst, & src);
   2767  1.7  christos       else if ((dst.X_add_number & ~R_INDEX) <= 7)
   2768  1.7  christos         emit_ld_r_n (& dst, & src);
   2769  1.7  christos       else
   2770  1.7  christos         emit_ld_rr_nn (& dst, & src);
   2771  1.7  christos     }
   2772  1.7  christos   else
   2773  1.7  christos     ill_op ();
   2774  1.7  christos 
   2775  1.7  christos   return p;
   2776  1.7  christos }
   2777  1.7  christos 
   2778  1.7  christos static const char *
   2779  1.7  christos emit_lddldi (char prefix, char opcode, const char * args)
   2780  1.7  christos {
   2781  1.7  christos   expressionS dst, src;
   2782  1.7  christos   const char *p;
   2783  1.7  christos   char *q;
   2784  1.7  christos 
   2785  1.7  christos   if (!(ins_ok & INS_GBZ80))
   2786  1.7  christos     return emit_insn (prefix, opcode, args);
   2787  1.7  christos 
   2788  1.7  christos   p = parse_exp (args, & dst);
   2789  1.7  christos   if (*p++ != ',')
   2790  1.7  christos     error (_("bad instruction syntax"));
   2791  1.8  christos   p = parse_exp (p, & src);
   2792  1.7  christos 
   2793  1.7  christos   if (dst.X_op != O_register || src.X_op != O_register)
   2794  1.7  christos     ill_op ();
   2795  1.7  christos 
   2796  1.7  christos   /* convert opcode 0xA0 . 0x22, 0xA8 . 0x32 */
   2797  1.7  christos   opcode = (opcode & 0x08) * 2 + 0x22;
   2798  1.7  christos 
   2799  1.7  christos   if (dst.X_md != 0
   2800  1.7  christos       && dst.X_add_number == REG_HL
   2801  1.7  christos       && src.X_md == 0
   2802  1.7  christos       && src.X_add_number == REG_A)
   2803  1.7  christos     opcode |= 0x00; /* LDx (HL),A */
   2804  1.7  christos   else if (dst.X_md == 0
   2805  1.7  christos       && dst.X_add_number == REG_A
   2806  1.7  christos       && src.X_md != 0
   2807  1.7  christos       && src.X_add_number == REG_HL)
   2808  1.7  christos     opcode |= 0x08; /* LDx A,(HL) */
   2809  1.7  christos   else
   2810  1.7  christos     ill_op ();
   2811  1.7  christos 
   2812  1.7  christos   q = frag_more (1);
   2813  1.7  christos   *q = opcode;
   2814  1.7  christos   return p;
   2815  1.7  christos }
   2816  1.7  christos 
   2817  1.7  christos static const char *
   2818  1.7  christos emit_ldh (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
   2819  1.7  christos         const char * args)
   2820  1.7  christos {
   2821  1.7  christos   expressionS dst, src;
   2822  1.7  christos   const char *p;
   2823  1.7  christos   char *q;
   2824  1.1  christos 
   2825  1.7  christos   p = parse_exp (args, & dst);
   2826  1.7  christos   if (*p++ != ',')
   2827  1.7  christos     {
   2828  1.7  christos       error (_("bad instruction syntax"));
   2829  1.7  christos       return p;
   2830  1.7  christos     }
   2831  1.7  christos 
   2832  1.7  christos   p = parse_exp (p, & src);
   2833  1.7  christos   if (dst.X_md == 0
   2834  1.7  christos       && dst.X_op == O_register
   2835  1.7  christos       && dst.X_add_number == REG_A
   2836  1.7  christos       && src.X_md != 0
   2837  1.8  christos       && src.X_op != O_md1)
   2838  1.7  christos     {
   2839  1.8  christos       if (src.X_op != O_register)
   2840  1.8  christos 	{
   2841  1.8  christos 	  q = frag_more (1);
   2842  1.8  christos 	  *q = 0xF0;
   2843  1.8  christos 	  emit_byte (& src, BFD_RELOC_8);
   2844  1.8  christos 	}
   2845  1.8  christos       else if (src.X_add_number == REG_C)
   2846  1.8  christos 	*frag_more (1) = 0xF2;
   2847  1.8  christos       else
   2848  1.8  christos 	ill_op ();
   2849  1.7  christos     }
   2850  1.7  christos   else if (dst.X_md != 0
   2851  1.7  christos       && dst.X_op != O_md1
   2852  1.7  christos       && src.X_md == 0
   2853  1.7  christos       && src.X_op == O_register
   2854  1.7  christos       && src.X_add_number == REG_A)
   2855  1.7  christos     {
   2856  1.7  christos       if (dst.X_op == O_register)
   2857  1.7  christos         {
   2858  1.7  christos           if (dst.X_add_number == REG_C)
   2859  1.7  christos             {
   2860  1.7  christos               q = frag_more (1);
   2861  1.7  christos               *q = 0xE2;
   2862  1.7  christos             }
   2863  1.7  christos           else
   2864  1.7  christos             ill_op ();
   2865  1.7  christos         }
   2866  1.1  christos       else
   2867  1.7  christos         {
   2868  1.7  christos           q = frag_more (1);
   2869  1.7  christos           *q = 0xE0;
   2870  1.7  christos           emit_byte (& dst, BFD_RELOC_8);
   2871  1.7  christos         }
   2872  1.7  christos     }
   2873  1.7  christos   else
   2874  1.7  christos     ill_op ();
   2875  1.7  christos 
   2876  1.7  christos   return p;
   2877  1.7  christos }
   2878  1.7  christos 
   2879  1.7  christos static const char *
   2880  1.8  christos emit_ldhl (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   2881  1.8  christos {
   2882  1.8  christos   expressionS dst, src;
   2883  1.8  christos   const char *p;
   2884  1.8  christos   char *q;
   2885  1.8  christos   p = parse_exp (args, & dst);
   2886  1.8  christos   if (*p++ != ',')
   2887  1.8  christos     {
   2888  1.8  christos       error (_("bad instruction syntax"));
   2889  1.8  christos       return p;
   2890  1.8  christos     }
   2891  1.8  christos 
   2892  1.8  christos   p = parse_exp (p, & src);
   2893  1.8  christos   if (dst.X_md || dst.X_op != O_register || dst.X_add_number != REG_SP
   2894  1.8  christos       || src.X_md || src.X_op == O_register || src.X_op == O_md1)
   2895  1.8  christos     ill_op ();
   2896  1.8  christos   q = frag_more (1);
   2897  1.8  christos   *q = opcode;
   2898  1.8  christos   emit_byte (& src, BFD_RELOC_Z80_DISP8);
   2899  1.8  christos   return p;
   2900  1.8  christos }
   2901  1.8  christos 
   2902  1.8  christos static const char *
   2903  1.7  christos parse_lea_pea_args (const char * args, expressionS *op)
   2904  1.7  christos {
   2905  1.7  christos   const char *p;
   2906  1.7  christos   p = parse_exp (args, op);
   2907  1.7  christos   if (sdcc_compat && *p == ',' && op->X_op == O_register)
   2908  1.7  christos     {
   2909  1.7  christos       expressionS off;
   2910  1.7  christos       p = parse_exp (p + 1, &off);
   2911  1.7  christos       op->X_op = O_add;
   2912  1.7  christos       op->X_add_symbol = make_expr_symbol (&off);
   2913  1.7  christos     }
   2914  1.7  christos   return p;
   2915  1.7  christos }
   2916  1.7  christos 
   2917  1.7  christos static const char *
   2918  1.7  christos emit_lea (char prefix, char opcode, const char * args)
   2919  1.7  christos {
   2920  1.7  christos   expressionS dst, src;
   2921  1.7  christos   const char *p;
   2922  1.7  christos   char *q;
   2923  1.7  christos   int rnum;
   2924  1.7  christos 
   2925  1.7  christos   p = parse_exp (args, & dst);
   2926  1.7  christos   if (dst.X_md != 0 || dst.X_op != O_register)
   2927  1.7  christos     ill_op ();
   2928  1.7  christos 
   2929  1.7  christos   rnum = dst.X_add_number;
   2930  1.7  christos   switch (rnum)
   2931  1.7  christos     {
   2932  1.7  christos     case REG_BC:
   2933  1.7  christos     case REG_DE:
   2934  1.7  christos     case REG_HL:
   2935  1.7  christos       opcode = 0x02 | ((rnum & 0x03) << 4);
   2936  1.7  christos       break;
   2937  1.7  christos     case REG_IX:
   2938  1.7  christos       opcode = 0x32; /* lea ix,ix+d has opcode 0x32; lea ix,iy+d has opcode 0x54 */
   2939  1.7  christos       break;
   2940  1.7  christos     case REG_IY:
   2941  1.7  christos       opcode = 0x33; /* lea iy,iy+d has opcode 0x33; lea iy,ix+d has opcode 0x55 */
   2942  1.7  christos       break;
   2943  1.7  christos     default:
   2944  1.7  christos       ill_op ();
   2945  1.7  christos     }
   2946  1.7  christos 
   2947  1.7  christos   if (*p++ != ',')
   2948  1.7  christos     error (_("bad instruction syntax"));
   2949  1.7  christos 
   2950  1.7  christos   p = parse_lea_pea_args (p, & src);
   2951  1.7  christos   if (src.X_md != 0 || src.X_op != O_add /*&& src.X_op != O_register*/)
   2952  1.7  christos     ill_op ();
   2953  1.7  christos 
   2954  1.7  christos   rnum = src.X_add_number;
   2955  1.7  christos   switch (src.X_op)
   2956  1.7  christos     {
   2957  1.7  christos     case O_add:
   2958  1.1  christos       break;
   2959  1.7  christos     case O_register: /* permit instructions like LEA rr,IX without displacement specified */
   2960  1.7  christos       src.X_add_symbol = zero;
   2961  1.7  christos       break;
   2962  1.7  christos     default:
   2963  1.7  christos       ill_op ();
   2964  1.7  christos     }
   2965  1.7  christos 
   2966  1.7  christos   switch (rnum)
   2967  1.7  christos     {
   2968  1.7  christos     case REG_IX:
   2969  1.7  christos       opcode = (opcode == (char)0x33) ? 0x55 : (opcode|0x00);
   2970  1.7  christos       break;
   2971  1.7  christos     case REG_IY:
   2972  1.7  christos       opcode = (opcode == (char)0x32) ? 0x54 : (opcode|0x01);
   2973  1.7  christos     }
   2974  1.7  christos 
   2975  1.7  christos   q = frag_more (2);
   2976  1.7  christos   *q++ = prefix;
   2977  1.7  christos   *q = opcode;
   2978  1.7  christos 
   2979  1.7  christos   src.X_op = O_symbol;
   2980  1.7  christos   src.X_add_number = 0;
   2981  1.7  christos   emit_byte (& src, BFD_RELOC_Z80_DISP8);
   2982  1.7  christos 
   2983  1.7  christos   return p;
   2984  1.7  christos }
   2985  1.7  christos 
   2986  1.7  christos static const char *
   2987  1.7  christos emit_mlt (char prefix, char opcode, const char * args)
   2988  1.7  christos {
   2989  1.7  christos   expressionS arg;
   2990  1.7  christos   const char *p;
   2991  1.7  christos   char *q;
   2992  1.7  christos 
   2993  1.7  christos   p = parse_exp (args, & arg);
   2994  1.7  christos   if (arg.X_md != 0 || arg.X_op != O_register || !(arg.X_add_number & R_ARITH))
   2995  1.7  christos     ill_op ();
   2996  1.7  christos 
   2997  1.7  christos   q = frag_more (2);
   2998  1.8  christos   if (ins_ok & INS_Z80N)
   2999  1.8  christos     {
   3000  1.8  christos       if (arg.X_add_number != REG_DE)
   3001  1.8  christos 	ill_op ();
   3002  1.8  christos       *q++ = 0xED;
   3003  1.8  christos       *q = 0x30;
   3004  1.8  christos     }
   3005  1.8  christos   else
   3006  1.8  christos     {
   3007  1.8  christos       *q++ = prefix;
   3008  1.8  christos       *q = opcode | ((arg.X_add_number & 3) << 4);
   3009  1.8  christos     }
   3010  1.8  christos 
   3011  1.8  christos   return p;
   3012  1.8  christos }
   3013  1.8  christos 
   3014  1.8  christos /* MUL D,E (Z80N only) */
   3015  1.8  christos static const char *
   3016  1.8  christos emit_mul (char prefix, char opcode, const char * args)
   3017  1.8  christos {
   3018  1.8  christos   expressionS r1, r2;
   3019  1.8  christos   const char *p;
   3020  1.8  christos   char *q;
   3021  1.8  christos 
   3022  1.8  christos   p = parse_exp (args, & r1);
   3023  1.8  christos   if (*p++ != ',')
   3024  1.8  christos     error (_("bad instruction syntax"));
   3025  1.8  christos   p = parse_exp (p, & r2);
   3026  1.8  christos 
   3027  1.8  christos   if (r1.X_md != 0 || r1.X_op != O_register || r1.X_add_number != REG_D ||
   3028  1.8  christos       r2.X_md != 0 || r2.X_op != O_register || r2.X_add_number != REG_E)
   3029  1.8  christos     ill_op ();
   3030  1.8  christos 
   3031  1.8  christos   q = frag_more (2);
   3032  1.7  christos   *q++ = prefix;
   3033  1.8  christos   *q = opcode;
   3034  1.7  christos 
   3035  1.7  christos   return p;
   3036  1.7  christos }
   3037  1.7  christos 
   3038  1.7  christos static const char *
   3039  1.8  christos emit_nextreg (char prefix, char opcode ATTRIBUTE_UNUSED, const char * args)
   3040  1.8  christos {
   3041  1.8  christos   expressionS rr, nn;
   3042  1.8  christos   const char *p;
   3043  1.8  christos   char *q;
   3044  1.8  christos 
   3045  1.8  christos   p = parse_exp (args, & rr);
   3046  1.8  christos   if (*p++ != ',')
   3047  1.8  christos     error (_("bad instruction syntax"));
   3048  1.8  christos   p = parse_exp (p, & nn);
   3049  1.8  christos   if (rr.X_md != 0 || rr.X_op == O_register || rr.X_op == O_md1 ||
   3050  1.8  christos       nn.X_md != 0 || nn.X_op == O_md1)
   3051  1.8  christos     ill_op ();
   3052  1.8  christos   q = frag_more (2);
   3053  1.8  christos   *q++ = prefix;
   3054  1.8  christos   emit_byte (&rr, BFD_RELOC_8);
   3055  1.8  christos   if (nn.X_op == O_register && nn.X_add_number == REG_A)
   3056  1.8  christos     *q = 0x92;
   3057  1.8  christos   else if (nn.X_op != O_register)
   3058  1.8  christos     {
   3059  1.8  christos       *q = 0x91;
   3060  1.8  christos       emit_byte (&nn, BFD_RELOC_8);
   3061  1.8  christos     }
   3062  1.8  christos   else
   3063  1.8  christos     ill_op ();
   3064  1.8  christos   return p;
   3065  1.8  christos }
   3066  1.8  christos 
   3067  1.8  christos static const char *
   3068  1.7  christos emit_pea (char prefix, char opcode, const char * args)
   3069  1.7  christos {
   3070  1.7  christos   expressionS arg;
   3071  1.7  christos   const char *p;
   3072  1.7  christos   char *q;
   3073  1.1  christos 
   3074  1.7  christos   p = parse_lea_pea_args (args, & arg);
   3075  1.7  christos   if (arg.X_md != 0
   3076  1.7  christos       || (/*arg.X_op != O_register &&*/ arg.X_op != O_add)
   3077  1.7  christos       || !(arg.X_add_number & R_INDEX))
   3078  1.7  christos     ill_op ();
   3079  1.7  christos   /* PEA ii without displacement is mostly typo,
   3080  1.7  christos      because there is PUSH instruction which is shorter and faster */
   3081  1.7  christos   /*if (arg.X_op == O_register)
   3082  1.7  christos     as_warn (_("PEA is used without displacement, use PUSH instead"));*/
   3083  1.7  christos 
   3084  1.7  christos   q = frag_more (2);
   3085  1.7  christos   *q++ = prefix;
   3086  1.7  christos   *q = opcode + (arg.X_add_number == REG_IY ? 1 : 0);
   3087  1.1  christos 
   3088  1.7  christos   arg.X_op = O_symbol;
   3089  1.7  christos   arg.X_add_number = 0;
   3090  1.7  christos   emit_byte (& arg, BFD_RELOC_Z80_DISP8);
   3091  1.1  christos 
   3092  1.7  christos   return p;
   3093  1.7  christos }
   3094  1.1  christos 
   3095  1.7  christos static const char *
   3096  1.7  christos emit_reti (char prefix, char opcode, const char * args)
   3097  1.7  christos {
   3098  1.7  christos   if (ins_ok & INS_GBZ80)
   3099  1.7  christos     return emit_insn (0x00, 0xD9, args);
   3100  1.1  christos 
   3101  1.7  christos   return emit_insn (prefix, opcode, args);
   3102  1.1  christos }
   3103  1.1  christos 
   3104  1.1  christos static const char *
   3105  1.7  christos emit_tst (char prefix, char opcode, const char *args)
   3106  1.1  christos {
   3107  1.7  christos   expressionS arg_s;
   3108  1.1  christos   const char *p;
   3109  1.1  christos   char *q;
   3110  1.7  christos   int rnum;
   3111  1.1  christos 
   3112  1.7  christos   p = parse_exp (args, & arg_s);
   3113  1.7  christos   if (*p == ',' && arg_s.X_md == 0 && arg_s.X_op == O_register && arg_s.X_add_number == REG_A)
   3114  1.7  christos     {
   3115  1.7  christos       if (!(ins_ok & INS_EZ80))
   3116  1.7  christos         ill_op ();
   3117  1.7  christos       ++p;
   3118  1.7  christos       p = parse_exp (p, & arg_s);
   3119  1.7  christos     }
   3120  1.1  christos 
   3121  1.7  christos   rnum = arg_s.X_add_number;
   3122  1.7  christos   switch (arg_s.X_op)
   3123  1.1  christos     {
   3124  1.1  christos     case O_md1:
   3125  1.7  christos       ill_op ();
   3126  1.1  christos       break;
   3127  1.1  christos     case O_register:
   3128  1.7  christos       rnum = arg_s.X_add_number;
   3129  1.7  christos       if (arg_s.X_md != 0)
   3130  1.7  christos         {
   3131  1.7  christos           if (rnum != REG_HL)
   3132  1.7  christos             ill_op ();
   3133  1.7  christos           else
   3134  1.7  christos             rnum = 6;
   3135  1.7  christos         }
   3136  1.7  christos       q = frag_more (2);
   3137  1.7  christos       *q++ = prefix;
   3138  1.7  christos       *q = opcode | (rnum << 3);
   3139  1.1  christos       break;
   3140  1.1  christos     default:
   3141  1.7  christos       if (arg_s.X_md)
   3142  1.7  christos         ill_op ();
   3143  1.7  christos       q = frag_more (2);
   3144  1.8  christos       if (ins_ok & INS_Z80N)
   3145  1.8  christos 	{
   3146  1.8  christos 	  *q++ = 0xED;
   3147  1.8  christos 	  *q = 0x27;
   3148  1.8  christos 	}
   3149  1.8  christos       else
   3150  1.8  christos 	{
   3151  1.8  christos 	  *q++ = prefix;
   3152  1.8  christos 	  *q = opcode | 0x60;
   3153  1.8  christos 	}
   3154  1.7  christos       emit_byte (& arg_s, BFD_RELOC_8);
   3155  1.1  christos     }
   3156  1.1  christos   return p;
   3157  1.1  christos }
   3158  1.1  christos 
   3159  1.7  christos static const char *
   3160  1.8  christos emit_insn_n (char prefix, char opcode, const char *args)
   3161  1.7  christos {
   3162  1.7  christos   expressionS arg;
   3163  1.7  christos   const char *p;
   3164  1.7  christos   char *q;
   3165  1.7  christos 
   3166  1.7  christos   p = parse_exp (args, & arg);
   3167  1.7  christos   if (arg.X_md || arg.X_op == O_register || arg.X_op == O_md1)
   3168  1.7  christos     ill_op ();
   3169  1.7  christos 
   3170  1.7  christos   q = frag_more (2);
   3171  1.7  christos   *q++ = prefix;
   3172  1.7  christos   *q = opcode;
   3173  1.7  christos   emit_byte (& arg, BFD_RELOC_8);
   3174  1.7  christos 
   3175  1.7  christos   return p;
   3176  1.7  christos }
   3177  1.7  christos 
   3178  1.1  christos static void
   3179  1.1  christos emit_data (int size ATTRIBUTE_UNUSED)
   3180  1.1  christos {
   3181  1.1  christos   const char *p, *q;
   3182  1.1  christos   char *u, quote;
   3183  1.1  christos   int cnt;
   3184  1.1  christos   expressionS exp;
   3185  1.1  christos 
   3186  1.1  christos   if (is_it_end_of_statement ())
   3187  1.1  christos     {
   3188  1.1  christos       demand_empty_rest_of_line ();
   3189  1.1  christos       return;
   3190  1.1  christos     }
   3191  1.1  christos   p = skip_space (input_line_pointer);
   3192  1.1  christos 
   3193  1.1  christos   do
   3194  1.1  christos     {
   3195  1.1  christos       if (*p == '\"' || *p == '\'')
   3196  1.1  christos 	{
   3197  1.1  christos 	    for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
   3198  1.1  christos 	      ;
   3199  1.1  christos 	    u = frag_more (cnt);
   3200  1.1  christos 	    memcpy (u, q, cnt);
   3201  1.1  christos 	    if (!*p)
   3202  1.1  christos 	      as_warn (_("unterminated string"));
   3203  1.1  christos 	    else
   3204  1.1  christos 	      p = skip_space (p+1);
   3205  1.1  christos 	}
   3206  1.1  christos       else
   3207  1.1  christos 	{
   3208  1.1  christos 	  p = parse_exp (p, &exp);
   3209  1.1  christos 	  if (exp.X_op == O_md1 || exp.X_op == O_register)
   3210  1.1  christos 	    {
   3211  1.1  christos 	      ill_op ();
   3212  1.1  christos 	      break;
   3213  1.1  christos 	    }
   3214  1.1  christos 	  if (exp.X_md)
   3215  1.1  christos 	    as_warn (_("parentheses ignored"));
   3216  1.1  christos 	  emit_byte (&exp, BFD_RELOC_8);
   3217  1.1  christos 	  p = skip_space (p);
   3218  1.1  christos 	}
   3219  1.1  christos     }
   3220  1.1  christos   while (*p++ == ',') ;
   3221  1.1  christos   input_line_pointer = (char *)(p-1);
   3222  1.1  christos }
   3223  1.1  christos 
   3224  1.7  christos static void
   3225  1.7  christos z80_cons (int size)
   3226  1.7  christos {
   3227  1.7  christos   const char *p;
   3228  1.7  christos   expressionS exp;
   3229  1.7  christos 
   3230  1.7  christos   if (is_it_end_of_statement ())
   3231  1.7  christos     {
   3232  1.7  christos       demand_empty_rest_of_line ();
   3233  1.7  christos       return;
   3234  1.7  christos     }
   3235  1.7  christos   p = skip_space (input_line_pointer);
   3236  1.7  christos 
   3237  1.7  christos   do
   3238  1.7  christos     {
   3239  1.7  christos       p = parse_exp (p, &exp);
   3240  1.7  christos       if (exp.X_op == O_md1 || exp.X_op == O_register)
   3241  1.7  christos 	{
   3242  1.7  christos 	  ill_op ();
   3243  1.7  christos 	  break;
   3244  1.7  christos 	}
   3245  1.7  christos       if (exp.X_md)
   3246  1.7  christos 	as_warn (_("parentheses ignored"));
   3247  1.7  christos       emit_data_val (&exp, size);
   3248  1.7  christos       p = skip_space (p);
   3249  1.7  christos   } while (*p++ == ',') ;
   3250  1.7  christos   input_line_pointer = (char *)(p-1);
   3251  1.7  christos }
   3252  1.7  christos 
   3253  1.7  christos /* next functions were commented out because it is difficult to mix
   3254  1.7  christos    both ADL and Z80 mode instructions within one COFF file:
   3255  1.7  christos    objdump cannot recognize point of mode switching.
   3256  1.7  christos */
   3257  1.7  christos static void
   3258  1.7  christos set_cpu_mode (int mode)
   3259  1.7  christos {
   3260  1.7  christos   if (ins_ok & INS_EZ80)
   3261  1.7  christos     cpu_mode = mode;
   3262  1.7  christos   else
   3263  1.7  christos     error (_("CPU mode is unsupported by target"));
   3264  1.7  christos }
   3265  1.7  christos 
   3266  1.7  christos static void
   3267  1.7  christos assume (int arg ATTRIBUTE_UNUSED)
   3268  1.7  christos {
   3269  1.7  christos   char *name;
   3270  1.7  christos   char c;
   3271  1.7  christos   int n;
   3272  1.7  christos 
   3273  1.7  christos   input_line_pointer = (char*)skip_space (input_line_pointer);
   3274  1.7  christos   c = get_symbol_name (& name);
   3275  1.7  christos   if (strncasecmp (name, "ADL", 4) != 0)
   3276  1.7  christos     {
   3277  1.7  christos       ill_op ();
   3278  1.7  christos       return;
   3279  1.7  christos     }
   3280  1.7  christos 
   3281  1.7  christos   restore_line_pointer (c);
   3282  1.7  christos   input_line_pointer = (char*)skip_space (input_line_pointer);
   3283  1.7  christos   if (*input_line_pointer++ != '=')
   3284  1.7  christos     {
   3285  1.7  christos       error (_("assignment expected"));
   3286  1.7  christos       return;
   3287  1.7  christos     }
   3288  1.7  christos   input_line_pointer = (char*)skip_space (input_line_pointer);
   3289  1.7  christos   n = get_single_number ();
   3290  1.7  christos 
   3291  1.7  christos   set_cpu_mode (n);
   3292  1.7  christos }
   3293  1.7  christos 
   3294  1.1  christos static const char *
   3295  1.1  christos emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   3296  1.1  christos {
   3297  1.1  christos   const char *p;
   3298  1.1  christos 
   3299  1.1  christos   p = skip_space (args);
   3300  1.1  christos   if (TOLOWER (*p++) != 'a' || *p++ != ',')
   3301  1.1  christos     ill_op ();
   3302  1.1  christos   else
   3303  1.1  christos     {
   3304  1.1  christos       char *q, reg;
   3305  1.1  christos 
   3306  1.1  christos       reg = TOLOWER (*p++);
   3307  1.1  christos       switch (reg)
   3308  1.1  christos 	{
   3309  1.1  christos 	case 'b':
   3310  1.1  christos 	case 'c':
   3311  1.1  christos 	case 'd':
   3312  1.1  christos 	case 'e':
   3313  1.1  christos 	  check_mach (INS_R800);
   3314  1.1  christos 	  if (!*skip_space (p))
   3315  1.1  christos 	    {
   3316  1.1  christos 	      q = frag_more (2);
   3317  1.1  christos 	      *q++ = prefix;
   3318  1.1  christos 	      *q = opcode + ((reg - 'b') << 3);
   3319  1.1  christos 	      break;
   3320  1.1  christos 	    }
   3321  1.6  christos 	  /* Fall through.  */
   3322  1.1  christos 	default:
   3323  1.1  christos 	  ill_op ();
   3324  1.1  christos 	}
   3325  1.1  christos     }
   3326  1.1  christos   return p;
   3327  1.1  christos }
   3328  1.1  christos 
   3329  1.1  christos static const char *
   3330  1.1  christos emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   3331  1.1  christos {
   3332  1.1  christos   const char *p;
   3333  1.1  christos 
   3334  1.1  christos   p = skip_space (args);
   3335  1.1  christos   if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
   3336  1.1  christos     ill_op ();
   3337  1.1  christos   else
   3338  1.1  christos     {
   3339  1.1  christos       expressionS reg;
   3340  1.1  christos       char *q;
   3341  1.1  christos 
   3342  1.1  christos       p = parse_exp (p, & reg);
   3343  1.1  christos 
   3344  1.1  christos       if ((!reg.X_md) && reg.X_op == O_register)
   3345  1.1  christos 	switch (reg.X_add_number)
   3346  1.1  christos 	  {
   3347  1.1  christos 	  case REG_BC:
   3348  1.1  christos 	  case REG_SP:
   3349  1.1  christos 	    check_mach (INS_R800);
   3350  1.1  christos 	    q = frag_more (2);
   3351  1.1  christos 	    *q++ = prefix;
   3352  1.1  christos 	    *q = opcode + ((reg.X_add_number & 3) << 4);
   3353  1.1  christos 	    break;
   3354  1.1  christos 	  default:
   3355  1.1  christos 	    ill_op ();
   3356  1.1  christos 	  }
   3357  1.1  christos     }
   3358  1.1  christos   return p;
   3359  1.1  christos }
   3360  1.1  christos 
   3361  1.7  christos static int
   3362  1.7  christos assemble_suffix (const char **suffix)
   3363  1.7  christos {
   3364  1.7  christos   static
   3365  1.7  christos   const char sf[8][4] =
   3366  1.7  christos     {
   3367  1.7  christos       "il",
   3368  1.7  christos       "is",
   3369  1.7  christos       "l",
   3370  1.7  christos       "lil",
   3371  1.7  christos       "lis",
   3372  1.7  christos       "s",
   3373  1.7  christos       "sil",
   3374  1.7  christos       "sis"
   3375  1.7  christos     };
   3376  1.7  christos   const char *p;
   3377  1.7  christos   const char (*t)[4];
   3378  1.7  christos   char sbuf[4];
   3379  1.7  christos   int i;
   3380  1.7  christos 
   3381  1.7  christos   p = *suffix;
   3382  1.7  christos   if (*p++ != '.')
   3383  1.7  christos     return 0;
   3384  1.7  christos 
   3385  1.7  christos   for (i = 0; (i < 3) && (ISALPHA (*p)); i++)
   3386  1.7  christos     sbuf[i] = TOLOWER (*p++);
   3387  1.7  christos   if (*p && !ISSPACE (*p))
   3388  1.7  christos     return 0;
   3389  1.7  christos   *suffix = p;
   3390  1.7  christos   sbuf[i] = 0;
   3391  1.7  christos 
   3392  1.7  christos   t = bsearch (sbuf, sf, ARRAY_SIZE (sf), sizeof (sf[0]), (int(*)(const void*, const void*)) strcmp);
   3393  1.7  christos   if (t == NULL)
   3394  1.7  christos     return 0;
   3395  1.7  christos   i = t - sf;
   3396  1.7  christos   switch (i)
   3397  1.7  christos     {
   3398  1.7  christos       case 0: /* IL */
   3399  1.7  christos         i = cpu_mode ? 0x5B : 0x52;
   3400  1.7  christos         break;
   3401  1.7  christos       case 1: /* IS */
   3402  1.7  christos         i = cpu_mode ? 0x49 : 0x40;
   3403  1.7  christos         break;
   3404  1.7  christos       case 2: /* L */
   3405  1.7  christos         i = cpu_mode ? 0x5B : 0x49;
   3406  1.7  christos         break;
   3407  1.7  christos       case 3: /* LIL */
   3408  1.7  christos         i = 0x5B;
   3409  1.7  christos         break;
   3410  1.7  christos       case 4: /* LIS */
   3411  1.7  christos         i = 0x49;
   3412  1.7  christos         break;
   3413  1.7  christos       case 5: /* S */
   3414  1.7  christos         i = cpu_mode ? 0x52 : 0x40;
   3415  1.7  christos         break;
   3416  1.7  christos       case 6: /* SIL */
   3417  1.7  christos         i = 0x52;
   3418  1.7  christos         break;
   3419  1.7  christos       case 7: /* SIS */
   3420  1.7  christos         i = 0x40;
   3421  1.7  christos         break;
   3422  1.7  christos     }
   3423  1.7  christos   *frag_more (1) = (char)i;
   3424  1.7  christos   switch (i)
   3425  1.7  christos     {
   3426  1.7  christos     case 0x40: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IS; break;
   3427  1.7  christos     case 0x49: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IS; break;
   3428  1.7  christos     case 0x52: inst_mode = INST_MODE_FORCED | INST_MODE_S | INST_MODE_IL; break;
   3429  1.7  christos     case 0x5B: inst_mode = INST_MODE_FORCED | INST_MODE_L | INST_MODE_IL; break;
   3430  1.7  christos     }
   3431  1.7  christos   return 1;
   3432  1.7  christos }
   3433  1.7  christos 
   3434  1.7  christos static void
   3435  1.7  christos psect (int arg)
   3436  1.7  christos {
   3437  1.7  christos #if defined(OBJ_ELF)
   3438  1.7  christos   return obj_elf_section (arg);
   3439  1.7  christos #elif defined(OBJ_COFF)
   3440  1.7  christos   return obj_coff_section (arg);
   3441  1.7  christos #else
   3442  1.7  christos #error Unknown object format
   3443  1.7  christos #endif
   3444  1.7  christos }
   3445  1.7  christos 
   3446  1.7  christos static void
   3447  1.7  christos set_inss (int inss)
   3448  1.7  christos {
   3449  1.7  christos   int old_ins;
   3450  1.7  christos 
   3451  1.7  christos   if (!sdcc_compat)
   3452  1.7  christos     as_fatal (_("Invalid directive"));
   3453  1.7  christos 
   3454  1.7  christos   old_ins = ins_ok;
   3455  1.7  christos   ins_ok &= INS_MARCH_MASK;
   3456  1.7  christos   ins_ok |= inss;
   3457  1.7  christos   if (old_ins != ins_ok)
   3458  1.7  christos     cpu_mode = 0;
   3459  1.7  christos }
   3460  1.7  christos 
   3461  1.7  christos static void
   3462  1.7  christos ignore (int arg ATTRIBUTE_UNUSED)
   3463  1.7  christos {
   3464  1.7  christos   ignore_rest_of_line ();
   3465  1.7  christos }
   3466  1.7  christos 
   3467  1.7  christos static void
   3468  1.7  christos area (int arg)
   3469  1.7  christos {
   3470  1.7  christos   char *p;
   3471  1.7  christos   if (!sdcc_compat)
   3472  1.7  christos     as_fatal (_("Invalid directive"));
   3473  1.7  christos   for (p = input_line_pointer; *p && *p != '(' && *p != '\n'; p++)
   3474  1.7  christos     ;
   3475  1.7  christos   if (*p == '(')
   3476  1.7  christos     {
   3477  1.7  christos       *p = '\n';
   3478  1.7  christos       psect (arg);
   3479  1.7  christos       *p++ = '(';
   3480  1.7  christos       ignore_rest_of_line ();
   3481  1.7  christos     }
   3482  1.7  christos   else
   3483  1.7  christos     psect (arg);
   3484  1.7  christos }
   3485  1.7  christos 
   3486  1.1  christos /* Port specific pseudo ops.  */
   3487  1.1  christos const pseudo_typeS md_pseudo_table[] =
   3488  1.1  christos {
   3489  1.7  christos   { ".area", area, 0},
   3490  1.7  christos   { ".assume", assume, 0},
   3491  1.7  christos   { ".ez80", set_inss, INS_EZ80},
   3492  1.7  christos   { ".gbz80", set_inss, INS_GBZ80},
   3493  1.7  christos   { ".module", ignore, 0},
   3494  1.7  christos   { ".optsdcc", ignore, 0},
   3495  1.7  christos   { ".r800", set_inss, INS_R800},
   3496  1.7  christos   { ".set", s_set, 0},
   3497  1.7  christos   { ".z180", set_inss, INS_Z180},
   3498  1.8  christos   { ".hd64", set_inss, INS_Z180},
   3499  1.7  christos   { ".z80", set_inss, INS_Z80},
   3500  1.8  christos   { ".z80n", set_inss, INS_Z80N},
   3501  1.1  christos   { "db" , emit_data, 1},
   3502  1.7  christos   { "d24", z80_cons, 3},
   3503  1.7  christos   { "d32", z80_cons, 4},
   3504  1.7  christos   { "def24", z80_cons, 3},
   3505  1.7  christos   { "def32", z80_cons, 4},
   3506  1.3  christos   { "defb", emit_data, 1},
   3507  1.7  christos   { "defm", emit_data, 1},
   3508  1.1  christos   { "defs", s_space, 1}, /* Synonym for ds on some assemblers.  */
   3509  1.7  christos   { "defw", z80_cons, 2},
   3510  1.1  christos   { "ds",   s_space, 1}, /* Fill with bytes rather than words.  */
   3511  1.7  christos   { "dw", z80_cons, 2},
   3512  1.7  christos   { "psect", psect, 0}, /* TODO: Translate attributes.  */
   3513  1.1  christos   { "set", 0, 0}, 		/* Real instruction on z80.  */
   3514  1.8  christos   { "xdef", s_globl, 0},	/* Synonym for .GLOBAL */
   3515  1.8  christos   { "xref", s_ignore, 0},	/* Synonym for .EXTERN */
   3516  1.1  christos   { NULL, 0, 0 }
   3517  1.1  christos } ;
   3518  1.1  christos 
   3519  1.1  christos static table_t instab[] =
   3520  1.1  christos {
   3521  1.7  christos   { "adc",  0x88, 0x4A, emit_adc,  INS_ALL },
   3522  1.7  christos   { "add",  0x80, 0x09, emit_add,  INS_ALL },
   3523  1.7  christos   { "and",  0x00, 0xA0, emit_s,    INS_ALL },
   3524  1.7  christos   { "bit",  0xCB, 0x40, emit_bit,  INS_ALL },
   3525  1.8  christos   { "brlc", 0xED, 0x2C, emit_bshft,INS_Z80N },
   3526  1.8  christos   { "bsla", 0xED, 0x28, emit_bshft,INS_Z80N },
   3527  1.8  christos   { "bsra", 0xED, 0x29, emit_bshft,INS_Z80N },
   3528  1.8  christos   { "bsrf", 0xED, 0x2B, emit_bshft,INS_Z80N },
   3529  1.8  christos   { "bsrl", 0xED, 0x2A, emit_bshft,INS_Z80N },
   3530  1.7  christos   { "call", 0xCD, 0xC4, emit_jpcc, INS_ALL },
   3531  1.7  christos   { "ccf",  0x00, 0x3F, emit_insn, INS_ALL },
   3532  1.7  christos   { "cp",   0x00, 0xB8, emit_s,    INS_ALL },
   3533  1.7  christos   { "cpd",  0xED, 0xA9, emit_insn, INS_NOT_GBZ80 },
   3534  1.7  christos   { "cpdr", 0xED, 0xB9, emit_insn, INS_NOT_GBZ80 },
   3535  1.7  christos   { "cpi",  0xED, 0xA1, emit_insn, INS_NOT_GBZ80 },
   3536  1.7  christos   { "cpir", 0xED, 0xB1, emit_insn, INS_NOT_GBZ80 },
   3537  1.7  christos   { "cpl",  0x00, 0x2F, emit_insn, INS_ALL },
   3538  1.7  christos   { "daa",  0x00, 0x27, emit_insn, INS_ALL },
   3539  1.7  christos   { "dec",  0x0B, 0x05, emit_incdec,INS_ALL },
   3540  1.7  christos   { "di",   0x00, 0xF3, emit_insn, INS_ALL },
   3541  1.7  christos   { "djnz", 0x00, 0x10, emit_jr,   INS_NOT_GBZ80 },
   3542  1.7  christos   { "ei",   0x00, 0xFB, emit_insn, INS_ALL },
   3543  1.7  christos   { "ex",   0x00, 0x00, emit_ex,   INS_NOT_GBZ80 },
   3544  1.7  christos   { "exx",  0x00, 0xD9, emit_insn, INS_NOT_GBZ80 },
   3545  1.7  christos   { "halt", 0x00, 0x76, emit_insn, INS_ALL },
   3546  1.7  christos   { "im",   0xED, 0x46, emit_im,   INS_NOT_GBZ80 },
   3547  1.7  christos   { "in",   0x00, 0x00, emit_in,   INS_NOT_GBZ80 },
   3548  1.7  christos   { "in0",  0xED, 0x00, emit_in0,  INS_Z180|INS_EZ80 },
   3549  1.7  christos   { "inc",  0x03, 0x04, emit_incdec,INS_ALL },
   3550  1.7  christos   { "ind",  0xED, 0xAA, emit_insn, INS_NOT_GBZ80 },
   3551  1.7  christos   { "ind2", 0xED, 0x8C, emit_insn, INS_EZ80 },
   3552  1.7  christos   { "ind2r",0xED, 0x9C, emit_insn, INS_EZ80 },
   3553  1.7  christos   { "indm", 0xED, 0x8A, emit_insn, INS_EZ80 },
   3554  1.7  christos   { "indmr",0xED, 0x9A, emit_insn, INS_EZ80 },
   3555  1.7  christos   { "indr", 0xED, 0xBA, emit_insn, INS_NOT_GBZ80 },
   3556  1.7  christos   { "indrx",0xED, 0xCA, emit_insn, INS_EZ80 },
   3557  1.7  christos   { "ini",  0xED, 0xA2, emit_insn, INS_NOT_GBZ80 },
   3558  1.7  christos   { "ini2", 0xED, 0x84, emit_insn, INS_EZ80 },
   3559  1.7  christos   { "ini2r",0xED, 0x94, emit_insn, INS_EZ80 },
   3560  1.7  christos   { "inim", 0xED, 0x82, emit_insn, INS_EZ80 },
   3561  1.7  christos   { "inimr",0xED, 0x92, emit_insn, INS_EZ80 },
   3562  1.7  christos   { "inir", 0xED, 0xB2, emit_insn, INS_NOT_GBZ80 },
   3563  1.7  christos   { "inirx",0xED, 0xC2, emit_insn, INS_EZ80 },
   3564  1.7  christos   { "jp",   0xC3, 0xC2, emit_jpcc, INS_ALL },
   3565  1.7  christos   { "jr",   0x18, 0x20, emit_jrcc, INS_ALL },
   3566  1.7  christos   { "ld",   0x00, 0x00, emit_ld,   INS_ALL },
   3567  1.7  christos   { "ldd",  0xED, 0xA8, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
   3568  1.7  christos   { "lddr", 0xED, 0xB8, emit_insn, INS_NOT_GBZ80 },
   3569  1.8  christos   { "lddrx",0xED, 0xBC, emit_insn, INS_Z80N },
   3570  1.8  christos   { "lddx", 0xED, 0xAC, emit_insn, INS_Z80N },
   3571  1.7  christos   { "ldh",  0xE0, 0x00, emit_ldh,  INS_GBZ80 },
   3572  1.8  christos   { "ldhl", 0x00, 0xF8, emit_ldhl, INS_GBZ80 },
   3573  1.7  christos   { "ldi",  0xED, 0xA0, emit_lddldi,INS_ALL }, /* GBZ80 has special meaning */
   3574  1.7  christos   { "ldir", 0xED, 0xB0, emit_insn, INS_NOT_GBZ80 },
   3575  1.8  christos   { "ldirx",0xED, 0xB4, emit_insn, INS_Z80N },
   3576  1.8  christos   { "ldix", 0xED, 0xA4, emit_insn, INS_Z80N },
   3577  1.8  christos   { "ldpirx",0xED,0xB7, emit_insn, INS_Z80N },
   3578  1.8  christos   { "ldws", 0xED, 0xA5, emit_insn, INS_Z80N },
   3579  1.7  christos   { "lea",  0xED, 0x02, emit_lea,  INS_EZ80 },
   3580  1.8  christos   { "mirror",0xED,0x24, emit_insn, INS_Z80N },
   3581  1.8  christos   { "mlt",  0xED, 0x4C, emit_mlt,  INS_Z180|INS_EZ80|INS_Z80N },
   3582  1.8  christos   { "mul",  0xED, 0x30, emit_mul,  INS_Z80N },
   3583  1.7  christos   { "mulub",0xED, 0xC5, emit_mulub,INS_R800 },
   3584  1.7  christos   { "muluw",0xED, 0xC3, emit_muluw,INS_R800 },
   3585  1.8  christos   { "neg",  0xED, 0x44, emit_insn, INS_NOT_GBZ80 },
   3586  1.8  christos   { "nextreg",0xED,0x91,emit_nextreg,INS_Z80N },
   3587  1.7  christos   { "nop",  0x00, 0x00, emit_insn, INS_ALL },
   3588  1.7  christos   { "or",   0x00, 0xB0, emit_s,    INS_ALL },
   3589  1.7  christos   { "otd2r",0xED, 0xBC, emit_insn, INS_EZ80 },
   3590  1.7  christos   { "otdm", 0xED, 0x8B, emit_insn, INS_Z180|INS_EZ80 },
   3591  1.7  christos   { "otdmr",0xED, 0x9B, emit_insn, INS_Z180|INS_EZ80 },
   3592  1.7  christos   { "otdr", 0xED, 0xBB, emit_insn, INS_NOT_GBZ80 },
   3593  1.7  christos   { "otdrx",0xED, 0xCB, emit_insn, INS_EZ80 },
   3594  1.7  christos   { "oti2r",0xED, 0xB4, emit_insn, INS_EZ80 },
   3595  1.7  christos   { "otim", 0xED, 0x83, emit_insn, INS_Z180|INS_EZ80 },
   3596  1.7  christos   { "otimr",0xED, 0x93, emit_insn, INS_Z180|INS_EZ80 },
   3597  1.7  christos   { "otir", 0xED, 0xB3, emit_insn, INS_NOT_GBZ80 },
   3598  1.7  christos   { "otirx",0xED, 0xC3, emit_insn, INS_EZ80 },
   3599  1.7  christos   { "out",  0x00, 0x00, emit_out,  INS_NOT_GBZ80 },
   3600  1.7  christos   { "out0", 0xED, 0x01, emit_out0, INS_Z180|INS_EZ80 },
   3601  1.7  christos   { "outd", 0xED, 0xAB, emit_insn, INS_NOT_GBZ80 },
   3602  1.7  christos   { "outd2",0xED, 0xAC, emit_insn, INS_EZ80 },
   3603  1.7  christos   { "outi", 0xED, 0xA3, emit_insn, INS_NOT_GBZ80 },
   3604  1.7  christos   { "outi2",0xED, 0xA4, emit_insn, INS_EZ80 },
   3605  1.8  christos   { "outinb",0xED,0x90, emit_insn, INS_Z80N },
   3606  1.7  christos   { "pea",  0xED, 0x65, emit_pea,  INS_EZ80 },
   3607  1.8  christos   { "pixelad",0xED,0x94,emit_insn, INS_Z80N },
   3608  1.8  christos   { "pixeldn",0xED,0x93,emit_insn, INS_Z80N },
   3609  1.7  christos   { "pop",  0x00, 0xC1, emit_pop,  INS_ALL },
   3610  1.8  christos   { "push", 0x00, 0xC5, emit_push, INS_ALL },
   3611  1.7  christos   { "res",  0xCB, 0x80, emit_bit,  INS_ALL },
   3612  1.7  christos   { "ret",  0xC9, 0xC0, emit_retcc,INS_ALL },
   3613  1.7  christos   { "reti", 0xED, 0x4D, emit_reti, INS_ALL }, /*GBZ80 has its own opcode for it*/
   3614  1.7  christos   { "retn", 0xED, 0x45, emit_insn, INS_NOT_GBZ80 },
   3615  1.7  christos   { "rl",   0xCB, 0x10, emit_mr,   INS_ALL },
   3616  1.7  christos   { "rla",  0x00, 0x17, emit_insn, INS_ALL },
   3617  1.7  christos   { "rlc",  0xCB, 0x00, emit_mr,   INS_ALL },
   3618  1.7  christos   { "rlca", 0x00, 0x07, emit_insn, INS_ALL },
   3619  1.7  christos   { "rld",  0xED, 0x6F, emit_insn, INS_NOT_GBZ80 },
   3620  1.7  christos   { "rr",   0xCB, 0x18, emit_mr,   INS_ALL },
   3621  1.7  christos   { "rra",  0x00, 0x1F, emit_insn, INS_ALL },
   3622  1.7  christos   { "rrc",  0xCB, 0x08, emit_mr,   INS_ALL },
   3623  1.7  christos   { "rrca", 0x00, 0x0F, emit_insn, INS_ALL },
   3624  1.7  christos   { "rrd",  0xED, 0x67, emit_insn, INS_NOT_GBZ80 },
   3625  1.7  christos   { "rsmix",0xED, 0x7E, emit_insn, INS_EZ80 },
   3626  1.7  christos   { "rst",  0x00, 0xC7, emit_rst,  INS_ALL },
   3627  1.7  christos   { "sbc",  0x98, 0x42, emit_adc,  INS_ALL },
   3628  1.7  christos   { "scf",  0x00, 0x37, emit_insn, INS_ALL },
   3629  1.7  christos   { "set",  0xCB, 0xC0, emit_bit,  INS_ALL },
   3630  1.8  christos   { "setae",0xED, 0x95, emit_insn, INS_Z80N },
   3631  1.8  christos   { "sl1",  0xCB, 0x30, emit_mr,   INS_SLI|INS_Z80N },
   3632  1.7  christos   { "sla",  0xCB, 0x20, emit_mr,   INS_ALL },
   3633  1.8  christos   { "sli",  0xCB, 0x30, emit_mr,   INS_SLI|INS_Z80N },
   3634  1.8  christos   { "sll",  0xCB, 0x30, emit_mr,   INS_SLI|INS_Z80N },
   3635  1.7  christos   { "slp",  0xED, 0x76, emit_insn, INS_Z180|INS_EZ80 },
   3636  1.7  christos   { "sra",  0xCB, 0x28, emit_mr,   INS_ALL },
   3637  1.7  christos   { "srl",  0xCB, 0x38, emit_mr,   INS_ALL },
   3638  1.7  christos   { "stmix",0xED, 0x7D, emit_insn, INS_EZ80 },
   3639  1.7  christos   { "stop", 0x00, 0x10, emit_insn, INS_GBZ80 },
   3640  1.8  christos   { "sub",  0x00, 0x90, emit_sub,  INS_ALL },
   3641  1.8  christos   { "swap", 0xCB, 0x30, emit_swap, INS_GBZ80|INS_Z80N },
   3642  1.8  christos   { "swapnib",0xED,0x23,emit_insn, INS_Z80N },
   3643  1.8  christos   { "test", 0xED, 0x27, emit_insn_n, INS_Z80N },
   3644  1.8  christos   { "tst",  0xED, 0x04, emit_tst,  INS_Z180|INS_EZ80|INS_Z80N },
   3645  1.8  christos   { "tstio",0xED, 0x74, emit_insn_n,INS_Z180|INS_EZ80 },
   3646  1.7  christos   { "xor",  0x00, 0xA8, emit_s,    INS_ALL },
   3647  1.1  christos } ;
   3648  1.1  christos 
   3649  1.1  christos void
   3650  1.7  christos md_assemble (char *str)
   3651  1.1  christos {
   3652  1.1  christos   const char *p;
   3653  1.1  christos   char * old_ptr;
   3654  1.1  christos   int i;
   3655  1.1  christos   table_t *insp;
   3656  1.1  christos 
   3657  1.1  christos   err_flag = 0;
   3658  1.7  christos   inst_mode = cpu_mode ? (INST_MODE_L | INST_MODE_IL) : (INST_MODE_S | INST_MODE_IS);
   3659  1.1  christos   old_ptr = input_line_pointer;
   3660  1.1  christos   p = skip_space (str);
   3661  1.7  christos   for (i = 0; (i < BUFLEN) && (ISALPHA (*p) || ISDIGIT (*p));)
   3662  1.1  christos     buf[i++] = TOLOWER (*p++);
   3663  1.1  christos 
   3664  1.1  christos   if (i == BUFLEN)
   3665  1.1  christos     {
   3666  1.1  christos       buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated.  */
   3667  1.1  christos       buf[BUFLEN-1] = 0;
   3668  1.1  christos       as_bad (_("Unknown instruction '%s'"), buf);
   3669  1.1  christos     }
   3670  1.3  christos   else
   3671  1.1  christos     {
   3672  1.7  christos       dwarf2_emit_insn (0);
   3673  1.7  christos       if ((*p) && (!ISSPACE (*p)))
   3674  1.7  christos         {
   3675  1.7  christos           if (*p != '.' || !(ins_ok & INS_EZ80) || !assemble_suffix (&p))
   3676  1.7  christos             {
   3677  1.7  christos               as_bad (_("syntax error"));
   3678  1.7  christos               goto end;
   3679  1.7  christos             }
   3680  1.7  christos         }
   3681  1.1  christos       buf[i] = 0;
   3682  1.1  christos       p = skip_space (p);
   3683  1.1  christos       key = buf;
   3684  1.3  christos 
   3685  1.1  christos       insp = bsearch (&key, instab, ARRAY_SIZE (instab),
   3686  1.1  christos 		    sizeof (instab[0]), key_cmp);
   3687  1.7  christos       if (!insp || (insp->inss && !(insp->inss & ins_ok)))
   3688  1.8  christos 	{
   3689  1.8  christos 	  *frag_more (1) = 0;
   3690  1.8  christos 	  as_bad (_("Unknown instruction `%s'"), buf);
   3691  1.8  christos 	}
   3692  1.1  christos       else
   3693  1.1  christos 	{
   3694  1.1  christos 	  p = insp->fp (insp->prefix, insp->opcode, p);
   3695  1.1  christos 	  p = skip_space (p);
   3696  1.8  christos 	  if ((!err_flag) && *p)
   3697  1.8  christos 	    as_bad (_("junk at end of line, "
   3698  1.8  christos 		      "first unrecognized character is `%c'"), *p);
   3699  1.1  christos 	}
   3700  1.1  christos     }
   3701  1.8  christos  end:
   3702  1.1  christos   input_line_pointer = old_ptr;
   3703  1.1  christos }
   3704  1.1  christos 
   3705  1.8  christos static int
   3706  1.8  christos signed_overflow (signed long value, unsigned bitsize)
   3707  1.8  christos {
   3708  1.8  christos   signed long max = (signed long) ((1UL << (bitsize - 1)) - 1);
   3709  1.8  christos   return value < -max - 1 || value > max;
   3710  1.8  christos }
   3711  1.8  christos 
   3712  1.8  christos static int
   3713  1.8  christos unsigned_overflow (unsigned long value, unsigned bitsize)
   3714  1.8  christos {
   3715  1.8  christos   return value >> (bitsize - 1) >> 1 != 0;
   3716  1.8  christos }
   3717  1.8  christos 
   3718  1.8  christos static int
   3719  1.8  christos is_overflow (long value, unsigned bitsize)
   3720  1.8  christos {
   3721  1.8  christos   if (value < 0)
   3722  1.8  christos     return signed_overflow (value, bitsize);
   3723  1.8  christos   return unsigned_overflow ((unsigned long)value, bitsize);
   3724  1.8  christos }
   3725  1.8  christos 
   3726  1.1  christos void
   3727  1.8  christos md_apply_fix (fixS * fixP, valueT* valP, segT seg)
   3728  1.1  christos {
   3729  1.8  christos   long val = *valP;
   3730  1.1  christos   char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal;
   3731  1.1  christos 
   3732  1.8  christos   if (fixP->fx_addsy == NULL)
   3733  1.8  christos     fixP->fx_done = 1;
   3734  1.8  christos   else if (fixP->fx_pcrel)
   3735  1.8  christos     {
   3736  1.8  christos       segT s = S_GET_SEGMENT (fixP->fx_addsy);
   3737  1.8  christos       if (s == seg || s == absolute_section)
   3738  1.8  christos 	{
   3739  1.8  christos 	  val += S_GET_VALUE (fixP->fx_addsy);
   3740  1.8  christos 	  fixP->fx_done = 1;
   3741  1.8  christos 	}
   3742  1.8  christos     }
   3743  1.8  christos 
   3744  1.1  christos   switch (fixP->fx_r_type)
   3745  1.1  christos     {
   3746  1.1  christos     case BFD_RELOC_8_PCREL:
   3747  1.8  christos     case BFD_RELOC_Z80_DISP8:
   3748  1.8  christos     case BFD_RELOC_8:
   3749  1.8  christos     case BFD_RELOC_16:
   3750  1.8  christos     case BFD_RELOC_24:
   3751  1.8  christos     case BFD_RELOC_32:
   3752  1.8  christos     case BFD_RELOC_Z80_16_BE:
   3753  1.8  christos       fixP->fx_no_overflow = 0;
   3754  1.8  christos       break;
   3755  1.8  christos     default:
   3756  1.8  christos       fixP->fx_no_overflow = 1;
   3757  1.1  christos       break;
   3758  1.8  christos     }
   3759  1.1  christos 
   3760  1.8  christos   switch (fixP->fx_r_type)
   3761  1.8  christos     {
   3762  1.8  christos     case BFD_RELOC_8_PCREL:
   3763  1.1  christos     case BFD_RELOC_Z80_DISP8:
   3764  1.8  christos       if (fixP->fx_done && signed_overflow (val, 8))
   3765  1.8  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
   3766  1.8  christos 		      _("8-bit signed offset out of range (%+ld)"), val);
   3767  1.8  christos       *p_lit++ = val;
   3768  1.1  christos       break;
   3769  1.1  christos 
   3770  1.7  christos     case BFD_RELOC_Z80_BYTE0:
   3771  1.7  christos       *p_lit++ = val;
   3772  1.7  christos       break;
   3773  1.7  christos 
   3774  1.7  christos     case BFD_RELOC_Z80_BYTE1:
   3775  1.7  christos       *p_lit++ = (val >> 8);
   3776  1.7  christos       break;
   3777  1.7  christos 
   3778  1.7  christos     case BFD_RELOC_Z80_BYTE2:
   3779  1.7  christos       *p_lit++ = (val >> 16);
   3780  1.7  christos       break;
   3781  1.7  christos 
   3782  1.7  christos     case BFD_RELOC_Z80_BYTE3:
   3783  1.7  christos       *p_lit++ = (val >> 24);
   3784  1.7  christos       break;
   3785  1.7  christos 
   3786  1.1  christos     case BFD_RELOC_8:
   3787  1.8  christos       if (fixP->fx_done && is_overflow(val, 8))
   3788  1.8  christos 	as_warn_where (fixP->fx_file, fixP->fx_line,
   3789  1.8  christos 		       _("8-bit overflow (%+ld)"), val);
   3790  1.1  christos       *p_lit++ = val;
   3791  1.1  christos       break;
   3792  1.1  christos 
   3793  1.7  christos     case BFD_RELOC_Z80_WORD1:
   3794  1.7  christos       *p_lit++ = (val >> 16);
   3795  1.7  christos       *p_lit++ = (val >> 24);
   3796  1.7  christos       break;
   3797  1.7  christos 
   3798  1.7  christos     case BFD_RELOC_Z80_WORD0:
   3799  1.8  christos       *p_lit++ = val;
   3800  1.8  christos       *p_lit++ = (val >> 8);
   3801  1.8  christos       break;
   3802  1.8  christos 
   3803  1.1  christos     case BFD_RELOC_16:
   3804  1.8  christos       if (fixP->fx_done && is_overflow(val, 16))
   3805  1.8  christos 	as_warn_where (fixP->fx_file, fixP->fx_line,
   3806  1.8  christos 		       _("16-bit overflow (%+ld)"), val);
   3807  1.1  christos       *p_lit++ = val;
   3808  1.1  christos       *p_lit++ = (val >> 8);
   3809  1.1  christos       break;
   3810  1.1  christos 
   3811  1.1  christos     case BFD_RELOC_24: /* Def24 may produce this.  */
   3812  1.8  christos       if (fixP->fx_done && is_overflow(val, 24))
   3813  1.8  christos 	as_warn_where (fixP->fx_file, fixP->fx_line,
   3814  1.8  christos 		       _("24-bit overflow (%+ld)"), val);
   3815  1.1  christos       *p_lit++ = val;
   3816  1.1  christos       *p_lit++ = (val >> 8);
   3817  1.1  christos       *p_lit++ = (val >> 16);
   3818  1.1  christos       break;
   3819  1.1  christos 
   3820  1.1  christos     case BFD_RELOC_32: /* Def32 and .long may produce this.  */
   3821  1.8  christos       if (fixP->fx_done && is_overflow(val, 32))
   3822  1.8  christos 	as_warn_where (fixP->fx_file, fixP->fx_line,
   3823  1.8  christos 		       _("32-bit overflow (%+ld)"), val);
   3824  1.1  christos       *p_lit++ = val;
   3825  1.1  christos       *p_lit++ = (val >> 8);
   3826  1.1  christos       *p_lit++ = (val >> 16);
   3827  1.1  christos       *p_lit++ = (val >> 24);
   3828  1.8  christos       break;
   3829  1.8  christos 
   3830  1.8  christos     case BFD_RELOC_Z80_16_BE: /* Z80N PUSH nn instruction produce this.  */
   3831  1.8  christos       *p_lit++ = val >> 8;
   3832  1.8  christos       *p_lit++ = val;
   3833  1.1  christos       break;
   3834  1.1  christos 
   3835  1.1  christos     default:
   3836  1.8  christos       printf (_("md_apply_fix: unknown reloc type 0x%x\n"), fixP->fx_r_type);
   3837  1.1  christos       abort ();
   3838  1.1  christos     }
   3839  1.1  christos }
   3840  1.1  christos 
   3841  1.1  christos /* GAS will call this to generate a reloc.  GAS will pass the
   3842  1.1  christos    resulting reloc to `bfd_install_relocation'.  This currently works
   3843  1.1  christos    poorly, as `bfd_install_relocation' often does the wrong thing, and
   3844  1.1  christos    instances of `tc_gen_reloc' have been written to work around the
   3845  1.1  christos    problems, which in turns makes it difficult to fix
   3846  1.1  christos    `bfd_install_relocation'.  */
   3847  1.1  christos 
   3848  1.1  christos /* If while processing a fixup, a reloc really
   3849  1.1  christos    needs to be created then it is done here.  */
   3850  1.1  christos 
   3851  1.1  christos arelent *
   3852  1.1  christos tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
   3853  1.1  christos {
   3854  1.1  christos   arelent *reloc;
   3855  1.1  christos 
   3856  1.8  christos   if (fixp->fx_subsy != NULL)
   3857  1.1  christos     {
   3858  1.8  christos       as_bad_subtract (fixp);
   3859  1.1  christos       return NULL;
   3860  1.1  christos     }
   3861  1.1  christos 
   3862  1.5  christos   reloc               = XNEW (arelent);
   3863  1.5  christos   reloc->sym_ptr_ptr  = XNEW (asymbol *);
   3864  1.1  christos   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   3865  1.1  christos   reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;
   3866  1.8  christos   reloc->addend       = fixp->fx_offset;
   3867  1.1  christos   reloc->howto        = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   3868  1.8  christos   if (reloc->howto == NULL)
   3869  1.8  christos     {
   3870  1.8  christos       as_bad_where (fixp->fx_file, fixp->fx_line,
   3871  1.8  christos 		    _("reloc %d not supported by object file format"),
   3872  1.8  christos 		    (int) fixp->fx_r_type);
   3873  1.8  christos       return NULL;
   3874  1.8  christos     }
   3875  1.8  christos 
   3876  1.8  christos   if (fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
   3877  1.8  christos       || fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
   3878  1.8  christos     reloc->address = fixp->fx_offset;
   3879  1.1  christos 
   3880  1.1  christos   return reloc;
   3881  1.1  christos }
   3882  1.7  christos 
   3883  1.7  christos int
   3884  1.8  christos z80_tc_labels_without_colon (void)
   3885  1.8  christos {
   3886  1.8  christos   return colonless_labels;
   3887  1.8  christos }
   3888  1.8  christos 
   3889  1.8  christos int
   3890  1.7  christos z80_tc_label_is_local (const char *name)
   3891  1.7  christos {
   3892  1.7  christos   const char *n;
   3893  1.7  christos   const char *p;
   3894  1.7  christos   if (local_label_prefix == NULL)
   3895  1.7  christos     return 0;
   3896  1.7  christos   for (p = local_label_prefix, n = name; *p && *n && *n == *p; p++, n++)
   3897  1.7  christos     ;
   3898  1.7  christos   return *p == '\0';
   3899  1.7  christos }
   3900  1.7  christos 
   3901  1.7  christos /* Parse floating point number from string and compute mantissa and
   3902  1.7  christos    exponent. Mantissa is normalized.
   3903  1.7  christos */
   3904  1.7  christos #define EXP_MIN -0x10000
   3905  1.7  christos #define EXP_MAX 0x10000
   3906  1.7  christos static int
   3907  1.8  christos str_to_broken_float (bool *signP, uint64_t *mantissaP, int *expP)
   3908  1.7  christos {
   3909  1.7  christos   char *p;
   3910  1.8  christos   bool sign;
   3911  1.8  christos   uint64_t mantissa = 0;
   3912  1.7  christos   int exponent = 0;
   3913  1.7  christos   int i;
   3914  1.7  christos 
   3915  1.7  christos   p = (char*)skip_space (input_line_pointer);
   3916  1.7  christos   sign = (*p == '-');
   3917  1.7  christos   *signP = sign;
   3918  1.7  christos   if (sign || *p == '+')
   3919  1.7  christos     ++p;
   3920  1.7  christos   if (strncasecmp (p, "NaN", 3) == 0)
   3921  1.7  christos     {
   3922  1.7  christos       *mantissaP = 0;
   3923  1.7  christos       *expP = 0;
   3924  1.7  christos       input_line_pointer = p + 3;
   3925  1.7  christos       return 1;
   3926  1.7  christos     }
   3927  1.7  christos   if (strncasecmp (p, "inf", 3) == 0)
   3928  1.7  christos     {
   3929  1.7  christos       *mantissaP = 1ull << 63;
   3930  1.7  christos       *expP = EXP_MAX;
   3931  1.7  christos       input_line_pointer = p + 3;
   3932  1.7  christos       return 1;
   3933  1.7  christos     }
   3934  1.7  christos   for (; ISDIGIT (*p); ++p)
   3935  1.7  christos     {
   3936  1.7  christos       if (mantissa >> 60)
   3937  1.7  christos 	{
   3938  1.7  christos 	  if (*p >= '5')
   3939  1.7  christos 	    mantissa++;
   3940  1.7  christos 	  break;
   3941  1.7  christos 	}
   3942  1.7  christos       mantissa = mantissa * 10 + (*p - '0');
   3943  1.7  christos     }
   3944  1.7  christos   /* skip non-significant digits */
   3945  1.7  christos   for (; ISDIGIT (*p); ++p)
   3946  1.7  christos     exponent++;
   3947  1.7  christos 
   3948  1.7  christos   if (*p == '.')
   3949  1.7  christos     {
   3950  1.7  christos       p++;
   3951  1.8  christos       if (!exponent) /* If no precision overflow.  */
   3952  1.7  christos 	{
   3953  1.7  christos 	  for (; ISDIGIT (*p); ++p, --exponent)
   3954  1.7  christos 	    {
   3955  1.7  christos 	      if (mantissa >> 60)
   3956  1.7  christos 		{
   3957  1.7  christos 		  if (*p >= '5')
   3958  1.7  christos 		    mantissa++;
   3959  1.7  christos 		  break;
   3960  1.7  christos 		}
   3961  1.7  christos 	      mantissa = mantissa * 10 + (*p - '0');
   3962  1.7  christos 	    }
   3963  1.7  christos 	}
   3964  1.7  christos       for (; ISDIGIT (*p); ++p)
   3965  1.7  christos 	;
   3966  1.7  christos     }
   3967  1.7  christos   if (*p == 'e' || *p == 'E')
   3968  1.7  christos     {
   3969  1.7  christos       int es;
   3970  1.7  christos       int t = 0;
   3971  1.7  christos       ++p;
   3972  1.7  christos       es = (*p == '-');
   3973  1.7  christos       if (es || *p == '+')
   3974  1.7  christos         p++;
   3975  1.7  christos       for (; ISDIGIT (*p); ++p)
   3976  1.7  christos 	{
   3977  1.7  christos 	  if (t < 100)
   3978  1.7  christos 	    t = t * 10 + (*p - '0');
   3979  1.7  christos 	}
   3980  1.7  christos       exponent += (es) ? -t : t;
   3981  1.7  christos     }
   3982  1.7  christos   if (ISALNUM (*p) || *p == '.')
   3983  1.7  christos     return 0;
   3984  1.7  christos   input_line_pointer = p;
   3985  1.7  christos   if (mantissa == 0)
   3986  1.7  christos     {
   3987  1.7  christos       *mantissaP = 1ull << 63;
   3988  1.7  christos       *expP = EXP_MIN;
   3989  1.7  christos       return 1; /* result is 0 */
   3990  1.7  christos     }
   3991  1.7  christos   /* normalization */
   3992  1.7  christos   for (; mantissa <= ~0ull/10; --exponent)
   3993  1.7  christos     mantissa *= 10;
   3994  1.7  christos   /* Now we have sign, mantissa, and signed decimal exponent
   3995  1.7  christos      need to recompute to binary exponent.  */
   3996  1.7  christos   for (i = 64; exponent > 0; --exponent)
   3997  1.7  christos     {
   3998  1.7  christos       /* be sure that no integer overflow */
   3999  1.7  christos       while (mantissa > ~0ull/10)
   4000  1.7  christos 	{
   4001  1.7  christos 	  mantissa >>= 1;
   4002  1.7  christos 	  i += 1;
   4003  1.7  christos 	}
   4004  1.7  christos 	mantissa *= 10;
   4005  1.7  christos     }
   4006  1.7  christos   for (; exponent < 0; ++exponent)
   4007  1.7  christos     {
   4008  1.7  christos       while (!(mantissa >> 63))
   4009  1.7  christos 	{
   4010  1.7  christos 	  mantissa <<= 1;
   4011  1.7  christos 	  i -= 1;
   4012  1.7  christos 	}
   4013  1.7  christos 	mantissa /= 10;
   4014  1.7  christos     }
   4015  1.7  christos   /* normalization */
   4016  1.7  christos   for (; !(mantissa >> 63); --i)
   4017  1.7  christos     mantissa <<= 1;
   4018  1.7  christos   *mantissaP = mantissa;
   4019  1.7  christos   *expP = i;
   4020  1.7  christos   return 1;
   4021  1.7  christos }
   4022  1.7  christos 
   4023  1.7  christos static const char *
   4024  1.7  christos str_to_zeda32(char *litP, int *sizeP)
   4025  1.7  christos {
   4026  1.8  christos   uint64_t mantissa;
   4027  1.8  christos   bool sign;
   4028  1.7  christos   int exponent;
   4029  1.7  christos   unsigned i;
   4030  1.7  christos 
   4031  1.7  christos   *sizeP = 4;
   4032  1.7  christos   if (!str_to_broken_float (&sign, &mantissa, &exponent))
   4033  1.7  christos     return _("invalid syntax");
   4034  1.7  christos   /* I do not know why decrement is needed */
   4035  1.7  christos   --exponent;
   4036  1.7  christos   /* shift by 39 bits right keeping 25 bit mantissa for rounding */
   4037  1.7  christos   mantissa >>= 39;
   4038  1.7  christos   /* do rounding */
   4039  1.7  christos   ++mantissa;
   4040  1.7  christos   /* make 24 bit mantissa */
   4041  1.7  christos   mantissa >>= 1;
   4042  1.7  christos   /* check for overflow */
   4043  1.7  christos   if (mantissa >> 24)
   4044  1.7  christos     {
   4045  1.7  christos       mantissa >>= 1;
   4046  1.7  christos       ++exponent;
   4047  1.7  christos     }
   4048  1.7  christos   /* check for 0 */
   4049  1.7  christos   if (exponent < -127)
   4050  1.7  christos     {
   4051  1.7  christos       exponent = -128;
   4052  1.7  christos       mantissa = 0;
   4053  1.7  christos     }
   4054  1.7  christos   else if (exponent > 127)
   4055  1.7  christos     {
   4056  1.7  christos       exponent = -128;
   4057  1.7  christos       mantissa = sign ? 0xc00000 : 0x400000;
   4058  1.7  christos     }
   4059  1.7  christos   else if (mantissa == 0)
   4060  1.7  christos     {
   4061  1.7  christos       exponent = -128;
   4062  1.7  christos       mantissa = 0x200000;
   4063  1.7  christos     }
   4064  1.7  christos   else if (!sign)
   4065  1.7  christos     mantissa &= (1ull << 23) - 1;
   4066  1.7  christos   for (i = 0; i < 24; i += 8)
   4067  1.7  christos     *litP++ = (char)(mantissa >> i);
   4068  1.7  christos   *litP = (char)(0x80 + exponent);
   4069  1.7  christos   return NULL;
   4070  1.7  christos }
   4071  1.7  christos 
   4072  1.7  christos /*
   4073  1.7  christos   Math48 by Anders Hejlsberg support.
   4074  1.7  christos   Mantissa is 39 bits wide, exponent 8 bit wide.
   4075  1.7  christos   Format is:
   4076  1.7  christos   bit 47: sign
   4077  1.7  christos   bit 46-8: normalized mantissa (bits 38-0, bit39 assumed to be 1)
   4078  1.7  christos   bit 7-0: exponent+128 (0 - value is null)
   4079  1.7  christos   MIN: 2.938735877e-39
   4080  1.7  christos   MAX: 1.701411835e+38
   4081  1.7  christos */
   4082  1.7  christos static const char *
   4083  1.7  christos str_to_float48(char *litP, int *sizeP)
   4084  1.7  christos {
   4085  1.8  christos   uint64_t mantissa;
   4086  1.8  christos   bool sign;
   4087  1.7  christos   int exponent;
   4088  1.7  christos   unsigned i;
   4089  1.7  christos 
   4090  1.7  christos   *sizeP = 6;
   4091  1.7  christos   if (!str_to_broken_float (&sign, &mantissa, &exponent))
   4092  1.7  christos     return _("invalid syntax");
   4093  1.7  christos   /* shift by 23 bits right keeping 41 bit mantissa for rounding */
   4094  1.7  christos   mantissa >>= 23;
   4095  1.7  christos   /* do rounding */
   4096  1.7  christos   ++mantissa;
   4097  1.7  christos   /* make 40 bit mantissa */
   4098  1.7  christos   mantissa >>= 1;
   4099  1.7  christos   /* check for overflow */
   4100  1.7  christos   if (mantissa >> 40)
   4101  1.7  christos     {
   4102  1.7  christos       mantissa >>= 1;
   4103  1.7  christos       ++exponent;
   4104  1.7  christos     }
   4105  1.7  christos   if (exponent < -127)
   4106  1.7  christos     {
   4107  1.7  christos       memset (litP, 0, 6);
   4108  1.7  christos       return NULL;
   4109  1.7  christos     }
   4110  1.7  christos   if (exponent > 127)
   4111  1.7  christos     return _("overflow");
   4112  1.7  christos   if (!sign)
   4113  1.7  christos     mantissa &= (1ull << 39) - 1;
   4114  1.7  christos   *litP++ = (char)(0x80 + exponent);
   4115  1.7  christos   for (i = 0; i < 40; i += 8)
   4116  1.7  christos     *litP++ = (char)(mantissa >> i);
   4117  1.7  christos   return NULL;
   4118  1.7  christos }
   4119  1.7  christos 
   4120  1.7  christos static const char *
   4121  1.7  christos str_to_ieee754_h(char *litP, int *sizeP)
   4122  1.7  christos {
   4123  1.8  christos   return ieee_md_atof ('h', litP, sizeP, false);
   4124  1.7  christos }
   4125  1.7  christos 
   4126  1.7  christos static const char *
   4127  1.7  christos str_to_ieee754_s(char *litP, int *sizeP)
   4128  1.7  christos {
   4129  1.8  christos   return ieee_md_atof ('s', 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_d(char *litP, int *sizeP)
   4134  1.7  christos {
   4135  1.8  christos   return ieee_md_atof ('d', litP, sizeP, false);
   4136  1.8  christos }
   4137  1.8  christos 
   4138  1.8  christos #ifdef TARGET_USE_CFIPOP
   4139  1.8  christos /* Initialize the DWARF-2 unwind information for this procedure. */
   4140  1.8  christos void
   4141  1.8  christos z80_tc_frame_initial_instructions (void)
   4142  1.8  christos {
   4143  1.8  christos   static int sp_regno = -1;
   4144  1.8  christos 
   4145  1.8  christos   if (sp_regno < 0)
   4146  1.8  christos     sp_regno = z80_tc_regname_to_dw2regnum ("sp");
   4147  1.8  christos 
   4148  1.8  christos   cfi_add_CFA_def_cfa (sp_regno, 0);
   4149  1.8  christos }
   4150  1.8  christos 
   4151  1.8  christos int
   4152  1.8  christos z80_tc_regname_to_dw2regnum (const char *regname)
   4153  1.8  christos {
   4154  1.8  christos   static const char *regs[] =
   4155  1.8  christos     { /* same registers as for GDB */
   4156  1.8  christos       "af", "bc", "de", "hl",
   4157  1.8  christos       "sp", "pc", "ix", "iy",
   4158  1.8  christos       "af_", "bc_", "de_", "hl_",
   4159  1.8  christos       "ir"
   4160  1.8  christos     };
   4161  1.8  christos   unsigned i;
   4162  1.8  christos 
   4163  1.8  christos   for (i = 0; i < ARRAY_SIZE(regs); ++i)
   4164  1.8  christos     if (!strcasecmp (regs[i], regname))
   4165  1.8  christos       return i;
   4166  1.8  christos 
   4167  1.8  christos   return -1;
   4168  1.8  christos }
   4169  1.8  christos #endif
   4170  1.8  christos 
   4171  1.8  christos /* Implement DWARF2_ADDR_SIZE.  */
   4172  1.8  christos int
   4173  1.8  christos z80_dwarf2_addr_size (const bfd *abfd)
   4174  1.8  christos {
   4175  1.8  christos   switch (bfd_get_mach (abfd))
   4176  1.8  christos     {
   4177  1.8  christos     case bfd_mach_ez80_adl:
   4178  1.8  christos       return 3;
   4179  1.8  christos     default:
   4180  1.8  christos       return 2;
   4181  1.8  christos     }
   4182  1.7  christos }
   4183