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