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