Home | History | Annotate | Line # | Download | only in config
tc-z8k.c revision 1.1
      1  1.1  skrll /* tc-z8k.c -- Assemble code for the Zilog Z800n
      2  1.1  skrll    Copyright 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 2002, 2003,
      3  1.1  skrll    2005, 2006, 2007  Free Software Foundation, Inc.
      4  1.1  skrll 
      5  1.1  skrll    This file is part of GAS, the GNU Assembler.
      6  1.1  skrll 
      7  1.1  skrll    GAS is free software; you can redistribute it and/or modify
      8  1.1  skrll    it under the terms of the GNU General Public License as published by
      9  1.1  skrll    the Free Software Foundation; either version 3, or (at your option)
     10  1.1  skrll    any later version.
     11  1.1  skrll 
     12  1.1  skrll    GAS is distributed in the hope that it will be useful,
     13  1.1  skrll    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14  1.1  skrll    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15  1.1  skrll    GNU General Public License for more details.
     16  1.1  skrll 
     17  1.1  skrll    You should have received a copy of the GNU General Public License
     18  1.1  skrll    along with GAS; see the file COPYING.  If not, write to the Free
     19  1.1  skrll    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     20  1.1  skrll    02110-1301, USA.  */
     21  1.1  skrll 
     22  1.1  skrll /* Written By Steve Chamberlain <sac (at) cygnus.com>.  */
     23  1.1  skrll 
     24  1.1  skrll #include "as.h"
     25  1.1  skrll #include "safe-ctype.h"
     26  1.1  skrll #define DEFINE_TABLE
     27  1.1  skrll #include "opcodes/z8k-opc.h"
     28  1.1  skrll 
     29  1.1  skrll const char comment_chars[] = "!";
     30  1.1  skrll const char line_comment_chars[] = "#";
     31  1.1  skrll const char line_separator_chars[] = ";";
     32  1.1  skrll 
     33  1.1  skrll extern int machine;
     34  1.1  skrll extern int coff_flags;
     35  1.1  skrll int segmented_mode;
     36  1.1  skrll 
     37  1.1  skrll /* This is non-zero if target was set from the command line.  */
     38  1.1  skrll static int z8k_target_from_cmdline;
     39  1.1  skrll 
     40  1.1  skrll static void
     41  1.1  skrll s_segm (int segm)
     42  1.1  skrll {
     43  1.1  skrll   if (segm)
     44  1.1  skrll     {
     45  1.1  skrll       segmented_mode = 1;
     46  1.1  skrll       bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8001);
     47  1.1  skrll     }
     48  1.1  skrll   else
     49  1.1  skrll     {
     50  1.1  skrll       segmented_mode = 0;
     51  1.1  skrll       bfd_set_arch_mach (stdoutput, TARGET_ARCH, bfd_mach_z8002);
     52  1.1  skrll     }
     53  1.1  skrll }
     54  1.1  skrll 
     55  1.1  skrll static void
     56  1.1  skrll even (int ignore ATTRIBUTE_UNUSED)
     57  1.1  skrll {
     58  1.1  skrll   frag_align (1, 0, 0);
     59  1.1  skrll   record_alignment (now_seg, 1);
     60  1.1  skrll }
     61  1.1  skrll 
     62  1.1  skrll static int
     63  1.1  skrll tohex (int c)
     64  1.1  skrll {
     65  1.1  skrll   if (ISDIGIT (c))
     66  1.1  skrll     return c - '0';
     67  1.1  skrll   if (ISLOWER (c))
     68  1.1  skrll     return c - 'a' + 10;
     69  1.1  skrll   return c - 'A' + 10;
     70  1.1  skrll }
     71  1.1  skrll 
     72  1.1  skrll static void
     73  1.1  skrll sval (int ignore ATTRIBUTE_UNUSED)
     74  1.1  skrll {
     75  1.1  skrll   SKIP_WHITESPACE ();
     76  1.1  skrll   if (*input_line_pointer == '\'')
     77  1.1  skrll     {
     78  1.1  skrll       int c;
     79  1.1  skrll       input_line_pointer++;
     80  1.1  skrll       c = *input_line_pointer++;
     81  1.1  skrll       while (c != '\'')
     82  1.1  skrll 	{
     83  1.1  skrll 	  if (c == '%')
     84  1.1  skrll 	    {
     85  1.1  skrll 	      c = (tohex (input_line_pointer[0]) << 4)
     86  1.1  skrll 		| tohex (input_line_pointer[1]);
     87  1.1  skrll 	      input_line_pointer += 2;
     88  1.1  skrll 	    }
     89  1.1  skrll 	  FRAG_APPEND_1_CHAR (c);
     90  1.1  skrll 	  c = *input_line_pointer++;
     91  1.1  skrll 	}
     92  1.1  skrll       demand_empty_rest_of_line ();
     93  1.1  skrll     }
     94  1.1  skrll }
     95  1.1  skrll 
     96  1.1  skrll /* This table describes all the machine specific pseudo-ops the assembler
     97  1.1  skrll    has to support.  The fields are:
     98  1.1  skrll    pseudo-op name without dot
     99  1.1  skrll    function to call to execute this pseudo-op
    100  1.1  skrll    Integer arg to pass to the function
    101  1.1  skrll    */
    102  1.1  skrll 
    103  1.1  skrll const pseudo_typeS md_pseudo_table[] = {
    104  1.1  skrll   {"int"    , cons            , 2},
    105  1.1  skrll   {"data.b" , cons            , 1},
    106  1.1  skrll   {"data.w" , cons            , 2},
    107  1.1  skrll   {"data.l" , cons            , 4},
    108  1.1  skrll   {"form"   , listing_psize   , 0},
    109  1.1  skrll   {"heading", listing_title   , 0},
    110  1.1  skrll   {"import" , s_ignore        , 0},
    111  1.1  skrll   {"page"   , listing_eject   , 0},
    112  1.1  skrll   {"program", s_ignore        , 0},
    113  1.1  skrll   {"z8001"  , s_segm          , 1},
    114  1.1  skrll   {"z8002"  , s_segm          , 0},
    115  1.1  skrll 
    116  1.1  skrll   {"segm"   , s_segm          , 1},
    117  1.1  skrll   {"unsegm" , s_segm          , 0},
    118  1.1  skrll   {"unseg"  , s_segm          , 0},
    119  1.1  skrll   {"name"   , s_app_file      , 0},
    120  1.1  skrll   {"global" , s_globl         , 0},
    121  1.1  skrll   {"wval"   , cons            , 2},
    122  1.1  skrll   {"lval"   , cons            , 4},
    123  1.1  skrll   {"bval"   , cons            , 1},
    124  1.1  skrll   {"sval"   , sval            , 0},
    125  1.1  skrll   {"rsect"  , obj_coff_section, 0},
    126  1.1  skrll   {"sect"   , obj_coff_section, 0},
    127  1.1  skrll   {"block"  , s_space         , 0},
    128  1.1  skrll   {"even"   , even            , 0},
    129  1.1  skrll   {0        , 0               , 0}
    130  1.1  skrll };
    131  1.1  skrll 
    132  1.1  skrll const char EXP_CHARS[] = "eE";
    133  1.1  skrll 
    134  1.1  skrll /* Chars that mean this number is a floating point constant.
    135  1.1  skrll    As in 0f12.456
    136  1.1  skrll    or    0d1.2345e12  */
    137  1.1  skrll const char FLT_CHARS[] = "rRsSfFdDxXpP";
    138  1.1  skrll 
    139  1.1  skrll /* Opcode mnemonics.  */
    140  1.1  skrll static struct hash_control *opcode_hash_control;
    141  1.1  skrll 
    142  1.1  skrll void
    143  1.1  skrll md_begin (void)
    144  1.1  skrll {
    145  1.1  skrll   const opcode_entry_type *opcode;
    146  1.1  skrll   int idx = -1;
    147  1.1  skrll 
    148  1.1  skrll   opcode_hash_control = hash_new ();
    149  1.1  skrll 
    150  1.1  skrll   for (opcode = z8k_table; opcode->name; opcode++)
    151  1.1  skrll     {
    152  1.1  skrll       /* Only enter unique codes into the table.  */
    153  1.1  skrll       if (idx != opcode->idx)
    154  1.1  skrll 	hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
    155  1.1  skrll       idx = opcode->idx;
    156  1.1  skrll     }
    157  1.1  skrll 
    158  1.1  skrll   /* Default to z8002.  */
    159  1.1  skrll   if (! z8k_target_from_cmdline)
    160  1.1  skrll     s_segm (0);
    161  1.1  skrll 
    162  1.1  skrll   /* Insert the pseudo ops, too.  */
    163  1.1  skrll   for (idx = 0; md_pseudo_table[idx].poc_name; idx++)
    164  1.1  skrll     {
    165  1.1  skrll       opcode_entry_type *fake_opcode;
    166  1.1  skrll       fake_opcode = (opcode_entry_type *) malloc (sizeof (opcode_entry_type));
    167  1.1  skrll       fake_opcode->name = md_pseudo_table[idx].poc_name;
    168  1.1  skrll       fake_opcode->func = (void *) (md_pseudo_table + idx);
    169  1.1  skrll       fake_opcode->opcode = 250;
    170  1.1  skrll       hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
    171  1.1  skrll     }
    172  1.1  skrll }
    173  1.1  skrll 
    174  1.1  skrll typedef struct z8k_op {
    175  1.1  skrll   /* CLASS_REG_xxx.  */
    176  1.1  skrll   int regsize;
    177  1.1  skrll 
    178  1.1  skrll   /* 0 .. 15.  */
    179  1.1  skrll   unsigned int reg;
    180  1.1  skrll 
    181  1.1  skrll   int mode;
    182  1.1  skrll 
    183  1.1  skrll   /* Any other register associated with the mode.  */
    184  1.1  skrll   unsigned int x_reg;
    185  1.1  skrll 
    186  1.1  skrll   /* Any expression.  */
    187  1.1  skrll   expressionS exp;
    188  1.1  skrll } op_type;
    189  1.1  skrll 
    190  1.1  skrll static expressionS *da_operand;
    191  1.1  skrll static expressionS *imm_operand;
    192  1.1  skrll 
    193  1.1  skrll static int reg[16];
    194  1.1  skrll static int the_cc;
    195  1.1  skrll static int the_ctrl;
    196  1.1  skrll static int the_flags;
    197  1.1  skrll static int the_interrupt;
    198  1.1  skrll 
    199  1.1  skrll /* Determine register number.  src points to the ascii number
    200  1.1  skrll    (after "rl", "rh", "r", "rr", or "rq").  If a character
    201  1.1  skrll    outside the set of {0,',',')','('} follows the number,
    202  1.1  skrll    return NULL to indicate that it's not a valid register
    203  1.1  skrll    number.  */
    204  1.1  skrll 
    205  1.1  skrll static char *
    206  1.1  skrll whatreg (unsigned int *reg, char *src)
    207  1.1  skrll {
    208  1.1  skrll   unsigned int new_reg;
    209  1.1  skrll 
    210  1.1  skrll   /* src[0] is already known to be a digit.  */
    211  1.1  skrll   if (ISDIGIT (src[1]))
    212  1.1  skrll     {
    213  1.1  skrll       new_reg = (src[0] - '0') * 10 + src[1] - '0';
    214  1.1  skrll       src += 2;
    215  1.1  skrll     }
    216  1.1  skrll   else
    217  1.1  skrll     {
    218  1.1  skrll       new_reg = (src[0] - '0');
    219  1.1  skrll       src += 1;
    220  1.1  skrll     }
    221  1.1  skrll 
    222  1.1  skrll   if (src[0] != 0 && src[0] != ',' && src[0] != '(' && src[0] != ')')
    223  1.1  skrll     return NULL;
    224  1.1  skrll 
    225  1.1  skrll   *reg = new_reg;
    226  1.1  skrll   return src;
    227  1.1  skrll }
    228  1.1  skrll 
    229  1.1  skrll /* Parse operands
    230  1.1  skrll 
    231  1.1  skrll    rh0-rh7, rl0-rl7
    232  1.1  skrll    r0-r15
    233  1.1  skrll    rr0-rr14
    234  1.1  skrll    rq0--rq12
    235  1.1  skrll    WREG r0,r1,r2,r3,r4,r5,r6,r7,fp,sp
    236  1.1  skrll    r0l,r0h,..r7l,r7h
    237  1.1  skrll    @WREG
    238  1.1  skrll    @WREG+
    239  1.1  skrll    @-WREG
    240  1.1  skrll    #const
    241  1.1  skrll */
    242  1.1  skrll 
    243  1.1  skrll /* Try to parse a reg name.  Return a pointer to the first character
    244  1.1  skrll    in SRC after the reg name.  */
    245  1.1  skrll 
    246  1.1  skrll static char *
    247  1.1  skrll parse_reg (char *src, int *mode, unsigned int *reg)
    248  1.1  skrll {
    249  1.1  skrll   char *res = NULL;
    250  1.1  skrll   char regno;
    251  1.1  skrll 
    252  1.1  skrll   /* Check for stack pointer "sp" alias.  */
    253  1.1  skrll   if ((src[0] == 's' || src[0] == 'S')
    254  1.1  skrll       && (src[1] == 'p' || src[1] == 'P')
    255  1.1  skrll       && (src[2] == 0 || src[2] == ','))
    256  1.1  skrll     {
    257  1.1  skrll       if (segmented_mode)
    258  1.1  skrll 	{
    259  1.1  skrll 	  *mode = CLASS_REG_LONG;
    260  1.1  skrll 	  *reg = 14;
    261  1.1  skrll 	}
    262  1.1  skrll       else
    263  1.1  skrll 	{
    264  1.1  skrll 	  *mode = CLASS_REG_WORD;
    265  1.1  skrll 	  *reg = 15;
    266  1.1  skrll 	}
    267  1.1  skrll       return src + 2;
    268  1.1  skrll     }
    269  1.1  skrll 
    270  1.1  skrll   if (src[0] == 'r' || src[0] == 'R')
    271  1.1  skrll     {
    272  1.1  skrll       if (src[1] == 'r' || src[1] == 'R')
    273  1.1  skrll 	{
    274  1.1  skrll 	  if (src[2] < '0' || src[2] > '9')
    275  1.1  skrll 	    return NULL;	/* Assume no register name but a label starting with 'rr'.  */
    276  1.1  skrll 	  *mode = CLASS_REG_LONG;
    277  1.1  skrll 	  res = whatreg (reg, src + 2);
    278  1.1  skrll 	  if (res == NULL)
    279  1.1  skrll 	    return NULL;	/* Not a valid register name.  */
    280  1.1  skrll 	  regno = *reg;
    281  1.1  skrll 	  if (regno > 14)
    282  1.1  skrll 	    as_bad (_("register rr%d out of range"), regno);
    283  1.1  skrll 	  if (regno & 1)
    284  1.1  skrll 	    as_bad (_("register rr%d does not exist"), regno);
    285  1.1  skrll 	}
    286  1.1  skrll       else if (src[1] == 'h' || src[1] == 'H')
    287  1.1  skrll 	{
    288  1.1  skrll 	  if (src[2] < '0' || src[2] > '9')
    289  1.1  skrll 	    return NULL;	/* Assume no register name but a label starting with 'rh'.  */
    290  1.1  skrll 	  *mode = CLASS_REG_BYTE;
    291  1.1  skrll 	  res = whatreg (reg, src + 2);
    292  1.1  skrll 	  if (res == NULL)
    293  1.1  skrll 	    return NULL;	/* Not a valid register name.  */
    294  1.1  skrll 	  regno = *reg;
    295  1.1  skrll 	  if (regno > 7)
    296  1.1  skrll 	    as_bad (_("register rh%d out of range"), regno);
    297  1.1  skrll 	}
    298  1.1  skrll       else if (src[1] == 'l' || src[1] == 'L')
    299  1.1  skrll 	{
    300  1.1  skrll 	  if (src[2] < '0' || src[2] > '9')
    301  1.1  skrll 	    return NULL;	/* Assume no register name but a label starting with 'rl'.  */
    302  1.1  skrll 	  *mode = CLASS_REG_BYTE;
    303  1.1  skrll 	  res = whatreg (reg, src + 2);
    304  1.1  skrll 	  if (res == NULL)
    305  1.1  skrll 	    return NULL;	/* Not a valid register name.  */
    306  1.1  skrll 	  regno = *reg;
    307  1.1  skrll 	  if (regno > 7)
    308  1.1  skrll 	    as_bad (_("register rl%d out of range"), regno);
    309  1.1  skrll 	  *reg += 8;
    310  1.1  skrll 	}
    311  1.1  skrll       else if (src[1] == 'q' || src[1] == 'Q')
    312  1.1  skrll 	{
    313  1.1  skrll 	  if (src[2] < '0' || src[2] > '9')
    314  1.1  skrll 	    return NULL;	/* Assume no register name but a label starting with 'rq'.  */
    315  1.1  skrll 	  *mode = CLASS_REG_QUAD;
    316  1.1  skrll 	  res = whatreg (reg, src + 2);
    317  1.1  skrll 	  if (res == NULL)
    318  1.1  skrll 	    return NULL;	/* Not a valid register name.  */
    319  1.1  skrll 	  regno = *reg;
    320  1.1  skrll 	  if (regno > 12)
    321  1.1  skrll 	    as_bad (_("register rq%d out of range"), regno);
    322  1.1  skrll 	  if (regno & 3)
    323  1.1  skrll 	    as_bad (_("register rq%d does not exist"), regno);
    324  1.1  skrll 	}
    325  1.1  skrll       else
    326  1.1  skrll 	{
    327  1.1  skrll 	  if (src[1] < '0' || src[1] > '9')
    328  1.1  skrll 	    return NULL;	/* Assume no register name but a label starting with 'r'.  */
    329  1.1  skrll 	  *mode = CLASS_REG_WORD;
    330  1.1  skrll 	  res = whatreg (reg, src + 1);
    331  1.1  skrll 	  if (res == NULL)
    332  1.1  skrll 	    return NULL;	/* Not a valid register name.  */
    333  1.1  skrll 	  regno = *reg;
    334  1.1  skrll 	  if (regno > 15)
    335  1.1  skrll 	    as_bad (_("register r%d out of range"), regno);
    336  1.1  skrll 	}
    337  1.1  skrll     }
    338  1.1  skrll   return res;
    339  1.1  skrll }
    340  1.1  skrll 
    341  1.1  skrll static char *
    342  1.1  skrll parse_exp (char *s, expressionS *op)
    343  1.1  skrll {
    344  1.1  skrll   char *save = input_line_pointer;
    345  1.1  skrll   char *new;
    346  1.1  skrll 
    347  1.1  skrll   input_line_pointer = s;
    348  1.1  skrll   expression (op);
    349  1.1  skrll   if (op->X_op == O_absent)
    350  1.1  skrll     as_bad (_("missing operand"));
    351  1.1  skrll   new = input_line_pointer;
    352  1.1  skrll   input_line_pointer = save;
    353  1.1  skrll   return new;
    354  1.1  skrll }
    355  1.1  skrll 
    356  1.1  skrll /* The many forms of operand:
    357  1.1  skrll 
    358  1.1  skrll    <rb>
    359  1.1  skrll    <r>
    360  1.1  skrll    <rr>
    361  1.1  skrll    <rq>
    362  1.1  skrll    @r
    363  1.1  skrll    #exp
    364  1.1  skrll    exp
    365  1.1  skrll    exp(r)
    366  1.1  skrll    r(#exp)
    367  1.1  skrll    r(r)
    368  1.1  skrll    */
    369  1.1  skrll 
    370  1.1  skrll static char *
    371  1.1  skrll checkfor (char *ptr, char what)
    372  1.1  skrll {
    373  1.1  skrll   if (*ptr == what)
    374  1.1  skrll     ptr++;
    375  1.1  skrll   else
    376  1.1  skrll     as_bad (_("expected %c"), what);
    377  1.1  skrll 
    378  1.1  skrll   return ptr;
    379  1.1  skrll }
    380  1.1  skrll 
    381  1.1  skrll /* Make sure the mode supplied is the size of a word.  */
    382  1.1  skrll 
    383  1.1  skrll static void
    384  1.1  skrll regword (int mode, char *string)
    385  1.1  skrll {
    386  1.1  skrll   int ok;
    387  1.1  skrll 
    388  1.1  skrll   ok = CLASS_REG_WORD;
    389  1.1  skrll   if (ok != mode)
    390  1.1  skrll     {
    391  1.1  skrll       as_bad (_("register is wrong size for a word %s"), string);
    392  1.1  skrll     }
    393  1.1  skrll }
    394  1.1  skrll 
    395  1.1  skrll /* Make sure the mode supplied is the size of an address.  */
    396  1.1  skrll 
    397  1.1  skrll static void
    398  1.1  skrll regaddr (int mode, char *string)
    399  1.1  skrll {
    400  1.1  skrll   int ok;
    401  1.1  skrll 
    402  1.1  skrll   ok = segmented_mode ? CLASS_REG_LONG : CLASS_REG_WORD;
    403  1.1  skrll   if (ok != mode)
    404  1.1  skrll     {
    405  1.1  skrll       as_bad (_("register is wrong size for address %s"), string);
    406  1.1  skrll     }
    407  1.1  skrll }
    408  1.1  skrll 
    409  1.1  skrll struct ctrl_names {
    410  1.1  skrll   int value;
    411  1.1  skrll   char *name;
    412  1.1  skrll };
    413  1.1  skrll 
    414  1.1  skrll static struct ctrl_names ctrl_table[] = {
    415  1.1  skrll   { 0x1, "flags" },   /* ldctlb only.  */
    416  1.1  skrll   { 0x2, "fcw" },     /* ldctl only.  Applies to all remaining control registers.  */
    417  1.1  skrll   { 0x3, "refresh" },
    418  1.1  skrll   { 0x4, "psapseg" },
    419  1.1  skrll   { 0x5, "psapoff" },
    420  1.1  skrll   { 0x5, "psap" },
    421  1.1  skrll   { 0x6, "nspseg" },
    422  1.1  skrll   { 0x7, "nspoff" },
    423  1.1  skrll   { 0x7, "nsp" },
    424  1.1  skrll   { 0  , 0 }
    425  1.1  skrll };
    426  1.1  skrll 
    427  1.1  skrll static void
    428  1.1  skrll get_ctrl_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
    429  1.1  skrll {
    430  1.1  skrll   char *src = *ptr;
    431  1.1  skrll   int i, l;
    432  1.1  skrll 
    433  1.1  skrll   while (*src == ' ')
    434  1.1  skrll     src++;
    435  1.1  skrll 
    436  1.1  skrll   mode->mode = CLASS_CTRL;
    437  1.1  skrll   for (i = 0; ctrl_table[i].name; i++)
    438  1.1  skrll     {
    439  1.1  skrll       l = strlen (ctrl_table[i].name);
    440  1.1  skrll       if (! strncasecmp (ctrl_table[i].name, src, l))
    441  1.1  skrll         {
    442  1.1  skrll           the_ctrl = ctrl_table[i].value;
    443  1.1  skrll           if (*(src + l) && *(src + l) != ',')
    444  1.1  skrll             break;
    445  1.1  skrll           *ptr = src + l;  /* Valid control name found: "consume" it.  */
    446  1.1  skrll           return;
    447  1.1  skrll         }
    448  1.1  skrll     }
    449  1.1  skrll   the_ctrl = 0;
    450  1.1  skrll }
    451  1.1  skrll 
    452  1.1  skrll struct flag_names {
    453  1.1  skrll   int value;
    454  1.1  skrll   char *name;
    455  1.1  skrll };
    456  1.1  skrll 
    457  1.1  skrll static struct flag_names flag_table[] = {
    458  1.1  skrll   { 0x1, "P" },
    459  1.1  skrll   { 0x1, "V" },
    460  1.1  skrll   { 0x2, "S" },
    461  1.1  skrll   { 0x4, "Z" },
    462  1.1  skrll   { 0x8, "C" },
    463  1.1  skrll   { 0x0, "+" },
    464  1.1  skrll   { 0x0, "," },
    465  1.1  skrll   { 0, 0 }
    466  1.1  skrll };
    467  1.1  skrll 
    468  1.1  skrll static void
    469  1.1  skrll get_flags_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
    470  1.1  skrll {
    471  1.1  skrll   char *src = *ptr;
    472  1.1  skrll   char c;
    473  1.1  skrll   int i;
    474  1.1  skrll   int j;
    475  1.1  skrll 
    476  1.1  skrll   while (*src == ' ')
    477  1.1  skrll     src++;
    478  1.1  skrll 
    479  1.1  skrll   mode->mode = CLASS_FLAGS;
    480  1.1  skrll   the_flags = 0;
    481  1.1  skrll   for (j = 0; j <= 9; j++)
    482  1.1  skrll     {
    483  1.1  skrll       if (!src[j])
    484  1.1  skrll 	goto done;
    485  1.1  skrll       c = TOUPPER(src[j]);
    486  1.1  skrll       for (i = 0; flag_table[i].name; i++)
    487  1.1  skrll 	{
    488  1.1  skrll 	  if (flag_table[i].name[0] == c)
    489  1.1  skrll 	    {
    490  1.1  skrll 	      the_flags = the_flags | flag_table[i].value;
    491  1.1  skrll 	      goto match;
    492  1.1  skrll 	    }
    493  1.1  skrll 	}
    494  1.1  skrll       goto done;
    495  1.1  skrll     match:
    496  1.1  skrll       ;
    497  1.1  skrll     }
    498  1.1  skrll  done:
    499  1.1  skrll   *ptr = src + j;
    500  1.1  skrll }
    501  1.1  skrll 
    502  1.1  skrll struct interrupt_names {
    503  1.1  skrll   int value;
    504  1.1  skrll   char *name;
    505  1.1  skrll };
    506  1.1  skrll 
    507  1.1  skrll static struct interrupt_names intr_table[] = {
    508  1.1  skrll   { 0x1, "nvi" },
    509  1.1  skrll   { 0x2, "vi" },
    510  1.1  skrll   { 0x3, "both" },
    511  1.1  skrll   { 0x3, "all" },
    512  1.1  skrll   { 0, 0 }
    513  1.1  skrll };
    514  1.1  skrll 
    515  1.1  skrll static void
    516  1.1  skrll get_interrupt_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
    517  1.1  skrll {
    518  1.1  skrll   char *src = *ptr;
    519  1.1  skrll   int i, l;
    520  1.1  skrll 
    521  1.1  skrll   while (*src == ' ')
    522  1.1  skrll     src++;
    523  1.1  skrll 
    524  1.1  skrll   mode->mode = CLASS_IMM;
    525  1.1  skrll   the_interrupt = 0;
    526  1.1  skrll 
    527  1.1  skrll   while (*src)
    528  1.1  skrll     {
    529  1.1  skrll       for (i = 0; intr_table[i].name; i++)
    530  1.1  skrll 	{
    531  1.1  skrll 	  l = strlen (intr_table[i].name);
    532  1.1  skrll 	  if (! strncasecmp (intr_table[i].name, src, l))
    533  1.1  skrll 	    {
    534  1.1  skrll 	      the_interrupt |= intr_table[i].value;
    535  1.1  skrll 	      if (*(src + l) && *(src + l) != ',')
    536  1.1  skrll 		{
    537  1.1  skrll 		  *ptr = src + l;
    538  1.1  skrll 		invalid:
    539  1.1  skrll 		  as_bad (_("unknown interrupt %s"), src);
    540  1.1  skrll 		  while (**ptr && ! is_end_of_line[(unsigned char) **ptr])
    541  1.1  skrll 		    (*ptr)++;	 /* Consume rest of line.  */
    542  1.1  skrll 		  return;
    543  1.1  skrll 		}
    544  1.1  skrll 	      src += l;
    545  1.1  skrll 	      if (! *src)
    546  1.1  skrll 		{
    547  1.1  skrll 		  *ptr = src;
    548  1.1  skrll 		  return;
    549  1.1  skrll 		}
    550  1.1  skrll 	    }
    551  1.1  skrll 	}
    552  1.1  skrll       if (*src == ',')
    553  1.1  skrll 	src++;
    554  1.1  skrll       else
    555  1.1  skrll 	{
    556  1.1  skrll 	  *ptr = src;
    557  1.1  skrll 	  goto invalid;
    558  1.1  skrll 	}
    559  1.1  skrll     }
    560  1.1  skrll 
    561  1.1  skrll   /* No interrupt type specified, opcode won't do anything.  */
    562  1.1  skrll   as_warn (_("opcode has no effect"));
    563  1.1  skrll   the_interrupt = 0x0;
    564  1.1  skrll }
    565  1.1  skrll 
    566  1.1  skrll struct cc_names {
    567  1.1  skrll   int value;
    568  1.1  skrll   char *name;
    569  1.1  skrll };
    570  1.1  skrll 
    571  1.1  skrll static struct cc_names table[] = {
    572  1.1  skrll   { 0x0, "f" },
    573  1.1  skrll   { 0x1, "lt" },
    574  1.1  skrll   { 0x2, "le" },
    575  1.1  skrll   { 0x3, "ule" },
    576  1.1  skrll   { 0x4, "ov/pe" },
    577  1.1  skrll   { 0x4, "ov" },
    578  1.1  skrll   { 0x4, "pe/ov" },
    579  1.1  skrll   { 0x4, "pe" },
    580  1.1  skrll   { 0x5, "mi" },
    581  1.1  skrll   { 0x6, "eq" },
    582  1.1  skrll   { 0x6, "z" },
    583  1.1  skrll   { 0x7, "c/ult" },
    584  1.1  skrll   { 0x7, "c" },
    585  1.1  skrll   { 0x7, "ult/c" },
    586  1.1  skrll   { 0x7, "ult" },
    587  1.1  skrll   { 0x8, "t" },
    588  1.1  skrll   { 0x9, "ge" },
    589  1.1  skrll   { 0xa, "gt" },
    590  1.1  skrll   { 0xb, "ugt" },
    591  1.1  skrll   { 0xc, "nov/po" },
    592  1.1  skrll   { 0xc, "nov" },
    593  1.1  skrll   { 0xc, "po/nov" },
    594  1.1  skrll   { 0xc, "po" },
    595  1.1  skrll   { 0xd, "pl" },
    596  1.1  skrll   { 0xe, "ne" },
    597  1.1  skrll   { 0xe, "nz" },
    598  1.1  skrll   { 0xf, "nc/uge" },
    599  1.1  skrll   { 0xf, "nc" },
    600  1.1  skrll   { 0xf, "uge/nc" },
    601  1.1  skrll   { 0xf, "uge" },
    602  1.1  skrll   { 0  ,  0 }
    603  1.1  skrll };
    604  1.1  skrll 
    605  1.1  skrll static void
    606  1.1  skrll get_cc_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
    607  1.1  skrll {
    608  1.1  skrll   char *src = *ptr;
    609  1.1  skrll   int i, l;
    610  1.1  skrll 
    611  1.1  skrll   while (*src == ' ')
    612  1.1  skrll     src++;
    613  1.1  skrll 
    614  1.1  skrll   mode->mode = CLASS_CC;
    615  1.1  skrll   for (i = 0; table[i].name; i++)
    616  1.1  skrll     {
    617  1.1  skrll       l = strlen (table[i].name);
    618  1.1  skrll       if (! strncasecmp (table[i].name, src, l))
    619  1.1  skrll         {
    620  1.1  skrll           the_cc = table[i].value;
    621  1.1  skrll           if (*(src + l) && *(src + l) != ',')
    622  1.1  skrll             break;
    623  1.1  skrll           *ptr = src + l;  /* Valid cc found: "consume" it.  */
    624  1.1  skrll           return;
    625  1.1  skrll         }
    626  1.1  skrll     }
    627  1.1  skrll   the_cc = 0x8;  /* Not recognizing the cc defaults to t.  (Assuming no cc present.)  */
    628  1.1  skrll }
    629  1.1  skrll 
    630  1.1  skrll static void
    631  1.1  skrll get_operand (char **ptr, struct z8k_op *mode, unsigned int dst ATTRIBUTE_UNUSED)
    632  1.1  skrll {
    633  1.1  skrll   char *src = *ptr;
    634  1.1  skrll   char *end;
    635  1.1  skrll 
    636  1.1  skrll   mode->mode = 0;
    637  1.1  skrll 
    638  1.1  skrll   while (*src == ' ')
    639  1.1  skrll     src++;
    640  1.1  skrll   if (*src == '#')
    641  1.1  skrll     {
    642  1.1  skrll       mode->mode = CLASS_IMM;
    643  1.1  skrll       imm_operand = &(mode->exp);
    644  1.1  skrll       src = parse_exp (src + 1, &(mode->exp));
    645  1.1  skrll     }
    646  1.1  skrll   else if (*src == '@')
    647  1.1  skrll     {
    648  1.1  skrll       mode->mode = CLASS_IR;
    649  1.1  skrll       src = parse_reg (src + 1, &mode->regsize, &mode->reg);
    650  1.1  skrll     }
    651  1.1  skrll   else
    652  1.1  skrll     {
    653  1.1  skrll       unsigned int regn;
    654  1.1  skrll 
    655  1.1  skrll       end = parse_reg (src, &mode->mode, &regn);
    656  1.1  skrll 
    657  1.1  skrll       if (end)
    658  1.1  skrll 	{
    659  1.1  skrll 	  int nw;
    660  1.1  skrll 	  unsigned int nr;
    661  1.1  skrll 
    662  1.1  skrll 	  src = end;
    663  1.1  skrll 	  if (*src == '(')
    664  1.1  skrll 	    {
    665  1.1  skrll 	      src++;
    666  1.1  skrll 	      end = parse_reg (src, &nw, &nr);
    667  1.1  skrll 	      if (end)
    668  1.1  skrll 		{
    669  1.1  skrll 		  /* Got Ra(Rb).  */
    670  1.1  skrll 		  src = end;
    671  1.1  skrll 
    672  1.1  skrll 		  if (*src != ')')
    673  1.1  skrll 		    as_bad (_("Missing ) in ra(rb)"));
    674  1.1  skrll 		  else
    675  1.1  skrll 		    src++;
    676  1.1  skrll 
    677  1.1  skrll 		  regaddr (mode->mode, "ra(rb) ra");
    678  1.1  skrll 		  mode->mode = CLASS_BX;
    679  1.1  skrll 		  mode->reg = regn;
    680  1.1  skrll 		  mode->x_reg = nr;
    681  1.1  skrll 		  reg[ARG_RX] = nr;
    682  1.1  skrll 		}
    683  1.1  skrll 	      else
    684  1.1  skrll 		{
    685  1.1  skrll 		  /* Got Ra(disp).  */
    686  1.1  skrll 		  if (*src == '#')
    687  1.1  skrll 		    src++;
    688  1.1  skrll 		  src = parse_exp (src, &(mode->exp));
    689  1.1  skrll 		  src = checkfor (src, ')');
    690  1.1  skrll 		  mode->mode = CLASS_BA;
    691  1.1  skrll 		  mode->reg = regn;
    692  1.1  skrll 		  mode->x_reg = 0;
    693  1.1  skrll 		  imm_operand = &(mode->exp);
    694  1.1  skrll 		}
    695  1.1  skrll 	    }
    696  1.1  skrll 	  else
    697  1.1  skrll 	    {
    698  1.1  skrll 	      mode->reg = regn;
    699  1.1  skrll 	      mode->x_reg = 0;
    700  1.1  skrll 	    }
    701  1.1  skrll 	}
    702  1.1  skrll       else
    703  1.1  skrll 	{
    704  1.1  skrll 	  /* No initial reg.  */
    705  1.1  skrll 	  src = parse_exp (src, &(mode->exp));
    706  1.1  skrll 	  if (*src == '(')
    707  1.1  skrll 	    {
    708  1.1  skrll 	      src++;
    709  1.1  skrll 	      end = parse_reg (src, &(mode->mode), &regn);
    710  1.1  skrll 	      regword (mode->mode, "addr(Ra) ra");
    711  1.1  skrll 	      mode->mode = CLASS_X;
    712  1.1  skrll 	      mode->reg = regn;
    713  1.1  skrll 	      mode->x_reg = 0;
    714  1.1  skrll 	      da_operand = &(mode->exp);
    715  1.1  skrll 	      src = checkfor (end, ')');
    716  1.1  skrll 	    }
    717  1.1  skrll 	  else
    718  1.1  skrll 	    {
    719  1.1  skrll 	      /* Just an address.  */
    720  1.1  skrll 	      mode->mode = CLASS_DA;
    721  1.1  skrll 	      mode->reg = 0;
    722  1.1  skrll 	      mode->x_reg = 0;
    723  1.1  skrll 	      da_operand = &(mode->exp);
    724  1.1  skrll 	    }
    725  1.1  skrll 	}
    726  1.1  skrll     }
    727  1.1  skrll   *ptr = src;
    728  1.1  skrll }
    729  1.1  skrll 
    730  1.1  skrll static char *
    731  1.1  skrll get_operands (const opcode_entry_type *opcode, char *op_end, op_type *operand)
    732  1.1  skrll {
    733  1.1  skrll   char *ptr = op_end;
    734  1.1  skrll   char *savptr;
    735  1.1  skrll 
    736  1.1  skrll   switch (opcode->noperands)
    737  1.1  skrll     {
    738  1.1  skrll     case 0:
    739  1.1  skrll       operand[0].mode = 0;
    740  1.1  skrll       operand[1].mode = 0;
    741  1.1  skrll       while (*ptr == ' ')
    742  1.1  skrll         ptr++;
    743  1.1  skrll       break;
    744  1.1  skrll 
    745  1.1  skrll     case 1:
    746  1.1  skrll       if (opcode->arg_info[0] == CLASS_CC)
    747  1.1  skrll         {
    748  1.1  skrll           get_cc_operand (&ptr, operand + 0, 0);
    749  1.1  skrll           while (*ptr == ' ')
    750  1.1  skrll             ptr++;
    751  1.1  skrll           if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
    752  1.1  skrll             {
    753  1.1  skrll               as_bad (_("invalid condition code '%s'"), ptr);
    754  1.1  skrll               while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
    755  1.1  skrll                 ptr++;   /* Consume rest of line.  */
    756  1.1  skrll             }
    757  1.1  skrll         }
    758  1.1  skrll       else if (opcode->arg_info[0] == CLASS_FLAGS)
    759  1.1  skrll 	{
    760  1.1  skrll 	  get_flags_operand (&ptr, operand + 0, 0);
    761  1.1  skrll 	  while (*ptr == ' ')
    762  1.1  skrll 	    ptr++;
    763  1.1  skrll 	  if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
    764  1.1  skrll 	    {
    765  1.1  skrll 	      as_bad (_("invalid flag '%s'"), ptr);
    766  1.1  skrll 	      while (*ptr && ! is_end_of_line[(unsigned char) *ptr])
    767  1.1  skrll 		ptr++;	 /* Consume rest of line.  */
    768  1.1  skrll 	    }
    769  1.1  skrll 	}
    770  1.1  skrll       else if (opcode->arg_info[0] == (CLASS_IMM + (ARG_IMM2)))
    771  1.1  skrll 	get_interrupt_operand (&ptr, operand + 0, 0);
    772  1.1  skrll       else
    773  1.1  skrll 	get_operand (&ptr, operand + 0, 0);
    774  1.1  skrll 
    775  1.1  skrll       operand[1].mode = 0;
    776  1.1  skrll       break;
    777  1.1  skrll 
    778  1.1  skrll     case 2:
    779  1.1  skrll       savptr = ptr;
    780  1.1  skrll       if (opcode->arg_info[0] == CLASS_CC)
    781  1.1  skrll         {
    782  1.1  skrll           get_cc_operand (&ptr, operand + 0, 0);
    783  1.1  skrll           while (*ptr == ' ')
    784  1.1  skrll             ptr++;
    785  1.1  skrll           if (*ptr != ',' && strchr (ptr + 1, ','))
    786  1.1  skrll             {
    787  1.1  skrll               savptr = ptr;
    788  1.1  skrll               while (*ptr != ',')
    789  1.1  skrll                 ptr++;
    790  1.1  skrll               *ptr = 0;
    791  1.1  skrll               ptr++;
    792  1.1  skrll               as_bad (_("invalid condition code '%s'"), savptr);
    793  1.1  skrll             }
    794  1.1  skrll         }
    795  1.1  skrll       else if (opcode->arg_info[0] == CLASS_CTRL)
    796  1.1  skrll 	{
    797  1.1  skrll 	  get_ctrl_operand (&ptr, operand + 0, 0);
    798  1.1  skrll 
    799  1.1  skrll 	  if (the_ctrl == 0)
    800  1.1  skrll 	    {
    801  1.1  skrll 	      ptr = savptr;
    802  1.1  skrll 	      get_operand (&ptr, operand + 0, 0);
    803  1.1  skrll 
    804  1.1  skrll 	      if (ptr == 0)
    805  1.1  skrll 		return NULL;
    806  1.1  skrll 	      if (*ptr == ',')
    807  1.1  skrll 		ptr++;
    808  1.1  skrll 	      get_ctrl_operand (&ptr, operand + 1, 1);
    809  1.1  skrll 	      if (the_ctrl == 0)
    810  1.1  skrll 		return NULL;
    811  1.1  skrll 	      return ptr;
    812  1.1  skrll 	    }
    813  1.1  skrll 	}
    814  1.1  skrll       else
    815  1.1  skrll 	get_operand (&ptr, operand + 0, 0);
    816  1.1  skrll 
    817  1.1  skrll       if (ptr == 0)
    818  1.1  skrll 	return NULL;
    819  1.1  skrll       if (*ptr == ',')
    820  1.1  skrll 	ptr++;
    821  1.1  skrll       get_operand (&ptr, operand + 1, 1);
    822  1.1  skrll       break;
    823  1.1  skrll 
    824  1.1  skrll     case 3:
    825  1.1  skrll       get_operand (&ptr, operand + 0, 0);
    826  1.1  skrll       if (*ptr == ',')
    827  1.1  skrll 	ptr++;
    828  1.1  skrll       get_operand (&ptr, operand + 1, 1);
    829  1.1  skrll       if (*ptr == ',')
    830  1.1  skrll 	ptr++;
    831  1.1  skrll       get_operand (&ptr, operand + 2, 2);
    832  1.1  skrll       break;
    833  1.1  skrll 
    834  1.1  skrll     case 4:
    835  1.1  skrll       get_operand (&ptr, operand + 0, 0);
    836  1.1  skrll       if (*ptr == ',')
    837  1.1  skrll 	ptr++;
    838  1.1  skrll       get_operand (&ptr, operand + 1, 1);
    839  1.1  skrll       if (*ptr == ',')
    840  1.1  skrll 	ptr++;
    841  1.1  skrll       get_operand (&ptr, operand + 2, 2);
    842  1.1  skrll       if (*ptr == ',')
    843  1.1  skrll 	ptr++;
    844  1.1  skrll       get_cc_operand (&ptr, operand + 3, 3);
    845  1.1  skrll       break;
    846  1.1  skrll 
    847  1.1  skrll     default:
    848  1.1  skrll       abort ();
    849  1.1  skrll     }
    850  1.1  skrll 
    851  1.1  skrll   return ptr;
    852  1.1  skrll }
    853  1.1  skrll 
    854  1.1  skrll /* Passed a pointer to a list of opcodes which use different
    855  1.1  skrll    addressing modes.  Return the opcode which matches the opcodes
    856  1.1  skrll    provided.  */
    857  1.1  skrll 
    858  1.1  skrll static opcode_entry_type *
    859  1.1  skrll get_specific (opcode_entry_type *opcode, op_type *operands)
    860  1.1  skrll {
    861  1.1  skrll   opcode_entry_type *this_try = opcode;
    862  1.1  skrll   int found = 0;
    863  1.1  skrll   unsigned int noperands = opcode->noperands;
    864  1.1  skrll 
    865  1.1  skrll   int this_index = opcode->idx;
    866  1.1  skrll 
    867  1.1  skrll   while (this_index == opcode->idx && !found)
    868  1.1  skrll     {
    869  1.1  skrll       unsigned int i;
    870  1.1  skrll 
    871  1.1  skrll       this_try = opcode++;
    872  1.1  skrll       for (i = 0; i < noperands; i++)
    873  1.1  skrll 	{
    874  1.1  skrll 	  unsigned int mode = operands[i].mode;
    875  1.1  skrll 
    876  1.1  skrll           if (((mode & CLASS_MASK) == CLASS_IR) && ((this_try->arg_info[i] & CLASS_MASK) == CLASS_IRO))
    877  1.1  skrll             {
    878  1.1  skrll               mode = operands[i].mode = (operands[i].mode & ~CLASS_MASK) | CLASS_IRO;
    879  1.1  skrll             }
    880  1.1  skrll 
    881  1.1  skrll 	  if ((mode & CLASS_MASK) != (this_try->arg_info[i] & CLASS_MASK))
    882  1.1  skrll 	    {
    883  1.1  skrll 	      /* It could be a pc rel operand, if this is a da mode
    884  1.1  skrll 		 and we like disps, then insert it.  */
    885  1.1  skrll 
    886  1.1  skrll 	      if (mode == CLASS_DA && this_try->arg_info[i] == CLASS_DISP)
    887  1.1  skrll 		{
    888  1.1  skrll 		  /* This is the case.  */
    889  1.1  skrll 		  operands[i].mode = CLASS_DISP;
    890  1.1  skrll 		}
    891  1.1  skrll 	      else if (mode == CLASS_BA && this_try->arg_info[i])
    892  1.1  skrll 		{
    893  1.1  skrll 		  /* Can't think of a way to turn what we've been
    894  1.1  skrll 		     given into something that's OK.  */
    895  1.1  skrll 		  goto fail;
    896  1.1  skrll 		}
    897  1.1  skrll 	      else if (this_try->arg_info[i] & CLASS_PR)
    898  1.1  skrll 		{
    899  1.1  skrll 		  if (mode == CLASS_REG_LONG && segmented_mode)
    900  1.1  skrll 		    {
    901  1.1  skrll 		      /* OK.  */
    902  1.1  skrll 		    }
    903  1.1  skrll 		  else if (mode == CLASS_REG_WORD && !segmented_mode)
    904  1.1  skrll 		    {
    905  1.1  skrll 		      /* OK.  */
    906  1.1  skrll 		    }
    907  1.1  skrll 		  else
    908  1.1  skrll 		    goto fail;
    909  1.1  skrll 		}
    910  1.1  skrll 	      else
    911  1.1  skrll 		goto fail;
    912  1.1  skrll 	    }
    913  1.1  skrll 	  switch (mode & CLASS_MASK)
    914  1.1  skrll 	    {
    915  1.1  skrll 	    default:
    916  1.1  skrll 	      break;
    917  1.1  skrll 	    case CLASS_IRO:
    918  1.1  skrll 	      if (operands[i].regsize != CLASS_REG_WORD)
    919  1.1  skrll 		as_bad (_("invalid indirect register size"));
    920  1.1  skrll 	      reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
    921  1.1  skrll 	      break;
    922  1.1  skrll 	    case CLASS_IR:
    923  1.1  skrll 	      if ((segmented_mode && operands[i].regsize != CLASS_REG_LONG)
    924  1.1  skrll 		  || (!segmented_mode && operands[i].regsize != CLASS_REG_WORD))
    925  1.1  skrll 		as_bad (_("invalid indirect register size"));
    926  1.1  skrll 	      reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
    927  1.1  skrll 	      break;
    928  1.1  skrll 	    case CLASS_X:
    929  1.1  skrll 	    case CLASS_BA:
    930  1.1  skrll 	    case CLASS_BX:
    931  1.1  skrll 	    case CLASS_DISP:
    932  1.1  skrll 	    case CLASS_REG:
    933  1.1  skrll 	    case CLASS_REG_WORD:
    934  1.1  skrll 	    case CLASS_REG_BYTE:
    935  1.1  skrll 	    case CLASS_REG_QUAD:
    936  1.1  skrll 	    case CLASS_REG_LONG:
    937  1.1  skrll 	    case CLASS_REGN0:
    938  1.1  skrll 	      reg[this_try->arg_info[i] & ARG_MASK] = operands[i].reg;
    939  1.1  skrll 	      break;
    940  1.1  skrll 	    case CLASS_CTRL:
    941  1.1  skrll 	      if (this_try->opcode == OPC_ldctlb && the_ctrl != 1)
    942  1.1  skrll 		as_bad (_("invalid control register name"));
    943  1.1  skrll 	      break;
    944  1.1  skrll 	    }
    945  1.1  skrll 	}
    946  1.1  skrll 
    947  1.1  skrll       found = 1;
    948  1.1  skrll     fail:
    949  1.1  skrll       ;
    950  1.1  skrll     }
    951  1.1  skrll   if (found)
    952  1.1  skrll     return this_try;
    953  1.1  skrll   else
    954  1.1  skrll     return 0;
    955  1.1  skrll }
    956  1.1  skrll 
    957  1.1  skrll static char buffer[20];
    958  1.1  skrll 
    959  1.1  skrll static void
    960  1.1  skrll newfix (int ptr, int type, int size, expressionS *operand)
    961  1.1  skrll {
    962  1.1  skrll   int is_pcrel = 0;
    963  1.1  skrll   fixS *fixP;
    964  1.1  skrll 
    965  1.1  skrll   /* Size is in nibbles.  */
    966  1.1  skrll   if (operand->X_add_symbol
    967  1.1  skrll       || operand->X_op_symbol
    968  1.1  skrll       || operand->X_add_number)
    969  1.1  skrll     {
    970  1.1  skrll       switch(type)
    971  1.1  skrll         {
    972  1.1  skrll         case BFD_RELOC_8_PCREL:
    973  1.1  skrll         case BFD_RELOC_Z8K_CALLR:
    974  1.1  skrll         case BFD_RELOC_Z8K_DISP7:
    975  1.1  skrll           is_pcrel = 1;
    976  1.1  skrll         }
    977  1.1  skrll       fixP = fix_new_exp (frag_now, ptr, size / 2,
    978  1.1  skrll                           operand, is_pcrel, type);
    979  1.1  skrll       if (is_pcrel)
    980  1.1  skrll 	fixP->fx_no_overflow = 1;
    981  1.1  skrll     }
    982  1.1  skrll }
    983  1.1  skrll 
    984  1.1  skrll static char *
    985  1.1  skrll apply_fix (char *ptr, int type, expressionS *operand, int size)
    986  1.1  skrll {
    987  1.1  skrll   long n = operand->X_add_number;
    988  1.1  skrll 
    989  1.1  skrll   /* size is in nibbles.  */
    990  1.1  skrll 
    991  1.1  skrll   newfix ((ptr - buffer) / 2, type, size + 1, operand);
    992  1.1  skrll   switch (size)
    993  1.1  skrll     {
    994  1.1  skrll     case 8:			/* 8 nibbles == 32 bits.  */
    995  1.1  skrll       *ptr++ = n >> 28;
    996  1.1  skrll       *ptr++ = n >> 24;
    997  1.1  skrll       *ptr++ = n >> 20;
    998  1.1  skrll       *ptr++ = n >> 16;
    999  1.1  skrll     case 4:			/* 4 nibbles == 16 bits.  */
   1000  1.1  skrll       *ptr++ = n >> 12;
   1001  1.1  skrll       *ptr++ = n >> 8;
   1002  1.1  skrll     case 2:
   1003  1.1  skrll       *ptr++ = n >> 4;
   1004  1.1  skrll     case 1:
   1005  1.1  skrll       *ptr++ = n >> 0;
   1006  1.1  skrll       break;
   1007  1.1  skrll     }
   1008  1.1  skrll   return ptr;
   1009  1.1  skrll }
   1010  1.1  skrll 
   1011  1.1  skrll /* Now we know what sort of opcodes it is.  Let's build the bytes.  */
   1012  1.1  skrll 
   1013  1.1  skrll static void
   1014  1.1  skrll build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED)
   1015  1.1  skrll {
   1016  1.1  skrll   char *output_ptr = buffer;
   1017  1.1  skrll   int c;
   1018  1.1  skrll   int nibble;
   1019  1.1  skrll   unsigned int *class_ptr;
   1020  1.1  skrll 
   1021  1.1  skrll   frag_wane (frag_now);
   1022  1.1  skrll   frag_new (0);
   1023  1.1  skrll 
   1024  1.1  skrll   if (frag_room () < 8)
   1025  1.1  skrll     frag_grow (8);  /* Make room for maximum instruction size.  */
   1026  1.1  skrll 
   1027  1.1  skrll   memset (buffer, 0, sizeof (buffer));
   1028  1.1  skrll   class_ptr = this_try->byte_info;
   1029  1.1  skrll 
   1030  1.1  skrll   for (nibble = 0; (c = *class_ptr++); nibble++)
   1031  1.1  skrll     {
   1032  1.1  skrll 
   1033  1.1  skrll       switch (c & CLASS_MASK)
   1034  1.1  skrll 	{
   1035  1.1  skrll 	default:
   1036  1.1  skrll 	  abort ();
   1037  1.1  skrll 
   1038  1.1  skrll 	case CLASS_ADDRESS:
   1039  1.1  skrll 	  /* Direct address, we don't cope with the SS mode right now.  */
   1040  1.1  skrll 	  if (segmented_mode)
   1041  1.1  skrll 	    {
   1042  1.1  skrll 	      /* da_operand->X_add_number |= 0x80000000;  --  Now set at relocation time.  */
   1043  1.1  skrll 	      output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8);
   1044  1.1  skrll 	    }
   1045  1.1  skrll 	  else
   1046  1.1  skrll 	    {
   1047  1.1  skrll 	      output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
   1048  1.1  skrll 	    }
   1049  1.1  skrll 	  da_operand = 0;
   1050  1.1  skrll 	  break;
   1051  1.1  skrll 	case CLASS_DISP8:
   1052  1.1  skrll 	  /* pc rel 8 bit  */
   1053  1.1  skrll 	  output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2);
   1054  1.1  skrll 	  da_operand = 0;
   1055  1.1  skrll 	  break;
   1056  1.1  skrll 
   1057  1.1  skrll 	case CLASS_0DISP7:
   1058  1.1  skrll 	  /* pc rel 7 bit  */
   1059  1.1  skrll 	  *output_ptr = 0;
   1060  1.1  skrll 	  output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
   1061  1.1  skrll 	  da_operand = 0;
   1062  1.1  skrll 	  break;
   1063  1.1  skrll 
   1064  1.1  skrll 	case CLASS_1DISP7:
   1065  1.1  skrll 	  /* pc rel 7 bit  */
   1066  1.1  skrll 	  *output_ptr = 0x80;
   1067  1.1  skrll 	  output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
   1068  1.1  skrll 	  output_ptr[-2] = 0x8;
   1069  1.1  skrll 	  da_operand = 0;
   1070  1.1  skrll 	  break;
   1071  1.1  skrll 
   1072  1.1  skrll 	case CLASS_BIT_1OR2:
   1073  1.1  skrll 	  *output_ptr = c & 0xf;
   1074  1.1  skrll 	  if (imm_operand)
   1075  1.1  skrll 	    {
   1076  1.1  skrll 	      if (imm_operand->X_add_number == 2)
   1077  1.1  skrll 		*output_ptr |= 2;
   1078  1.1  skrll 	      else if (imm_operand->X_add_number != 1)
   1079  1.1  skrll 		as_bad (_("immediate must be 1 or 2"));
   1080  1.1  skrll 	    }
   1081  1.1  skrll 	  else
   1082  1.1  skrll 	    as_bad (_("immediate 1 or 2 expected"));
   1083  1.1  skrll 	  output_ptr++;
   1084  1.1  skrll 	  break;
   1085  1.1  skrll 	case CLASS_CC:
   1086  1.1  skrll 	  *output_ptr++ = the_cc;
   1087  1.1  skrll 	  break;
   1088  1.1  skrll 	case CLASS_0CCC:
   1089  1.1  skrll 	  if (the_ctrl < 2 || the_ctrl > 7)
   1090  1.1  skrll 	    as_bad (_("invalid control register name"));
   1091  1.1  skrll 	  *output_ptr++ = the_ctrl;
   1092  1.1  skrll 	  break;
   1093  1.1  skrll 	case CLASS_1CCC:
   1094  1.1  skrll 	  if (the_ctrl < 2 || the_ctrl > 7)
   1095  1.1  skrll 	    as_bad (_("invalid control register name"));
   1096  1.1  skrll 	  *output_ptr++ = the_ctrl | 0x8;
   1097  1.1  skrll 	  break;
   1098  1.1  skrll 	case CLASS_00II:
   1099  1.1  skrll 	  *output_ptr++ = (~the_interrupt & 0x3);
   1100  1.1  skrll 	  break;
   1101  1.1  skrll 	case CLASS_01II:
   1102  1.1  skrll 	  *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
   1103  1.1  skrll 	  break;
   1104  1.1  skrll 	case CLASS_FLAGS:
   1105  1.1  skrll 	  *output_ptr++ = the_flags;
   1106  1.1  skrll 	  break;
   1107  1.1  skrll 	case CLASS_IGNORE:
   1108  1.1  skrll 	case CLASS_BIT:
   1109  1.1  skrll 	  *output_ptr++ = c & 0xf;
   1110  1.1  skrll 	  break;
   1111  1.1  skrll 	case CLASS_REGN0:
   1112  1.1  skrll 	  if (reg[c & 0xf] == 0)
   1113  1.1  skrll 	    as_bad (_("can't use R0 here"));
   1114  1.1  skrll 	  /* Fall through.  */
   1115  1.1  skrll 	case CLASS_REG:
   1116  1.1  skrll 	case CLASS_REG_BYTE:
   1117  1.1  skrll 	case CLASS_REG_WORD:
   1118  1.1  skrll 	case CLASS_REG_LONG:
   1119  1.1  skrll 	case CLASS_REG_QUAD:
   1120  1.1  skrll 	  /* Insert bit mattern of right reg.  */
   1121  1.1  skrll 	  *output_ptr++ = reg[c & 0xf];
   1122  1.1  skrll 	  break;
   1123  1.1  skrll 	case CLASS_DISP:
   1124  1.1  skrll           switch (c & ARG_MASK)
   1125  1.1  skrll             {
   1126  1.1  skrll             case ARG_DISP12:
   1127  1.1  skrll               output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4);
   1128  1.1  skrll               break;
   1129  1.1  skrll             case ARG_DISP16:
   1130  1.1  skrll 	      output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4);
   1131  1.1  skrll 	      break;
   1132  1.1  skrll 	    default:
   1133  1.1  skrll 	      output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
   1134  1.1  skrll 	    }
   1135  1.1  skrll 	  da_operand = 0;
   1136  1.1  skrll 	  break;
   1137  1.1  skrll 
   1138  1.1  skrll 	case CLASS_IMM:
   1139  1.1  skrll 	  {
   1140  1.1  skrll 	    switch (c & ARG_MASK)
   1141  1.1  skrll 	      {
   1142  1.1  skrll 	      case ARG_NIM4:
   1143  1.1  skrll                 if (imm_operand->X_add_number > 15)
   1144  1.1  skrll 		  as_bad (_("immediate value out of range"));
   1145  1.1  skrll 		imm_operand->X_add_number = -imm_operand->X_add_number;
   1146  1.1  skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
   1147  1.1  skrll 		break;
   1148  1.1  skrll               /*case ARG_IMMNMINUS1: not used.  */
   1149  1.1  skrll 	      case ARG_IMM4M1:
   1150  1.1  skrll 		imm_operand->X_add_number--;
   1151  1.1  skrll                 /* Drop through.  */
   1152  1.1  skrll 	      case ARG_IMM4:
   1153  1.1  skrll                 if (imm_operand->X_add_number > 15)
   1154  1.1  skrll 		  as_bad (_("immediate value out of range"));
   1155  1.1  skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
   1156  1.1  skrll 		break;
   1157  1.1  skrll 	      case ARG_NIM8:
   1158  1.1  skrll 		imm_operand->X_add_number = -imm_operand->X_add_number;
   1159  1.1  skrll                 /* Drop through.  */
   1160  1.1  skrll 	      case ARG_IMM8:
   1161  1.1  skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2);
   1162  1.1  skrll 		break;
   1163  1.1  skrll 	      case ARG_IMM16:
   1164  1.1  skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4);
   1165  1.1  skrll 		break;
   1166  1.1  skrll 	      case ARG_IMM32:
   1167  1.1  skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8);
   1168  1.1  skrll 		break;
   1169  1.1  skrll 	      default:
   1170  1.1  skrll 		abort ();
   1171  1.1  skrll 	      }
   1172  1.1  skrll 	  }
   1173  1.1  skrll 	}
   1174  1.1  skrll     }
   1175  1.1  skrll 
   1176  1.1  skrll   /* Copy from the nibble buffer into the frag.  */
   1177  1.1  skrll   {
   1178  1.1  skrll     int length = (output_ptr - buffer) / 2;
   1179  1.1  skrll     char *src = buffer;
   1180  1.1  skrll     char *fragp = frag_more (length);
   1181  1.1  skrll 
   1182  1.1  skrll     while (src < output_ptr)
   1183  1.1  skrll       {
   1184  1.1  skrll 	*fragp = (src[0] << 4) | src[1];
   1185  1.1  skrll 	src += 2;
   1186  1.1  skrll 	fragp++;
   1187  1.1  skrll       }
   1188  1.1  skrll   }
   1189  1.1  skrll }
   1190  1.1  skrll 
   1191  1.1  skrll /* This is the guts of the machine-dependent assembler.  STR points to a
   1192  1.1  skrll    machine dependent instruction.  This function is supposed to emit
   1193  1.1  skrll    the frags/bytes it assembles to.  */
   1194  1.1  skrll 
   1195  1.1  skrll void
   1196  1.1  skrll md_assemble (char *str)
   1197  1.1  skrll {
   1198  1.1  skrll   char c;
   1199  1.1  skrll   char *op_start;
   1200  1.1  skrll   char *op_end;
   1201  1.1  skrll   struct z8k_op operand[4];
   1202  1.1  skrll   opcode_entry_type *opcode;
   1203  1.1  skrll 
   1204  1.1  skrll   /* Drop leading whitespace.  */
   1205  1.1  skrll   while (*str == ' ')
   1206  1.1  skrll     str++;
   1207  1.1  skrll 
   1208  1.1  skrll   /* Find the op code end.  */
   1209  1.1  skrll   for (op_start = op_end = str;
   1210  1.1  skrll        *op_end != 0 && *op_end != ' ' && ! is_end_of_line[(unsigned char) *op_end];
   1211  1.1  skrll        op_end++)
   1212  1.1  skrll     ;
   1213  1.1  skrll 
   1214  1.1  skrll   if (op_end == op_start)
   1215  1.1  skrll     {
   1216  1.1  skrll       as_bad (_("can't find opcode "));
   1217  1.1  skrll     }
   1218  1.1  skrll   c = *op_end;
   1219  1.1  skrll 
   1220  1.1  skrll   *op_end = 0;  /* Zero-terminate op code string for hash_find() call.  */
   1221  1.1  skrll 
   1222  1.1  skrll   opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);
   1223  1.1  skrll 
   1224  1.1  skrll   if (opcode == NULL)
   1225  1.1  skrll     {
   1226  1.1  skrll       as_bad (_("unknown opcode"));
   1227  1.1  skrll       return;
   1228  1.1  skrll     }
   1229  1.1  skrll 
   1230  1.1  skrll   *op_end = c;  /* Restore original string.  */
   1231  1.1  skrll 
   1232  1.1  skrll   if (opcode->opcode == 250)
   1233  1.1  skrll     {
   1234  1.1  skrll       pseudo_typeS *p;
   1235  1.1  skrll       char oc;
   1236  1.1  skrll       char *old = input_line_pointer;
   1237  1.1  skrll 
   1238  1.1  skrll       /* Was really a pseudo op.  */
   1239  1.1  skrll 
   1240  1.1  skrll       input_line_pointer = op_end;
   1241  1.1  skrll 
   1242  1.1  skrll       oc = *old;
   1243  1.1  skrll       *old = '\n';
   1244  1.1  skrll       while (*input_line_pointer == ' ')
   1245  1.1  skrll 	input_line_pointer++;
   1246  1.1  skrll       p = (pseudo_typeS *) (opcode->func);
   1247  1.1  skrll 
   1248  1.1  skrll       (p->poc_handler) (p->poc_val);
   1249  1.1  skrll       input_line_pointer = old;
   1250  1.1  skrll       *old = oc;
   1251  1.1  skrll     }
   1252  1.1  skrll   else
   1253  1.1  skrll     {
   1254  1.1  skrll       char *new_input_line_pointer;
   1255  1.1  skrll 
   1256  1.1  skrll       new_input_line_pointer = get_operands (opcode, op_end, operand);
   1257  1.1  skrll       if (new_input_line_pointer)
   1258  1.1  skrll         {
   1259  1.1  skrll           input_line_pointer = new_input_line_pointer;
   1260  1.1  skrll           opcode = get_specific (opcode, operand);
   1261  1.1  skrll         }
   1262  1.1  skrll 
   1263  1.1  skrll       if (new_input_line_pointer == NULL || opcode == NULL)
   1264  1.1  skrll 	{
   1265  1.1  skrll 	  /* Couldn't find an opcode which matched the operands.  */
   1266  1.1  skrll 	  char *where = frag_more (2);
   1267  1.1  skrll 
   1268  1.1  skrll 	  where[0] = 0x0;
   1269  1.1  skrll 	  where[1] = 0x0;
   1270  1.1  skrll 
   1271  1.1  skrll 	  as_bad (_("Can't find opcode to match operands"));
   1272  1.1  skrll 	  return;
   1273  1.1  skrll 	}
   1274  1.1  skrll 
   1275  1.1  skrll       build_bytes (opcode, operand);
   1276  1.1  skrll     }
   1277  1.1  skrll }
   1278  1.1  skrll 
   1279  1.1  skrll /* We have no need to default values of symbols.  */
   1280  1.1  skrll 
   1281  1.1  skrll symbolS *
   1282  1.1  skrll md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   1283  1.1  skrll {
   1284  1.1  skrll   return 0;
   1285  1.1  skrll }
   1286  1.1  skrll 
   1287  1.1  skrll /* Various routines to kill one day.  */
   1288  1.1  skrll 
   1289  1.1  skrll char *
   1290  1.1  skrll md_atof (int type, char *litP, int *sizeP)
   1291  1.1  skrll {
   1292  1.1  skrll   return ieee_md_atof (type, litP, sizeP, TRUE);
   1293  1.1  skrll }
   1294  1.1  skrll 
   1295  1.1  skrll const char *md_shortopts = "z:";
   1297  1.1  skrll 
   1298  1.1  skrll struct option md_longopts[] =
   1299  1.1  skrll   {
   1300  1.1  skrll #define OPTION_RELAX  (OPTION_MD_BASE)
   1301  1.1  skrll     {"linkrelax", no_argument, NULL, OPTION_RELAX},
   1302  1.1  skrll     {NULL, no_argument, NULL, 0}
   1303  1.1  skrll   };
   1304  1.1  skrll 
   1305  1.1  skrll size_t md_longopts_size = sizeof (md_longopts);
   1306  1.1  skrll 
   1307  1.1  skrll int
   1308  1.1  skrll md_parse_option (int c, char *arg)
   1309  1.1  skrll {
   1310  1.1  skrll   switch (c)
   1311  1.1  skrll     {
   1312  1.1  skrll     case 'z':
   1313  1.1  skrll       if (!strcmp (arg, "8001"))
   1314  1.1  skrll 	s_segm (1);
   1315  1.1  skrll       else if (!strcmp (arg, "8002"))
   1316  1.1  skrll 	s_segm (0);
   1317  1.1  skrll       else
   1318  1.1  skrll 	{
   1319  1.1  skrll 	  as_bad (_("invalid architecture -z%s"), arg);
   1320  1.1  skrll 	  return 0;
   1321  1.1  skrll 	}
   1322  1.1  skrll       z8k_target_from_cmdline = 1;
   1323  1.1  skrll       break;
   1324  1.1  skrll 
   1325  1.1  skrll     case OPTION_RELAX:
   1326  1.1  skrll       linkrelax = 1;
   1327  1.1  skrll       break;
   1328  1.1  skrll 
   1329  1.1  skrll     default:
   1330  1.1  skrll       return 0;
   1331  1.1  skrll     }
   1332  1.1  skrll 
   1333  1.1  skrll   return 1;
   1334  1.1  skrll }
   1335  1.1  skrll 
   1336  1.1  skrll void
   1337  1.1  skrll md_show_usage (FILE *stream)
   1338  1.1  skrll {
   1339  1.1  skrll   fprintf (stream, _("\
   1340  1.1  skrll  Z8K options:\n\
   1341  1.1  skrll   -z8001                  generate segmented code\n\
   1342  1.1  skrll   -z8002                  generate unsegmented code\n\
   1343  1.1  skrll   -linkrelax              create linker relaxable code\n"));
   1344  1.1  skrll }
   1345  1.1  skrll 
   1346  1.1  skrll void
   1348  1.1  skrll md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   1349  1.1  skrll                  segT sec ATTRIBUTE_UNUSED,
   1350  1.1  skrll                  fragS *fragP ATTRIBUTE_UNUSED)
   1351  1.1  skrll {
   1352  1.1  skrll   printf (_("call to md_convert_frag\n"));
   1353  1.1  skrll   abort ();
   1354  1.1  skrll }
   1355  1.1  skrll 
   1356  1.1  skrll /* Generate a machine dependent reloc from a fixup.  */
   1357  1.1  skrll 
   1358  1.1  skrll arelent*
   1359  1.1  skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
   1360  1.1  skrll 	      fixS *fixp      ATTRIBUTE_UNUSED)
   1361  1.1  skrll {
   1362  1.1  skrll   arelent *reloc;
   1363  1.1  skrll 
   1364  1.1  skrll   reloc = xmalloc (sizeof (*reloc));
   1365  1.1  skrll   reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
   1366  1.1  skrll   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   1367  1.1  skrll   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   1368  1.1  skrll   reloc->addend = fixp->fx_offset;
   1369  1.1  skrll   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   1370  1.1  skrll 
   1371  1.1  skrll   if (! reloc->howto)
   1372  1.1  skrll     {
   1373  1.1  skrll       as_bad_where (fixp->fx_file, fixp->fx_line,
   1374  1.1  skrll                     "Cannot represent %s relocation in object file",
   1375  1.1  skrll                     bfd_get_reloc_code_name (fixp->fx_r_type));
   1376  1.1  skrll       abort ();
   1377  1.1  skrll     }
   1378  1.1  skrll   return reloc;
   1379  1.1  skrll }
   1380  1.1  skrll 
   1381  1.1  skrll valueT
   1382  1.1  skrll md_section_align (segT seg, valueT size)
   1383  1.1  skrll {
   1384  1.1  skrll   int align = bfd_get_section_alignment (stdoutput, seg);
   1385  1.1  skrll   valueT mask = ((valueT) 1 << align) - 1;
   1386  1.1  skrll 
   1387  1.1  skrll   return (size + mask) & ~mask;
   1388  1.1  skrll }
   1389  1.1  skrll 
   1390  1.1  skrll /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
   1391  1.1  skrll    has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
   1392  1.1  skrll    we will have to generate a reloc entry.  */
   1393  1.1  skrll void
   1394  1.1  skrll md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
   1395  1.1  skrll {
   1396  1.1  skrll   long val = * (long *) valP;
   1397  1.1  skrll   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
   1398  1.1  skrll 
   1399  1.1  skrll   switch (fixP->fx_r_type)
   1400  1.1  skrll     {
   1401  1.1  skrll     case BFD_RELOC_Z8K_IMM4L:
   1402  1.1  skrll       if (fixP->fx_addsy)
   1403  1.1  skrll         {
   1404  1.1  skrll           fixP->fx_no_overflow = 1;
   1405  1.1  skrll           fixP->fx_done = 0;
   1406  1.1  skrll         }
   1407  1.1  skrll       else
   1408  1.1  skrll 	buf[0] = (buf[0] & 0xf0) | (val & 0xf);
   1409  1.1  skrll       break;
   1410  1.1  skrll 
   1411  1.1  skrll     case BFD_RELOC_8:
   1412  1.1  skrll       if (fixP->fx_addsy)
   1413  1.1  skrll         {
   1414  1.1  skrll           fixP->fx_no_overflow = 1;
   1415  1.1  skrll           fixP->fx_done = 0;
   1416  1.1  skrll         }
   1417  1.1  skrll       else
   1418  1.1  skrll 	*buf++ = val;
   1419  1.1  skrll       break;
   1420  1.1  skrll 
   1421  1.1  skrll     case BFD_RELOC_16:
   1422  1.1  skrll       if (fixP->fx_addsy)
   1423  1.1  skrll         {
   1424  1.1  skrll           fixP->fx_no_overflow = 1;
   1425  1.1  skrll           fixP->fx_done = 0;
   1426  1.1  skrll         }
   1427  1.1  skrll       else
   1428  1.1  skrll         {
   1429  1.1  skrll           *buf++ = (val >> 8);
   1430  1.1  skrll           *buf++ = val;
   1431  1.1  skrll         }
   1432  1.1  skrll       break;
   1433  1.1  skrll 
   1434  1.1  skrll     case BFD_RELOC_32:
   1435  1.1  skrll       if (fixP->fx_addsy)
   1436  1.1  skrll         {
   1437  1.1  skrll           fixP->fx_no_overflow = 1;
   1438  1.1  skrll           fixP->fx_done = 0;
   1439  1.1  skrll         }
   1440  1.1  skrll       else
   1441  1.1  skrll         {
   1442  1.1  skrll           *buf++ = (val >> 24);
   1443  1.1  skrll           *buf++ = (val >> 16);
   1444  1.1  skrll           *buf++ = (val >> 8);
   1445  1.1  skrll           *buf++ = val;
   1446  1.1  skrll         }
   1447  1.1  skrll       break;
   1448  1.1  skrll 
   1449  1.1  skrll     case BFD_RELOC_8_PCREL:
   1450  1.1  skrll       if (fixP->fx_addsy)
   1451  1.1  skrll         {
   1452  1.1  skrll           fixP->fx_no_overflow = 1;
   1453  1.1  skrll           fixP->fx_done = 0;
   1454  1.1  skrll         }
   1455  1.1  skrll       else
   1456  1.1  skrll         {
   1457  1.1  skrll           if (val & 1)
   1458  1.1  skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1459  1.1  skrll                           _("cannot branch to odd address"));
   1460  1.1  skrll           val /= 2;
   1461  1.1  skrll           if (val > 127 || val < -128)
   1462  1.1  skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1463  1.1  skrll                           _("relative jump out of range"));
   1464  1.1  skrll           *buf++ = val;
   1465  1.1  skrll           fixP->fx_no_overflow = 1;
   1466  1.1  skrll           fixP->fx_done = 1;
   1467  1.1  skrll         }
   1468  1.1  skrll       break;
   1469  1.1  skrll 
   1470  1.1  skrll     case BFD_RELOC_16_PCREL:
   1471  1.1  skrll       if (fixP->fx_addsy)
   1472  1.1  skrll         {
   1473  1.1  skrll           fixP->fx_no_overflow = 1;
   1474  1.1  skrll           fixP->fx_done = 0;
   1475  1.1  skrll         }
   1476  1.1  skrll       else
   1477  1.1  skrll         {
   1478  1.1  skrll           val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
   1479  1.1  skrll           if (val > 32767 || val < -32768)
   1480  1.1  skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1481  1.1  skrll                           _("relative address out of range"));
   1482  1.1  skrll           *buf++ = (val >> 8);
   1483  1.1  skrll           *buf++ = val;
   1484  1.1  skrll           fixP->fx_no_overflow = 1;
   1485  1.1  skrll           fixP->fx_done = 1;
   1486  1.1  skrll         }
   1487  1.1  skrll       break;
   1488  1.1  skrll 
   1489  1.1  skrll     case BFD_RELOC_Z8K_CALLR:
   1490  1.1  skrll       if (fixP->fx_addsy)
   1491  1.1  skrll         {
   1492  1.1  skrll           fixP->fx_no_overflow = 1;
   1493  1.1  skrll           fixP->fx_done = 0;
   1494  1.1  skrll         }
   1495  1.1  skrll       else
   1496  1.1  skrll         {
   1497  1.1  skrll           if (val & 1)
   1498  1.1  skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1499  1.1  skrll                           _("cannot branch to odd address"));
   1500  1.1  skrll           if (val > 4096 || val < -4095)
   1501  1.1  skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1502  1.1  skrll                           _("relative call out of range"));
   1503  1.1  skrll           val = -val / 2;
   1504  1.1  skrll           *buf = (*buf & 0xf0) | ((val >> 8) & 0xf);
   1505  1.1  skrll           buf++;
   1506  1.1  skrll           *buf++ = val & 0xff;
   1507  1.1  skrll           fixP->fx_no_overflow = 1;
   1508  1.1  skrll           fixP->fx_done = 1;
   1509  1.1  skrll         }
   1510  1.1  skrll       break;
   1511  1.1  skrll 
   1512  1.1  skrll     case BFD_RELOC_Z8K_DISP7:
   1513  1.1  skrll       if (fixP->fx_addsy)
   1514  1.1  skrll         {
   1515  1.1  skrll           fixP->fx_no_overflow = 1;
   1516  1.1  skrll           fixP->fx_done = 0;
   1517  1.1  skrll         }
   1518  1.1  skrll       else
   1519  1.1  skrll         {
   1520  1.1  skrll           if (val & 1)
   1521  1.1  skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1522  1.1  skrll                           _("cannot branch to odd address"));
   1523  1.1  skrll           val /= 2;
   1524  1.1  skrll           if (val > 0 || val < -127)
   1525  1.1  skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1526  1.1  skrll                           _("relative jump out of range"));
   1527  1.1  skrll           *buf = (*buf & 0x80) | (-val & 0x7f);
   1528  1.1  skrll           fixP->fx_no_overflow = 1;
   1529  1.1  skrll           fixP->fx_done = 1;
   1530  1.1  skrll         }
   1531  1.1  skrll       break;
   1532  1.1  skrll 
   1533  1.1  skrll     default:
   1534  1.1  skrll       printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
   1535  1.1  skrll       abort ();
   1536  1.1  skrll     }
   1537  1.1  skrll 
   1538  1.1  skrll   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
   1539  1.1  skrll     fixP->fx_done = 1;
   1540  1.1  skrll }
   1541  1.1  skrll 
   1542  1.1  skrll int
   1543  1.1  skrll md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
   1544  1.1  skrll                                segT segment_type ATTRIBUTE_UNUSED)
   1545  1.1  skrll {
   1546  1.1  skrll   printf (_("call to md_estimate_size_before_relax\n"));
   1547  1.1  skrll   abort ();
   1548  1.1  skrll }
   1549  1.1  skrll 
   1550  1.1  skrll /* Put number into target byte order.  */
   1551  1.1  skrll 
   1552  1.1  skrll void
   1553  1.1  skrll md_number_to_chars (char *ptr, valueT use, int nbytes)
   1554  1.1  skrll {
   1555  1.1  skrll   number_to_chars_bigendian (ptr, use, nbytes);
   1556  1.1  skrll }
   1557  1.1  skrll 
   1558  1.1  skrll /* On the Z8000, a PC-relative offset is relative to the address of the
   1559  1.1  skrll    instruction plus its size.  */
   1560  1.1  skrll long
   1561  1.1  skrll md_pcrel_from (fixS *fixP)
   1562  1.1  skrll {
   1563  1.1  skrll   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
   1564  1.1  skrll }
   1565  1.1  skrll 
   1566  1.1  skrll void
   1567  1.1  skrll tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED)
   1568             {
   1569             }
   1570