Home | History | Annotate | Line # | Download | only in config
tc-z80.c revision 1.1.1.2
      1      1.1     skrll /* tc-z80.c -- Assemble code for the Zilog Z80 and ASCII R800
      2  1.1.1.2  christos    Copyright 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
      3      1.1     skrll    Contributed by Arnold Metselaar <arnold_m (at) operamail.com>
      4      1.1     skrll 
      5      1.1     skrll    This file is part of GAS, the GNU Assembler.
      6      1.1     skrll 
      7      1.1     skrll    GAS is free software; you can redistribute it and/or modify
      8      1.1     skrll    it under the terms of the GNU General Public License as published by
      9      1.1     skrll    the Free Software Foundation; either version 3, or (at your option)
     10      1.1     skrll    any later version.
     11      1.1     skrll 
     12      1.1     skrll    GAS is distributed in the hope that it will be useful,
     13      1.1     skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14      1.1     skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15      1.1     skrll    GNU General Public License for more details.
     16      1.1     skrll 
     17      1.1     skrll    You should have received a copy of the GNU General Public License
     18      1.1     skrll    along with GAS; see the file COPYING.  If not, write to the Free
     19      1.1     skrll    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     20      1.1     skrll    02110-1301, USA.  */
     21      1.1     skrll 
     22      1.1     skrll #include "as.h"
     23      1.1     skrll #include "safe-ctype.h"
     24      1.1     skrll #include "subsegs.h"
     25      1.1     skrll 
     26      1.1     skrll /* Exported constants.  */
     27      1.1     skrll const char comment_chars[] = ";\0";
     28      1.1     skrll const char line_comment_chars[] = "#;\0";
     29      1.1     skrll const char line_separator_chars[] = "\0";
     30      1.1     skrll const char EXP_CHARS[] = "eE\0";
     31      1.1     skrll const char FLT_CHARS[] = "RrFf\0";
     32      1.1     skrll 
     33      1.1     skrll /* For machine specific options.  */
     34      1.1     skrll const char * md_shortopts = ""; /* None yet.  */
     35      1.1     skrll 
     36      1.1     skrll enum options
     37      1.1     skrll {
     38      1.1     skrll   OPTION_MACH_Z80 = OPTION_MD_BASE,
     39      1.1     skrll   OPTION_MACH_R800,
     40      1.1     skrll   OPTION_MACH_IUD,
     41      1.1     skrll   OPTION_MACH_WUD,
     42      1.1     skrll   OPTION_MACH_FUD,
     43      1.1     skrll   OPTION_MACH_IUP,
     44      1.1     skrll   OPTION_MACH_WUP,
     45      1.1     skrll   OPTION_MACH_FUP
     46      1.1     skrll };
     47      1.1     skrll 
     48      1.1     skrll #define INS_Z80    1
     49      1.1     skrll #define INS_UNDOC  2
     50      1.1     skrll #define INS_UNPORT 4
     51      1.1     skrll #define INS_R800   8
     52      1.1     skrll 
     53      1.1     skrll struct option md_longopts[] =
     54      1.1     skrll {
     55      1.1     skrll   { "z80",       no_argument, NULL, OPTION_MACH_Z80},
     56      1.1     skrll   { "r800",      no_argument, NULL, OPTION_MACH_R800},
     57      1.1     skrll   { "ignore-undocumented-instructions", no_argument, NULL, OPTION_MACH_IUD },
     58      1.1     skrll   { "Wnud",  no_argument, NULL, OPTION_MACH_IUD },
     59      1.1     skrll   { "warn-undocumented-instructions",  no_argument, NULL, OPTION_MACH_WUD },
     60      1.1     skrll   { "Wud",  no_argument, NULL, OPTION_MACH_WUD },
     61      1.1     skrll   { "forbid-undocumented-instructions", no_argument, NULL, OPTION_MACH_FUD },
     62      1.1     skrll   { "Fud",  no_argument, NULL, OPTION_MACH_FUD },
     63      1.1     skrll   { "ignore-unportable-instructions", no_argument, NULL, OPTION_MACH_IUP },
     64      1.1     skrll   { "Wnup",  no_argument, NULL, OPTION_MACH_IUP },
     65      1.1     skrll   { "warn-unportable-instructions",  no_argument, NULL, OPTION_MACH_WUP },
     66      1.1     skrll   { "Wup",  no_argument, NULL, OPTION_MACH_WUP },
     67      1.1     skrll   { "forbid-unportable-instructions", no_argument, NULL, OPTION_MACH_FUP },
     68      1.1     skrll   { "Fup",  no_argument, NULL, OPTION_MACH_FUP },
     69      1.1     skrll 
     70      1.1     skrll   { NULL, no_argument, NULL, 0 }
     71      1.1     skrll } ;
     72      1.1     skrll 
     73      1.1     skrll size_t md_longopts_size = sizeof (md_longopts);
     74      1.1     skrll 
     75      1.1     skrll extern int coff_flags;
     76      1.1     skrll /* Instruction classes that silently assembled.  */
     77      1.1     skrll static int ins_ok = INS_Z80 | INS_UNDOC;
     78      1.1     skrll /* Instruction classes that generate errors.  */
     79      1.1     skrll static int ins_err = INS_R800;
     80      1.1     skrll /* Instruction classes actually used, determines machine type.  */
     81      1.1     skrll static int ins_used = INS_Z80;
     82      1.1     skrll 
     83      1.1     skrll int
     84      1.1     skrll md_parse_option (int c, char* arg ATTRIBUTE_UNUSED)
     85      1.1     skrll {
     86      1.1     skrll   switch (c)
     87      1.1     skrll     {
     88      1.1     skrll     default:
     89      1.1     skrll       return 0;
     90      1.1     skrll     case OPTION_MACH_Z80:
     91      1.1     skrll       ins_ok &= ~INS_R800;
     92      1.1     skrll       ins_err |= INS_R800;
     93      1.1     skrll       break;
     94      1.1     skrll     case OPTION_MACH_R800:
     95      1.1     skrll       ins_ok = INS_Z80 | INS_UNDOC | INS_R800;
     96      1.1     skrll       ins_err = INS_UNPORT;
     97      1.1     skrll       break;
     98      1.1     skrll     case OPTION_MACH_IUD:
     99      1.1     skrll       ins_ok |= INS_UNDOC;
    100      1.1     skrll       ins_err &= ~INS_UNDOC;
    101      1.1     skrll       break;
    102      1.1     skrll     case OPTION_MACH_IUP:
    103      1.1     skrll       ins_ok |= INS_UNDOC | INS_UNPORT;
    104      1.1     skrll       ins_err &= ~(INS_UNDOC | INS_UNPORT);
    105      1.1     skrll       break;
    106      1.1     skrll     case OPTION_MACH_WUD:
    107      1.1     skrll       if ((ins_ok & INS_R800) == 0)
    108      1.1     skrll 	{
    109      1.1     skrll 	  ins_ok &= ~(INS_UNDOC|INS_UNPORT);
    110      1.1     skrll 	  ins_err &= ~INS_UNDOC;
    111      1.1     skrll 	}
    112      1.1     skrll       break;
    113      1.1     skrll     case OPTION_MACH_WUP:
    114      1.1     skrll       ins_ok &= ~INS_UNPORT;
    115      1.1     skrll       ins_err &= ~(INS_UNDOC|INS_UNPORT);
    116      1.1     skrll       break;
    117      1.1     skrll     case OPTION_MACH_FUD:
    118      1.1     skrll       if ((ins_ok & INS_R800) == 0)
    119      1.1     skrll 	{
    120      1.1     skrll 	  ins_ok &= (INS_UNDOC | INS_UNPORT);
    121      1.1     skrll 	  ins_err |= INS_UNDOC | INS_UNPORT;
    122      1.1     skrll 	}
    123      1.1     skrll       break;
    124      1.1     skrll     case OPTION_MACH_FUP:
    125      1.1     skrll       ins_ok &= ~INS_UNPORT;
    126      1.1     skrll       ins_err |= INS_UNPORT;
    127      1.1     skrll       break;
    128      1.1     skrll     }
    129      1.1     skrll 
    130      1.1     skrll   return 1;
    131      1.1     skrll }
    132      1.1     skrll 
    133      1.1     skrll void
    134      1.1     skrll md_show_usage (FILE * f)
    135      1.1     skrll {
    136      1.1     skrll   fprintf (f, "\n\
    137      1.1     skrll CPU model/instruction set options:\n\
    138      1.1     skrll \n\
    139      1.1     skrll   -z80\t\t  assemble for Z80\n\
    140      1.1     skrll   -ignore-undocumented-instructions\n\
    141      1.1     skrll   -Wnud\n\
    142      1.1     skrll \tsilently assemble undocumented Z80-instructions that work on R800\n\
    143      1.1     skrll   -ignore-unportable-instructions\n\
    144      1.1     skrll   -Wnup\n\
    145      1.1     skrll \tsilently assemble all undocumented Z80-instructions\n\
    146      1.1     skrll   -warn-undocumented-instructions\n\
    147      1.1     skrll   -Wud\n\
    148      1.1     skrll \tissue warnings for undocumented Z80-instructions that work on R800\n\
    149      1.1     skrll   -warn-unportable-instructions\n\
    150      1.1     skrll   -Wup\n\
    151      1.1     skrll \tissue warnings for other undocumented Z80-instructions\n\
    152      1.1     skrll   -forbid-undocumented-instructions\n\
    153      1.1     skrll   -Fud\n\
    154      1.1     skrll \ttreat all undocumented z80-instructions as errors\n\
    155      1.1     skrll   -forbid-unportable-instructions\n\
    156      1.1     skrll   -Fup\n\
    157      1.1     skrll \ttreat undocumented z80-instructions that do not work on R800 as errors\n\
    158      1.1     skrll   -r800\t  assemble for R800\n\n\
    159      1.1     skrll Default: -z80 -ignore-undocument-instructions -warn-unportable-instructions.\n");
    160      1.1     skrll }
    161      1.1     skrll 
    162      1.1     skrll static symbolS * zero;
    163      1.1     skrll 
    164      1.1     skrll void
    165      1.1     skrll md_begin (void)
    166      1.1     skrll {
    167      1.1     skrll   expressionS nul;
    168      1.1     skrll   char * p;
    169      1.1     skrll 
    170      1.1     skrll   p = input_line_pointer;
    171      1.1     skrll   input_line_pointer = "0";
    172      1.1     skrll   nul.X_md=0;
    173      1.1     skrll   expression (& nul);
    174      1.1     skrll   input_line_pointer = p;
    175      1.1     skrll   zero = make_expr_symbol (& nul);
    176      1.1     skrll   /* We do not use relaxation (yet).  */
    177      1.1     skrll   linkrelax = 0;
    178      1.1     skrll }
    179      1.1     skrll 
    180      1.1     skrll void
    181      1.1     skrll z80_md_end (void)
    182      1.1     skrll {
    183      1.1     skrll   int mach_type;
    184      1.1     skrll 
    185      1.1     skrll   if (ins_used & (INS_UNPORT | INS_R800))
    186      1.1     skrll     ins_used |= INS_UNDOC;
    187      1.1     skrll 
    188      1.1     skrll   switch (ins_used)
    189      1.1     skrll     {
    190      1.1     skrll     case INS_Z80:
    191      1.1     skrll       mach_type = bfd_mach_z80strict;
    192      1.1     skrll       break;
    193      1.1     skrll     case INS_Z80|INS_UNDOC:
    194      1.1     skrll       mach_type = bfd_mach_z80;
    195      1.1     skrll       break;
    196      1.1     skrll     case INS_Z80|INS_UNDOC|INS_UNPORT:
    197      1.1     skrll       mach_type = bfd_mach_z80full;
    198      1.1     skrll       break;
    199      1.1     skrll     case INS_Z80|INS_UNDOC|INS_R800:
    200      1.1     skrll       mach_type = bfd_mach_r800;
    201      1.1     skrll       break;
    202      1.1     skrll     default:
    203      1.1     skrll       mach_type = 0;
    204      1.1     skrll     }
    205      1.1     skrll 
    206      1.1     skrll   bfd_set_arch_mach (stdoutput, TARGET_ARCH, mach_type);
    207      1.1     skrll }
    208      1.1     skrll 
    209      1.1     skrll static const char *
    210      1.1     skrll skip_space (const char *s)
    211      1.1     skrll {
    212      1.1     skrll   while (*s == ' ' || *s == '\t')
    213      1.1     skrll     ++s;
    214      1.1     skrll   return s;
    215      1.1     skrll }
    216      1.1     skrll 
    217      1.1     skrll /* A non-zero return-value causes a continue in the
    218      1.1     skrll    function read_a_source_file () in ../read.c.  */
    219      1.1     skrll int
    220      1.1     skrll z80_start_line_hook (void)
    221      1.1     skrll {
    222      1.1     skrll   char *p, quote;
    223      1.1     skrll   char buf[4];
    224      1.1     skrll 
    225      1.1     skrll   /* Convert one character constants.  */
    226      1.1     skrll   for (p = input_line_pointer; *p && *p != '\n'; ++p)
    227      1.1     skrll     {
    228      1.1     skrll       switch (*p)
    229      1.1     skrll 	{
    230      1.1     skrll 	case '\'':
    231      1.1     skrll 	  if (p[1] != 0 && p[1] != '\'' && p[2] == '\'')
    232      1.1     skrll 	    {
    233      1.1     skrll 	      snprintf (buf, 4, "%3d", (unsigned char)p[1]);
    234      1.1     skrll 	      *p++ = buf[0];
    235      1.1     skrll 	      *p++ = buf[1];
    236      1.1     skrll 	      *p++ = buf[2];
    237      1.1     skrll 	      break;
    238      1.1     skrll 	    }
    239      1.1     skrll 	case '"':
    240      1.1     skrll 	  for (quote = *p++; quote != *p && '\n' != *p; ++p)
    241      1.1     skrll 	    /* No escapes.  */ ;
    242      1.1     skrll 	  if (quote != *p)
    243      1.1     skrll 	    {
    244      1.1     skrll 	      as_bad (_("-- unterminated string"));
    245      1.1     skrll 	      ignore_rest_of_line ();
    246      1.1     skrll 	      return 1;
    247      1.1     skrll 	    }
    248      1.1     skrll 	  break;
    249      1.1     skrll 	}
    250      1.1     skrll     }
    251      1.1     skrll   /* Check for <label>[:] [.](EQU|DEFL) <value>.  */
    252      1.1     skrll   if (is_name_beginner (*input_line_pointer))
    253      1.1     skrll     {
    254      1.1     skrll       char c, *rest, *line_start;
    255      1.1     skrll       int len;
    256      1.1     skrll 
    257      1.1     skrll       line_start = input_line_pointer;
    258      1.1     skrll       if (ignore_input ())
    259      1.1     skrll 	return 0;
    260      1.1     skrll 
    261      1.1     skrll       c = get_symbol_end ();
    262      1.1     skrll       rest = input_line_pointer + 1;
    263      1.1     skrll 
    264      1.1     skrll       if (*rest == ':')
    265      1.1     skrll 	++rest;
    266      1.1     skrll       if (*rest == ' ' || *rest == '\t')
    267      1.1     skrll 	++rest;
    268      1.1     skrll       if (*rest == '.')
    269      1.1     skrll 	++rest;
    270      1.1     skrll       if (strncasecmp (rest, "EQU", 3) == 0)
    271      1.1     skrll 	len = 3;
    272      1.1     skrll       else if (strncasecmp (rest, "DEFL", 4) == 0)
    273      1.1     skrll 	len = 4;
    274      1.1     skrll       else
    275      1.1     skrll 	len = 0;
    276  1.1.1.2  christos       if (len && (!ISALPHA(rest[len]) ) )
    277      1.1     skrll 	{
    278      1.1     skrll 	  /* Handle assignment here.  */
    279      1.1     skrll 	  if (line_start[-1] == '\n')
    280      1.1     skrll 	    {
    281  1.1.1.2  christos 	      bump_line_counters ();
    282  1.1.1.2  christos 	      LISTING_NEWLINE ();
    283      1.1     skrll 	    }
    284  1.1.1.2  christos 	  input_line_pointer = rest + len - 1;
    285  1.1.1.2  christos 	  /* Allow redefining with "DEFL" (len == 4), but not with "EQU".  */
    286  1.1.1.2  christos 	  equals (line_start, len == 4);
    287      1.1     skrll 	  return 1;
    288      1.1     skrll 	}
    289      1.1     skrll       else
    290      1.1     skrll 	{
    291      1.1     skrll 	  /* Restore line and pointer.  */
    292      1.1     skrll 	  *input_line_pointer = c;
    293      1.1     skrll 	  input_line_pointer = line_start;
    294      1.1     skrll 	}
    295      1.1     skrll     }
    296      1.1     skrll   return 0;
    297      1.1     skrll }
    298      1.1     skrll 
    299      1.1     skrll symbolS *
    300      1.1     skrll md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
    301      1.1     skrll {
    302      1.1     skrll   return NULL;
    303      1.1     skrll }
    304      1.1     skrll 
    305      1.1     skrll char *
    306      1.1     skrll md_atof (int type ATTRIBUTE_UNUSED, char *litP ATTRIBUTE_UNUSED,
    307      1.1     skrll 	 int *sizeP ATTRIBUTE_UNUSED)
    308      1.1     skrll {
    309      1.1     skrll   return _("floating point numbers are not implemented");
    310      1.1     skrll }
    311      1.1     skrll 
    312      1.1     skrll valueT
    313      1.1     skrll md_section_align (segT seg ATTRIBUTE_UNUSED, valueT size)
    314      1.1     skrll {
    315      1.1     skrll   return size;
    316      1.1     skrll }
    317      1.1     skrll 
    318      1.1     skrll long
    319      1.1     skrll md_pcrel_from (fixS * fixp)
    320      1.1     skrll {
    321      1.1     skrll   return fixp->fx_where +
    322      1.1     skrll     fixp->fx_frag->fr_address + 1;
    323      1.1     skrll }
    324      1.1     skrll 
    325      1.1     skrll typedef const char * (asfunc)(char, char, const char*);
    326      1.1     skrll 
    327      1.1     skrll typedef struct _table_t
    328      1.1     skrll {
    329      1.1     skrll   char* name;
    330      1.1     skrll   char prefix;
    331      1.1     skrll   char opcode;
    332      1.1     skrll   asfunc * fp;
    333      1.1     skrll } table_t;
    334      1.1     skrll 
    335      1.1     skrll /* Compares the key for structs that start with a char * to the key.  */
    336      1.1     skrll static int
    337      1.1     skrll key_cmp (const void * a, const void * b)
    338      1.1     skrll {
    339      1.1     skrll   const char *str_a, *str_b;
    340      1.1     skrll 
    341      1.1     skrll   str_a = *((const char**)a);
    342      1.1     skrll   str_b = *((const char**)b);
    343      1.1     skrll   return strcmp (str_a, str_b);
    344      1.1     skrll }
    345      1.1     skrll 
    346      1.1     skrll #define BUFLEN 8 /* Large enough for any keyword.  */
    347      1.1     skrll 
    348      1.1     skrll char buf[BUFLEN];
    349      1.1     skrll const char *key = buf;
    350      1.1     skrll 
    351      1.1     skrll #define R_STACKABLE (0x80)
    352      1.1     skrll #define R_ARITH     (0x40)
    353      1.1     skrll #define R_IX        (0x20)
    354      1.1     skrll #define R_IY        (0x10)
    355      1.1     skrll #define R_INDEX     (R_IX | R_IY)
    356      1.1     skrll 
    357      1.1     skrll #define REG_A (7)
    358      1.1     skrll #define REG_B (0)
    359      1.1     skrll #define REG_C (1)
    360      1.1     skrll #define REG_D (2)
    361      1.1     skrll #define REG_E (3)
    362      1.1     skrll #define REG_H (4)
    363      1.1     skrll #define REG_L (5)
    364      1.1     skrll #define REG_F (6 | 8)
    365      1.1     skrll #define REG_I (9)
    366      1.1     skrll #define REG_R (10)
    367      1.1     skrll 
    368      1.1     skrll #define REG_AF (3 | R_STACKABLE)
    369      1.1     skrll #define REG_BC (0 | R_STACKABLE | R_ARITH)
    370      1.1     skrll #define REG_DE (1 | R_STACKABLE | R_ARITH)
    371      1.1     skrll #define REG_HL (2 | R_STACKABLE | R_ARITH)
    372      1.1     skrll #define REG_SP (3 | R_ARITH)
    373      1.1     skrll 
    374      1.1     skrll static const struct reg_entry
    375      1.1     skrll {
    376      1.1     skrll   char* name;
    377      1.1     skrll   int number;
    378      1.1     skrll } regtable[] =
    379      1.1     skrll {
    380      1.1     skrll   {"a",  REG_A },
    381      1.1     skrll   {"af", REG_AF },
    382      1.1     skrll   {"b",  REG_B },
    383      1.1     skrll   {"bc", REG_BC },
    384      1.1     skrll   {"c",  REG_C },
    385      1.1     skrll   {"d",  REG_D },
    386      1.1     skrll   {"de", REG_DE },
    387      1.1     skrll   {"e",  REG_E },
    388      1.1     skrll   {"f",  REG_F },
    389      1.1     skrll   {"h",  REG_H },
    390      1.1     skrll   {"hl", REG_HL },
    391      1.1     skrll   {"i",  REG_I },
    392      1.1     skrll   {"ix", REG_HL | R_IX },
    393      1.1     skrll   {"ixh",REG_H | R_IX },
    394      1.1     skrll   {"ixl",REG_L | R_IX },
    395      1.1     skrll   {"iy", REG_HL | R_IY },
    396      1.1     skrll   {"iyh",REG_H | R_IY },
    397      1.1     skrll   {"iyl",REG_L | R_IY },
    398      1.1     skrll   {"l",  REG_L },
    399      1.1     skrll   {"r",  REG_R },
    400      1.1     skrll   {"sp", REG_SP },
    401      1.1     skrll } ;
    402      1.1     skrll 
    403      1.1     skrll /* Prevent an error on a line from also generating
    404      1.1     skrll    a "junk at end of line" error message.  */
    405      1.1     skrll static char err_flag;
    406      1.1     skrll 
    407      1.1     skrll static void
    408      1.1     skrll error (const char * message)
    409      1.1     skrll {
    410  1.1.1.2  christos   as_bad ("%s", message);
    411      1.1     skrll   err_flag = 1;
    412      1.1     skrll }
    413      1.1     skrll 
    414      1.1     skrll static void
    415      1.1     skrll ill_op (void)
    416      1.1     skrll {
    417      1.1     skrll   error (_("illegal operand"));
    418      1.1     skrll }
    419      1.1     skrll 
    420      1.1     skrll static void
    421      1.1     skrll wrong_mach (int ins_type)
    422      1.1     skrll {
    423      1.1     skrll   const char *p;
    424      1.1     skrll 
    425      1.1     skrll   switch (ins_type)
    426      1.1     skrll     {
    427      1.1     skrll     case INS_UNDOC:
    428      1.1     skrll       p = "undocumented instruction";
    429      1.1     skrll       break;
    430      1.1     skrll     case INS_UNPORT:
    431      1.1     skrll       p = "instruction does not work on R800";
    432      1.1     skrll       break;
    433      1.1     skrll     case INS_R800:
    434      1.1     skrll       p = "instruction only works R800";
    435      1.1     skrll       break;
    436      1.1     skrll     default:
    437      1.1     skrll       p = 0; /* Not reachable.  */
    438      1.1     skrll     }
    439      1.1     skrll 
    440      1.1     skrll   if (ins_type & ins_err)
    441      1.1     skrll     error (_(p));
    442      1.1     skrll   else
    443      1.1     skrll     as_warn (_(p));
    444      1.1     skrll }
    445      1.1     skrll 
    446      1.1     skrll static void
    447      1.1     skrll check_mach (int ins_type)
    448      1.1     skrll {
    449      1.1     skrll   if ((ins_type & ins_ok) == 0)
    450      1.1     skrll     wrong_mach (ins_type);
    451      1.1     skrll   ins_used |= ins_type;
    452      1.1     skrll }
    453      1.1     skrll 
    454      1.1     skrll /* Check whether an expression is indirect.  */
    455      1.1     skrll static int
    456      1.1     skrll is_indir (const char *s)
    457      1.1     skrll {
    458      1.1     skrll   char quote;
    459      1.1     skrll   const char *p;
    460      1.1     skrll   int indir, depth;
    461      1.1     skrll 
    462      1.1     skrll   /* Indirection is indicated with parentheses.  */
    463      1.1     skrll   indir = (*s == '(');
    464      1.1     skrll 
    465      1.1     skrll   for (p = s, depth = 0; *p && *p != ','; ++p)
    466      1.1     skrll     {
    467      1.1     skrll       switch (*p)
    468      1.1     skrll 	{
    469      1.1     skrll 	case '"':
    470      1.1     skrll 	case '\'':
    471      1.1     skrll 	  for (quote = *p++; quote != *p && *p != '\n'; ++p)
    472      1.1     skrll 	    if (*p == '\\' && p[1])
    473      1.1     skrll 	      ++p;
    474      1.1     skrll 	  break;
    475      1.1     skrll 	case '(':
    476      1.1     skrll 	  ++ depth;
    477      1.1     skrll 	  break;
    478      1.1     skrll 	case ')':
    479      1.1     skrll 	  -- depth;
    480      1.1     skrll 	  if (depth == 0)
    481      1.1     skrll 	    {
    482      1.1     skrll 	      p = skip_space (p + 1);
    483      1.1     skrll 	      if (*p && *p != ',')
    484      1.1     skrll 		indir = 0;
    485      1.1     skrll 	      --p;
    486      1.1     skrll 	    }
    487      1.1     skrll 	  if (depth < 0)
    488      1.1     skrll 	    error (_("mismatched parentheses"));
    489      1.1     skrll 	  break;
    490      1.1     skrll 	}
    491      1.1     skrll     }
    492      1.1     skrll 
    493      1.1     skrll   if (depth != 0)
    494      1.1     skrll     error (_("mismatched parentheses"));
    495      1.1     skrll 
    496      1.1     skrll   return indir;
    497      1.1     skrll }
    498      1.1     skrll 
    499      1.1     skrll /* Parse general expression.  */
    500      1.1     skrll static const char *
    501      1.1     skrll parse_exp2 (const char *s, expressionS *op, segT *pseg)
    502      1.1     skrll {
    503      1.1     skrll   const char *p;
    504      1.1     skrll   int indir;
    505      1.1     skrll   int i;
    506      1.1     skrll   const struct reg_entry * regp;
    507      1.1     skrll   expressionS offset;
    508      1.1     skrll 
    509      1.1     skrll   p = skip_space (s);
    510      1.1     skrll   op->X_md = indir = is_indir (p);
    511      1.1     skrll   if (indir)
    512      1.1     skrll     p = skip_space (p + 1);
    513      1.1     skrll 
    514      1.1     skrll   for (i = 0; i < BUFLEN; ++i)
    515      1.1     skrll     {
    516      1.1     skrll       if (!ISALPHA (p[i])) /* Register names consist of letters only.  */
    517      1.1     skrll 	break;
    518      1.1     skrll       buf[i] = TOLOWER (p[i]);
    519      1.1     skrll     }
    520      1.1     skrll 
    521      1.1     skrll   if ((i < BUFLEN) && ((p[i] == 0) || (strchr (")+-, \t", p[i]))))
    522      1.1     skrll     {
    523      1.1     skrll       buf[i] = 0;
    524      1.1     skrll       regp = bsearch (& key, regtable, ARRAY_SIZE (regtable),
    525      1.1     skrll 		      sizeof (regtable[0]), key_cmp);
    526      1.1     skrll       if (regp)
    527      1.1     skrll 	{
    528      1.1     skrll 	  *pseg = reg_section;
    529      1.1     skrll 	  op->X_add_symbol = op->X_op_symbol = 0;
    530      1.1     skrll 	  op->X_add_number = regp->number;
    531      1.1     skrll 	  op->X_op = O_register;
    532      1.1     skrll 	  p += strlen (regp->name);
    533      1.1     skrll 	  p = skip_space (p);
    534      1.1     skrll 	  if (indir)
    535      1.1     skrll 	    {
    536      1.1     skrll 	      if (*p == ')')
    537      1.1     skrll 		++p;
    538      1.1     skrll 	      if ((regp->number & R_INDEX) && (regp->number & R_ARITH))
    539      1.1     skrll 		{
    540      1.1     skrll 		  op->X_op = O_md1;
    541      1.1     skrll 
    542      1.1     skrll 		  if  ((*p == '+') || (*p == '-'))
    543      1.1     skrll 		    {
    544      1.1     skrll 		      input_line_pointer = (char*) p;
    545      1.1     skrll 		      expression (& offset);
    546      1.1     skrll 		      p = skip_space (input_line_pointer);
    547      1.1     skrll 		      if (*p != ')')
    548      1.1     skrll 			error (_("bad offset expression syntax"));
    549      1.1     skrll 		      else
    550      1.1     skrll 			++ p;
    551      1.1     skrll 		      op->X_add_symbol = make_expr_symbol (& offset);
    552      1.1     skrll 		      return p;
    553      1.1     skrll 		    }
    554      1.1     skrll 
    555      1.1     skrll 		  /* We treat (i[xy]) as (i[xy]+0), which is how it will
    556      1.1     skrll 		     end up anyway, unless we're processing jp (i[xy]).  */
    557      1.1     skrll 		  op->X_add_symbol = zero;
    558      1.1     skrll 		}
    559      1.1     skrll 	    }
    560      1.1     skrll 	  p = skip_space (p);
    561      1.1     skrll 
    562      1.1     skrll 	  if ((*p == 0) || (*p == ','))
    563      1.1     skrll 	    return p;
    564      1.1     skrll 	}
    565      1.1     skrll     }
    566      1.1     skrll   /* Not an argument involving a register; use the generic parser.  */
    567      1.1     skrll   input_line_pointer = (char*) s ;
    568      1.1     skrll   *pseg = expression (op);
    569      1.1     skrll   if (op->X_op == O_absent)
    570      1.1     skrll     error (_("missing operand"));
    571      1.1     skrll   if (op->X_op == O_illegal)
    572      1.1     skrll     error (_("bad expression syntax"));
    573      1.1     skrll   return input_line_pointer;
    574      1.1     skrll }
    575      1.1     skrll 
    576      1.1     skrll static const char *
    577      1.1     skrll parse_exp (const char *s, expressionS *op)
    578      1.1     skrll {
    579      1.1     skrll   segT dummy;
    580      1.1     skrll   return parse_exp2 (s, op, & dummy);
    581      1.1     skrll }
    582      1.1     skrll 
    583      1.1     skrll /* Condition codes, including some synonyms provided by HiTech zas.  */
    584      1.1     skrll static const struct reg_entry cc_tab[] =
    585      1.1     skrll {
    586      1.1     skrll   { "age", 6 << 3 },
    587      1.1     skrll   { "alt", 7 << 3 },
    588      1.1     skrll   { "c",   3 << 3 },
    589      1.1     skrll   { "di",  4 << 3 },
    590      1.1     skrll   { "ei",  5 << 3 },
    591      1.1     skrll   { "lge", 2 << 3 },
    592      1.1     skrll   { "llt", 3 << 3 },
    593      1.1     skrll   { "m",   7 << 3 },
    594      1.1     skrll   { "nc",  2 << 3 },
    595      1.1     skrll   { "nz",  0 << 3 },
    596      1.1     skrll   { "p",   6 << 3 },
    597      1.1     skrll   { "pe",  5 << 3 },
    598      1.1     skrll   { "po",  4 << 3 },
    599      1.1     skrll   { "z",   1 << 3 },
    600      1.1     skrll } ;
    601      1.1     skrll 
    602      1.1     skrll /* Parse condition code.  */
    603      1.1     skrll static const char *
    604      1.1     skrll parse_cc (const char *s, char * op)
    605      1.1     skrll {
    606      1.1     skrll   const char *p;
    607      1.1     skrll   int i;
    608      1.1     skrll   struct reg_entry * cc_p;
    609      1.1     skrll 
    610      1.1     skrll   for (i = 0; i < BUFLEN; ++i)
    611      1.1     skrll     {
    612      1.1     skrll       if (!ISALPHA (s[i])) /* Condition codes consist of letters only.  */
    613      1.1     skrll 	break;
    614      1.1     skrll       buf[i] = TOLOWER (s[i]);
    615      1.1     skrll     }
    616      1.1     skrll 
    617      1.1     skrll   if ((i < BUFLEN)
    618      1.1     skrll       && ((s[i] == 0) || (s[i] == ',')))
    619      1.1     skrll     {
    620      1.1     skrll       buf[i] = 0;
    621      1.1     skrll       cc_p = bsearch (&key, cc_tab, ARRAY_SIZE (cc_tab),
    622      1.1     skrll 		      sizeof (cc_tab[0]), key_cmp);
    623      1.1     skrll     }
    624      1.1     skrll   else
    625      1.1     skrll     cc_p = NULL;
    626      1.1     skrll 
    627      1.1     skrll   if (cc_p)
    628      1.1     skrll     {
    629      1.1     skrll       *op = cc_p->number;
    630      1.1     skrll       p = s + i;
    631      1.1     skrll     }
    632      1.1     skrll   else
    633      1.1     skrll     p = NULL;
    634      1.1     skrll 
    635      1.1     skrll   return p;
    636      1.1     skrll }
    637      1.1     skrll 
    638      1.1     skrll static const char *
    639      1.1     skrll emit_insn (char prefix, char opcode, const char * args)
    640      1.1     skrll {
    641      1.1     skrll   char *p;
    642      1.1     skrll 
    643      1.1     skrll   if (prefix)
    644      1.1     skrll     {
    645      1.1     skrll       p = frag_more (2);
    646      1.1     skrll       *p++ = prefix;
    647      1.1     skrll     }
    648      1.1     skrll   else
    649      1.1     skrll     p = frag_more (1);
    650      1.1     skrll   *p = opcode;
    651      1.1     skrll   return args;
    652      1.1     skrll }
    653      1.1     skrll 
    654      1.1     skrll void z80_cons_fix_new (fragS *frag_p, int offset, int nbytes, expressionS *exp)
    655      1.1     skrll {
    656      1.1     skrll   bfd_reloc_code_real_type r[4] =
    657      1.1     skrll     {
    658      1.1     skrll       BFD_RELOC_8,
    659      1.1     skrll       BFD_RELOC_16,
    660      1.1     skrll       BFD_RELOC_24,
    661      1.1     skrll       BFD_RELOC_32
    662      1.1     skrll     };
    663      1.1     skrll 
    664      1.1     skrll   if (nbytes < 1 || nbytes > 4)
    665      1.1     skrll     {
    666      1.1     skrll       as_bad (_("unsupported BFD relocation size %u"), nbytes);
    667      1.1     skrll     }
    668      1.1     skrll   else
    669      1.1     skrll     {
    670      1.1     skrll       fix_new_exp (frag_p, offset, nbytes, exp, 0, r[nbytes-1]);
    671      1.1     skrll     }
    672      1.1     skrll }
    673      1.1     skrll 
    674      1.1     skrll static void
    675      1.1     skrll emit_byte (expressionS * val, bfd_reloc_code_real_type r_type)
    676      1.1     skrll {
    677      1.1     skrll   char *p;
    678      1.1     skrll   int lo, hi;
    679      1.1     skrll   fixS * fixp;
    680      1.1     skrll 
    681      1.1     skrll   p = frag_more (1);
    682      1.1     skrll   *p = val->X_add_number;
    683      1.1     skrll   if ((r_type == BFD_RELOC_8_PCREL) && (val->X_op == O_constant))
    684      1.1     skrll     {
    685  1.1.1.2  christos       as_bad (_("cannot make a relative jump to an absolute location"));
    686      1.1     skrll     }
    687      1.1     skrll   else if (val->X_op == O_constant)
    688      1.1     skrll     {
    689      1.1     skrll       lo = -128;
    690      1.1     skrll       hi = (BFD_RELOC_8 == r_type) ? 255 : 127;
    691      1.1     skrll 
    692      1.1     skrll       if ((val->X_add_number < lo) || (val->X_add_number > hi))
    693      1.1     skrll 	{
    694      1.1     skrll 	  if (r_type == BFD_RELOC_Z80_DISP8)
    695      1.1     skrll 	    as_bad (_("offset too large"));
    696      1.1     skrll 	  else
    697      1.1     skrll 	    as_warn (_("overflow"));
    698      1.1     skrll 	}
    699      1.1     skrll     }
    700      1.1     skrll   else
    701      1.1     skrll     {
    702      1.1     skrll       fixp = fix_new_exp (frag_now, p - frag_now->fr_literal, 1, val,
    703      1.1     skrll 			  (r_type == BFD_RELOC_8_PCREL) ? TRUE : FALSE, r_type);
    704      1.1     skrll       /* FIXME : Process constant offsets immediately.  */
    705      1.1     skrll     }
    706      1.1     skrll }
    707      1.1     skrll 
    708      1.1     skrll static void
    709      1.1     skrll emit_word (expressionS * val)
    710      1.1     skrll {
    711      1.1     skrll   char *p;
    712      1.1     skrll 
    713      1.1     skrll   p = frag_more (2);
    714      1.1     skrll   if (   (val->X_op == O_register)
    715      1.1     skrll       || (val->X_op == O_md1))
    716      1.1     skrll     ill_op ();
    717      1.1     skrll   else
    718      1.1     skrll     {
    719      1.1     skrll       *p = val->X_add_number;
    720      1.1     skrll       p[1] = (val->X_add_number>>8);
    721      1.1     skrll       if (val->X_op != O_constant)
    722      1.1     skrll 	fix_new_exp (frag_now, p - frag_now->fr_literal, 2,
    723      1.1     skrll 		     val, FALSE, BFD_RELOC_16);
    724      1.1     skrll     }
    725      1.1     skrll }
    726      1.1     skrll 
    727      1.1     skrll static void
    728      1.1     skrll emit_mx (char prefix, char opcode, int shift, expressionS * arg)
    729      1.1     skrll      /* The operand m may be r, (hl), (ix+d), (iy+d),
    730      1.1     skrll 	if 0 == prefix m may also be ixl, ixh, iyl, iyh.  */
    731      1.1     skrll {
    732      1.1     skrll   char *q;
    733      1.1     skrll   int rnum;
    734      1.1     skrll 
    735      1.1     skrll   rnum = arg->X_add_number;
    736      1.1     skrll   switch (arg->X_op)
    737      1.1     skrll     {
    738      1.1     skrll     case O_register:
    739      1.1     skrll       if (arg->X_md)
    740      1.1     skrll 	{
    741      1.1     skrll 	  if (rnum != REG_HL)
    742      1.1     skrll 	    {
    743      1.1     skrll 	      ill_op ();
    744      1.1     skrll 	      break;
    745      1.1     skrll 	    }
    746      1.1     skrll 	  else
    747      1.1     skrll 	    rnum = 6;
    748      1.1     skrll 	}
    749      1.1     skrll       else
    750      1.1     skrll 	{
    751      1.1     skrll 	  if ((prefix == 0) && (rnum & R_INDEX))
    752      1.1     skrll 	    {
    753      1.1     skrll 	      prefix = (rnum & R_IX) ? 0xDD : 0xFD;
    754      1.1     skrll 	      check_mach (INS_UNDOC);
    755      1.1     skrll 	      rnum &= ~R_INDEX;
    756      1.1     skrll 	    }
    757      1.1     skrll 	  if (rnum > 7)
    758      1.1     skrll 	    {
    759      1.1     skrll 	      ill_op ();
    760      1.1     skrll 	      break;
    761      1.1     skrll 	    }
    762      1.1     skrll 	}
    763      1.1     skrll       q = frag_more (prefix ? 2 : 1);
    764      1.1     skrll       if (prefix)
    765      1.1     skrll 	* q ++ = prefix;
    766      1.1     skrll       * q ++ = opcode + (rnum << shift);
    767      1.1     skrll       break;
    768      1.1     skrll     case O_md1:
    769      1.1     skrll       q = frag_more (2);
    770      1.1     skrll       *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
    771      1.1     skrll       *q = (prefix) ? prefix : (opcode + (6 << shift));
    772  1.1.1.2  christos       {
    773  1.1.1.2  christos 	expressionS offset = *arg;
    774  1.1.1.2  christos 	offset.X_op = O_symbol;
    775  1.1.1.2  christos 	offset.X_add_number = 0;
    776  1.1.1.2  christos 	emit_byte (&offset, BFD_RELOC_Z80_DISP8);
    777  1.1.1.2  christos       }
    778      1.1     skrll       if (prefix)
    779      1.1     skrll 	{
    780      1.1     skrll 	  q = frag_more (1);
    781      1.1     skrll 	  *q = opcode+(6<<shift);
    782      1.1     skrll 	}
    783      1.1     skrll       break;
    784      1.1     skrll     default:
    785      1.1     skrll       abort ();
    786      1.1     skrll     }
    787      1.1     skrll }
    788      1.1     skrll 
    789      1.1     skrll /* The operand m may be r, (hl), (ix+d), (iy+d),
    790      1.1     skrll    if 0 = prefix m may also be ixl, ixh, iyl, iyh.  */
    791      1.1     skrll static const char *
    792      1.1     skrll emit_m (char prefix, char opcode, const char *args)
    793      1.1     skrll {
    794      1.1     skrll   expressionS arg_m;
    795      1.1     skrll   const char *p;
    796      1.1     skrll 
    797      1.1     skrll   p = parse_exp (args, &arg_m);
    798      1.1     skrll   switch (arg_m.X_op)
    799      1.1     skrll     {
    800      1.1     skrll     case O_md1:
    801      1.1     skrll     case O_register:
    802      1.1     skrll       emit_mx (prefix, opcode, 0, &arg_m);
    803      1.1     skrll       break;
    804      1.1     skrll     default:
    805      1.1     skrll       ill_op ();
    806      1.1     skrll     }
    807      1.1     skrll   return p;
    808      1.1     skrll }
    809      1.1     skrll 
    810      1.1     skrll /* The operand m may be as above or one of the undocumented
    811      1.1     skrll    combinations (ix+d),r and (iy+d),r (if unportable instructions
    812      1.1     skrll    are allowed).  */
    813      1.1     skrll static const char *
    814      1.1     skrll emit_mr (char prefix, char opcode, const char *args)
    815      1.1     skrll {
    816      1.1     skrll   expressionS arg_m, arg_r;
    817      1.1     skrll   const char *p;
    818      1.1     skrll 
    819      1.1     skrll   p = parse_exp (args, & arg_m);
    820      1.1     skrll 
    821      1.1     skrll   switch (arg_m.X_op)
    822      1.1     skrll     {
    823      1.1     skrll     case O_md1:
    824      1.1     skrll       if (*p == ',')
    825      1.1     skrll 	{
    826      1.1     skrll 	  p = parse_exp (p + 1, & arg_r);
    827      1.1     skrll 
    828      1.1     skrll 	  if ((arg_r.X_md == 0)
    829      1.1     skrll 	      && (arg_r.X_op == O_register)
    830      1.1     skrll 	      && (arg_r.X_add_number < 8))
    831      1.1     skrll 	    opcode += arg_r.X_add_number-6; /* Emit_mx () will add 6.  */
    832      1.1     skrll 	  else
    833      1.1     skrll 	    {
    834      1.1     skrll 	      ill_op ();
    835      1.1     skrll 	      break;
    836      1.1     skrll 	    }
    837      1.1     skrll 	  check_mach (INS_UNPORT);
    838      1.1     skrll 	}
    839      1.1     skrll     case O_register:
    840      1.1     skrll       emit_mx (prefix, opcode, 0, & arg_m);
    841      1.1     skrll       break;
    842      1.1     skrll     default:
    843      1.1     skrll       ill_op ();
    844      1.1     skrll     }
    845      1.1     skrll   return p;
    846      1.1     skrll }
    847      1.1     skrll 
    848      1.1     skrll static void
    849      1.1     skrll emit_sx (char prefix, char opcode, expressionS * arg_p)
    850      1.1     skrll {
    851      1.1     skrll   char *q;
    852      1.1     skrll 
    853      1.1     skrll   switch (arg_p->X_op)
    854      1.1     skrll     {
    855      1.1     skrll     case O_register:
    856      1.1     skrll     case O_md1:
    857      1.1     skrll       emit_mx (prefix, opcode, 0, arg_p);
    858      1.1     skrll       break;
    859      1.1     skrll     default:
    860      1.1     skrll       if (arg_p->X_md)
    861      1.1     skrll 	ill_op ();
    862      1.1     skrll       else
    863      1.1     skrll 	{
    864      1.1     skrll 	  q = frag_more (prefix ? 2 : 1);
    865      1.1     skrll 	  if (prefix)
    866      1.1     skrll 	    *q++ = prefix;
    867      1.1     skrll 	  *q = opcode ^ 0x46;
    868      1.1     skrll 	  emit_byte (arg_p, BFD_RELOC_8);
    869      1.1     skrll 	}
    870      1.1     skrll     }
    871      1.1     skrll }
    872      1.1     skrll 
    873      1.1     skrll /* The operand s may be r, (hl), (ix+d), (iy+d), n.  */
    874      1.1     skrll static const char *
    875      1.1     skrll emit_s (char prefix, char opcode, const char *args)
    876      1.1     skrll {
    877      1.1     skrll   expressionS arg_s;
    878      1.1     skrll   const char *p;
    879      1.1     skrll 
    880      1.1     skrll   p = parse_exp (args, & arg_s);
    881      1.1     skrll   emit_sx (prefix, opcode, & arg_s);
    882      1.1     skrll   return p;
    883      1.1     skrll }
    884      1.1     skrll 
    885      1.1     skrll static const char *
    886      1.1     skrll emit_call (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
    887      1.1     skrll {
    888      1.1     skrll   expressionS addr;
    889      1.1     skrll   const char *p;  char *q;
    890      1.1     skrll 
    891      1.1     skrll   p = parse_exp (args, &addr);
    892      1.1     skrll   if (addr.X_md)
    893      1.1     skrll     ill_op ();
    894      1.1     skrll   else
    895      1.1     skrll     {
    896      1.1     skrll       q = frag_more (1);
    897      1.1     skrll       *q = opcode;
    898      1.1     skrll       emit_word (& addr);
    899      1.1     skrll     }
    900      1.1     skrll   return p;
    901      1.1     skrll }
    902      1.1     skrll 
    903      1.1     skrll /* Operand may be rr, r, (hl), (ix+d), (iy+d).  */
    904      1.1     skrll static const char *
    905      1.1     skrll emit_incdec (char prefix, char opcode, const char * args)
    906      1.1     skrll {
    907      1.1     skrll   expressionS operand;
    908      1.1     skrll   int rnum;
    909      1.1     skrll   const char *p;  char *q;
    910      1.1     skrll 
    911      1.1     skrll   p = parse_exp (args, &operand);
    912      1.1     skrll   rnum = operand.X_add_number;
    913      1.1     skrll   if ((! operand.X_md)
    914      1.1     skrll       && (operand.X_op == O_register)
    915      1.1     skrll       && (R_ARITH&rnum))
    916      1.1     skrll     {
    917      1.1     skrll       q = frag_more ((rnum & R_INDEX) ? 2 : 1);
    918      1.1     skrll       if (rnum & R_INDEX)
    919      1.1     skrll 	*q++ = (rnum & R_IX) ? 0xDD : 0xFD;
    920      1.1     skrll       *q = prefix + ((rnum & 3) << 4);
    921      1.1     skrll     }
    922      1.1     skrll   else
    923      1.1     skrll     {
    924      1.1     skrll       if ((operand.X_op == O_md1) || (operand.X_op == O_register))
    925      1.1     skrll 	emit_mx (0, opcode, 3, & operand);
    926      1.1     skrll       else
    927      1.1     skrll 	ill_op ();
    928      1.1     skrll     }
    929      1.1     skrll   return p;
    930      1.1     skrll }
    931      1.1     skrll 
    932      1.1     skrll static const char *
    933      1.1     skrll emit_jr (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
    934      1.1     skrll {
    935      1.1     skrll   expressionS addr;
    936      1.1     skrll   const char *p;
    937      1.1     skrll   char *q;
    938      1.1     skrll 
    939      1.1     skrll   p = parse_exp (args, &addr);
    940      1.1     skrll   if (addr.X_md)
    941      1.1     skrll     ill_op ();
    942      1.1     skrll   else
    943      1.1     skrll     {
    944      1.1     skrll       q = frag_more (1);
    945      1.1     skrll       *q = opcode;
    946      1.1     skrll       emit_byte (&addr, BFD_RELOC_8_PCREL);
    947      1.1     skrll     }
    948      1.1     skrll   return p;
    949      1.1     skrll }
    950      1.1     skrll 
    951      1.1     skrll static const char *
    952      1.1     skrll emit_jp (char prefix, char opcode, const char * args)
    953      1.1     skrll {
    954      1.1     skrll   expressionS addr;
    955      1.1     skrll   const char *p;
    956      1.1     skrll   char *q;
    957      1.1     skrll   int rnum;
    958      1.1     skrll 
    959      1.1     skrll   p = parse_exp (args, & addr);
    960      1.1     skrll   if (addr.X_md)
    961      1.1     skrll     {
    962      1.1     skrll       rnum = addr.X_add_number;
    963      1.1     skrll       if ((addr.X_op == O_register && (rnum & ~R_INDEX) == REG_HL)
    964      1.1     skrll 	 /* An operand (i[xy]) would have been rewritten to (i[xy]+0)
    965      1.1     skrll             in parse_exp ().  */
    966      1.1     skrll 	  || (addr.X_op == O_md1 && addr.X_add_symbol == zero))
    967      1.1     skrll 	{
    968      1.1     skrll 	  q = frag_more ((rnum & R_INDEX) ? 2 : 1);
    969      1.1     skrll 	  if (rnum & R_INDEX)
    970      1.1     skrll 	    *q++ = (rnum & R_IX) ? 0xDD : 0xFD;
    971      1.1     skrll 	  *q = prefix;
    972      1.1     skrll 	}
    973      1.1     skrll       else
    974      1.1     skrll 	ill_op ();
    975      1.1     skrll     }
    976      1.1     skrll   else
    977      1.1     skrll     {
    978      1.1     skrll       q = frag_more (1);
    979      1.1     skrll       *q = opcode;
    980      1.1     skrll       emit_word (& addr);
    981      1.1     skrll     }
    982      1.1     skrll   return p;
    983      1.1     skrll }
    984      1.1     skrll 
    985      1.1     skrll static const char *
    986      1.1     skrll emit_im (char prefix, char opcode, const char * args)
    987      1.1     skrll {
    988      1.1     skrll   expressionS mode;
    989      1.1     skrll   const char *p;
    990      1.1     skrll   char *q;
    991      1.1     skrll 
    992      1.1     skrll   p = parse_exp (args, & mode);
    993      1.1     skrll   if (mode.X_md || (mode.X_op != O_constant))
    994      1.1     skrll     ill_op ();
    995      1.1     skrll   else
    996      1.1     skrll     switch (mode.X_add_number)
    997      1.1     skrll       {
    998      1.1     skrll       case 1:
    999      1.1     skrll       case 2:
   1000      1.1     skrll 	++mode.X_add_number;
   1001      1.1     skrll 	/* Fall through.  */
   1002      1.1     skrll       case 0:
   1003      1.1     skrll 	q = frag_more (2);
   1004      1.1     skrll 	*q++ = prefix;
   1005      1.1     skrll 	*q = opcode + 8*mode.X_add_number;
   1006      1.1     skrll 	break;
   1007      1.1     skrll       default:
   1008      1.1     skrll 	ill_op ();
   1009      1.1     skrll       }
   1010      1.1     skrll   return p;
   1011      1.1     skrll }
   1012      1.1     skrll 
   1013      1.1     skrll static const char *
   1014      1.1     skrll emit_pop (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1015      1.1     skrll {
   1016      1.1     skrll   expressionS regp;
   1017      1.1     skrll   const char *p;
   1018      1.1     skrll   char *q;
   1019      1.1     skrll 
   1020      1.1     skrll   p = parse_exp (args, & regp);
   1021      1.1     skrll   if ((!regp.X_md)
   1022      1.1     skrll       && (regp.X_op == O_register)
   1023      1.1     skrll       && (regp.X_add_number & R_STACKABLE))
   1024      1.1     skrll     {
   1025      1.1     skrll       int rnum;
   1026      1.1     skrll 
   1027      1.1     skrll       rnum = regp.X_add_number;
   1028      1.1     skrll       if (rnum&R_INDEX)
   1029      1.1     skrll 	{
   1030      1.1     skrll 	  q = frag_more (2);
   1031      1.1     skrll 	  *q++ = (rnum&R_IX)?0xDD:0xFD;
   1032      1.1     skrll 	}
   1033      1.1     skrll       else
   1034      1.1     skrll 	q = frag_more (1);
   1035      1.1     skrll       *q = opcode + ((rnum & 3) << 4);
   1036      1.1     skrll     }
   1037      1.1     skrll   else
   1038      1.1     skrll     ill_op ();
   1039      1.1     skrll 
   1040      1.1     skrll   return p;
   1041      1.1     skrll }
   1042      1.1     skrll 
   1043      1.1     skrll static const char *
   1044      1.1     skrll emit_retcc (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1045      1.1     skrll {
   1046      1.1     skrll   char cc, *q;
   1047      1.1     skrll   const char *p;
   1048      1.1     skrll 
   1049      1.1     skrll   p = parse_cc (args, &cc);
   1050      1.1     skrll   q = frag_more (1);
   1051      1.1     skrll   if (p)
   1052      1.1     skrll     *q = opcode + cc;
   1053      1.1     skrll   else
   1054      1.1     skrll     *q = prefix;
   1055      1.1     skrll   return p ? p : args;
   1056      1.1     skrll }
   1057      1.1     skrll 
   1058      1.1     skrll static const char *
   1059      1.1     skrll emit_adc (char prefix, char opcode, const char * args)
   1060      1.1     skrll {
   1061      1.1     skrll   expressionS term;
   1062      1.1     skrll   int rnum;
   1063      1.1     skrll   const char *p;
   1064      1.1     skrll   char *q;
   1065      1.1     skrll 
   1066      1.1     skrll   p = parse_exp (args, &term);
   1067      1.1     skrll   if (*p++ != ',')
   1068      1.1     skrll     {
   1069      1.1     skrll       error (_("bad intruction syntax"));
   1070      1.1     skrll       return p;
   1071      1.1     skrll     }
   1072      1.1     skrll 
   1073      1.1     skrll   if ((term.X_md) || (term.X_op != O_register))
   1074      1.1     skrll     ill_op ();
   1075      1.1     skrll   else
   1076      1.1     skrll     switch (term.X_add_number)
   1077      1.1     skrll       {
   1078      1.1     skrll       case REG_A:
   1079      1.1     skrll 	p = emit_s (0, prefix, p);
   1080      1.1     skrll 	break;
   1081      1.1     skrll       case REG_HL:
   1082      1.1     skrll 	p = parse_exp (p, &term);
   1083      1.1     skrll 	if ((!term.X_md) && (term.X_op == O_register))
   1084      1.1     skrll 	  {
   1085      1.1     skrll 	    rnum = term.X_add_number;
   1086      1.1     skrll 	    if (R_ARITH == (rnum & (R_ARITH | R_INDEX)))
   1087      1.1     skrll 	      {
   1088      1.1     skrll 		q = frag_more (2);
   1089      1.1     skrll 		*q++ = 0xED;
   1090      1.1     skrll 		*q = opcode + ((rnum & 3) << 4);
   1091      1.1     skrll 		break;
   1092      1.1     skrll 	      }
   1093      1.1     skrll 	  }
   1094      1.1     skrll 	/* Fall through.  */
   1095      1.1     skrll       default:
   1096      1.1     skrll 	ill_op ();
   1097      1.1     skrll       }
   1098      1.1     skrll   return p;
   1099      1.1     skrll }
   1100      1.1     skrll 
   1101      1.1     skrll static const char *
   1102      1.1     skrll emit_add (char prefix, char opcode, const char * args)
   1103      1.1     skrll {
   1104      1.1     skrll   expressionS term;
   1105      1.1     skrll   int lhs, rhs;
   1106      1.1     skrll   const char *p;
   1107      1.1     skrll   char *q;
   1108      1.1     skrll 
   1109      1.1     skrll   p = parse_exp (args, &term);
   1110      1.1     skrll   if (*p++ != ',')
   1111      1.1     skrll     {
   1112      1.1     skrll       error (_("bad intruction syntax"));
   1113      1.1     skrll       return p;
   1114      1.1     skrll     }
   1115      1.1     skrll 
   1116      1.1     skrll   if ((term.X_md) || (term.X_op != O_register))
   1117      1.1     skrll     ill_op ();
   1118      1.1     skrll   else
   1119      1.1     skrll     switch (term.X_add_number & ~R_INDEX)
   1120      1.1     skrll       {
   1121      1.1     skrll       case REG_A:
   1122      1.1     skrll 	p = emit_s (0, prefix, p);
   1123      1.1     skrll 	break;
   1124      1.1     skrll       case REG_HL:
   1125      1.1     skrll 	lhs = term.X_add_number;
   1126      1.1     skrll 	p = parse_exp (p, &term);
   1127      1.1     skrll 	if ((!term.X_md) && (term.X_op == O_register))
   1128      1.1     skrll 	  {
   1129      1.1     skrll 	    rhs = term.X_add_number;
   1130      1.1     skrll 	    if ((rhs & R_ARITH)
   1131      1.1     skrll 		&& ((rhs == lhs) || ((rhs & ~R_INDEX) != REG_HL)))
   1132      1.1     skrll 	      {
   1133      1.1     skrll 		q = frag_more ((lhs & R_INDEX) ? 2 : 1);
   1134      1.1     skrll 		if (lhs & R_INDEX)
   1135      1.1     skrll 		  *q++ = (lhs & R_IX) ? 0xDD : 0xFD;
   1136      1.1     skrll 		*q = opcode + ((rhs & 3) << 4);
   1137      1.1     skrll 		break;
   1138      1.1     skrll 	      }
   1139      1.1     skrll 	  }
   1140      1.1     skrll 	/* Fall through.  */
   1141      1.1     skrll       default:
   1142      1.1     skrll 	ill_op ();
   1143      1.1     skrll       }
   1144      1.1     skrll   return p;
   1145      1.1     skrll }
   1146      1.1     skrll 
   1147      1.1     skrll static const char *
   1148      1.1     skrll emit_bit (char prefix, char opcode, const char * args)
   1149      1.1     skrll {
   1150      1.1     skrll   expressionS b;
   1151      1.1     skrll   int bn;
   1152      1.1     skrll   const char *p;
   1153      1.1     skrll 
   1154      1.1     skrll   p = parse_exp (args, &b);
   1155      1.1     skrll   if (*p++ != ',')
   1156      1.1     skrll     error (_("bad intruction syntax"));
   1157      1.1     skrll 
   1158      1.1     skrll   bn = b.X_add_number;
   1159      1.1     skrll   if ((!b.X_md)
   1160      1.1     skrll       && (b.X_op == O_constant)
   1161      1.1     skrll       && (0 <= bn)
   1162      1.1     skrll       && (bn < 8))
   1163      1.1     skrll     {
   1164      1.1     skrll       if (opcode == 0x40)
   1165      1.1     skrll 	/* Bit : no optional third operand.  */
   1166      1.1     skrll 	p = emit_m (prefix, opcode + (bn << 3), p);
   1167      1.1     skrll       else
   1168      1.1     skrll 	/* Set, res : resulting byte can be copied to register.  */
   1169      1.1     skrll 	p = emit_mr (prefix, opcode + (bn << 3), p);
   1170      1.1     skrll     }
   1171      1.1     skrll   else
   1172      1.1     skrll     ill_op ();
   1173      1.1     skrll   return p;
   1174      1.1     skrll }
   1175      1.1     skrll 
   1176      1.1     skrll static const char *
   1177      1.1     skrll emit_jpcc (char prefix, char opcode, const char * args)
   1178      1.1     skrll {
   1179      1.1     skrll   char cc;
   1180      1.1     skrll   const char *p;
   1181      1.1     skrll 
   1182      1.1     skrll   p = parse_cc (args, & cc);
   1183      1.1     skrll   if (p && *p++ == ',')
   1184      1.1     skrll     p = emit_call (0, opcode + cc, p);
   1185      1.1     skrll   else
   1186      1.1     skrll     p = (prefix == (char)0xC3)
   1187      1.1     skrll       ? emit_jp (0xE9, prefix, args)
   1188      1.1     skrll       : emit_call (0, prefix, args);
   1189      1.1     skrll   return p;
   1190      1.1     skrll }
   1191      1.1     skrll 
   1192      1.1     skrll static const char *
   1193      1.1     skrll emit_jrcc (char prefix, char opcode, const char * args)
   1194      1.1     skrll {
   1195      1.1     skrll   char cc;
   1196      1.1     skrll   const char *p;
   1197      1.1     skrll 
   1198      1.1     skrll   p = parse_cc (args, &cc);
   1199      1.1     skrll   if (p && *p++ == ',')
   1200      1.1     skrll     {
   1201      1.1     skrll       if (cc > (3 << 3))
   1202      1.1     skrll 	error (_("condition code invalid for jr"));
   1203      1.1     skrll       else
   1204      1.1     skrll 	p = emit_jr (0, opcode + cc, p);
   1205      1.1     skrll     }
   1206      1.1     skrll   else
   1207      1.1     skrll     p = emit_jr (0, prefix, args);
   1208      1.1     skrll 
   1209      1.1     skrll   return p;
   1210      1.1     skrll }
   1211      1.1     skrll 
   1212      1.1     skrll static const char *
   1213      1.1     skrll emit_ex (char prefix_in ATTRIBUTE_UNUSED,
   1214      1.1     skrll 	 char opcode_in ATTRIBUTE_UNUSED, const char * args)
   1215      1.1     skrll {
   1216      1.1     skrll   expressionS op;
   1217      1.1     skrll   const char * p;
   1218      1.1     skrll   char prefix, opcode;
   1219      1.1     skrll 
   1220      1.1     skrll   p = parse_exp (args, &op);
   1221      1.1     skrll   p = skip_space (p);
   1222      1.1     skrll   if (*p++ != ',')
   1223      1.1     skrll     {
   1224      1.1     skrll       error (_("bad instruction syntax"));
   1225      1.1     skrll       return p;
   1226      1.1     skrll     }
   1227      1.1     skrll 
   1228      1.1     skrll   prefix = opcode = 0;
   1229      1.1     skrll   if (op.X_op == O_register)
   1230      1.1     skrll     switch (op.X_add_number | (op.X_md ? 0x8000 : 0))
   1231      1.1     skrll       {
   1232      1.1     skrll       case REG_AF:
   1233      1.1     skrll 	if (TOLOWER (*p++) == 'a' && TOLOWER (*p++) == 'f')
   1234      1.1     skrll 	  {
   1235      1.1     skrll 	    /* The scrubber changes '\'' to '`' in this context.  */
   1236      1.1     skrll 	    if (*p == '`')
   1237      1.1     skrll 	      ++p;
   1238      1.1     skrll 	    opcode = 0x08;
   1239      1.1     skrll 	  }
   1240      1.1     skrll 	break;
   1241      1.1     skrll       case REG_DE:
   1242      1.1     skrll 	if (TOLOWER (*p++) == 'h' && TOLOWER (*p++) == 'l')
   1243      1.1     skrll 	  opcode = 0xEB;
   1244      1.1     skrll 	break;
   1245      1.1     skrll       case REG_SP|0x8000:
   1246      1.1     skrll 	p = parse_exp (p, & op);
   1247      1.1     skrll 	if (op.X_op == O_register
   1248      1.1     skrll 	    && op.X_md == 0
   1249      1.1     skrll 	    && (op.X_add_number & ~R_INDEX) == REG_HL)
   1250      1.1     skrll 	  {
   1251      1.1     skrll 	    opcode = 0xE3;
   1252      1.1     skrll 	    if (R_INDEX & op.X_add_number)
   1253      1.1     skrll 	      prefix = (R_IX & op.X_add_number) ? 0xDD : 0xFD;
   1254      1.1     skrll 	  }
   1255      1.1     skrll 	break;
   1256      1.1     skrll       }
   1257      1.1     skrll   if (opcode)
   1258      1.1     skrll     emit_insn (prefix, opcode, p);
   1259      1.1     skrll   else
   1260      1.1     skrll     ill_op ();
   1261      1.1     skrll 
   1262      1.1     skrll   return p;
   1263      1.1     skrll }
   1264      1.1     skrll 
   1265      1.1     skrll static const char *
   1266      1.1     skrll emit_in (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
   1267      1.1     skrll 	const char * args)
   1268      1.1     skrll {
   1269      1.1     skrll   expressionS reg, port;
   1270      1.1     skrll   const char *p;
   1271      1.1     skrll   char *q;
   1272      1.1     skrll 
   1273      1.1     skrll   p = parse_exp (args, &reg);
   1274      1.1     skrll   if (*p++ != ',')
   1275      1.1     skrll     {
   1276      1.1     skrll       error (_("bad intruction syntax"));
   1277      1.1     skrll       return p;
   1278      1.1     skrll     }
   1279      1.1     skrll 
   1280      1.1     skrll   p = parse_exp (p, &port);
   1281      1.1     skrll   if (reg.X_md == 0
   1282      1.1     skrll       && reg.X_op == O_register
   1283      1.1     skrll       && (reg.X_add_number <= 7 || reg.X_add_number == REG_F)
   1284      1.1     skrll       && (port.X_md))
   1285      1.1     skrll     {
   1286      1.1     skrll       if (port.X_op != O_md1 && port.X_op != O_register)
   1287      1.1     skrll 	{
   1288      1.1     skrll 	  if (REG_A == reg.X_add_number)
   1289      1.1     skrll 	    {
   1290      1.1     skrll 	      q = frag_more (1);
   1291      1.1     skrll 	      *q = 0xDB;
   1292      1.1     skrll 	      emit_byte (&port, BFD_RELOC_8);
   1293      1.1     skrll 	    }
   1294      1.1     skrll 	  else
   1295      1.1     skrll 	    ill_op ();
   1296      1.1     skrll 	}
   1297      1.1     skrll       else
   1298      1.1     skrll 	{
   1299      1.1     skrll 	  if (port.X_add_number == REG_C)
   1300      1.1     skrll 	    {
   1301      1.1     skrll 	      if (reg.X_add_number == REG_F)
   1302      1.1     skrll 		check_mach (INS_UNDOC);
   1303      1.1     skrll 	      else
   1304      1.1     skrll 		{
   1305      1.1     skrll 		  q = frag_more (2);
   1306      1.1     skrll 		  *q++ = 0xED;
   1307      1.1     skrll 		  *q = 0x40|((reg.X_add_number&7)<<3);
   1308      1.1     skrll 		}
   1309      1.1     skrll 	    }
   1310      1.1     skrll 	  else
   1311      1.1     skrll 	    ill_op ();
   1312      1.1     skrll 	}
   1313      1.1     skrll     }
   1314      1.1     skrll   else
   1315      1.1     skrll     ill_op ();
   1316      1.1     skrll   return p;
   1317      1.1     skrll }
   1318      1.1     skrll 
   1319      1.1     skrll static const char *
   1320      1.1     skrll emit_out (char prefix ATTRIBUTE_UNUSED, char opcode ATTRIBUTE_UNUSED,
   1321      1.1     skrll 	 const char * args)
   1322      1.1     skrll {
   1323      1.1     skrll   expressionS reg, port;
   1324      1.1     skrll   const char *p;
   1325      1.1     skrll   char *q;
   1326      1.1     skrll 
   1327      1.1     skrll   p = parse_exp (args, & port);
   1328      1.1     skrll   if (*p++ != ',')
   1329      1.1     skrll     {
   1330      1.1     skrll       error (_("bad intruction syntax"));
   1331      1.1     skrll       return p;
   1332      1.1     skrll     }
   1333      1.1     skrll   p = parse_exp (p, &reg);
   1334      1.1     skrll   if (!port.X_md)
   1335      1.1     skrll     { ill_op (); return p; }
   1336      1.1     skrll   /* Allow "out (c), 0" as unportable instruction.  */
   1337      1.1     skrll   if (reg.X_op == O_constant && reg.X_add_number == 0)
   1338      1.1     skrll     {
   1339      1.1     skrll       check_mach (INS_UNPORT);
   1340      1.1     skrll       reg.X_op = O_register;
   1341      1.1     skrll       reg.X_add_number = 6;
   1342      1.1     skrll     }
   1343      1.1     skrll   if (reg.X_md
   1344      1.1     skrll       || reg.X_op != O_register
   1345      1.1     skrll       || reg.X_add_number > 7)
   1346      1.1     skrll     ill_op ();
   1347      1.1     skrll   else
   1348      1.1     skrll     if (port.X_op != O_register && port.X_op != O_md1)
   1349      1.1     skrll       {
   1350      1.1     skrll 	if (REG_A == reg.X_add_number)
   1351      1.1     skrll 	  {
   1352      1.1     skrll 	    q = frag_more (1);
   1353      1.1     skrll 	    *q = 0xD3;
   1354      1.1     skrll 	    emit_byte (&port, BFD_RELOC_8);
   1355      1.1     skrll 	  }
   1356      1.1     skrll 	else
   1357      1.1     skrll 	  ill_op ();
   1358      1.1     skrll       }
   1359      1.1     skrll     else
   1360      1.1     skrll       {
   1361      1.1     skrll 	if (REG_C == port.X_add_number)
   1362      1.1     skrll 	  {
   1363      1.1     skrll 	    q = frag_more (2);
   1364      1.1     skrll 	    *q++ = 0xED;
   1365      1.1     skrll 	    *q = 0x41 | (reg.X_add_number << 3);
   1366      1.1     skrll 	  }
   1367      1.1     skrll 	else
   1368      1.1     skrll 	  ill_op ();
   1369      1.1     skrll       }
   1370      1.1     skrll   return p;
   1371      1.1     skrll }
   1372      1.1     skrll 
   1373      1.1     skrll static const char *
   1374      1.1     skrll emit_rst (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1375      1.1     skrll {
   1376      1.1     skrll   expressionS addr;
   1377      1.1     skrll   const char *p;
   1378      1.1     skrll   char *q;
   1379      1.1     skrll 
   1380      1.1     skrll   p = parse_exp (args, &addr);
   1381      1.1     skrll   if (addr.X_op != O_constant)
   1382      1.1     skrll     {
   1383      1.1     skrll       error ("rst needs constant address");
   1384      1.1     skrll       return p;
   1385      1.1     skrll     }
   1386      1.1     skrll 
   1387      1.1     skrll   if (addr.X_add_number & ~(7 << 3))
   1388      1.1     skrll     ill_op ();
   1389      1.1     skrll   else
   1390      1.1     skrll     {
   1391      1.1     skrll       q = frag_more (1);
   1392      1.1     skrll       *q = opcode + (addr.X_add_number & (7 << 3));
   1393      1.1     skrll     }
   1394      1.1     skrll   return p;
   1395      1.1     skrll }
   1396      1.1     skrll 
   1397      1.1     skrll static void
   1398      1.1     skrll emit_ldxhl (char prefix, char opcode, expressionS *src, expressionS *d)
   1399      1.1     skrll {
   1400      1.1     skrll   char *q;
   1401      1.1     skrll 
   1402      1.1     skrll   if (src->X_md)
   1403      1.1     skrll     ill_op ();
   1404      1.1     skrll   else
   1405      1.1     skrll     {
   1406      1.1     skrll       if (src->X_op == O_register)
   1407      1.1     skrll 	{
   1408      1.1     skrll 	  if (src->X_add_number>7)
   1409      1.1     skrll 	    ill_op ();
   1410      1.1     skrll 	  if (prefix)
   1411      1.1     skrll 	    {
   1412      1.1     skrll 	      q = frag_more (2);
   1413      1.1     skrll 	      *q++ = prefix;
   1414      1.1     skrll 	    }
   1415      1.1     skrll 	  else
   1416      1.1     skrll 	q = frag_more (1);
   1417      1.1     skrll 	  *q = opcode + src->X_add_number;
   1418      1.1     skrll 	  if (d)
   1419      1.1     skrll 	    emit_byte (d, BFD_RELOC_Z80_DISP8);
   1420      1.1     skrll 	}
   1421      1.1     skrll       else
   1422      1.1     skrll 	{
   1423      1.1     skrll 	  if (prefix)
   1424      1.1     skrll 	    {
   1425      1.1     skrll 	      q = frag_more (2);
   1426      1.1     skrll 	      *q++ = prefix;
   1427      1.1     skrll 	    }
   1428      1.1     skrll 	  else
   1429      1.1     skrll 	    q = frag_more (1);
   1430      1.1     skrll 	  *q = opcode^0x46;
   1431      1.1     skrll 	  if (d)
   1432      1.1     skrll 	    emit_byte (d, BFD_RELOC_Z80_DISP8);
   1433      1.1     skrll 	  emit_byte (src, BFD_RELOC_8);
   1434      1.1     skrll 	}
   1435      1.1     skrll     }
   1436      1.1     skrll }
   1437      1.1     skrll 
   1438      1.1     skrll static void
   1439      1.1     skrll emit_ldreg (int dest, expressionS * src)
   1440      1.1     skrll {
   1441      1.1     skrll   char *q;
   1442      1.1     skrll   int rnum;
   1443      1.1     skrll 
   1444      1.1     skrll   switch (dest)
   1445      1.1     skrll     {
   1446      1.1     skrll       /* 8 Bit ld group:  */
   1447      1.1     skrll     case REG_I:
   1448      1.1     skrll     case REG_R:
   1449      1.1     skrll       if (src->X_md == 0 && src->X_op == O_register && src->X_add_number == REG_A)
   1450      1.1     skrll 	{
   1451      1.1     skrll 	  q = frag_more (2);
   1452      1.1     skrll 	  *q++ = 0xED;
   1453      1.1     skrll 	  *q = (dest == REG_I) ? 0x47 : 0x4F;
   1454      1.1     skrll 	}
   1455      1.1     skrll       else
   1456      1.1     skrll 	ill_op ();
   1457      1.1     skrll       break;
   1458      1.1     skrll 
   1459      1.1     skrll     case REG_A:
   1460      1.1     skrll       if ((src->X_md) && src->X_op != O_register && src->X_op != O_md1)
   1461      1.1     skrll 	{
   1462      1.1     skrll 	  q = frag_more (1);
   1463      1.1     skrll 	  *q = 0x3A;
   1464      1.1     skrll 	  emit_word (src);
   1465      1.1     skrll 	  break;
   1466      1.1     skrll 	}
   1467      1.1     skrll 
   1468      1.1     skrll       if ((src->X_md)
   1469      1.1     skrll 	  && src->X_op == O_register
   1470      1.1     skrll 	  && (src->X_add_number == REG_BC || src->X_add_number == REG_DE))
   1471      1.1     skrll 	{
   1472      1.1     skrll 	  q = frag_more (1);
   1473  1.1.1.2  christos 	  *q = 0x0A + ((src->X_add_number & 1) << 4);
   1474      1.1     skrll 	  break;
   1475      1.1     skrll 	}
   1476      1.1     skrll 
   1477      1.1     skrll       if ((!src->X_md)
   1478      1.1     skrll 	  && src->X_op == O_register
   1479      1.1     skrll 	  && (src->X_add_number == REG_R || src->X_add_number == REG_I))
   1480      1.1     skrll 	{
   1481      1.1     skrll 	  q = frag_more (2);
   1482      1.1     skrll 	  *q++ = 0xED;
   1483      1.1     skrll 	  *q = (src->X_add_number == REG_I) ? 0x57 : 0x5F;
   1484      1.1     skrll 	  break;
   1485      1.1     skrll 	}
   1486      1.1     skrll       /* Fall through.  */
   1487      1.1     skrll     case REG_B:
   1488      1.1     skrll     case REG_C:
   1489      1.1     skrll     case REG_D:
   1490      1.1     skrll     case REG_E:
   1491      1.1     skrll       emit_sx (0, 0x40 + (dest << 3), src);
   1492      1.1     skrll       break;
   1493      1.1     skrll 
   1494      1.1     skrll     case REG_H:
   1495      1.1     skrll     case REG_L:
   1496      1.1     skrll       if ((src->X_md == 0)
   1497      1.1     skrll 	  && (src->X_op == O_register)
   1498      1.1     skrll 	  && (src->X_add_number & R_INDEX))
   1499      1.1     skrll 	ill_op ();
   1500      1.1     skrll       else
   1501      1.1     skrll 	emit_sx (0, 0x40 + (dest << 3), src);
   1502      1.1     skrll       break;
   1503      1.1     skrll 
   1504      1.1     skrll     case R_IX | REG_H:
   1505      1.1     skrll     case R_IX | REG_L:
   1506      1.1     skrll     case R_IY | REG_H:
   1507      1.1     skrll     case R_IY | REG_L:
   1508      1.1     skrll       if (src->X_md)
   1509      1.1     skrll 	{
   1510      1.1     skrll 	  ill_op ();
   1511      1.1     skrll 	  break;
   1512      1.1     skrll 	}
   1513      1.1     skrll       check_mach (INS_UNDOC);
   1514      1.1     skrll       if (src-> X_op == O_register)
   1515      1.1     skrll 	{
   1516      1.1     skrll 	  rnum = src->X_add_number;
   1517      1.1     skrll 	  if ((rnum & ~R_INDEX) < 8
   1518      1.1     skrll 	      && ((rnum & R_INDEX) == (dest & R_INDEX)
   1519      1.1     skrll 		   || (   (rnum & ~R_INDEX) != REG_H
   1520      1.1     skrll 		       && (rnum & ~R_INDEX) != REG_L)))
   1521      1.1     skrll 	    {
   1522      1.1     skrll 	      q = frag_more (2);
   1523      1.1     skrll 	      *q++ = (dest & R_IX) ? 0xDD : 0xFD;
   1524      1.1     skrll 	      *q = 0x40 + ((dest & 0x07) << 3) + (rnum & 7);
   1525      1.1     skrll 	    }
   1526      1.1     skrll 	  else
   1527      1.1     skrll 	    ill_op ();
   1528      1.1     skrll 	}
   1529      1.1     skrll       else
   1530      1.1     skrll 	{
   1531      1.1     skrll 	  q = frag_more (2);
   1532      1.1     skrll 	  *q++ = (dest & R_IX) ? 0xDD : 0xFD;
   1533      1.1     skrll 	  *q = 0x06 + ((dest & 0x07) << 3);
   1534      1.1     skrll 	  emit_byte (src, BFD_RELOC_8);
   1535      1.1     skrll 	}
   1536      1.1     skrll       break;
   1537      1.1     skrll 
   1538      1.1     skrll       /* 16 Bit ld group:  */
   1539      1.1     skrll     case REG_SP:
   1540      1.1     skrll       if (src->X_md == 0
   1541      1.1     skrll 	  && src->X_op == O_register
   1542      1.1     skrll 	  && REG_HL == (src->X_add_number &~ R_INDEX))
   1543      1.1     skrll 	{
   1544      1.1     skrll 	  q = frag_more ((src->X_add_number & R_INDEX) ? 2 : 1);
   1545      1.1     skrll 	  if (src->X_add_number & R_INDEX)
   1546      1.1     skrll 	    *q++ = (src->X_add_number & R_IX) ? 0xDD : 0xFD;
   1547      1.1     skrll 	  *q = 0xF9;
   1548      1.1     skrll 	  break;
   1549      1.1     skrll 	}
   1550      1.1     skrll       /* Fall through.  */
   1551      1.1     skrll     case REG_BC:
   1552      1.1     skrll     case REG_DE:
   1553      1.1     skrll       if (src->X_op == O_register || src->X_op == O_md1)
   1554      1.1     skrll 	ill_op ();
   1555      1.1     skrll       q = frag_more (src->X_md ? 2 : 1);
   1556      1.1     skrll       if (src->X_md)
   1557      1.1     skrll 	{
   1558      1.1     skrll 	  *q++ = 0xED;
   1559      1.1     skrll 	  *q = 0x4B + ((dest & 3) << 4);
   1560      1.1     skrll 	}
   1561      1.1     skrll       else
   1562      1.1     skrll 	*q = 0x01 + ((dest & 3) << 4);
   1563      1.1     skrll       emit_word (src);
   1564      1.1     skrll       break;
   1565      1.1     skrll 
   1566      1.1     skrll     case REG_HL:
   1567      1.1     skrll     case REG_HL | R_IX:
   1568      1.1     skrll     case REG_HL | R_IY:
   1569      1.1     skrll       if (src->X_op == O_register || src->X_op == O_md1)
   1570      1.1     skrll 	ill_op ();
   1571      1.1     skrll       q = frag_more ((dest & R_INDEX) ? 2 : 1);
   1572      1.1     skrll       if (dest & R_INDEX)
   1573      1.1     skrll 	* q ++ = (dest & R_IX) ? 0xDD : 0xFD;
   1574      1.1     skrll       *q = (src->X_md) ? 0x2A : 0x21;
   1575      1.1     skrll       emit_word (src);
   1576      1.1     skrll       break;
   1577      1.1     skrll 
   1578      1.1     skrll     case REG_AF:
   1579      1.1     skrll     case REG_F:
   1580      1.1     skrll       ill_op ();
   1581      1.1     skrll       break;
   1582      1.1     skrll 
   1583      1.1     skrll     default:
   1584      1.1     skrll       abort ();
   1585      1.1     skrll     }
   1586      1.1     skrll }
   1587      1.1     skrll 
   1588      1.1     skrll static const char *
   1589      1.1     skrll emit_ld (char prefix_in ATTRIBUTE_UNUSED, char opcode_in ATTRIBUTE_UNUSED,
   1590      1.1     skrll 	const char * args)
   1591      1.1     skrll {
   1592      1.1     skrll   expressionS dst, src;
   1593      1.1     skrll   const char *p;
   1594      1.1     skrll   char *q;
   1595      1.1     skrll   char prefix, opcode;
   1596      1.1     skrll 
   1597      1.1     skrll   p = parse_exp (args, &dst);
   1598      1.1     skrll   if (*p++ != ',')
   1599      1.1     skrll     error (_("bad intruction syntax"));
   1600      1.1     skrll   p = parse_exp (p, &src);
   1601      1.1     skrll 
   1602      1.1     skrll   switch (dst.X_op)
   1603      1.1     skrll     {
   1604      1.1     skrll     case O_md1:
   1605  1.1.1.2  christos       {
   1606  1.1.1.2  christos         expressionS dst_offset = dst;
   1607  1.1.1.2  christos 	dst_offset.X_op = O_symbol;
   1608  1.1.1.2  christos 	dst_offset.X_add_number = 0;
   1609  1.1.1.2  christos 	emit_ldxhl ((dst.X_add_number & R_IX) ? 0xDD : 0xFD, 0x70,
   1610  1.1.1.2  christos 		    &src, &dst_offset);
   1611  1.1.1.2  christos       }
   1612      1.1     skrll       break;
   1613      1.1     skrll 
   1614      1.1     skrll     case O_register:
   1615      1.1     skrll       if (dst.X_md)
   1616      1.1     skrll 	{
   1617      1.1     skrll 	  switch (dst.X_add_number)
   1618      1.1     skrll 	    {
   1619      1.1     skrll 	    case REG_BC:
   1620      1.1     skrll 	    case REG_DE:
   1621      1.1     skrll 	      if (src.X_md == 0 && src.X_op == O_register && src.X_add_number == REG_A)
   1622      1.1     skrll 		{
   1623      1.1     skrll 		  q = frag_more (1);
   1624      1.1     skrll 		  *q = 0x02 + ( (dst.X_add_number & 1) << 4);
   1625      1.1     skrll 		}
   1626      1.1     skrll 	      else
   1627      1.1     skrll 		ill_op ();
   1628      1.1     skrll 	      break;
   1629      1.1     skrll 	    case REG_HL:
   1630      1.1     skrll 	      emit_ldxhl (0, 0x70, &src, NULL);
   1631      1.1     skrll 	      break;
   1632      1.1     skrll 	    default:
   1633      1.1     skrll 	      ill_op ();
   1634      1.1     skrll 	    }
   1635      1.1     skrll 	}
   1636      1.1     skrll       else
   1637      1.1     skrll 	emit_ldreg (dst.X_add_number, &src);
   1638      1.1     skrll       break;
   1639      1.1     skrll 
   1640      1.1     skrll     default:
   1641      1.1     skrll       if (src.X_md != 0 || src.X_op != O_register)
   1642      1.1     skrll 	ill_op ();
   1643      1.1     skrll       prefix = opcode = 0;
   1644      1.1     skrll       switch (src.X_add_number)
   1645      1.1     skrll 	{
   1646      1.1     skrll 	case REG_A:
   1647      1.1     skrll 	  opcode = 0x32; break;
   1648      1.1     skrll 	case REG_BC: case REG_DE: case REG_SP:
   1649      1.1     skrll 	  prefix = 0xED; opcode = 0x43 + ((src.X_add_number&3)<<4); break;
   1650      1.1     skrll 	case REG_HL:
   1651      1.1     skrll 	  opcode = 0x22; break;
   1652      1.1     skrll 	case REG_HL|R_IX:
   1653      1.1     skrll 	  prefix = 0xDD; opcode = 0x22; break;
   1654      1.1     skrll 	case REG_HL|R_IY:
   1655      1.1     skrll 	  prefix = 0xFD; opcode = 0x22; break;
   1656      1.1     skrll 	}
   1657      1.1     skrll       if (opcode)
   1658      1.1     skrll 	{
   1659      1.1     skrll 	  q = frag_more (prefix?2:1);
   1660      1.1     skrll 	  if (prefix)
   1661      1.1     skrll 	    *q++ = prefix;
   1662      1.1     skrll 	  *q = opcode;
   1663      1.1     skrll 	  emit_word (&dst);
   1664      1.1     skrll 	}
   1665      1.1     skrll       else
   1666      1.1     skrll 	ill_op ();
   1667      1.1     skrll     }
   1668      1.1     skrll   return p;
   1669      1.1     skrll }
   1670      1.1     skrll 
   1671      1.1     skrll static void
   1672      1.1     skrll emit_data (int size ATTRIBUTE_UNUSED)
   1673      1.1     skrll {
   1674      1.1     skrll   const char *p, *q;
   1675      1.1     skrll   char *u, quote;
   1676      1.1     skrll   int cnt;
   1677      1.1     skrll   expressionS exp;
   1678      1.1     skrll 
   1679      1.1     skrll   if (is_it_end_of_statement ())
   1680      1.1     skrll     {
   1681      1.1     skrll       demand_empty_rest_of_line ();
   1682      1.1     skrll       return;
   1683      1.1     skrll     }
   1684      1.1     skrll   p = skip_space (input_line_pointer);
   1685      1.1     skrll 
   1686      1.1     skrll   do
   1687      1.1     skrll     {
   1688      1.1     skrll       if (*p == '\"' || *p == '\'')
   1689      1.1     skrll 	{
   1690      1.1     skrll 	    for (quote = *p, q = ++p, cnt = 0; *p && quote != *p; ++p, ++cnt)
   1691      1.1     skrll 	      ;
   1692      1.1     skrll 	    u = frag_more (cnt);
   1693      1.1     skrll 	    memcpy (u, q, cnt);
   1694      1.1     skrll 	    if (!*p)
   1695      1.1     skrll 	      as_warn (_("unterminated string"));
   1696      1.1     skrll 	    else
   1697      1.1     skrll 	      p = skip_space (p+1);
   1698      1.1     skrll 	}
   1699      1.1     skrll       else
   1700      1.1     skrll 	{
   1701      1.1     skrll 	  p = parse_exp (p, &exp);
   1702      1.1     skrll 	  if (exp.X_op == O_md1 || exp.X_op == O_register)
   1703      1.1     skrll 	    {
   1704      1.1     skrll 	      ill_op ();
   1705      1.1     skrll 	      break;
   1706      1.1     skrll 	    }
   1707      1.1     skrll 	  if (exp.X_md)
   1708      1.1     skrll 	    as_warn (_("parentheses ignored"));
   1709      1.1     skrll 	  emit_byte (&exp, BFD_RELOC_8);
   1710      1.1     skrll 	  p = skip_space (p);
   1711      1.1     skrll 	}
   1712      1.1     skrll     }
   1713      1.1     skrll   while (*p++ == ',') ;
   1714      1.1     skrll   input_line_pointer = (char *)(p-1);
   1715      1.1     skrll }
   1716      1.1     skrll 
   1717      1.1     skrll static const char *
   1718      1.1     skrll emit_mulub (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1719      1.1     skrll {
   1720      1.1     skrll   const char *p;
   1721      1.1     skrll 
   1722      1.1     skrll   p = skip_space (args);
   1723      1.1     skrll   if (TOLOWER (*p++) != 'a' || *p++ != ',')
   1724      1.1     skrll     ill_op ();
   1725      1.1     skrll   else
   1726      1.1     skrll     {
   1727      1.1     skrll       char *q, reg;
   1728      1.1     skrll 
   1729      1.1     skrll       reg = TOLOWER (*p++);
   1730      1.1     skrll       switch (reg)
   1731      1.1     skrll 	{
   1732      1.1     skrll 	case 'b':
   1733      1.1     skrll 	case 'c':
   1734      1.1     skrll 	case 'd':
   1735      1.1     skrll 	case 'e':
   1736      1.1     skrll 	  check_mach (INS_R800);
   1737      1.1     skrll 	  if (!*skip_space (p))
   1738      1.1     skrll 	    {
   1739      1.1     skrll 	      q = frag_more (2);
   1740      1.1     skrll 	      *q++ = prefix;
   1741      1.1     skrll 	      *q = opcode + ((reg - 'b') << 3);
   1742      1.1     skrll 	      break;
   1743      1.1     skrll 	    }
   1744      1.1     skrll 	default:
   1745      1.1     skrll 	  ill_op ();
   1746      1.1     skrll 	}
   1747      1.1     skrll     }
   1748      1.1     skrll   return p;
   1749      1.1     skrll }
   1750      1.1     skrll 
   1751      1.1     skrll static const char *
   1752      1.1     skrll emit_muluw (char prefix ATTRIBUTE_UNUSED, char opcode, const char * args)
   1753      1.1     skrll {
   1754      1.1     skrll   const char *p;
   1755      1.1     skrll 
   1756      1.1     skrll   p = skip_space (args);
   1757      1.1     skrll   if (TOLOWER (*p++) != 'h' || TOLOWER (*p++) != 'l' || *p++ != ',')
   1758      1.1     skrll     ill_op ();
   1759      1.1     skrll   else
   1760      1.1     skrll     {
   1761      1.1     skrll       expressionS reg;
   1762      1.1     skrll       char *q;
   1763      1.1     skrll 
   1764      1.1     skrll       p = parse_exp (p, & reg);
   1765      1.1     skrll 
   1766      1.1     skrll       if ((!reg.X_md) && reg.X_op == O_register)
   1767      1.1     skrll 	switch (reg.X_add_number)
   1768      1.1     skrll 	  {
   1769      1.1     skrll 	  case REG_BC:
   1770      1.1     skrll 	  case REG_SP:
   1771      1.1     skrll 	    check_mach (INS_R800);
   1772      1.1     skrll 	    q = frag_more (2);
   1773      1.1     skrll 	    *q++ = prefix;
   1774      1.1     skrll 	    *q = opcode + ((reg.X_add_number & 3) << 4);
   1775      1.1     skrll 	    break;
   1776      1.1     skrll 	  default:
   1777      1.1     skrll 	    ill_op ();
   1778      1.1     skrll 	  }
   1779      1.1     skrll     }
   1780      1.1     skrll   return p;
   1781      1.1     skrll }
   1782      1.1     skrll 
   1783      1.1     skrll /* Port specific pseudo ops.  */
   1784      1.1     skrll const pseudo_typeS md_pseudo_table[] =
   1785      1.1     skrll {
   1786      1.1     skrll   { "db" , emit_data, 1},
   1787      1.1     skrll   { "d24", cons, 3},
   1788      1.1     skrll   { "d32", cons, 4},
   1789      1.1     skrll   { "def24", cons, 3},
   1790      1.1     skrll   { "def32", cons, 4},
   1791      1.1     skrll   { "defb", emit_data, 1},
   1792      1.1     skrll   { "defs", s_space, 1}, /* Synonym for ds on some assemblers.  */
   1793      1.1     skrll   { "defw", cons, 2},
   1794      1.1     skrll   { "ds",   s_space, 1}, /* Fill with bytes rather than words.  */
   1795      1.1     skrll   { "dw", cons, 2},
   1796      1.1     skrll   { "psect", obj_coff_section, 0}, /* TODO: Translate attributes.  */
   1797      1.1     skrll   { "set", 0, 0}, 		/* Real instruction on z80.  */
   1798      1.1     skrll   { NULL, 0, 0 }
   1799      1.1     skrll } ;
   1800      1.1     skrll 
   1801      1.1     skrll static table_t instab[] =
   1802      1.1     skrll {
   1803      1.1     skrll   { "adc",  0x88, 0x4A, emit_adc },
   1804      1.1     skrll   { "add",  0x80, 0x09, emit_add },
   1805      1.1     skrll   { "and",  0x00, 0xA0, emit_s },
   1806      1.1     skrll   { "bit",  0xCB, 0x40, emit_bit },
   1807      1.1     skrll   { "call", 0xCD, 0xC4, emit_jpcc },
   1808      1.1     skrll   { "ccf",  0x00, 0x3F, emit_insn },
   1809      1.1     skrll   { "cp",   0x00, 0xB8, emit_s },
   1810      1.1     skrll   { "cpd",  0xED, 0xA9, emit_insn },
   1811      1.1     skrll   { "cpdr", 0xED, 0xB9, emit_insn },
   1812      1.1     skrll   { "cpi",  0xED, 0xA1, emit_insn },
   1813      1.1     skrll   { "cpir", 0xED, 0xB1, emit_insn },
   1814      1.1     skrll   { "cpl",  0x00, 0x2F, emit_insn },
   1815      1.1     skrll   { "daa",  0x00, 0x27, emit_insn },
   1816      1.1     skrll   { "dec",  0x0B, 0x05, emit_incdec },
   1817      1.1     skrll   { "di",   0x00, 0xF3, emit_insn },
   1818      1.1     skrll   { "djnz", 0x00, 0x10, emit_jr },
   1819      1.1     skrll   { "ei",   0x00, 0xFB, emit_insn },
   1820      1.1     skrll   { "ex",   0x00, 0x00, emit_ex},
   1821      1.1     skrll   { "exx",  0x00, 0xD9, emit_insn },
   1822      1.1     skrll   { "halt", 0x00, 0x76, emit_insn },
   1823      1.1     skrll   { "im",   0xED, 0x46, emit_im },
   1824      1.1     skrll   { "in",   0x00, 0x00, emit_in },
   1825      1.1     skrll   { "inc",  0x03, 0x04, emit_incdec },
   1826      1.1     skrll   { "ind",  0xED, 0xAA, emit_insn },
   1827      1.1     skrll   { "indr", 0xED, 0xBA, emit_insn },
   1828      1.1     skrll   { "ini",  0xED, 0xA2, emit_insn },
   1829      1.1     skrll   { "inir", 0xED, 0xB2, emit_insn },
   1830      1.1     skrll   { "jp",   0xC3, 0xC2, emit_jpcc },
   1831      1.1     skrll   { "jr",   0x18, 0x20, emit_jrcc },
   1832      1.1     skrll   { "ld",   0x00, 0x00, emit_ld },
   1833      1.1     skrll   { "ldd",  0xED, 0xA8, emit_insn },
   1834      1.1     skrll   { "lddr", 0xED, 0xB8, emit_insn },
   1835      1.1     skrll   { "ldi",  0xED, 0xA0, emit_insn },
   1836      1.1     skrll   { "ldir", 0xED, 0xB0, emit_insn },
   1837      1.1     skrll   { "mulub", 0xED, 0xC5, emit_mulub }, /* R800 only.  */
   1838      1.1     skrll   { "muluw", 0xED, 0xC3, emit_muluw }, /* R800 only.  */
   1839      1.1     skrll   { "neg",  0xed, 0x44, emit_insn },
   1840      1.1     skrll   { "nop",  0x00, 0x00, emit_insn },
   1841      1.1     skrll   { "or",   0x00, 0xB0, emit_s },
   1842      1.1     skrll   { "otdr", 0xED, 0xBB, emit_insn },
   1843      1.1     skrll   { "otir", 0xED, 0xB3, emit_insn },
   1844      1.1     skrll   { "out",  0x00, 0x00, emit_out },
   1845      1.1     skrll   { "outd", 0xED, 0xAB, emit_insn },
   1846      1.1     skrll   { "outi", 0xED, 0xA3, emit_insn },
   1847      1.1     skrll   { "pop",  0x00, 0xC1, emit_pop },
   1848      1.1     skrll   { "push", 0x00, 0xC5, emit_pop },
   1849      1.1     skrll   { "res",  0xCB, 0x80, emit_bit },
   1850      1.1     skrll   { "ret",  0xC9, 0xC0, emit_retcc },
   1851      1.1     skrll   { "reti", 0xED, 0x4D, emit_insn },
   1852      1.1     skrll   { "retn", 0xED, 0x45, emit_insn },
   1853      1.1     skrll   { "rl",   0xCB, 0x10, emit_mr },
   1854      1.1     skrll   { "rla",  0x00, 0x17, emit_insn },
   1855      1.1     skrll   { "rlc",  0xCB, 0x00, emit_mr },
   1856      1.1     skrll   { "rlca", 0x00, 0x07, emit_insn },
   1857      1.1     skrll   { "rld",  0xED, 0x6F, emit_insn },
   1858      1.1     skrll   { "rr",   0xCB, 0x18, emit_mr },
   1859      1.1     skrll   { "rra",  0x00, 0x1F, emit_insn },
   1860      1.1     skrll   { "rrc",  0xCB, 0x08, emit_mr },
   1861      1.1     skrll   { "rrca", 0x00, 0x0F, emit_insn },
   1862      1.1     skrll   { "rrd",  0xED, 0x67, emit_insn },
   1863      1.1     skrll   { "rst",  0x00, 0xC7, emit_rst},
   1864      1.1     skrll   { "sbc",  0x98, 0x42, emit_adc },
   1865      1.1     skrll   { "scf",  0x00, 0x37, emit_insn },
   1866      1.1     skrll   { "set",  0xCB, 0xC0, emit_bit },
   1867      1.1     skrll   { "sla",  0xCB, 0x20, emit_mr },
   1868      1.1     skrll   { "sli",  0xCB, 0x30, emit_mr },
   1869      1.1     skrll   { "sll",  0xCB, 0x30, emit_mr },
   1870      1.1     skrll   { "sra",  0xCB, 0x28, emit_mr },
   1871      1.1     skrll   { "srl",  0xCB, 0x38, emit_mr },
   1872      1.1     skrll   { "sub",  0x00, 0x90, emit_s },
   1873      1.1     skrll   { "xor",  0x00, 0xA8, emit_s },
   1874      1.1     skrll } ;
   1875      1.1     skrll 
   1876      1.1     skrll void
   1877      1.1     skrll md_assemble (char* str)
   1878      1.1     skrll {
   1879      1.1     skrll   const char *p;
   1880      1.1     skrll   char * old_ptr;
   1881      1.1     skrll   int i;
   1882      1.1     skrll   table_t *insp;
   1883      1.1     skrll 
   1884      1.1     skrll   err_flag = 0;
   1885      1.1     skrll   old_ptr = input_line_pointer;
   1886      1.1     skrll   p = skip_space (str);
   1887      1.1     skrll   for (i = 0; (i < BUFLEN) && (ISALPHA (*p));)
   1888      1.1     skrll     buf[i++] = TOLOWER (*p++);
   1889      1.1     skrll 
   1890      1.1     skrll   if (i == BUFLEN)
   1891      1.1     skrll     {
   1892      1.1     skrll       buf[BUFLEN-3] = buf[BUFLEN-2] = '.'; /* Mark opcode as abbreviated.  */
   1893      1.1     skrll       buf[BUFLEN-1] = 0;
   1894      1.1     skrll       as_bad (_("Unknown instruction '%s'"), buf);
   1895      1.1     skrll     }
   1896      1.1     skrll   else if ((*p) && (!ISSPACE (*p)))
   1897      1.1     skrll     as_bad (_("syntax error"));
   1898      1.1     skrll   else
   1899      1.1     skrll     {
   1900      1.1     skrll       buf[i] = 0;
   1901      1.1     skrll       p = skip_space (p);
   1902      1.1     skrll       key = buf;
   1903      1.1     skrll 
   1904      1.1     skrll       insp = bsearch (&key, instab, ARRAY_SIZE (instab),
   1905      1.1     skrll 		    sizeof (instab[0]), key_cmp);
   1906      1.1     skrll       if (!insp)
   1907      1.1     skrll 	as_bad (_("Unknown instruction '%s'"), buf);
   1908      1.1     skrll       else
   1909      1.1     skrll 	{
   1910      1.1     skrll 	  p = insp->fp (insp->prefix, insp->opcode, p);
   1911      1.1     skrll 	  p = skip_space (p);
   1912      1.1     skrll 	if ((!err_flag) && *p)
   1913      1.1     skrll 	  as_bad (_("junk at end of line, first unrecognized character is `%c'"),
   1914      1.1     skrll 		  *p);
   1915      1.1     skrll 	}
   1916      1.1     skrll     }
   1917      1.1     skrll   input_line_pointer = old_ptr;
   1918      1.1     skrll }
   1919      1.1     skrll 
   1920      1.1     skrll void
   1921      1.1     skrll md_apply_fix (fixS * fixP, valueT* valP, segT seg ATTRIBUTE_UNUSED)
   1922      1.1     skrll {
   1923      1.1     skrll   long val = * (long *) valP;
   1924  1.1.1.2  christos   char *p_lit = fixP->fx_where + fixP->fx_frag->fr_literal;
   1925      1.1     skrll 
   1926      1.1     skrll   switch (fixP->fx_r_type)
   1927      1.1     skrll     {
   1928      1.1     skrll     case BFD_RELOC_8_PCREL:
   1929      1.1     skrll       if (fixP->fx_addsy)
   1930      1.1     skrll         {
   1931      1.1     skrll           fixP->fx_no_overflow = 1;
   1932      1.1     skrll           fixP->fx_done = 0;
   1933      1.1     skrll         }
   1934      1.1     skrll       else
   1935      1.1     skrll         {
   1936      1.1     skrll 	  fixP->fx_no_overflow = (-128 <= val && val < 128);
   1937      1.1     skrll 	  if (!fixP->fx_no_overflow)
   1938      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1939      1.1     skrll 			  _("relative jump out of range"));
   1940  1.1.1.2  christos 	  *p_lit++ = val;
   1941      1.1     skrll           fixP->fx_done = 1;
   1942      1.1     skrll         }
   1943      1.1     skrll       break;
   1944      1.1     skrll 
   1945      1.1     skrll     case BFD_RELOC_Z80_DISP8:
   1946      1.1     skrll       if (fixP->fx_addsy)
   1947      1.1     skrll         {
   1948      1.1     skrll           fixP->fx_no_overflow = 1;
   1949      1.1     skrll           fixP->fx_done = 0;
   1950      1.1     skrll         }
   1951      1.1     skrll       else
   1952      1.1     skrll         {
   1953      1.1     skrll 	  fixP->fx_no_overflow = (-128 <= val && val < 128);
   1954      1.1     skrll 	  if (!fixP->fx_no_overflow)
   1955      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1956      1.1     skrll 			  _("index offset  out of range"));
   1957  1.1.1.2  christos 	  *p_lit++ = val;
   1958      1.1     skrll           fixP->fx_done = 1;
   1959      1.1     skrll         }
   1960      1.1     skrll       break;
   1961      1.1     skrll 
   1962      1.1     skrll     case BFD_RELOC_8:
   1963      1.1     skrll       if (val > 255 || val < -128)
   1964      1.1     skrll 	as_warn_where (fixP->fx_file, fixP->fx_line, _("overflow"));
   1965  1.1.1.2  christos       *p_lit++ = val;
   1966      1.1     skrll       fixP->fx_no_overflow = 1;
   1967      1.1     skrll       if (fixP->fx_addsy == NULL)
   1968      1.1     skrll 	fixP->fx_done = 1;
   1969      1.1     skrll       break;
   1970      1.1     skrll 
   1971      1.1     skrll     case BFD_RELOC_16:
   1972  1.1.1.2  christos       *p_lit++ = val;
   1973  1.1.1.2  christos       *p_lit++ = (val >> 8);
   1974      1.1     skrll       fixP->fx_no_overflow = 1;
   1975      1.1     skrll       if (fixP->fx_addsy == NULL)
   1976      1.1     skrll 	fixP->fx_done = 1;
   1977      1.1     skrll       break;
   1978      1.1     skrll 
   1979      1.1     skrll     case BFD_RELOC_24: /* Def24 may produce this.  */
   1980  1.1.1.2  christos       *p_lit++ = val;
   1981  1.1.1.2  christos       *p_lit++ = (val >> 8);
   1982  1.1.1.2  christos       *p_lit++ = (val >> 16);
   1983      1.1     skrll       fixP->fx_no_overflow = 1;
   1984      1.1     skrll       if (fixP->fx_addsy == NULL)
   1985      1.1     skrll 	fixP->fx_done = 1;
   1986      1.1     skrll       break;
   1987      1.1     skrll 
   1988      1.1     skrll     case BFD_RELOC_32: /* Def32 and .long may produce this.  */
   1989  1.1.1.2  christos       *p_lit++ = val;
   1990  1.1.1.2  christos       *p_lit++ = (val >> 8);
   1991  1.1.1.2  christos       *p_lit++ = (val >> 16);
   1992  1.1.1.2  christos       *p_lit++ = (val >> 24);
   1993      1.1     skrll       if (fixP->fx_addsy == NULL)
   1994      1.1     skrll 	fixP->fx_done = 1;
   1995      1.1     skrll       break;
   1996      1.1     skrll 
   1997      1.1     skrll     default:
   1998      1.1     skrll       printf (_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
   1999      1.1     skrll       abort ();
   2000      1.1     skrll     }
   2001      1.1     skrll }
   2002      1.1     skrll 
   2003      1.1     skrll /* GAS will call this to generate a reloc.  GAS will pass the
   2004      1.1     skrll    resulting reloc to `bfd_install_relocation'.  This currently works
   2005      1.1     skrll    poorly, as `bfd_install_relocation' often does the wrong thing, and
   2006      1.1     skrll    instances of `tc_gen_reloc' have been written to work around the
   2007      1.1     skrll    problems, which in turns makes it difficult to fix
   2008      1.1     skrll    `bfd_install_relocation'.  */
   2009      1.1     skrll 
   2010      1.1     skrll /* If while processing a fixup, a reloc really
   2011      1.1     skrll    needs to be created then it is done here.  */
   2012      1.1     skrll 
   2013      1.1     skrll arelent *
   2014      1.1     skrll tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED , fixS *fixp)
   2015      1.1     skrll {
   2016      1.1     skrll   arelent *reloc;
   2017      1.1     skrll 
   2018      1.1     skrll   if (! bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type))
   2019      1.1     skrll     {
   2020      1.1     skrll       as_bad_where (fixp->fx_file, fixp->fx_line,
   2021      1.1     skrll 		    _("reloc %d not supported by object file format"),
   2022      1.1     skrll 		    (int) fixp->fx_r_type);
   2023      1.1     skrll       return NULL;
   2024      1.1     skrll     }
   2025      1.1     skrll 
   2026      1.1     skrll   reloc               = xmalloc (sizeof (arelent));
   2027      1.1     skrll   reloc->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
   2028      1.1     skrll   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   2029      1.1     skrll   reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;
   2030      1.1     skrll   reloc->howto        = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   2031      1.1     skrll   reloc->addend       = fixp->fx_offset;
   2032      1.1     skrll 
   2033      1.1     skrll   return reloc;
   2034      1.1     skrll }
   2035