Home | History | Annotate | Line # | Download | only in config
tc-z8k.c revision 1.1.1.5
      1      1.1     skrll /* tc-z8k.c -- Assemble code for the Zilog Z800n
      2  1.1.1.5  christos    Copyright (C) 1992-2018 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     skrll   {"name"   , s_app_file      , 0},
    120      1.1     skrll   {"global" , s_globl         , 0},
    121      1.1     skrll   {"wval"   , cons            , 2},
    122      1.1     skrll   {"lval"   , cons            , 4},
    123      1.1     skrll   {"bval"   , cons            , 1},
    124      1.1     skrll   {"sval"   , sval            , 0},
    125      1.1     skrll   {"rsect"  , obj_coff_section, 0},
    126      1.1     skrll   {"sect"   , obj_coff_section, 0},
    127      1.1     skrll   {"block"  , s_space         , 0},
    128      1.1     skrll   {"even"   , even            , 0},
    129      1.1     skrll   {0        , 0               , 0}
    130      1.1     skrll };
    131      1.1     skrll 
    132      1.1     skrll const char EXP_CHARS[] = "eE";
    133      1.1     skrll 
    134      1.1     skrll /* Chars that mean this number is a floating point constant.
    135      1.1     skrll    As in 0f12.456
    136      1.1     skrll    or    0d1.2345e12  */
    137      1.1     skrll const char FLT_CHARS[] = "rRsSfFdDxXpP";
    138      1.1     skrll 
    139      1.1     skrll /* Opcode mnemonics.  */
    140      1.1     skrll static struct hash_control *opcode_hash_control;
    141      1.1     skrll 
    142      1.1     skrll void
    143      1.1     skrll md_begin (void)
    144      1.1     skrll {
    145      1.1     skrll   const opcode_entry_type *opcode;
    146      1.1     skrll   int idx = -1;
    147      1.1     skrll 
    148      1.1     skrll   opcode_hash_control = hash_new ();
    149      1.1     skrll 
    150      1.1     skrll   for (opcode = z8k_table; opcode->name; opcode++)
    151      1.1     skrll     {
    152      1.1     skrll       /* Only enter unique codes into the table.  */
    153      1.1     skrll       if (idx != opcode->idx)
    154      1.1     skrll 	hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
    155      1.1     skrll       idx = opcode->idx;
    156      1.1     skrll     }
    157      1.1     skrll 
    158      1.1     skrll   /* Default to z8002.  */
    159  1.1.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     skrll       fake_opcode->func = (void *) (md_pseudo_table + idx);
    168      1.1     skrll       fake_opcode->opcode = 250;
    169      1.1     skrll       hash_insert (opcode_hash_control, fake_opcode->name, fake_opcode);
    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     skrll   while (*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     skrll   while (*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     skrll   while (*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     skrll 		  while (**ptr && ! is_end_of_line[(unsigned char) **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     skrll   while (*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     skrll   while (*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     skrll       while (*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     skrll           while (*ptr == ' ')
    749      1.1     skrll             ptr++;
    750      1.1     skrll           if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
    751      1.1     skrll             {
    752      1.1     skrll               as_bad (_("invalid condition code '%s'"), ptr);
    753      1.1     skrll               while (*ptr && ! is_end_of_line[(unsigned char) *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     skrll 	  while (*ptr == ' ')
    761      1.1     skrll 	    ptr++;
    762      1.1     skrll 	  if (*ptr && ! is_end_of_line[(unsigned char) *ptr])
    763      1.1     skrll 	    {
    764      1.1     skrll 	      as_bad (_("invalid flag '%s'"), ptr);
    765      1.1     skrll 	      while (*ptr && ! is_end_of_line[(unsigned char) *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     skrll           while (*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     skrll   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     skrll static 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     skrll static char *
    988  1.1.1.5  christos apply_fix (char *ptr, bfd_reloc_code_real_type type, expressionS *operand,
    989  1.1.1.5  christos 	   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     skrll   switch (size)
    997      1.1     skrll     {
    998      1.1     skrll     case 8:			/* 8 nibbles == 32 bits.  */
    999      1.1     skrll       *ptr++ = n >> 28;
   1000      1.1     skrll       *ptr++ = n >> 24;
   1001      1.1     skrll       *ptr++ = n >> 20;
   1002      1.1     skrll       *ptr++ = n >> 16;
   1003  1.1.1.5  christos       /* Fall through.  */
   1004      1.1     skrll     case 4:			/* 4 nibbles == 16 bits.  */
   1005      1.1     skrll       *ptr++ = n >> 12;
   1006      1.1     skrll       *ptr++ = n >> 8;
   1007  1.1.1.5  christos       /* Fall through.  */
   1008      1.1     skrll     case 2:
   1009      1.1     skrll       *ptr++ = n >> 4;
   1010  1.1.1.5  christos       /* Fall through.  */
   1011      1.1     skrll     case 1:
   1012      1.1     skrll       *ptr++ = n >> 0;
   1013      1.1     skrll       break;
   1014      1.1     skrll     }
   1015      1.1     skrll   return ptr;
   1016      1.1     skrll }
   1017      1.1     skrll 
   1018      1.1     skrll /* Now we know what sort of opcodes it is.  Let's build the bytes.  */
   1019      1.1     skrll 
   1020      1.1     skrll static void
   1021      1.1     skrll build_bytes (opcode_entry_type *this_try, struct z8k_op *operand ATTRIBUTE_UNUSED)
   1022      1.1     skrll {
   1023      1.1     skrll   char *output_ptr = buffer;
   1024      1.1     skrll   int c;
   1025      1.1     skrll   int nibble;
   1026      1.1     skrll   unsigned int *class_ptr;
   1027      1.1     skrll 
   1028      1.1     skrll   frag_wane (frag_now);
   1029      1.1     skrll   frag_new (0);
   1030      1.1     skrll 
   1031      1.1     skrll   if (frag_room () < 8)
   1032      1.1     skrll     frag_grow (8);  /* Make room for maximum instruction size.  */
   1033      1.1     skrll 
   1034      1.1     skrll   memset (buffer, 0, sizeof (buffer));
   1035      1.1     skrll   class_ptr = this_try->byte_info;
   1036      1.1     skrll 
   1037      1.1     skrll   for (nibble = 0; (c = *class_ptr++); nibble++)
   1038      1.1     skrll     {
   1039      1.1     skrll 
   1040      1.1     skrll       switch (c & CLASS_MASK)
   1041      1.1     skrll 	{
   1042      1.1     skrll 	default:
   1043      1.1     skrll 	  abort ();
   1044      1.1     skrll 
   1045      1.1     skrll 	case CLASS_ADDRESS:
   1046      1.1     skrll 	  /* Direct address, we don't cope with the SS mode right now.  */
   1047      1.1     skrll 	  if (segmented_mode)
   1048      1.1     skrll 	    {
   1049      1.1     skrll 	      /* da_operand->X_add_number |= 0x80000000;  --  Now set at relocation time.  */
   1050      1.1     skrll 	      output_ptr = apply_fix (output_ptr, BFD_RELOC_32, da_operand, 8);
   1051      1.1     skrll 	    }
   1052      1.1     skrll 	  else
   1053      1.1     skrll 	    {
   1054      1.1     skrll 	      output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
   1055      1.1     skrll 	    }
   1056      1.1     skrll 	  da_operand = 0;
   1057      1.1     skrll 	  break;
   1058      1.1     skrll 	case CLASS_DISP8:
   1059      1.1     skrll 	  /* pc rel 8 bit  */
   1060      1.1     skrll 	  output_ptr = apply_fix (output_ptr, BFD_RELOC_8_PCREL, da_operand, 2);
   1061      1.1     skrll 	  da_operand = 0;
   1062      1.1     skrll 	  break;
   1063      1.1     skrll 
   1064      1.1     skrll 	case CLASS_0DISP7:
   1065      1.1     skrll 	  /* pc rel 7 bit  */
   1066      1.1     skrll 	  *output_ptr = 0;
   1067      1.1     skrll 	  output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
   1068      1.1     skrll 	  da_operand = 0;
   1069      1.1     skrll 	  break;
   1070      1.1     skrll 
   1071      1.1     skrll 	case CLASS_1DISP7:
   1072      1.1     skrll 	  /* pc rel 7 bit  */
   1073      1.1     skrll 	  *output_ptr = 0x80;
   1074      1.1     skrll 	  output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_DISP7, da_operand, 2);
   1075      1.1     skrll 	  output_ptr[-2] = 0x8;
   1076      1.1     skrll 	  da_operand = 0;
   1077      1.1     skrll 	  break;
   1078      1.1     skrll 
   1079      1.1     skrll 	case CLASS_BIT_1OR2:
   1080      1.1     skrll 	  *output_ptr = c & 0xf;
   1081      1.1     skrll 	  if (imm_operand)
   1082      1.1     skrll 	    {
   1083      1.1     skrll 	      if (imm_operand->X_add_number == 2)
   1084      1.1     skrll 		*output_ptr |= 2;
   1085      1.1     skrll 	      else if (imm_operand->X_add_number != 1)
   1086      1.1     skrll 		as_bad (_("immediate must be 1 or 2"));
   1087      1.1     skrll 	    }
   1088      1.1     skrll 	  else
   1089      1.1     skrll 	    as_bad (_("immediate 1 or 2 expected"));
   1090      1.1     skrll 	  output_ptr++;
   1091      1.1     skrll 	  break;
   1092      1.1     skrll 	case CLASS_CC:
   1093      1.1     skrll 	  *output_ptr++ = the_cc;
   1094      1.1     skrll 	  break;
   1095      1.1     skrll 	case CLASS_0CCC:
   1096      1.1     skrll 	  if (the_ctrl < 2 || the_ctrl > 7)
   1097      1.1     skrll 	    as_bad (_("invalid control register name"));
   1098      1.1     skrll 	  *output_ptr++ = the_ctrl;
   1099      1.1     skrll 	  break;
   1100      1.1     skrll 	case CLASS_1CCC:
   1101      1.1     skrll 	  if (the_ctrl < 2 || the_ctrl > 7)
   1102      1.1     skrll 	    as_bad (_("invalid control register name"));
   1103      1.1     skrll 	  *output_ptr++ = the_ctrl | 0x8;
   1104      1.1     skrll 	  break;
   1105      1.1     skrll 	case CLASS_00II:
   1106      1.1     skrll 	  *output_ptr++ = (~the_interrupt & 0x3);
   1107      1.1     skrll 	  break;
   1108      1.1     skrll 	case CLASS_01II:
   1109      1.1     skrll 	  *output_ptr++ = (~the_interrupt & 0x3) | 0x4;
   1110      1.1     skrll 	  break;
   1111      1.1     skrll 	case CLASS_FLAGS:
   1112      1.1     skrll 	  *output_ptr++ = the_flags;
   1113      1.1     skrll 	  break;
   1114      1.1     skrll 	case CLASS_IGNORE:
   1115      1.1     skrll 	case CLASS_BIT:
   1116      1.1     skrll 	  *output_ptr++ = c & 0xf;
   1117      1.1     skrll 	  break;
   1118      1.1     skrll 	case CLASS_REGN0:
   1119      1.1     skrll 	  if (reg[c & 0xf] == 0)
   1120      1.1     skrll 	    as_bad (_("can't use R0 here"));
   1121      1.1     skrll 	  /* Fall through.  */
   1122      1.1     skrll 	case CLASS_REG:
   1123      1.1     skrll 	case CLASS_REG_BYTE:
   1124      1.1     skrll 	case CLASS_REG_WORD:
   1125      1.1     skrll 	case CLASS_REG_LONG:
   1126      1.1     skrll 	case CLASS_REG_QUAD:
   1127  1.1.1.5  christos 	  /* Insert bit pattern of right reg.  */
   1128      1.1     skrll 	  *output_ptr++ = reg[c & 0xf];
   1129      1.1     skrll 	  break;
   1130      1.1     skrll 	case CLASS_DISP:
   1131      1.1     skrll           switch (c & ARG_MASK)
   1132      1.1     skrll             {
   1133      1.1     skrll             case ARG_DISP12:
   1134      1.1     skrll               output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_CALLR, da_operand, 4);
   1135      1.1     skrll               break;
   1136      1.1     skrll             case ARG_DISP16:
   1137      1.1     skrll 	      output_ptr = apply_fix (output_ptr, BFD_RELOC_16_PCREL, da_operand, 4);
   1138      1.1     skrll 	      break;
   1139      1.1     skrll 	    default:
   1140      1.1     skrll 	      output_ptr = apply_fix (output_ptr, BFD_RELOC_16, da_operand, 4);
   1141      1.1     skrll 	    }
   1142      1.1     skrll 	  da_operand = 0;
   1143      1.1     skrll 	  break;
   1144      1.1     skrll 
   1145      1.1     skrll 	case CLASS_IMM:
   1146      1.1     skrll 	  {
   1147      1.1     skrll 	    switch (c & ARG_MASK)
   1148      1.1     skrll 	      {
   1149      1.1     skrll 	      case ARG_NIM4:
   1150      1.1     skrll                 if (imm_operand->X_add_number > 15)
   1151      1.1     skrll 		  as_bad (_("immediate value out of range"));
   1152      1.1     skrll 		imm_operand->X_add_number = -imm_operand->X_add_number;
   1153      1.1     skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_Z8K_IMM4L, imm_operand, 1);
   1154      1.1     skrll 		break;
   1155      1.1     skrll               /*case ARG_IMMNMINUS1: not used.  */
   1156      1.1     skrll 	      case ARG_IMM4M1:
   1157      1.1     skrll 		imm_operand->X_add_number--;
   1158  1.1.1.5  christos                 /* Fall through.  */
   1159      1.1     skrll 	      case ARG_IMM4:
   1160      1.1     skrll                 if (imm_operand->X_add_number > 15)
   1161      1.1     skrll 		  as_bad (_("immediate value out of range"));
   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_NIM8:
   1165      1.1     skrll 		imm_operand->X_add_number = -imm_operand->X_add_number;
   1166  1.1.1.5  christos                 /* Fall through.  */
   1167      1.1     skrll 	      case ARG_IMM8:
   1168      1.1     skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_8, imm_operand, 2);
   1169      1.1     skrll 		break;
   1170      1.1     skrll 	      case ARG_IMM16:
   1171      1.1     skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_16, imm_operand, 4);
   1172      1.1     skrll 		break;
   1173      1.1     skrll 	      case ARG_IMM32:
   1174      1.1     skrll 		output_ptr = apply_fix (output_ptr, BFD_RELOC_32, imm_operand, 8);
   1175      1.1     skrll 		break;
   1176      1.1     skrll 	      default:
   1177      1.1     skrll 		abort ();
   1178      1.1     skrll 	      }
   1179      1.1     skrll 	  }
   1180      1.1     skrll 	}
   1181      1.1     skrll     }
   1182      1.1     skrll 
   1183      1.1     skrll   /* Copy from the nibble buffer into the frag.  */
   1184      1.1     skrll   {
   1185      1.1     skrll     int length = (output_ptr - buffer) / 2;
   1186      1.1     skrll     char *src = buffer;
   1187      1.1     skrll     char *fragp = frag_more (length);
   1188      1.1     skrll 
   1189      1.1     skrll     while (src < output_ptr)
   1190      1.1     skrll       {
   1191      1.1     skrll 	*fragp = (src[0] << 4) | src[1];
   1192      1.1     skrll 	src += 2;
   1193      1.1     skrll 	fragp++;
   1194      1.1     skrll       }
   1195      1.1     skrll   }
   1196      1.1     skrll }
   1197      1.1     skrll 
   1198      1.1     skrll /* This is the guts of the machine-dependent assembler.  STR points to a
   1199      1.1     skrll    machine dependent instruction.  This function is supposed to emit
   1200      1.1     skrll    the frags/bytes it assembles to.  */
   1201      1.1     skrll 
   1202      1.1     skrll void
   1203      1.1     skrll md_assemble (char *str)
   1204      1.1     skrll {
   1205      1.1     skrll   char c;
   1206      1.1     skrll   char *op_start;
   1207      1.1     skrll   char *op_end;
   1208      1.1     skrll   struct z8k_op operand[4];
   1209      1.1     skrll   opcode_entry_type *opcode;
   1210      1.1     skrll 
   1211      1.1     skrll   /* Drop leading whitespace.  */
   1212      1.1     skrll   while (*str == ' ')
   1213      1.1     skrll     str++;
   1214      1.1     skrll 
   1215      1.1     skrll   /* Find the op code end.  */
   1216      1.1     skrll   for (op_start = op_end = str;
   1217      1.1     skrll        *op_end != 0 && *op_end != ' ' && ! is_end_of_line[(unsigned char) *op_end];
   1218      1.1     skrll        op_end++)
   1219      1.1     skrll     ;
   1220      1.1     skrll 
   1221      1.1     skrll   if (op_end == op_start)
   1222      1.1     skrll     {
   1223      1.1     skrll       as_bad (_("can't find opcode "));
   1224      1.1     skrll     }
   1225      1.1     skrll   c = *op_end;
   1226      1.1     skrll 
   1227      1.1     skrll   *op_end = 0;  /* Zero-terminate op code string for hash_find() call.  */
   1228      1.1     skrll 
   1229      1.1     skrll   opcode = (opcode_entry_type *) hash_find (opcode_hash_control, op_start);
   1230      1.1     skrll 
   1231      1.1     skrll   if (opcode == NULL)
   1232      1.1     skrll     {
   1233      1.1     skrll       as_bad (_("unknown opcode"));
   1234      1.1     skrll       return;
   1235      1.1     skrll     }
   1236      1.1     skrll 
   1237      1.1     skrll   *op_end = c;  /* Restore original string.  */
   1238      1.1     skrll 
   1239      1.1     skrll   if (opcode->opcode == 250)
   1240      1.1     skrll     {
   1241      1.1     skrll       pseudo_typeS *p;
   1242      1.1     skrll       char oc;
   1243      1.1     skrll       char *old = input_line_pointer;
   1244      1.1     skrll 
   1245      1.1     skrll       /* Was really a pseudo op.  */
   1246      1.1     skrll 
   1247      1.1     skrll       input_line_pointer = op_end;
   1248      1.1     skrll 
   1249      1.1     skrll       oc = *old;
   1250      1.1     skrll       *old = '\n';
   1251      1.1     skrll       while (*input_line_pointer == ' ')
   1252      1.1     skrll 	input_line_pointer++;
   1253      1.1     skrll       p = (pseudo_typeS *) (opcode->func);
   1254      1.1     skrll 
   1255      1.1     skrll       (p->poc_handler) (p->poc_val);
   1256      1.1     skrll       input_line_pointer = old;
   1257      1.1     skrll       *old = oc;
   1258      1.1     skrll     }
   1259      1.1     skrll   else
   1260      1.1     skrll     {
   1261      1.1     skrll       char *new_input_line_pointer;
   1262      1.1     skrll 
   1263      1.1     skrll       new_input_line_pointer = get_operands (opcode, op_end, operand);
   1264      1.1     skrll       if (new_input_line_pointer)
   1265      1.1     skrll         {
   1266      1.1     skrll           input_line_pointer = new_input_line_pointer;
   1267      1.1     skrll           opcode = get_specific (opcode, operand);
   1268      1.1     skrll         }
   1269      1.1     skrll 
   1270      1.1     skrll       if (new_input_line_pointer == NULL || opcode == NULL)
   1271      1.1     skrll 	{
   1272      1.1     skrll 	  /* Couldn't find an opcode which matched the operands.  */
   1273      1.1     skrll 	  char *where = frag_more (2);
   1274      1.1     skrll 
   1275      1.1     skrll 	  where[0] = 0x0;
   1276      1.1     skrll 	  where[1] = 0x0;
   1277      1.1     skrll 
   1278      1.1     skrll 	  as_bad (_("Can't find opcode to match operands"));
   1279      1.1     skrll 	  return;
   1280      1.1     skrll 	}
   1281      1.1     skrll 
   1282      1.1     skrll       build_bytes (opcode, operand);
   1283      1.1     skrll     }
   1284      1.1     skrll }
   1285      1.1     skrll 
   1286      1.1     skrll /* We have no need to default values of symbols.  */
   1287      1.1     skrll 
   1288      1.1     skrll symbolS *
   1289      1.1     skrll md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
   1290      1.1     skrll {
   1291      1.1     skrll   return 0;
   1292      1.1     skrll }
   1293      1.1     skrll 
   1294      1.1     skrll /* Various routines to kill one day.  */
   1295      1.1     skrll 
   1296  1.1.1.4  christos const char *
   1297      1.1     skrll md_atof (int type, char *litP, int *sizeP)
   1298      1.1     skrll {
   1299      1.1     skrll   return ieee_md_atof (type, litP, sizeP, TRUE);
   1300      1.1     skrll }
   1301      1.1     skrll 
   1302      1.1     skrll const char *md_shortopts = "z:";
   1304      1.1     skrll 
   1305      1.1     skrll struct option md_longopts[] =
   1306      1.1     skrll   {
   1307      1.1     skrll #define OPTION_RELAX  (OPTION_MD_BASE)
   1308      1.1     skrll     {"linkrelax", no_argument, NULL, OPTION_RELAX},
   1309      1.1     skrll     {NULL, no_argument, NULL, 0}
   1310      1.1     skrll   };
   1311      1.1     skrll 
   1312      1.1     skrll size_t md_longopts_size = sizeof (md_longopts);
   1313      1.1     skrll 
   1314  1.1.1.4  christos int
   1315      1.1     skrll md_parse_option (int c, const char *arg)
   1316      1.1     skrll {
   1317      1.1     skrll   switch (c)
   1318      1.1     skrll     {
   1319      1.1     skrll     case 'z':
   1320  1.1.1.3  christos       if (!strcmp (arg, "8001"))
   1321      1.1     skrll 	z8k_target_from_cmdline = 2;
   1322  1.1.1.3  christos       else if (!strcmp (arg, "8002"))
   1323      1.1     skrll 	z8k_target_from_cmdline = 1;
   1324      1.1     skrll       else
   1325      1.1     skrll 	{
   1326      1.1     skrll 	  as_bad (_("invalid architecture -z%s"), arg);
   1327      1.1     skrll 	  return 0;
   1328      1.1     skrll 	}
   1329      1.1     skrll       break;
   1330      1.1     skrll 
   1331      1.1     skrll     case OPTION_RELAX:
   1332      1.1     skrll       linkrelax = 1;
   1333      1.1     skrll       break;
   1334      1.1     skrll 
   1335      1.1     skrll     default:
   1336      1.1     skrll       return 0;
   1337      1.1     skrll     }
   1338      1.1     skrll 
   1339      1.1     skrll   return 1;
   1340      1.1     skrll }
   1341      1.1     skrll 
   1342      1.1     skrll void
   1343      1.1     skrll md_show_usage (FILE *stream)
   1344      1.1     skrll {
   1345      1.1     skrll   fprintf (stream, _("\
   1346      1.1     skrll  Z8K options:\n\
   1347      1.1     skrll   -z8001                  generate segmented code\n\
   1348      1.1     skrll   -z8002                  generate unsegmented code\n\
   1349      1.1     skrll   -linkrelax              create linker relaxable code\n"));
   1350      1.1     skrll }
   1351      1.1     skrll 
   1352      1.1     skrll void
   1354      1.1     skrll md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
   1355      1.1     skrll                  segT sec ATTRIBUTE_UNUSED,
   1356      1.1     skrll                  fragS *fragP ATTRIBUTE_UNUSED)
   1357      1.1     skrll {
   1358      1.1     skrll   printf (_("call to md_convert_frag\n"));
   1359      1.1     skrll   abort ();
   1360      1.1     skrll }
   1361      1.1     skrll 
   1362      1.1     skrll /* Generate a machine dependent reloc from a fixup.  */
   1363      1.1     skrll 
   1364      1.1     skrll arelent*
   1365      1.1     skrll tc_gen_reloc (asection *section ATTRIBUTE_UNUSED,
   1366      1.1     skrll 	      fixS *fixp      ATTRIBUTE_UNUSED)
   1367      1.1     skrll {
   1368  1.1.1.4  christos   arelent *reloc;
   1369  1.1.1.4  christos 
   1370      1.1     skrll   reloc = XNEW (arelent);
   1371      1.1     skrll   reloc->sym_ptr_ptr = XNEW (asymbol *);
   1372      1.1     skrll   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   1373      1.1     skrll   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   1374      1.1     skrll   reloc->addend = fixp->fx_offset;
   1375      1.1     skrll   reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
   1376      1.1     skrll 
   1377      1.1     skrll   if (! reloc->howto)
   1378  1.1.1.2  christos     {
   1379      1.1     skrll       as_bad_where (fixp->fx_file, fixp->fx_line,
   1380      1.1     skrll                     _("Cannot represent %s relocation in object file"),
   1381      1.1     skrll                     bfd_get_reloc_code_name (fixp->fx_r_type));
   1382      1.1     skrll       abort ();
   1383      1.1     skrll     }
   1384      1.1     skrll   return reloc;
   1385      1.1     skrll }
   1386      1.1     skrll 
   1387      1.1     skrll valueT
   1388      1.1     skrll md_section_align (segT seg, valueT size)
   1389      1.1     skrll {
   1390      1.1     skrll   int align = bfd_get_section_alignment (stdoutput, seg);
   1391      1.1     skrll   valueT mask = ((valueT) 1 << align) - 1;
   1392      1.1     skrll 
   1393      1.1     skrll   return (size + mask) & ~mask;
   1394      1.1     skrll }
   1395      1.1     skrll 
   1396      1.1     skrll /* Attempt to simplify or eliminate a fixup. To indicate that a fixup
   1397      1.1     skrll    has been eliminated, set fix->fx_done. If fix->fx_addsy is non-NULL,
   1398      1.1     skrll    we will have to generate a reloc entry.  */
   1399      1.1     skrll void
   1400      1.1     skrll md_apply_fix (fixS *fixP, valueT *valP, segT segment ATTRIBUTE_UNUSED)
   1401      1.1     skrll {
   1402      1.1     skrll   long val = * (long *) valP;
   1403      1.1     skrll   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
   1404      1.1     skrll 
   1405      1.1     skrll   switch (fixP->fx_r_type)
   1406      1.1     skrll     {
   1407      1.1     skrll     case BFD_RELOC_Z8K_IMM4L:
   1408      1.1     skrll       if (fixP->fx_addsy)
   1409      1.1     skrll         {
   1410      1.1     skrll           fixP->fx_no_overflow = 1;
   1411      1.1     skrll           fixP->fx_done = 0;
   1412      1.1     skrll         }
   1413      1.1     skrll       else
   1414      1.1     skrll 	buf[0] = (buf[0] & 0xf0) | (val & 0xf);
   1415      1.1     skrll       break;
   1416      1.1     skrll 
   1417      1.1     skrll     case BFD_RELOC_8:
   1418      1.1     skrll       if (fixP->fx_addsy)
   1419      1.1     skrll         {
   1420      1.1     skrll           fixP->fx_no_overflow = 1;
   1421      1.1     skrll           fixP->fx_done = 0;
   1422      1.1     skrll         }
   1423      1.1     skrll       else
   1424      1.1     skrll 	*buf++ = val;
   1425      1.1     skrll       break;
   1426      1.1     skrll 
   1427      1.1     skrll     case BFD_RELOC_16:
   1428      1.1     skrll       if (fixP->fx_addsy)
   1429      1.1     skrll         {
   1430      1.1     skrll           fixP->fx_no_overflow = 1;
   1431      1.1     skrll           fixP->fx_done = 0;
   1432      1.1     skrll         }
   1433      1.1     skrll       else
   1434      1.1     skrll         {
   1435      1.1     skrll           *buf++ = (val >> 8);
   1436      1.1     skrll           *buf++ = val;
   1437      1.1     skrll         }
   1438      1.1     skrll       break;
   1439      1.1     skrll 
   1440      1.1     skrll     case BFD_RELOC_32:
   1441      1.1     skrll       if (fixP->fx_addsy)
   1442      1.1     skrll         {
   1443      1.1     skrll           fixP->fx_no_overflow = 1;
   1444      1.1     skrll           fixP->fx_done = 0;
   1445      1.1     skrll         }
   1446      1.1     skrll       else
   1447      1.1     skrll         {
   1448      1.1     skrll           *buf++ = (val >> 24);
   1449      1.1     skrll           *buf++ = (val >> 16);
   1450      1.1     skrll           *buf++ = (val >> 8);
   1451      1.1     skrll           *buf++ = val;
   1452      1.1     skrll         }
   1453      1.1     skrll       break;
   1454      1.1     skrll 
   1455      1.1     skrll     case BFD_RELOC_8_PCREL:
   1456      1.1     skrll       if (fixP->fx_addsy)
   1457      1.1     skrll         {
   1458      1.1     skrll           fixP->fx_no_overflow = 1;
   1459      1.1     skrll           fixP->fx_done = 0;
   1460      1.1     skrll         }
   1461      1.1     skrll       else
   1462      1.1     skrll         {
   1463      1.1     skrll           if (val & 1)
   1464      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1465      1.1     skrll                           _("cannot branch to odd address"));
   1466      1.1     skrll           val /= 2;
   1467      1.1     skrll           if (val > 127 || val < -128)
   1468      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1469      1.1     skrll                           _("relative jump out of range"));
   1470      1.1     skrll           *buf++ = val;
   1471      1.1     skrll           fixP->fx_no_overflow = 1;
   1472      1.1     skrll           fixP->fx_done = 1;
   1473      1.1     skrll         }
   1474      1.1     skrll       break;
   1475      1.1     skrll 
   1476      1.1     skrll     case BFD_RELOC_16_PCREL:
   1477      1.1     skrll       if (fixP->fx_addsy)
   1478      1.1     skrll         {
   1479      1.1     skrll           fixP->fx_no_overflow = 1;
   1480      1.1     skrll           fixP->fx_done = 0;
   1481      1.1     skrll         }
   1482      1.1     skrll       else
   1483      1.1     skrll         {
   1484      1.1     skrll           val = val - fixP->fx_frag->fr_address + fixP->fx_where - fixP->fx_size;
   1485      1.1     skrll           if (val > 32767 || val < -32768)
   1486      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1487      1.1     skrll                           _("relative address out of range"));
   1488      1.1     skrll           *buf++ = (val >> 8);
   1489      1.1     skrll           *buf++ = val;
   1490      1.1     skrll           fixP->fx_no_overflow = 1;
   1491      1.1     skrll           fixP->fx_done = 1;
   1492      1.1     skrll         }
   1493      1.1     skrll       break;
   1494      1.1     skrll 
   1495      1.1     skrll     case BFD_RELOC_Z8K_CALLR:
   1496      1.1     skrll       if (fixP->fx_addsy)
   1497      1.1     skrll         {
   1498      1.1     skrll           fixP->fx_no_overflow = 1;
   1499      1.1     skrll           fixP->fx_done = 0;
   1500      1.1     skrll         }
   1501      1.1     skrll       else
   1502      1.1     skrll         {
   1503      1.1     skrll           if (val & 1)
   1504      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1505      1.1     skrll                           _("cannot branch to odd address"));
   1506      1.1     skrll           if (val > 4096 || val < -4095)
   1507      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1508      1.1     skrll                           _("relative call out of range"));
   1509      1.1     skrll           val = -val / 2;
   1510      1.1     skrll           *buf = (*buf & 0xf0) | ((val >> 8) & 0xf);
   1511      1.1     skrll           buf++;
   1512      1.1     skrll           *buf++ = val & 0xff;
   1513      1.1     skrll           fixP->fx_no_overflow = 1;
   1514      1.1     skrll           fixP->fx_done = 1;
   1515      1.1     skrll         }
   1516      1.1     skrll       break;
   1517      1.1     skrll 
   1518      1.1     skrll     case BFD_RELOC_Z8K_DISP7:
   1519      1.1     skrll       if (fixP->fx_addsy)
   1520      1.1     skrll         {
   1521      1.1     skrll           fixP->fx_no_overflow = 1;
   1522      1.1     skrll           fixP->fx_done = 0;
   1523      1.1     skrll         }
   1524      1.1     skrll       else
   1525      1.1     skrll         {
   1526      1.1     skrll           if (val & 1)
   1527      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1528      1.1     skrll                           _("cannot branch to odd address"));
   1529      1.1     skrll           val /= 2;
   1530      1.1     skrll           if (val > 0 || val < -127)
   1531      1.1     skrll             as_bad_where (fixP->fx_file, fixP->fx_line,
   1532      1.1     skrll                           _("relative jump out of range"));
   1533      1.1     skrll           *buf = (*buf & 0x80) | (-val & 0x7f);
   1534      1.1     skrll           fixP->fx_no_overflow = 1;
   1535      1.1     skrll           fixP->fx_done = 1;
   1536      1.1     skrll         }
   1537      1.1     skrll       break;
   1538      1.1     skrll 
   1539      1.1     skrll     default:
   1540      1.1     skrll       printf(_("md_apply_fix: unknown r_type 0x%x\n"), fixP->fx_r_type);
   1541      1.1     skrll       abort ();
   1542      1.1     skrll     }
   1543      1.1     skrll 
   1544      1.1     skrll   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
   1545      1.1     skrll     fixP->fx_done = 1;
   1546      1.1     skrll }
   1547      1.1     skrll 
   1548      1.1     skrll int
   1549      1.1     skrll md_estimate_size_before_relax (fragS *fragP ATTRIBUTE_UNUSED,
   1550      1.1     skrll                                segT segment_type ATTRIBUTE_UNUSED)
   1551      1.1     skrll {
   1552      1.1     skrll   printf (_("call to md_estimate_size_before_relax\n"));
   1553      1.1     skrll   abort ();
   1554      1.1     skrll }
   1555      1.1     skrll 
   1556      1.1     skrll /* Put number into target byte order.  */
   1557      1.1     skrll 
   1558      1.1     skrll void
   1559      1.1     skrll md_number_to_chars (char *ptr, valueT use, int nbytes)
   1560      1.1     skrll {
   1561      1.1     skrll   number_to_chars_bigendian (ptr, use, nbytes);
   1562      1.1     skrll }
   1563      1.1     skrll 
   1564      1.1     skrll /* On the Z8000, a PC-relative offset is relative to the address of the
   1565      1.1     skrll    instruction plus its size.  */
   1566      1.1     skrll long
   1567      1.1     skrll md_pcrel_from (fixS *fixP)
   1568      1.1     skrll {
   1569      1.1     skrll   return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
   1570      1.1     skrll }
   1571      1.1     skrll 
   1572      1.1     skrll void
   1573      1.1     skrll tc_coff_symbol_emit_hook (symbolS *s ATTRIBUTE_UNUSED)
   1574                    {
   1575                    }
   1576