Home | History | Annotate | Line # | Download | only in config
tc-moxie.c revision 1.1.1.4
      1      1.1  christos /* tc-moxie.c -- Assemble code for moxie
      2  1.1.1.4  christos    Copyright (C) 2009-2018 Free Software Foundation, Inc.
      3      1.1  christos 
      4      1.1  christos    This file is part of GAS, the GNU Assembler.
      5      1.1  christos 
      6      1.1  christos    GAS is free software; you can redistribute it and/or modify
      7      1.1  christos    it under the terms of the GNU General Public License as published by
      8      1.1  christos    the Free Software Foundation; either version 3, or (at your option)
      9      1.1  christos    any later version.
     10      1.1  christos 
     11      1.1  christos    GAS is distributed in the hope that it will be useful,
     12      1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13      1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14      1.1  christos    GNU General Public License for more details.
     15      1.1  christos 
     16      1.1  christos    You should have received a copy of the GNU General Public License
     17      1.1  christos    along with GAS; see the file COPYING.  If not, write to
     18      1.1  christos    the Free Software Foundation, 51 Franklin Street - Fifth Floor,
     19      1.1  christos    Boston, MA 02110-1301, USA.  */
     20      1.1  christos 
     21      1.1  christos /* Contributed by Anthony Green <green (at) moxielogic.com>.  */
     22      1.1  christos 
     23      1.1  christos #include "as.h"
     24      1.1  christos #include "safe-ctype.h"
     25      1.1  christos #include "opcode/moxie.h"
     26      1.1  christos #include "elf/moxie.h"
     27      1.1  christos 
     28      1.1  christos extern const moxie_opc_info_t moxie_opc_info[128];
     29      1.1  christos 
     30      1.1  christos const char comment_chars[]        = "#";
     31      1.1  christos const char line_separator_chars[] = ";";
     32      1.1  christos const char line_comment_chars[]   = "#";
     33      1.1  christos 
     34      1.1  christos static int pending_reloc;
     35      1.1  christos static struct hash_control *opcode_hash_control;
     36      1.1  christos 
     37      1.1  christos const pseudo_typeS md_pseudo_table[] =
     38      1.1  christos {
     39      1.1  christos   {0, 0, 0}
     40      1.1  christos };
     41      1.1  christos 
     42      1.1  christos const char FLT_CHARS[] = "rRsSfFdDxXpP";
     43      1.1  christos const char EXP_CHARS[] = "eE";
     44      1.1  christos 
     45  1.1.1.2  christos static valueT md_chars_to_number (char * buf, int n);
     46  1.1.1.2  christos 
     47  1.1.1.2  christos /* Byte order.  */
     48  1.1.1.2  christos extern int target_big_endian;
     49      1.1  christos 
     50      1.1  christos void
     51      1.1  christos md_operand (expressionS *op __attribute__((unused)))
     52      1.1  christos {
     53      1.1  christos   /* Empty for now. */
     54      1.1  christos }
     55      1.1  christos 
     56      1.1  christos /* This function is called once, at assembler startup time.  It sets
     57      1.1  christos    up the hash table with all the opcodes in it, and also initializes
     58      1.1  christos    some aliases for compatibility with other assemblers.  */
     59      1.1  christos 
     60      1.1  christos void
     61      1.1  christos md_begin (void)
     62      1.1  christos {
     63      1.1  christos   int count;
     64      1.1  christos   const moxie_opc_info_t *opcode;
     65      1.1  christos   opcode_hash_control = hash_new ();
     66      1.1  christos 
     67      1.1  christos   /* Insert names into hash table.  */
     68      1.1  christos   for (count = 0, opcode = moxie_form1_opc_info; count++ < 64; opcode++)
     69      1.1  christos     hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
     70      1.1  christos 
     71      1.1  christos   for (count = 0, opcode = moxie_form2_opc_info; count++ < 4; opcode++)
     72      1.1  christos     hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
     73      1.1  christos 
     74      1.1  christos   for (count = 0, opcode = moxie_form3_opc_info; count++ < 10; opcode++)
     75      1.1  christos     hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
     76      1.1  christos 
     77  1.1.1.2  christos   target_big_endian = TARGET_BYTES_BIG_ENDIAN;
     78  1.1.1.2  christos 
     79      1.1  christos   bfd_set_arch_mach (stdoutput, TARGET_ARCH, 0);
     80      1.1  christos }
     81      1.1  christos 
     82      1.1  christos /* Parse an expression and then restore the input line pointer.  */
     83      1.1  christos 
     84      1.1  christos static char *
     85      1.1  christos parse_exp_save_ilp (char *s, expressionS *op)
     86      1.1  christos {
     87      1.1  christos   char *save = input_line_pointer;
     88      1.1  christos 
     89      1.1  christos   input_line_pointer = s;
     90      1.1  christos   expression (op);
     91      1.1  christos   s = input_line_pointer;
     92      1.1  christos   input_line_pointer = save;
     93      1.1  christos   return s;
     94      1.1  christos }
     95      1.1  christos 
     96      1.1  christos static int
     97      1.1  christos parse_register_operand (char **ptr)
     98      1.1  christos {
     99      1.1  christos   int reg;
    100      1.1  christos   char *s = *ptr;
    101      1.1  christos 
    102      1.1  christos   if (*s != '$')
    103      1.1  christos     {
    104      1.1  christos       as_bad (_("expecting register"));
    105      1.1  christos       ignore_rest_of_line ();
    106      1.1  christos       return -1;
    107      1.1  christos     }
    108      1.1  christos   if (s[1] == 'f' && s[2] == 'p')
    109      1.1  christos     {
    110      1.1  christos       *ptr += 3;
    111      1.1  christos       return 0;
    112      1.1  christos     }
    113      1.1  christos   if (s[1] == 's' && s[2] == 'p')
    114      1.1  christos     {
    115      1.1  christos       *ptr += 3;
    116      1.1  christos       return 1;
    117      1.1  christos     }
    118      1.1  christos   if (s[1] == 'r')
    119      1.1  christos     {
    120      1.1  christos       reg = s[2] - '0';
    121      1.1  christos       if ((reg < 0) || (reg > 9))
    122      1.1  christos 	{
    123      1.1  christos 	  as_bad (_("illegal register number"));
    124      1.1  christos 	  ignore_rest_of_line ();
    125      1.1  christos 	  return -1;
    126      1.1  christos 	}
    127      1.1  christos       if (reg == 1)
    128      1.1  christos 	{
    129      1.1  christos 	  int r2 = s[3] - '0';
    130      1.1  christos 	  if ((r2 >= 0) && (r2 <= 3))
    131      1.1  christos 	    {
    132      1.1  christos 	      reg = 10 + r2;
    133      1.1  christos 	      *ptr += 1;
    134      1.1  christos 	    }
    135      1.1  christos 	}
    136      1.1  christos     }
    137      1.1  christos   else
    138      1.1  christos     {
    139      1.1  christos       as_bad (_("illegal register number"));
    140      1.1  christos       ignore_rest_of_line ();
    141      1.1  christos       return -1;
    142      1.1  christos     }
    143      1.1  christos 
    144      1.1  christos   *ptr += 3;
    145      1.1  christos 
    146      1.1  christos   return reg + 2;
    147      1.1  christos }
    148      1.1  christos 
    149      1.1  christos /* This is the guts of the machine-dependent assembler.  STR points to
    150      1.1  christos    a machine dependent instruction.  This function is supposed to emit
    151      1.1  christos    the frags/bytes it assembles to.  */
    152      1.1  christos 
    153      1.1  christos void
    154      1.1  christos md_assemble (char *str)
    155      1.1  christos {
    156      1.1  christos   char *op_start;
    157      1.1  christos   char *op_end;
    158      1.1  christos 
    159      1.1  christos   moxie_opc_info_t *opcode;
    160      1.1  christos   char *p;
    161      1.1  christos   char pend;
    162      1.1  christos 
    163      1.1  christos   unsigned short iword = 0;
    164      1.1  christos 
    165      1.1  christos   int nlen = 0;
    166      1.1  christos 
    167      1.1  christos   /* Drop leading whitespace.  */
    168      1.1  christos   while (*str == ' ')
    169      1.1  christos     str++;
    170      1.1  christos 
    171      1.1  christos   /* Find the op code end.  */
    172      1.1  christos   op_start = str;
    173      1.1  christos   for (op_end = str;
    174      1.1  christos        *op_end && !is_end_of_line[*op_end & 0xff] && *op_end != ' ';
    175      1.1  christos        op_end++)
    176      1.1  christos     nlen++;
    177      1.1  christos 
    178      1.1  christos   pend = *op_end;
    179      1.1  christos   *op_end = 0;
    180      1.1  christos 
    181      1.1  christos   if (nlen == 0)
    182      1.1  christos     as_bad (_("can't find opcode "));
    183      1.1  christos   opcode = (moxie_opc_info_t *) hash_find (opcode_hash_control, op_start);
    184      1.1  christos   *op_end = pend;
    185      1.1  christos 
    186      1.1  christos   if (opcode == NULL)
    187      1.1  christos     {
    188      1.1  christos       as_bad (_("unknown opcode %s"), op_start);
    189      1.1  christos       return;
    190      1.1  christos     }
    191      1.1  christos 
    192      1.1  christos   p = frag_more (2);
    193      1.1  christos 
    194      1.1  christos   switch (opcode->itype)
    195      1.1  christos     {
    196      1.1  christos     case MOXIE_F2_A8V:
    197      1.1  christos       iword = (1<<15) | (opcode->opcode << 12);
    198      1.1  christos       while (ISSPACE (*op_end))
    199      1.1  christos 	op_end++;
    200      1.1  christos       {
    201      1.1  christos 	expressionS arg;
    202      1.1  christos 	int reg;
    203      1.1  christos 	reg = parse_register_operand (&op_end);
    204      1.1  christos 	iword += (reg << 8);
    205      1.1  christos 	if (*op_end != ',')
    206      1.1  christos 	  as_warn (_("expecting comma delimited register operands"));
    207      1.1  christos 	op_end++;
    208      1.1  christos 	op_end = parse_exp_save_ilp (op_end, &arg);
    209      1.1  christos 	fix_new_exp (frag_now,
    210  1.1.1.2  christos 		     ((p + (target_big_endian ? 1 : 0)) - frag_now->fr_literal),
    211      1.1  christos 		     1,
    212      1.1  christos 		     &arg,
    213      1.1  christos 		     0,
    214      1.1  christos 		     BFD_RELOC_8);
    215      1.1  christos       }
    216      1.1  christos       break;
    217      1.1  christos     case MOXIE_F1_AB:
    218      1.1  christos       iword = opcode->opcode << 8;
    219      1.1  christos       while (ISSPACE (*op_end))
    220      1.1  christos 	op_end++;
    221      1.1  christos       {
    222      1.1  christos 	int dest, src;
    223      1.1  christos 	dest = parse_register_operand (&op_end);
    224      1.1  christos 	if (*op_end != ',')
    225      1.1  christos 	  as_warn (_("expecting comma delimited register operands"));
    226      1.1  christos 	op_end++;
    227      1.1  christos 	src  = parse_register_operand (&op_end);
    228      1.1  christos 	iword += (dest << 4) + src;
    229      1.1  christos 	while (ISSPACE (*op_end))
    230      1.1  christos 	  op_end++;
    231      1.1  christos 	if (*op_end != 0)
    232      1.1  christos 	  as_warn (_("extra stuff on line ignored"));
    233      1.1  christos       }
    234      1.1  christos       break;
    235      1.1  christos     case MOXIE_F1_A4:
    236      1.1  christos       iword = opcode->opcode << 8;
    237      1.1  christos       while (ISSPACE (*op_end))
    238      1.1  christos 	op_end++;
    239      1.1  christos       {
    240      1.1  christos 	expressionS arg;
    241      1.1  christos 	char *where;
    242      1.1  christos 	int regnum;
    243      1.1  christos 
    244      1.1  christos  	regnum = parse_register_operand (&op_end);
    245      1.1  christos 	while (ISSPACE (*op_end))
    246      1.1  christos 	  op_end++;
    247      1.1  christos 
    248      1.1  christos 	iword += (regnum << 4);
    249      1.1  christos 
    250      1.1  christos 	if (*op_end != ',')
    251      1.1  christos 	  {
    252      1.1  christos 	    as_bad (_("expecting comma delimited operands"));
    253      1.1  christos 	    ignore_rest_of_line ();
    254      1.1  christos 	    return;
    255      1.1  christos 	  }
    256      1.1  christos 	op_end++;
    257      1.1  christos 
    258      1.1  christos 	op_end = parse_exp_save_ilp (op_end, &arg);
    259      1.1  christos 	where = frag_more (4);
    260      1.1  christos 	fix_new_exp (frag_now,
    261      1.1  christos 		     (where - frag_now->fr_literal),
    262      1.1  christos 		     4,
    263      1.1  christos 		     &arg,
    264      1.1  christos 		     0,
    265      1.1  christos 		     BFD_RELOC_32);
    266      1.1  christos       }
    267      1.1  christos       break;
    268      1.1  christos     case MOXIE_F1_M:
    269      1.1  christos     case MOXIE_F1_4:
    270      1.1  christos       iword = opcode->opcode << 8;
    271      1.1  christos       while (ISSPACE (*op_end))
    272      1.1  christos 	op_end++;
    273      1.1  christos       {
    274      1.1  christos 	expressionS arg;
    275      1.1  christos 	char *where;
    276      1.1  christos 
    277      1.1  christos 	op_end = parse_exp_save_ilp (op_end, &arg);
    278      1.1  christos 	where = frag_more (4);
    279      1.1  christos 	fix_new_exp (frag_now,
    280      1.1  christos 		     (where - frag_now->fr_literal),
    281      1.1  christos 		     4,
    282      1.1  christos 		     &arg,
    283      1.1  christos 		     0,
    284      1.1  christos 		     BFD_RELOC_32);
    285      1.1  christos       }
    286      1.1  christos       break;
    287      1.1  christos     case MOXIE_F1_NARG:
    288      1.1  christos       iword = opcode->opcode << 8;
    289      1.1  christos       while (ISSPACE (*op_end))
    290      1.1  christos 	op_end++;
    291      1.1  christos       if (*op_end != 0)
    292      1.1  christos 	as_warn (_("extra stuff on line ignored"));
    293      1.1  christos       break;
    294      1.1  christos     case MOXIE_F1_A:
    295      1.1  christos       iword = opcode->opcode << 8;
    296      1.1  christos       while (ISSPACE (*op_end))
    297      1.1  christos 	op_end++;
    298      1.1  christos       {
    299      1.1  christos 	int reg;
    300      1.1  christos 	reg = parse_register_operand (&op_end);
    301      1.1  christos 	while (ISSPACE (*op_end))
    302      1.1  christos 	  op_end++;
    303      1.1  christos 	if (*op_end != 0)
    304      1.1  christos 	  as_warn (_("extra stuff on line ignored"));
    305      1.1  christos 	iword += (reg << 4);
    306      1.1  christos       }
    307      1.1  christos       break;
    308      1.1  christos     case MOXIE_F1_ABi:
    309      1.1  christos       iword = opcode->opcode << 8;
    310      1.1  christos       while (ISSPACE (*op_end))
    311      1.1  christos 	op_end++;
    312      1.1  christos       {
    313      1.1  christos 	int a, b;
    314      1.1  christos 	a = parse_register_operand (&op_end);
    315      1.1  christos 	if (*op_end != ',')
    316      1.1  christos 	  as_warn (_("expecting comma delimited register operands"));
    317      1.1  christos 	op_end++;
    318      1.1  christos 	if (*op_end != '(')
    319      1.1  christos 	  {
    320      1.1  christos 	    as_bad (_("expecting indirect register `($rA)'"));
    321      1.1  christos 	    ignore_rest_of_line ();
    322      1.1  christos 	    return;
    323      1.1  christos 	  }
    324      1.1  christos 	op_end++;
    325      1.1  christos 	b = parse_register_operand (&op_end);
    326      1.1  christos 	if (*op_end != ')')
    327      1.1  christos 	  {
    328      1.1  christos 	    as_bad (_("missing closing parenthesis"));
    329      1.1  christos 	    ignore_rest_of_line ();
    330      1.1  christos 	    return;
    331      1.1  christos 	  }
    332      1.1  christos 	op_end++;
    333      1.1  christos 	iword += (a << 4) + b;
    334      1.1  christos 	while (ISSPACE (*op_end))
    335      1.1  christos 	  op_end++;
    336      1.1  christos 	if (*op_end != 0)
    337      1.1  christos 	  as_warn (_("extra stuff on line ignored"));
    338      1.1  christos       }
    339      1.1  christos       break;
    340      1.1  christos     case MOXIE_F1_AiB:
    341      1.1  christos       iword = opcode->opcode << 8;
    342      1.1  christos       while (ISSPACE (*op_end))
    343      1.1  christos 	op_end++;
    344      1.1  christos       {
    345      1.1  christos 	int a, b;
    346      1.1  christos 	if (*op_end != '(')
    347      1.1  christos 	  {
    348      1.1  christos 	    as_bad (_("expecting indirect register `($rA)'"));
    349      1.1  christos 	    ignore_rest_of_line ();
    350      1.1  christos 	    return;
    351      1.1  christos 	  }
    352      1.1  christos 	op_end++;
    353      1.1  christos 	a = parse_register_operand (&op_end);
    354      1.1  christos 	if (*op_end != ')')
    355      1.1  christos 	  {
    356      1.1  christos 	    as_bad (_("missing closing parenthesis"));
    357      1.1  christos 	    ignore_rest_of_line ();
    358      1.1  christos 	    return;
    359      1.1  christos 	  }
    360      1.1  christos 	op_end++;
    361      1.1  christos 	if (*op_end != ',')
    362      1.1  christos 	  as_warn (_("expecting comma delimited register operands"));
    363      1.1  christos 	op_end++;
    364      1.1  christos 	b = parse_register_operand (&op_end);
    365      1.1  christos 	iword += (a << 4) + b;
    366      1.1  christos 	while (ISSPACE (*op_end))
    367      1.1  christos 	  op_end++;
    368      1.1  christos 	if (*op_end != 0)
    369      1.1  christos 	  as_warn (_("extra stuff on line ignored"));
    370      1.1  christos       }
    371      1.1  christos       break;
    372      1.1  christos     case MOXIE_F1_4A:
    373      1.1  christos       iword = opcode->opcode << 8;
    374      1.1  christos       while (ISSPACE (*op_end))
    375      1.1  christos 	op_end++;
    376      1.1  christos       {
    377      1.1  christos 	expressionS arg;
    378      1.1  christos 	char *where;
    379      1.1  christos 	int a;
    380      1.1  christos 
    381      1.1  christos 	op_end = parse_exp_save_ilp (op_end, &arg);
    382      1.1  christos 	where = frag_more (4);
    383      1.1  christos 	fix_new_exp (frag_now,
    384      1.1  christos 		     (where - frag_now->fr_literal),
    385      1.1  christos 		     4,
    386      1.1  christos 		     &arg,
    387      1.1  christos 		     0,
    388      1.1  christos 		     BFD_RELOC_32);
    389      1.1  christos 
    390      1.1  christos 	if (*op_end != ',')
    391      1.1  christos 	  {
    392      1.1  christos 	    as_bad (_("expecting comma delimited operands"));
    393      1.1  christos 	    ignore_rest_of_line ();
    394      1.1  christos 	    return;
    395      1.1  christos 	  }
    396      1.1  christos 	op_end++;
    397      1.1  christos 
    398      1.1  christos  	a = parse_register_operand (&op_end);
    399      1.1  christos 	while (ISSPACE (*op_end))
    400      1.1  christos 	  op_end++;
    401      1.1  christos 	if (*op_end != 0)
    402      1.1  christos 	  as_warn (_("extra stuff on line ignored"));
    403      1.1  christos 
    404      1.1  christos 	iword += (a << 4);
    405      1.1  christos       }
    406      1.1  christos       break;
    407  1.1.1.2  christos     case MOXIE_F1_ABi2:
    408      1.1  christos       iword = opcode->opcode << 8;
    409      1.1  christos       while (ISSPACE (*op_end))
    410      1.1  christos 	op_end++;
    411      1.1  christos       {
    412      1.1  christos 	expressionS arg;
    413      1.1  christos 	char *offset;
    414      1.1  christos 	int a, b;
    415      1.1  christos 
    416      1.1  christos  	a = parse_register_operand (&op_end);
    417      1.1  christos 	while (ISSPACE (*op_end))
    418      1.1  christos 	  op_end++;
    419      1.1  christos 
    420      1.1  christos 	if (*op_end != ',')
    421      1.1  christos 	  {
    422      1.1  christos 	    as_bad (_("expecting comma delimited operands"));
    423      1.1  christos 	    ignore_rest_of_line ();
    424      1.1  christos 	    return;
    425      1.1  christos 	  }
    426      1.1  christos 	op_end++;
    427      1.1  christos 
    428      1.1  christos 	op_end = parse_exp_save_ilp (op_end, &arg);
    429  1.1.1.2  christos 	offset = frag_more (2);
    430      1.1  christos 	fix_new_exp (frag_now,
    431      1.1  christos 		     (offset - frag_now->fr_literal),
    432  1.1.1.2  christos 		     2,
    433      1.1  christos 		     &arg,
    434      1.1  christos 		     0,
    435  1.1.1.2  christos 		     BFD_RELOC_16);
    436      1.1  christos 
    437      1.1  christos 	if (*op_end != '(')
    438      1.1  christos 	  {
    439      1.1  christos 	    as_bad (_("expecting indirect register `($rX)'"));
    440      1.1  christos 	    ignore_rest_of_line ();
    441      1.1  christos 	    return;
    442      1.1  christos 	  }
    443      1.1  christos 	op_end++;
    444      1.1  christos 	b = parse_register_operand (&op_end);
    445      1.1  christos 	if (*op_end != ')')
    446      1.1  christos 	  {
    447      1.1  christos 	    as_bad (_("missing closing parenthesis"));
    448      1.1  christos 	    ignore_rest_of_line ();
    449      1.1  christos 	    return;
    450      1.1  christos 	  }
    451      1.1  christos 	op_end++;
    452      1.1  christos 
    453      1.1  christos 	while (ISSPACE (*op_end))
    454      1.1  christos 	  op_end++;
    455      1.1  christos 	if (*op_end != 0)
    456      1.1  christos 	  as_warn (_("extra stuff on line ignored"));
    457      1.1  christos 
    458      1.1  christos 	iword += (a << 4) + b;
    459      1.1  christos       }
    460      1.1  christos       break;
    461  1.1.1.2  christos     case MOXIE_F1_AiB2:
    462      1.1  christos       iword = opcode->opcode << 8;
    463      1.1  christos       while (ISSPACE (*op_end))
    464      1.1  christos 	op_end++;
    465      1.1  christos       {
    466      1.1  christos 	expressionS arg;
    467      1.1  christos 	char *offset;
    468      1.1  christos 	int a, b;
    469      1.1  christos 
    470      1.1  christos 	op_end = parse_exp_save_ilp (op_end, &arg);
    471  1.1.1.2  christos 	offset = frag_more (2);
    472      1.1  christos 	fix_new_exp (frag_now,
    473      1.1  christos 		     (offset - frag_now->fr_literal),
    474  1.1.1.2  christos 		     2,
    475      1.1  christos 		     &arg,
    476      1.1  christos 		     0,
    477  1.1.1.2  christos 		     BFD_RELOC_16);
    478      1.1  christos 
    479      1.1  christos 	if (*op_end != '(')
    480      1.1  christos 	  {
    481      1.1  christos 	    as_bad (_("expecting indirect register `($rX)'"));
    482      1.1  christos 	    ignore_rest_of_line ();
    483      1.1  christos 	    return;
    484      1.1  christos 	  }
    485      1.1  christos 	op_end++;
    486      1.1  christos 	a = parse_register_operand (&op_end);
    487      1.1  christos 	if (*op_end != ')')
    488      1.1  christos 	  {
    489      1.1  christos 	    as_bad (_("missing closing parenthesis"));
    490      1.1  christos 	    ignore_rest_of_line ();
    491      1.1  christos 	    return;
    492      1.1  christos 	  }
    493      1.1  christos 	op_end++;
    494      1.1  christos 
    495      1.1  christos 	if (*op_end != ',')
    496      1.1  christos 	  {
    497      1.1  christos 	    as_bad (_("expecting comma delimited operands"));
    498      1.1  christos 	    ignore_rest_of_line ();
    499      1.1  christos 	    return;
    500      1.1  christos 	  }
    501      1.1  christos 	op_end++;
    502      1.1  christos 
    503      1.1  christos  	b = parse_register_operand (&op_end);
    504      1.1  christos 	while (ISSPACE (*op_end))
    505      1.1  christos 	  op_end++;
    506      1.1  christos 
    507      1.1  christos 	while (ISSPACE (*op_end))
    508      1.1  christos 	  op_end++;
    509      1.1  christos 	if (*op_end != 0)
    510      1.1  christos 	  as_warn (_("extra stuff on line ignored"));
    511      1.1  christos 
    512      1.1  christos 	iword += (a << 4) + b;
    513      1.1  christos       }
    514      1.1  christos       break;
    515      1.1  christos     case MOXIE_F2_NARG:
    516      1.1  christos       iword = opcode->opcode << 12;
    517      1.1  christos       while (ISSPACE (*op_end))
    518      1.1  christos 	op_end++;
    519      1.1  christos       if (*op_end != 0)
    520      1.1  christos 	as_warn (_("extra stuff on line ignored"));
    521      1.1  christos       break;
    522      1.1  christos     case MOXIE_F3_PCREL:
    523      1.1  christos       iword = (3<<14) | (opcode->opcode << 10);
    524      1.1  christos       while (ISSPACE (*op_end))
    525      1.1  christos 	op_end++;
    526      1.1  christos       {
    527      1.1  christos 	expressionS arg;
    528      1.1  christos 
    529      1.1  christos 	op_end = parse_exp_save_ilp (op_end, &arg);
    530      1.1  christos 	fix_new_exp (frag_now,
    531      1.1  christos 		     (p - frag_now->fr_literal),
    532      1.1  christos 		     2,
    533      1.1  christos 		     &arg,
    534      1.1  christos 		     TRUE,
    535      1.1  christos 		     BFD_RELOC_MOXIE_10_PCREL);
    536      1.1  christos       }
    537      1.1  christos       break;
    538  1.1.1.4  christos     case MOXIE_BAD:
    539  1.1.1.4  christos       iword = 0;
    540  1.1.1.4  christos       while (ISSPACE (*op_end))
    541  1.1.1.4  christos 	op_end++;
    542  1.1.1.4  christos       if (*op_end != 0)
    543  1.1.1.4  christos 	as_warn (_("extra stuff on line ignored"));
    544  1.1.1.4  christos       break;
    545      1.1  christos     default:
    546      1.1  christos       abort ();
    547      1.1  christos     }
    548      1.1  christos 
    549      1.1  christos   md_number_to_chars (p, iword, 2);
    550  1.1.1.3  christos   dwarf2_emit_insn (2);
    551      1.1  christos 
    552      1.1  christos   while (ISSPACE (*op_end))
    553      1.1  christos     op_end++;
    554      1.1  christos 
    555      1.1  christos   if (*op_end != 0)
    556      1.1  christos     as_warn (_("extra stuff on line ignored"));
    557      1.1  christos 
    558      1.1  christos   if (pending_reloc)
    559      1.1  christos     as_bad (_("Something forgot to clean up\n"));
    560      1.1  christos }
    561      1.1  christos 
    562      1.1  christos /* Turn a string in input_line_pointer into a floating point constant
    563      1.1  christos    of type type, and store the appropriate bytes in *LITP.  The number
    564      1.1  christos    of LITTLENUMS emitted is stored in *SIZEP .  An error message is
    565      1.1  christos    returned, or NULL on OK.  */
    566      1.1  christos 
    567  1.1.1.3  christos const char *
    568      1.1  christos md_atof (int type, char *litP, int *sizeP)
    569      1.1  christos {
    570      1.1  christos   int prec;
    571      1.1  christos   LITTLENUM_TYPE words[4];
    572      1.1  christos   char *t;
    573      1.1  christos   int i;
    574      1.1  christos 
    575      1.1  christos   switch (type)
    576      1.1  christos     {
    577      1.1  christos     case 'f':
    578      1.1  christos       prec = 2;
    579      1.1  christos       break;
    580      1.1  christos 
    581      1.1  christos     case 'd':
    582      1.1  christos       prec = 4;
    583      1.1  christos       break;
    584      1.1  christos 
    585      1.1  christos     default:
    586      1.1  christos       *sizeP = 0;
    587      1.1  christos       return _("bad call to md_atof");
    588      1.1  christos     }
    589      1.1  christos 
    590      1.1  christos   t = atof_ieee (input_line_pointer, type, words);
    591      1.1  christos   if (t)
    592      1.1  christos     input_line_pointer = t;
    593      1.1  christos 
    594      1.1  christos   *sizeP = prec * 2;
    595      1.1  christos 
    596      1.1  christos   for (i = prec - 1; i >= 0; i--)
    597      1.1  christos     {
    598      1.1  christos       md_number_to_chars (litP, (valueT) words[i], 2);
    599      1.1  christos       litP += 2;
    600      1.1  christos     }
    601      1.1  christos 
    602      1.1  christos   return NULL;
    603      1.1  christos }
    604  1.1.1.2  christos 
    605  1.1.1.2  christos enum options
    606  1.1.1.2  christos {
    607  1.1.1.2  christos   OPTION_EB = OPTION_MD_BASE,
    608  1.1.1.2  christos   OPTION_EL,
    609  1.1.1.2  christos };
    610      1.1  christos 
    611      1.1  christos struct option md_longopts[] =
    612      1.1  christos {
    613  1.1.1.2  christos   { "EB",          no_argument, NULL, OPTION_EB},
    614  1.1.1.2  christos   { "EL",          no_argument, NULL, OPTION_EL},
    615  1.1.1.2  christos   { NULL,          no_argument, NULL, 0}
    616      1.1  christos };
    617  1.1.1.2  christos 
    618      1.1  christos size_t md_longopts_size = sizeof (md_longopts);
    619  1.1.1.2  christos 
    620  1.1.1.2  christos const char *md_shortopts = "";
    622      1.1  christos 
    623  1.1.1.3  christos int
    624      1.1  christos md_parse_option (int c ATTRIBUTE_UNUSED, const char *arg ATTRIBUTE_UNUSED)
    625  1.1.1.2  christos {
    626  1.1.1.2  christos   switch (c)
    627  1.1.1.2  christos     {
    628  1.1.1.2  christos     case OPTION_EB:
    629  1.1.1.2  christos       target_big_endian = 1;
    630  1.1.1.2  christos       break;
    631  1.1.1.2  christos     case OPTION_EL:
    632  1.1.1.2  christos       target_big_endian = 0;
    633  1.1.1.2  christos       break;
    634  1.1.1.2  christos     default:
    635  1.1.1.2  christos       return 0;
    636  1.1.1.2  christos     }
    637  1.1.1.2  christos 
    638      1.1  christos   return 1;
    639      1.1  christos }
    640      1.1  christos 
    641      1.1  christos void
    642      1.1  christos md_show_usage (FILE *stream ATTRIBUTE_UNUSED)
    643  1.1.1.2  christos {
    644  1.1.1.2  christos   fprintf (stream, _("\
    645  1.1.1.2  christos   -EB                     assemble for a big endian system (default)\n\
    646      1.1  christos   -EL                     assemble for a little endian system\n"));
    647      1.1  christos }
    648      1.1  christos 
    649      1.1  christos /* Apply a fixup to the object file.  */
    650      1.1  christos 
    651  1.1.1.2  christos void
    652      1.1  christos md_apply_fix (fixS *fixP ATTRIBUTE_UNUSED,
    653      1.1  christos 	      valueT * valP ATTRIBUTE_UNUSED, segT seg ATTRIBUTE_UNUSED)
    654      1.1  christos {
    655      1.1  christos   char *buf = fixP->fx_where + fixP->fx_frag->fr_literal;
    656      1.1  christos   long val = *valP;
    657      1.1  christos   long newval;
    658      1.1  christos   long max, min;
    659      1.1  christos 
    660      1.1  christos   max = min = 0;
    661      1.1  christos   switch (fixP->fx_r_type)
    662      1.1  christos     {
    663  1.1.1.2  christos     case BFD_RELOC_32:
    664  1.1.1.2  christos       if (target_big_endian)
    665  1.1.1.2  christos 	{
    666  1.1.1.2  christos 	  buf[0] = val >> 24;
    667  1.1.1.2  christos 	  buf[1] = val >> 16;
    668  1.1.1.2  christos 	  buf[2] = val >> 8;
    669  1.1.1.2  christos 	  buf[3] = val >> 0;
    670  1.1.1.2  christos 	}
    671  1.1.1.2  christos       else
    672  1.1.1.2  christos 	{
    673  1.1.1.2  christos 	  buf[3] = val >> 24;
    674  1.1.1.2  christos 	  buf[2] = val >> 16;
    675  1.1.1.2  christos 	  buf[1] = val >> 8;
    676  1.1.1.2  christos 	  buf[0] = val >> 0;
    677  1.1.1.2  christos 	}
    678      1.1  christos       buf += 4;
    679      1.1  christos       break;
    680      1.1  christos 
    681  1.1.1.2  christos     case BFD_RELOC_16:
    682  1.1.1.2  christos       if (target_big_endian)
    683  1.1.1.2  christos 	{
    684  1.1.1.2  christos 	  buf[0] = val >> 8;
    685  1.1.1.2  christos 	  buf[1] = val >> 0;
    686  1.1.1.2  christos 	}
    687  1.1.1.2  christos       else
    688  1.1.1.2  christos 	{
    689  1.1.1.2  christos 	  buf[1] = val >> 8;
    690  1.1.1.2  christos 	  buf[0] = val >> 0;
    691  1.1.1.2  christos 	}
    692      1.1  christos       buf += 2;
    693      1.1  christos       break;
    694      1.1  christos 
    695      1.1  christos     case BFD_RELOC_8:
    696      1.1  christos       *buf++ = val;
    697      1.1  christos       break;
    698      1.1  christos 
    699      1.1  christos     case BFD_RELOC_MOXIE_10_PCREL:
    700      1.1  christos       if (!val)
    701      1.1  christos 	break;
    702      1.1  christos       if (val < -1024 || val > 1022)
    703      1.1  christos 	as_bad_where (fixP->fx_file, fixP->fx_line,
    704      1.1  christos                       _("pcrel too far BFD_RELOC_MOXIE_10"));
    705      1.1  christos       /* 11 bit offset even numbered, so we remove right bit.  */
    706      1.1  christos       val >>= 1;
    707      1.1  christos       newval = md_chars_to_number (buf, 2);
    708      1.1  christos       newval |= val & 0x03ff;
    709      1.1  christos       md_number_to_chars (buf, newval, 2);
    710      1.1  christos       break;
    711      1.1  christos 
    712      1.1  christos     default:
    713      1.1  christos       abort ();
    714      1.1  christos     }
    715      1.1  christos 
    716      1.1  christos   if (max != 0 && (val < min || val > max))
    717      1.1  christos     as_bad_where (fixP->fx_file, fixP->fx_line, _("offset out of range"));
    718      1.1  christos 
    719      1.1  christos   if (fixP->fx_addsy == NULL && fixP->fx_pcrel == 0)
    720      1.1  christos     fixP->fx_done = 1;
    721      1.1  christos }
    722  1.1.1.2  christos 
    723      1.1  christos /* Put number into target byte order.  */
    724      1.1  christos 
    725  1.1.1.2  christos void
    726      1.1  christos md_number_to_chars (char * ptr, valueT use, int nbytes)
    727  1.1.1.2  christos {
    728  1.1.1.2  christos   if (target_big_endian)
    729  1.1.1.2  christos     number_to_chars_bigendian (ptr, use, nbytes);
    730  1.1.1.2  christos   else
    731      1.1  christos     number_to_chars_littleendian (ptr, use, nbytes);
    732      1.1  christos }
    733      1.1  christos 
    734      1.1  christos /* Convert from target byte order to host byte order.  */
    735  1.1.1.2  christos 
    736  1.1.1.2  christos static valueT
    737      1.1  christos md_chars_to_number (char * buf, int n)
    738  1.1.1.2  christos {
    739  1.1.1.2  christos   valueT result = 0;
    740      1.1  christos   unsigned char * where = (unsigned char *) buf;
    741  1.1.1.2  christos 
    742  1.1.1.2  christos   if (target_big_endian)
    743  1.1.1.2  christos     {
    744  1.1.1.2  christos       while (n--)
    745  1.1.1.2  christos 	{
    746  1.1.1.2  christos 	  result <<= 8;
    747  1.1.1.2  christos 	  result |= (*where++ & 255);
    748  1.1.1.2  christos 	}
    749  1.1.1.2  christos     }
    750      1.1  christos   else
    751  1.1.1.2  christos     {
    752  1.1.1.2  christos       while (n--)
    753  1.1.1.2  christos 	{
    754  1.1.1.2  christos 	  result <<= 8;
    755  1.1.1.2  christos 	  result |= (where[n] & 255);
    756      1.1  christos 	}
    757      1.1  christos     }
    758  1.1.1.2  christos 
    759      1.1  christos   return result;
    760      1.1  christos }
    761      1.1  christos 
    762      1.1  christos /* Generate a machine-dependent relocation.  */
    763      1.1  christos arelent *
    764      1.1  christos tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixP)
    765      1.1  christos {
    766      1.1  christos   arelent *relP;
    767      1.1  christos   bfd_reloc_code_real_type code;
    768      1.1  christos 
    769      1.1  christos   switch (fixP->fx_r_type)
    770      1.1  christos     {
    771      1.1  christos     case BFD_RELOC_32:
    772      1.1  christos       code = fixP->fx_r_type;
    773      1.1  christos       break;
    774      1.1  christos     case BFD_RELOC_MOXIE_10_PCREL:
    775      1.1  christos       code = fixP->fx_r_type;
    776      1.1  christos       break;
    777      1.1  christos     default:
    778      1.1  christos       as_bad_where (fixP->fx_file, fixP->fx_line,
    779      1.1  christos 		    _("Semantics error.  This type of operand can not be relocated, it must be an assembly-time constant"));
    780      1.1  christos       return 0;
    781      1.1  christos     }
    782  1.1.1.3  christos 
    783  1.1.1.3  christos   relP = XNEW (arelent);
    784      1.1  christos   relP->sym_ptr_ptr = XNEW (asymbol *);
    785      1.1  christos   *relP->sym_ptr_ptr = symbol_get_bfdsym (fixP->fx_addsy);
    786      1.1  christos   relP->address = fixP->fx_frag->fr_address + fixP->fx_where;
    787      1.1  christos 
    788      1.1  christos   relP->addend = fixP->fx_offset;
    789      1.1  christos 
    790      1.1  christos   /* This is the standard place for KLUDGEs to work around bugs in
    791      1.1  christos      bfd_install_relocation (first such note in the documentation
    792      1.1  christos      appears with binutils-2.8).
    793      1.1  christos 
    794      1.1  christos      That function bfd_install_relocation does the wrong thing with
    795      1.1  christos      putting stuff into the addend of a reloc (it should stay out) for a
    796      1.1  christos      weak symbol.  The really bad thing is that it adds the
    797      1.1  christos      "segment-relative offset" of the symbol into the reloc.  In this
    798      1.1  christos      case, the reloc should instead be relative to the symbol with no
    799      1.1  christos      other offset than the assembly code shows; and since the symbol is
    800      1.1  christos      weak, any local definition should be ignored until link time (or
    801      1.1  christos      thereafter).
    802      1.1  christos      To wit:  weaksym+42  should be weaksym+42 in the reloc,
    803      1.1  christos      not weaksym+(offset_from_segment_of_local_weaksym_definition)
    804      1.1  christos 
    805      1.1  christos      To "work around" this, we subtract the segment-relative offset of
    806      1.1  christos      "known" weak symbols.  This evens out the extra offset.
    807      1.1  christos 
    808      1.1  christos      That happens for a.out but not for ELF, since for ELF,
    809      1.1  christos      bfd_install_relocation uses the "special function" field of the
    810      1.1  christos      howto, and does not execute the code that needs to be undone.  */
    811      1.1  christos 
    812      1.1  christos   if (OUTPUT_FLAVOR == bfd_target_aout_flavour
    813      1.1  christos       && fixP->fx_addsy && S_IS_WEAK (fixP->fx_addsy)
    814      1.1  christos       && ! bfd_is_und_section (S_GET_SEGMENT (fixP->fx_addsy)))
    815      1.1  christos     {
    816      1.1  christos       relP->addend -= S_GET_VALUE (fixP->fx_addsy);
    817      1.1  christos     }
    818      1.1  christos 
    819      1.1  christos   relP->howto = bfd_reloc_type_lookup (stdoutput, code);
    820      1.1  christos   if (! relP->howto)
    821      1.1  christos     {
    822      1.1  christos       const char *name;
    823      1.1  christos 
    824      1.1  christos       name = S_GET_NAME (fixP->fx_addsy);
    825      1.1  christos       if (name == NULL)
    826      1.1  christos 	name = _("<unknown>");
    827      1.1  christos       as_fatal (_("Cannot generate relocation type for symbol %s, code %s"),
    828      1.1  christos 		name, bfd_get_reloc_code_name (code));
    829      1.1  christos     }
    830      1.1  christos 
    831      1.1  christos   return relP;
    832      1.1  christos }
    833      1.1  christos 
    834      1.1  christos /* Decide from what point a pc-relative relocation is relative to,
    835      1.1  christos    relative to the pc-relative fixup.  Er, relatively speaking.  */
    836      1.1  christos long
    837      1.1  christos md_pcrel_from (fixS *fixP)
    838      1.1  christos {
    839      1.1  christos   valueT addr = fixP->fx_where + fixP->fx_frag->fr_address;
    840      1.1  christos 
    841      1.1  christos   switch (fixP->fx_r_type)
    842      1.1  christos     {
    843      1.1  christos     case BFD_RELOC_32:
    844      1.1  christos       return addr + 4;
    845  1.1.1.2  christos     case BFD_RELOC_MOXIE_10_PCREL:
    846  1.1.1.2  christos       /* Offset is from the end of the instruction.  */
    847      1.1  christos       return addr + 2;
    848      1.1  christos     default:
    849      1.1  christos       abort ();
    850      1.1  christos       return addr;
    851      1.1  christos     }
    852                    }
    853