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