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