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