Home | History | Annotate | Download | only in config
      1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
      2 
      3    Copyright (C) 2009-2014 Free Software Foundation, Inc.
      4 
      5    This file is part of GAS, the GNU Assembler.
      6 
      7    GAS is free software; you can redistribute it and/or modify
      8    it under the terms of the GNU General Public License as published by
      9    the Free Software Foundation; either version 3, or (at your option)
     10    any later version.
     11 
     12    GAS is distributed in the hope that it will be useful,
     13    but WITHOUT ANY WARRANTY; without even the implied warranty of
     14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     15    GNU General Public License for more details.
     16 
     17    You should have received a copy of the GNU General Public License
     18    along with GAS; see the file COPYING.  If not, write to the Free
     19    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     20    02110-1301, USA.  */
     21 
     22 #include "as.h"
     23 #include <stdio.h>
     24 #include "bfd.h"
     25 #include "subsegs.h"
     26 #define DEFINE_TABLE
     27 #include "../opcodes/microblaze-opc.h"
     28 #include "../opcodes/microblaze-opcm.h"
     29 #include "safe-ctype.h"
     30 #include <string.h>
     31 #include <dwarf2dbg.h>
     32 #include "aout/stab_gnu.h"
     33 
     34 #ifndef streq
     35 #define streq(a,b) (strcmp (a, b) == 0)
     36 #endif
     37 
     38 #define OPTION_EB (OPTION_MD_BASE + 0)
     39 #define OPTION_EL (OPTION_MD_BASE + 1)
     40 
     41 void microblaze_generate_symbol (char *sym);
     42 static bfd_boolean check_spl_reg (unsigned *);
     43 
     44 /* Several places in this file insert raw instructions into the
     45    object. They should generate the instruction
     46    and then use these four macros to crack the instruction value into
     47    the appropriate byte values.  */
     48 #define	INST_BYTE0(x)  (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF))
     49 #define	INST_BYTE1(x)  (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
     50 #define	INST_BYTE2(x)  (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
     51 #define	INST_BYTE3(x)  (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
     52 
     53 /* This array holds the chars that always start a comment.  If the
     54    pre-processor is disabled, these aren't very useful.  */
     55 const char comment_chars[] = "#";
     56 
     57 const char line_separator_chars[] = ";";
     58 
     59 /* This array holds the chars that only start a comment at the beginning of
     60    a line.  */
     61 const char line_comment_chars[] = "#";
     62 
     63 const int md_reloc_size = 8; /* Size of relocation record.  */
     64 
     65 /* Chars that can be used to separate mant
     66    from exp in floating point numbers.  */
     67 const char EXP_CHARS[] = "eE";
     68 
     69 /* Chars that mean this number is a floating point constant
     70    As in 0f12.456
     71    or    0d1.2345e12.  */
     72 const char FLT_CHARS[] = "rRsSfFdDxXpP";
     73 
     74 /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1.  */
     75 #define UNDEFINED_PC_OFFSET  2
     76 #define DEFINED_ABS_SEGMENT  3
     77 #define DEFINED_PC_OFFSET    4
     78 #define DEFINED_RO_SEGMENT   5
     79 #define DEFINED_RW_SEGMENT   6
     80 #define LARGE_DEFINED_PC_OFFSET 7
     81 #define GOT_OFFSET           8
     82 #define PLT_OFFSET           9
     83 #define GOTOFF_OFFSET        10
     84 #define TLSGD_OFFSET         11
     85 #define TLSLD_OFFSET         12
     86 #define TLSDTPMOD_OFFSET     13
     87 #define TLSDTPREL_OFFSET     14
     88 #define TLSGOTTPREL_OFFSET   15
     89 #define TLSTPREL_OFFSET      16
     90 
     91 /* Initialize the relax table.  */
     92 const relax_typeS md_relax_table[] =
     93 {
     94   {          1,          1,                0, 0 },  /*  0: Unused.  */
     95   {          1,          1,                0, 0 },  /*  1: Unused.  */
     96   {          1,          1,                0, 0 },  /*  2: Unused.  */
     97   {          1,          1,                0, 0 },  /*  3: Unused.  */
     98   {      32767,   -32768, INST_WORD_SIZE, LARGE_DEFINED_PC_OFFSET }, /* 4: DEFINED_PC_OFFSET.  */
     99   {    1,     1,       0, 0 },                      /*  5: Unused.  */
    100   {    1,     1,       0, 0 },                      /*  6: Unused.  */
    101   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /*  7: LARGE_DEFINED_PC_OFFSET.  */
    102   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /*  8: GOT_OFFSET.  */
    103   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /*  9: PLT_OFFSET.  */
    104   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 10: GOTOFF_OFFSET.  */
    105   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 11: TLSGD_OFFSET.  */
    106   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 12: TLSLD_OFFSET.  */
    107   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 },  /* 13: TLSDTPMOD_OFFSET.  */
    108   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 14: TLSDTPREL_OFFSET.  */
    109   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 },  /* 15: TLSGOTTPREL_OFFSET.  */
    110   { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }   /* 16: TLSTPREL_OFFSET.  */
    111 };
    112 
    113 static struct hash_control * opcode_hash_control;	/* Opcode mnemonics.  */
    114 
    115 static segT sbss_segment = 0; 	/* Small bss section.  */
    116 static segT sbss2_segment = 0; 	/* Section not used.  */
    117 static segT sdata_segment = 0; 	/* Small data section.  */
    118 static segT sdata2_segment = 0; /* Small read-only section.  */
    119 static segT rodata_segment = 0; /* read-only section.  */
    120 
    121 /* Generate a symbol for stabs information.  */
    122 
    123 void
    124 microblaze_generate_symbol (char *sym)
    125 {
    126 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
    127   static int microblaze_label_count;
    128   sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count);
    129   ++microblaze_label_count;
    130 }
    131 
    132 /* Handle the section changing pseudo-ops. */
    133 
    134 static void
    135 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
    136 {
    137 #ifdef OBJ_ELF
    138   obj_elf_text (ignore);
    139 #else
    140   s_text (ignore);
    141 #endif
    142 }
    143 
    144 static void
    145 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
    146 {
    147 #ifdef OBJ_ELF
    148   obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
    149 #else
    150   s_data (ignore);
    151 #endif
    152 }
    153 
    154 /* Things in the .sdata segment are always considered to be in the small data section.  */
    155 
    156 static void
    157 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
    158 {
    159 #ifdef OBJ_ELF
    160   obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
    161 #else
    162   s_data (ignore);
    163 #endif
    164 }
    165 
    166 /* Pseudo op to make file scope bss items.  */
    167 
    168 static void
    169 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
    170 {
    171   char *name;
    172   char c;
    173   char *p;
    174   offsetT size;
    175   symbolS *symbolP;
    176   offsetT align;
    177   char *pfrag;
    178   int align2;
    179   segT current_seg = now_seg;
    180   subsegT current_subseg = now_subseg;
    181 
    182   name = input_line_pointer;
    183   c = get_symbol_end ();
    184 
    185   /* Just after name is now '\0'.  */
    186   p = input_line_pointer;
    187   *p = c;
    188   SKIP_WHITESPACE ();
    189   if (*input_line_pointer != ',')
    190     {
    191       as_bad (_("Expected comma after symbol-name: rest of line ignored."));
    192       ignore_rest_of_line ();
    193       return;
    194     }
    195 
    196   input_line_pointer++;		/* skip ',' */
    197   if ((size = get_absolute_expression ()) < 0)
    198     {
    199       as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
    200       ignore_rest_of_line ();
    201       return;
    202     }
    203 
    204   /* The third argument to .lcomm is the alignment.  */
    205   if (*input_line_pointer != ',')
    206     align = 8;
    207   else
    208     {
    209       ++input_line_pointer;
    210       align = get_absolute_expression ();
    211       if (align <= 0)
    212 	{
    213 	  as_warn (_("ignoring bad alignment"));
    214 	  align = 8;
    215 	}
    216     }
    217 
    218   *p = 0;
    219   symbolP = symbol_find_or_make (name);
    220   *p = c;
    221 
    222   if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
    223     {
    224       as_bad (_("Ignoring attempt to re-define symbol `%s'."),
    225 	      S_GET_NAME (symbolP));
    226       ignore_rest_of_line ();
    227       return;
    228     }
    229 
    230   if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
    231     {
    232       as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
    233 	      S_GET_NAME (symbolP),
    234 	      (long) S_GET_VALUE (symbolP),
    235 	      (long) size);
    236 
    237       ignore_rest_of_line ();
    238       return;
    239     }
    240 
    241   /* Allocate_bss.  */
    242   if (align)
    243     {
    244       /* Convert to a power of 2 alignment.  */
    245       for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
    246       if (align != 1)
    247 	{
    248 	  as_bad (_("Common alignment not a power of 2"));
    249 	  ignore_rest_of_line ();
    250 	  return;
    251 	}
    252     }
    253   else
    254     align2 = 0;
    255 
    256   record_alignment (current_seg, align2);
    257   subseg_set (current_seg, current_subseg);
    258   if (align2)
    259     frag_align (align2, 0, 0);
    260   if (S_GET_SEGMENT (symbolP) == current_seg)
    261     symbol_get_frag (symbolP)->fr_symbol = 0;
    262   symbol_set_frag (symbolP, frag_now);
    263   pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
    264 		    (char *) 0);
    265   *pfrag = 0;
    266   S_SET_SIZE (symbolP, size);
    267   S_SET_SEGMENT (symbolP, current_seg);
    268   subseg_set (current_seg, current_subseg);
    269   demand_empty_rest_of_line ();
    270 }
    271 
    272 static void
    273 microblaze_s_rdata (int localvar)
    274 {
    275 #ifdef OBJ_ELF
    276   if (localvar == 0)
    277     {
    278       /* rodata.  */
    279       obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
    280       if (rodata_segment == 0)
    281 	rodata_segment = subseg_new (".rodata", 0);
    282     }
    283   else
    284     {
    285       /* 1 .sdata2.  */
    286       obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
    287     }
    288 #else
    289   s_data (ignore);
    290 #endif
    291 }
    292 
    293 static void
    294 microblaze_s_bss (int localvar)
    295 {
    296 #ifdef OBJ_ELF
    297   if (localvar == 0) /* bss.  */
    298     obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
    299   else if (localvar == 1)
    300     {
    301       /* sbss.  */
    302       obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
    303       if (sbss_segment == 0)
    304 	sbss_segment = subseg_new (".sbss", 0);
    305     }
    306 #else
    307   s_data (ignore);
    308 #endif
    309 }
    310 
    311 /* endp_p is always 1 as this func is called only for .end <funcname>
    312    This func consumes the <funcname> and calls regular processing
    313    s_func(1) with arg 1 (1 for end). */
    314 
    315 static void
    316 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
    317 {
    318   *input_line_pointer = get_symbol_end ();
    319   s_func (1);
    320 }
    321 
    322 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich.  */
    323 
    324 static void
    325 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
    326 {
    327   char *name;
    328   int c;
    329   symbolS *symbolP;
    330   expressionS exp;
    331 
    332   name = input_line_pointer;
    333   c = get_symbol_end ();
    334   symbolP = symbol_find_or_make (name);
    335   S_SET_WEAK (symbolP);
    336   *input_line_pointer = c;
    337 
    338   SKIP_WHITESPACE ();
    339 
    340   if (!is_end_of_line[(unsigned char) *input_line_pointer])
    341     {
    342       if (S_IS_DEFINED (symbolP))
    343 	{
    344 	  as_bad ("Ignoring attempt to redefine symbol `%s'.",
    345 		  S_GET_NAME (symbolP));
    346 	  ignore_rest_of_line ();
    347 	  return;
    348 	}
    349 
    350       if (*input_line_pointer == ',')
    351 	{
    352 	  ++input_line_pointer;
    353 	  SKIP_WHITESPACE ();
    354 	}
    355 
    356       expression (&exp);
    357       if (exp.X_op != O_symbol)
    358 	{
    359 	  as_bad ("bad .weakext directive");
    360 	  ignore_rest_of_line ();
    361 	  return;
    362 	}
    363       symbol_set_value_expression (symbolP, &exp);
    364     }
    365 
    366   demand_empty_rest_of_line ();
    367 }
    368 
    369 /* This table describes all the machine specific pseudo-ops the assembler
    370    has to support.  The fields are:
    371    Pseudo-op name without dot
    372    Function to call to execute this pseudo-op
    373    Integer arg to pass to the function.  */
    374 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
    375    and then in the read.c table.  */
    376 const pseudo_typeS md_pseudo_table[] =
    377 {
    378   {"lcomm", microblaze_s_lcomm, 1},
    379   {"data", microblaze_s_data, 0},
    380   {"data8", cons, 1},      /* Same as byte.  */
    381   {"data16", cons, 2},     /* Same as hword.  */
    382   {"data32", cons, 4},     /* Same as word.  */
    383   {"ent", s_func, 0}, /* Treat ent as function entry point.  */
    384   {"end", microblaze_s_func, 1}, /* Treat end as function end point.  */
    385   {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section.  */
    386   {"weakext", microblaze_s_weakext, 0},
    387   {"rodata", microblaze_s_rdata, 0},
    388   {"sdata2", microblaze_s_rdata, 1},
    389   {"sdata", microblaze_s_sdata, 0},
    390   {"bss", microblaze_s_bss, 0},
    391   {"sbss", microblaze_s_bss, 1},
    392   {"text", microblaze_s_text, 0},
    393   {"word", cons, 4},
    394   {"frame", s_ignore, 0},
    395   {"mask", s_ignore, 0}, /* Emitted by gcc.  */
    396   {NULL, NULL, 0}
    397 };
    398 
    399 /* This function is called once, at assembler startup time.  This should
    400    set up all the tables, etc that the MD part of the assembler needs.  */
    401 
    402 void
    403 md_begin (void)
    404 {
    405   struct op_code_struct * opcode;
    406 
    407   opcode_hash_control = hash_new ();
    408 
    409   /* Insert unique names into hash table.  */
    410   for (opcode = opcodes; opcode->name; opcode ++)
    411     hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
    412 }
    413 
    414 /* Try to parse a reg name.  */
    415 
    416 static char *
    417 parse_reg (char * s, unsigned * reg)
    418 {
    419   unsigned tmpreg = 0;
    420 
    421   /* Strip leading whitespace.  */
    422   while (ISSPACE (* s))
    423     ++ s;
    424 
    425   if (strncasecmp (s, "rpc", 3) == 0)
    426     {
    427       *reg = REG_PC;
    428       return s + 3;
    429     }
    430   else if (strncasecmp (s, "rmsr", 4) == 0)
    431     {
    432       *reg = REG_MSR;
    433       return s + 4;
    434     }
    435   else if (strncasecmp (s, "rear", 4) == 0)
    436     {
    437       *reg = REG_EAR;
    438       return s + 4;
    439     }
    440   else if (strncasecmp (s, "resr", 4) == 0)
    441     {
    442       *reg = REG_ESR;
    443       return s + 4;
    444     }
    445   else if (strncasecmp (s, "rfsr", 4) == 0)
    446     {
    447       *reg = REG_FSR;
    448       return s + 4;
    449     }
    450   else if (strncasecmp (s, "rbtr", 4) == 0)
    451     {
    452       *reg = REG_BTR;
    453       return s + 4;
    454     }
    455   else if (strncasecmp (s, "redr", 4) == 0)
    456     {
    457       *reg = REG_EDR;
    458       return s + 4;
    459     }
    460   /* MMU registers start.  */
    461   else if (strncasecmp (s, "rpid", 4) == 0)
    462     {
    463       *reg = REG_PID;
    464       return s + 4;
    465     }
    466   else if (strncasecmp (s, "rzpr", 4) == 0)
    467     {
    468       *reg = REG_ZPR;
    469       return s + 4;
    470     }
    471   else if (strncasecmp (s, "rtlbx", 5) == 0)
    472     {
    473       *reg = REG_TLBX;
    474       return s + 5;
    475     }
    476   else if (strncasecmp (s, "rtlblo", 6) == 0)
    477     {
    478       *reg = REG_TLBLO;
    479       return s + 6;
    480     }
    481   else if (strncasecmp (s, "rtlbhi", 6) == 0)
    482     {
    483       *reg = REG_TLBHI;
    484       return s + 6;
    485     }
    486   else if (strncasecmp (s, "rtlbsx", 6) == 0)
    487     {
    488       *reg = REG_TLBSX;
    489       return s + 6;
    490     }
    491   /* MMU registers end.  */
    492   else if (strncasecmp (s, "rpvr", 4) == 0)
    493     {
    494       if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
    495         {
    496           tmpreg = (s[4]-'0')*10 + s[5] - '0';
    497           s += 6;
    498         }
    499 
    500       else if (ISDIGIT (s[4]))
    501         {
    502           tmpreg = s[4] - '0';
    503           s += 5;
    504         }
    505       else
    506         as_bad (_("register expected, but saw '%.6s'"), s);
    507       if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
    508         *reg = REG_PVR + tmpreg;
    509       else
    510         {
    511           as_bad (_("Invalid register number at '%.6s'"), s);
    512           *reg = REG_PVR;
    513         }
    514       return s;
    515     }
    516   else if (strncasecmp (s, "rsp", 3) == 0)
    517     {
    518       *reg = REG_SP;
    519       return s + 3;
    520     }
    521   else if (strncasecmp (s, "rfsl", 4) == 0)
    522     {
    523       if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
    524         {
    525           tmpreg = (s[4] - '0') * 10 + s[5] - '0';
    526           s += 6;
    527         }
    528       else if (ISDIGIT (s[4]))
    529         {
    530           tmpreg = s[4] - '0';
    531           s += 5;
    532         }
    533       else
    534 	as_bad (_("register expected, but saw '%.6s'"), s);
    535 
    536       if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
    537         *reg = tmpreg;
    538       else
    539 	{
    540           as_bad (_("Invalid register number at '%.6s'"), s);
    541           *reg = 0;
    542 	}
    543       return s;
    544     }
    545   /* Stack protection registers.  */
    546   else if (strncasecmp (s, "rshr", 4) == 0)
    547     {
    548       *reg = REG_SHR;
    549       return s + 4;
    550     }
    551   else if (strncasecmp (s, "rslr", 4) == 0)
    552     {
    553       *reg = REG_SLR;
    554       return s + 4;
    555     }
    556   else
    557     {
    558       if (TOLOWER (s[0]) == 'r')
    559         {
    560           if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
    561             {
    562               tmpreg = (s[1] - '0') * 10 + s[2] - '0';
    563               s += 3;
    564             }
    565           else if (ISDIGIT (s[1]))
    566             {
    567               tmpreg = s[1] - '0';
    568               s += 2;
    569             }
    570           else
    571             as_bad (_("register expected, but saw '%.6s'"), s);
    572 
    573           if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
    574             *reg = tmpreg;
    575           else
    576 	    {
    577               as_bad (_("Invalid register number at '%.6s'"), s);
    578               *reg = 0;
    579 	    }
    580           return s;
    581         }
    582     }
    583   as_bad (_("register expected, but saw '%.6s'"), s);
    584   *reg = 0;
    585   return s;
    586 }
    587 
    588 static char *
    589 parse_exp (char *s, expressionS *e)
    590 {
    591   char *save;
    592   char *new_pointer;
    593 
    594   /* Skip whitespace.  */
    595   while (ISSPACE (* s))
    596     ++ s;
    597 
    598   save = input_line_pointer;
    599   input_line_pointer = s;
    600 
    601   expression (e);
    602 
    603   if (e->X_op == O_absent)
    604     as_fatal (_("missing operand"));
    605 
    606   new_pointer = input_line_pointer;
    607   input_line_pointer = save;
    608 
    609   return new_pointer;
    610 }
    611 
    612 /* Symbol modifiers (@GOT, @PLT, @GOTOFF).  */
    613 #define IMM_NONE   0
    614 #define IMM_GOT    1
    615 #define IMM_PLT    2
    616 #define IMM_GOTOFF 3
    617 #define IMM_TLSGD  4
    618 #define IMM_TLSLD  5
    619 #define IMM_TLSDTPMOD 6
    620 #define IMM_TLSDTPREL 7
    621 #define IMM_TLSTPREL  8
    622 #define IMM_MAX    9
    623 
    624 struct imm_type {
    625 	char *isuffix;	 /* Suffix String */
    626 	int itype;       /* Suffix Type */
    627 	int otype;       /* Offset Type */
    628 };
    629 
    630 /* These are NOT in assending order of type, GOTOFF is ahead to make
    631    sure @GOTOFF does not get matched with @GOT  */
    632 static struct imm_type imm_types[] = {
    633 	{ "NONE", IMM_NONE , 0 },
    634 	{ "GOTOFF", IMM_GOTOFF , GOTOFF_OFFSET },
    635 	{ "GOT", IMM_GOT , GOT_OFFSET },
    636 	{ "PLT", IMM_PLT , PLT_OFFSET },
    637 	{ "TLSGD", IMM_TLSGD , TLSGD_OFFSET },
    638 	{ "TLSLDM", IMM_TLSLD, TLSLD_OFFSET },
    639 	{ "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET },
    640 	{ "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET },
    641 	{ "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET }
    642 };
    643 
    644 static int
    645 match_imm (const char *s, int *ilen)
    646 {
    647   int i;
    648   int slen;
    649 
    650   /* Check for matching suffix */
    651   for (i = 1; i < IMM_MAX; i++)
    652     {
    653       slen = strlen (imm_types[i].isuffix);
    654 
    655       if (strncmp (imm_types[i].isuffix, s, slen) == 0)
    656         {
    657           *ilen = slen;
    658           return imm_types[i].itype;
    659         }
    660     } /* for */
    661   *ilen = 0;
    662   return 0;
    663 }
    664 
    665 static int
    666 get_imm_otype (int itype)
    667 {
    668   int i, otype;
    669 
    670   otype = 0;
    671   /* Check for matching itype */
    672   for (i = 1; i < IMM_MAX; i++)
    673     {
    674       if (imm_types[i].itype == itype)
    675         {
    676           otype = imm_types[i].otype;
    677           break;
    678         }
    679     }
    680   return otype;
    681 }
    682 
    683 static symbolS * GOT_symbol;
    684 
    685 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
    686 
    687 static char *
    688 parse_imm (char * s, expressionS * e, int min, int max)
    689 {
    690   char *new_pointer;
    691   char *atp;
    692   int itype, ilen;
    693 
    694   ilen = 0;
    695 
    696   /* Find the start of "@GOT" or "@PLT" suffix (if any) */
    697   for (atp = s; *atp != '@'; atp++)
    698     if (is_end_of_line[(unsigned char) *atp])
    699       break;
    700 
    701   if (*atp == '@')
    702     {
    703       itype = match_imm (atp + 1, &ilen);
    704       if (itype != 0)
    705         {
    706           *atp = 0;
    707           e->X_md = itype;
    708         }
    709       else
    710         {
    711           atp = NULL;
    712           e->X_md = 0;
    713           ilen = 0;
    714         }
    715       *atp = 0;
    716     }
    717   else
    718     {
    719       atp = NULL;
    720       e->X_md = 0;
    721     }
    722 
    723   if (atp && !GOT_symbol)
    724     {
    725       GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
    726     }
    727 
    728   new_pointer = parse_exp (s, e);
    729 
    730   if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20))
    731     {
    732       GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
    733     }
    734 
    735   if (e->X_op == O_absent)
    736     ; /* An error message has already been emitted.  */
    737   else if ((e->X_op != O_constant && e->X_op != O_symbol) )
    738     as_fatal (_("operand must be a constant or a label"));
    739   else if ((e->X_op == O_constant) && ((int) e->X_add_number < min
    740 				       || (int) e->X_add_number > max))
    741     {
    742       as_fatal (_("operand must be absolute in range %d..%d, not %d"),
    743                 min, max, (int) e->X_add_number);
    744     }
    745 
    746   if (atp)
    747     {
    748       *atp = '@'; /* restore back (needed?)  */
    749       if (new_pointer >= atp)
    750         new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */
    751     }
    752   return new_pointer;
    753 }
    754 
    755 static char *
    756 check_got (int * got_type, int * got_len)
    757 {
    758   char *new_pointer;
    759   char *atp;
    760   char *past_got;
    761   int first, second;
    762   char *tmpbuf;
    763 
    764   /* Find the start of "@GOT" or "@PLT" suffix (if any).  */
    765   for (atp = input_line_pointer; *atp != '@'; atp++)
    766     if (is_end_of_line[(unsigned char) *atp])
    767       return NULL;
    768 
    769   if (strncmp (atp + 1, "GOTOFF", 5) == 0)
    770     {
    771       *got_len = 6;
    772       *got_type = IMM_GOTOFF;
    773     }
    774   else if (strncmp (atp + 1, "GOT", 3) == 0)
    775     {
    776       *got_len = 3;
    777       *got_type = IMM_GOT;
    778     }
    779   else if (strncmp (atp + 1, "PLT", 3) == 0)
    780     {
    781       *got_len = 3;
    782       *got_type = IMM_PLT;
    783     }
    784   else
    785     return NULL;
    786 
    787   if (!GOT_symbol)
    788     GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
    789 
    790   first = atp - input_line_pointer;
    791 
    792   past_got = atp + *got_len + 1;
    793   for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
    794     ;
    795   second = new_pointer - past_got;
    796   tmpbuf = xmalloc (first + second + 2); /* One extra byte for ' ' and one for NUL.  */
    797   memcpy (tmpbuf, input_line_pointer, first);
    798   tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space.  */
    799   memcpy (tmpbuf + first + 1, past_got, second);
    800   tmpbuf[first + second + 1] = '\0';
    801 
    802   return tmpbuf;
    803 }
    804 
    805 extern bfd_reloc_code_real_type
    806 parse_cons_expression_microblaze (expressionS *exp, int size)
    807 {
    808   if (size == 4)
    809     {
    810       /* Handle @GOTOFF et.al.  */
    811       char *save, *gotfree_copy;
    812       int got_len, got_type;
    813 
    814       save = input_line_pointer;
    815       gotfree_copy = check_got (& got_type, & got_len);
    816       if (gotfree_copy)
    817         input_line_pointer = gotfree_copy;
    818 
    819       expression (exp);
    820 
    821       if (gotfree_copy)
    822 	{
    823           exp->X_md = got_type;
    824           input_line_pointer = save + (input_line_pointer - gotfree_copy)
    825 	    + got_len;
    826           free (gotfree_copy);
    827         }
    828     }
    829   else
    830     expression (exp);
    831   return BFD_RELOC_NONE;
    832 }
    833 
    834 /* This is the guts of the machine-dependent assembler.  STR points to a
    835    machine dependent instruction.  This function is supposed to emit
    836    the frags/bytes it assembles to.  */
    837 
    838 static char * str_microblaze_ro_anchor = "RO";
    839 static char * str_microblaze_rw_anchor = "RW";
    840 
    841 static bfd_boolean
    842 check_spl_reg (unsigned * reg)
    843 {
    844   if ((*reg == REG_MSR)   || (*reg == REG_PC)
    845       || (*reg == REG_EAR)   || (*reg == REG_ESR)
    846       || (*reg == REG_FSR)   || (*reg == REG_BTR) || (*reg == REG_EDR)
    847       || (*reg == REG_PID)   || (*reg == REG_ZPR)
    848       || (*reg == REG_TLBX)  || (*reg == REG_TLBLO)
    849       || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
    850       || (*reg == REG_SHR)   || (*reg == REG_SLR)
    851       || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
    852     return TRUE;
    853 
    854   return FALSE;
    855 }
    856 
    857 /* Here we decide which fixups can be adjusted to make them relative to
    858    the beginning of the section instead of the symbol.  Basically we need
    859    to make sure that the dynamic relocations are done correctly, so in
    860    some cases we force the original symbol to be used.  */
    861 
    862 int
    863 tc_microblaze_fix_adjustable (struct fix *fixP)
    864 {
    865   if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
    866     return 0;
    867 
    868   if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
    869       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
    870       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
    871       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT
    872       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGD
    873       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSLD
    874       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
    875       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPREL
    876       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSDTPREL
    877       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
    878       || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSTPREL)
    879     return 0;
    880 
    881   return 1;
    882 }
    883 
    884 void
    885 md_assemble (char * str)
    886 {
    887   char * op_start;
    888   char * op_end;
    889   struct op_code_struct * opcode, *opcode1;
    890   char * output = NULL;
    891   int nlen = 0;
    892   int i;
    893   unsigned long inst, inst1;
    894   unsigned reg1;
    895   unsigned reg2;
    896   unsigned reg3;
    897   unsigned isize;
    898   unsigned int immed, temp;
    899   expressionS exp;
    900   char name[20];
    901 
    902   /* Drop leading whitespace.  */
    903   while (ISSPACE (* str))
    904     str ++;
    905 
    906   /* Find the op code end.  */
    907   for (op_start = op_end = str;
    908        *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
    909        op_end++)
    910     {
    911       name[nlen] = op_start[nlen];
    912       nlen++;
    913       if (nlen == sizeof (name) - 1)
    914 	break;
    915     }
    916 
    917   name [nlen] = 0;
    918 
    919   if (nlen == 0)
    920     {
    921       as_bad (_("can't find opcode "));
    922       return;
    923     }
    924 
    925   opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
    926   if (opcode == NULL)
    927     {
    928       as_bad (_("unknown opcode \"%s\""), name);
    929       return;
    930     }
    931 
    932   inst = opcode->bit_sequence;
    933   isize = 4;
    934 
    935   switch (opcode->inst_type)
    936     {
    937     case INST_TYPE_RD_R1_R2:
    938       if (strcmp (op_end, ""))
    939         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
    940       else
    941         {
    942           as_fatal (_("Error in statement syntax"));
    943           reg1 = 0;
    944         }
    945       if (strcmp (op_end, ""))
    946         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
    947       else
    948 	{
    949           as_fatal (_("Error in statement syntax"));
    950           reg2 = 0;
    951         }
    952       if (strcmp (op_end, ""))
    953         op_end = parse_reg (op_end + 1, &reg3);  /* Get r2.  */
    954       else
    955  	{
    956           as_fatal (_("Error in statement syntax"));
    957           reg3 = 0;
    958         }
    959 
    960       /* Check for spl registers.  */
    961       if (check_spl_reg (& reg1))
    962         as_fatal (_("Cannot use special register with this instruction"));
    963       if (check_spl_reg (& reg2))
    964         as_fatal (_("Cannot use special register with this instruction"));
    965       if (check_spl_reg (& reg3))
    966         as_fatal (_("Cannot use special register with this instruction"));
    967 
    968       if (streq (name, "sub"))
    969 	{
    970           /* sub rd, r1, r2 becomes rsub rd, r2, r1.  */
    971           inst |= (reg1 << RD_LOW) & RD_MASK;
    972           inst |= (reg3 << RA_LOW) & RA_MASK;
    973           inst |= (reg2 << RB_LOW) & RB_MASK;
    974         }
    975       else
    976         {
    977           inst |= (reg1 << RD_LOW) & RD_MASK;
    978           inst |= (reg2 << RA_LOW) & RA_MASK;
    979           inst |= (reg3 << RB_LOW) & RB_MASK;
    980         }
    981       output = frag_more (isize);
    982       break;
    983 
    984     case INST_TYPE_RD_R1_IMM:
    985       if (strcmp (op_end, ""))
    986 	op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
    987       else
    988  	{
    989           as_fatal (_("Error in statement syntax"));
    990           reg1 = 0;
    991         }
    992       if (strcmp (op_end, ""))
    993 	op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
    994       else
    995 	{
    996           as_fatal (_("Error in statement syntax"));
    997           reg2 = 0;
    998         }
    999       if (strcmp (op_end, ""))
   1000 	op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
   1001       else
   1002 	as_fatal (_("Error in statement syntax"));
   1003 
   1004       /* Check for spl registers.  */
   1005       if (check_spl_reg (& reg1))
   1006 	as_fatal (_("Cannot use special register with this instruction"));
   1007       if (check_spl_reg (& reg2))
   1008 	as_fatal (_("Cannot use special register with this instruction"));
   1009 
   1010       if (exp.X_op != O_constant)
   1011 	{
   1012           char *opc;
   1013 	  relax_substateT subtype;
   1014 
   1015           if (streq (name, "lmi"))
   1016 	    as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
   1017 	  else if (streq (name, "smi"))
   1018 	    as_fatal (_("smi pseudo instruction should not use a label in imm field"));
   1019 
   1020 	  if (reg2 == REG_ROSDP)
   1021 	    opc = str_microblaze_ro_anchor;
   1022 	  else if (reg2 == REG_RWSDP)
   1023 	    opc = str_microblaze_rw_anchor;
   1024 	  else
   1025 	    opc = NULL;
   1026 	  if (exp.X_md != 0)
   1027 	    subtype = get_imm_otype(exp.X_md);
   1028 	  else
   1029 	    subtype = opcode->inst_offset_type;
   1030 
   1031 	  output = frag_var (rs_machine_dependent,
   1032 			     isize * 2, /* maxm of 2 words.  */
   1033 			     isize,     /* minm of 1 word.  */
   1034 			     subtype,   /* PC-relative or not.  */
   1035 			     exp.X_add_symbol,
   1036 			     exp.X_add_number,
   1037 			     opc);
   1038 	  immed = 0;
   1039         }
   1040       else
   1041 	{
   1042           output = frag_more (isize);
   1043           immed = exp.X_add_number;
   1044         }
   1045 
   1046       if (streq (name, "lmi") || streq (name, "smi"))
   1047 	{
   1048           /* Load/store 32-d consecutive registers.  Used on exit/entry
   1049              to subroutines to save and restore registers to stack.
   1050              Generate 32-d insts.  */
   1051           int count;
   1052 
   1053           count = 32 - reg1;
   1054           if (streq (name, "lmi"))
   1055             opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
   1056           else
   1057             opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
   1058           if (opcode == NULL)
   1059             {
   1060               as_bad (_("unknown opcode \"%s\""), "lwi");
   1061               return;
   1062             }
   1063           inst  = opcode->bit_sequence;
   1064           inst |= (reg1 << RD_LOW) & RD_MASK;
   1065           inst |= (reg2 << RA_LOW) & RA_MASK;
   1066           inst |= (immed << IMM_LOW) & IMM_MASK;
   1067 
   1068           for (i = 0; i < count - 1; i++)
   1069 	    {
   1070               output[0] = INST_BYTE0 (inst);
   1071               output[1] = INST_BYTE1 (inst);
   1072               output[2] = INST_BYTE2 (inst);
   1073               output[3] = INST_BYTE3 (inst);
   1074               output = frag_more (isize);
   1075               immed = immed + 4;
   1076               reg1++;
   1077               inst = opcode->bit_sequence;
   1078               inst |= (reg1 << RD_LOW) & RD_MASK;
   1079               inst |= (reg2 << RA_LOW) & RA_MASK;
   1080               inst |= (immed << IMM_LOW) & IMM_MASK;
   1081             }
   1082 	}
   1083       else
   1084 	{
   1085           temp = immed & 0xFFFF8000;
   1086           if ((temp != 0) && (temp != 0xFFFF8000))
   1087 	    {
   1088               /* Needs an immediate inst.  */
   1089               opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
   1090               if (opcode1 == NULL)
   1091                 {
   1092                   as_bad (_("unknown opcode \"%s\""), "imm");
   1093                   return;
   1094                 }
   1095 
   1096               inst1 = opcode1->bit_sequence;
   1097               inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
   1098               output[0] = INST_BYTE0 (inst1);
   1099               output[1] = INST_BYTE1 (inst1);
   1100               output[2] = INST_BYTE2 (inst1);
   1101               output[3] = INST_BYTE3 (inst1);
   1102               output = frag_more (isize);
   1103 	    }
   1104 	  inst |= (reg1 << RD_LOW) & RD_MASK;
   1105 	  inst |= (reg2 << RA_LOW) & RA_MASK;
   1106 	  inst |= (immed << IMM_LOW) & IMM_MASK;
   1107 	}
   1108       break;
   1109 
   1110     case INST_TYPE_RD_R1_IMM5:
   1111       if (strcmp (op_end, ""))
   1112         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1113       else
   1114 	{
   1115           as_fatal (_("Error in statement syntax"));
   1116           reg1 = 0;
   1117         }
   1118       if (strcmp (op_end, ""))
   1119         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
   1120       else
   1121 	{
   1122           as_fatal (_("Error in statement syntax"));
   1123           reg2 = 0;
   1124         }
   1125       if (strcmp (op_end, ""))
   1126         op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
   1127       else
   1128         as_fatal (_("Error in statement syntax"));
   1129 
   1130       /* Check for spl registers.  */
   1131       if (check_spl_reg (&reg1))
   1132         as_fatal (_("Cannot use special register with this instruction"));
   1133       if (check_spl_reg (&reg2))
   1134         as_fatal (_("Cannot use special register with this instruction"));
   1135 
   1136       if (exp.X_op != O_constant)
   1137         as_warn (_("Symbol used as immediate for shift instruction"));
   1138       else
   1139 	{
   1140           output = frag_more (isize);
   1141           immed = exp.X_add_number;
   1142         }
   1143 
   1144       if (immed != (immed % 32))
   1145 	{
   1146           as_warn (_("Shift value > 32. using <value %% 32>"));
   1147           immed = immed % 32;
   1148         }
   1149       inst |= (reg1 << RD_LOW) & RD_MASK;
   1150       inst |= (reg2 << RA_LOW) & RA_MASK;
   1151       inst |= (immed << IMM_LOW) & IMM5_MASK;
   1152       break;
   1153 
   1154     case INST_TYPE_R1_R2:
   1155       if (strcmp (op_end, ""))
   1156         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
   1157       else
   1158 	{
   1159           as_fatal (_("Error in statement syntax"));
   1160           reg1 = 0;
   1161         }
   1162       if (strcmp (op_end, ""))
   1163         op_end = parse_reg (op_end + 1, &reg2);  /* Get r2.  */
   1164       else
   1165 	{
   1166           as_fatal (_("Error in statement syntax"));
   1167           reg2 = 0;
   1168         }
   1169 
   1170       /* Check for spl registers.  */
   1171       if (check_spl_reg (& reg1))
   1172         as_fatal (_("Cannot use special register with this instruction"));
   1173       if (check_spl_reg (& reg2))
   1174         as_fatal (_("Cannot use special register with this instruction"));
   1175 
   1176       inst |= (reg1 << RA_LOW) & RA_MASK;
   1177       inst |= (reg2 << RB_LOW) & RB_MASK;
   1178       output = frag_more (isize);
   1179       break;
   1180 
   1181     case INST_TYPE_RD_R1:
   1182       if (strcmp (op_end, ""))
   1183         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1184       else
   1185 	{
   1186           as_fatal (_("Error in statement syntax"));
   1187           reg1 = 0;
   1188         }
   1189       if (strcmp (op_end, ""))
   1190         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
   1191       else
   1192 	{
   1193           as_fatal (_("Error in statement syntax"));
   1194           reg2 =0;
   1195         }
   1196 
   1197       /* Check for spl registers.  */
   1198       if (check_spl_reg (&reg1))
   1199         as_fatal (_("Cannot use special register with this instruction"));
   1200       if (check_spl_reg (&reg2))
   1201         as_fatal (_("Cannot use special register with this instruction"));
   1202 
   1203       inst |= (reg1 << RD_LOW) & RD_MASK;
   1204       inst |= (reg2 << RA_LOW) & RA_MASK;
   1205       output = frag_more (isize);
   1206       break;
   1207 
   1208     case INST_TYPE_RD_RFSL:
   1209       if (strcmp (op_end, ""))
   1210         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1211       else
   1212 	{
   1213           as_fatal (_("Error in statement syntax"));
   1214           reg1 = 0;
   1215         }
   1216       if (strcmp (op_end, ""))
   1217         op_end = parse_reg (op_end + 1, &immed);  /* Get rfslN.  */
   1218       else
   1219 	{
   1220           as_fatal (_("Error in statement syntax"));
   1221           immed = 0;
   1222         }
   1223 
   1224       /* Check for spl registers.  */
   1225       if (check_spl_reg (&reg1))
   1226         as_fatal (_("Cannot use special register with this instruction"));
   1227 
   1228       inst |= (reg1 << RD_LOW) & RD_MASK;
   1229       inst |= (immed << IMM_LOW) & RFSL_MASK;
   1230       output = frag_more (isize);
   1231       break;
   1232 
   1233     case INST_TYPE_RD_IMM15:
   1234       if (strcmp (op_end, ""))
   1235         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1236       else
   1237 	{
   1238           as_fatal (_("Error in statement syntax"));
   1239           reg1 = 0;
   1240         }
   1241 
   1242       if (strcmp (op_end, ""))
   1243         op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
   1244       else
   1245         as_fatal (_("Error in statement syntax"));
   1246 
   1247       /* Check for spl registers. */
   1248       if (check_spl_reg (&reg1))
   1249         as_fatal (_("Cannot use special register with this instruction"));
   1250 
   1251       if (exp.X_op != O_constant)
   1252         as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
   1253       else
   1254 	{
   1255           output = frag_more (isize);
   1256           immed = exp.X_add_number;
   1257         }
   1258       inst |= (reg1 << RD_LOW) & RD_MASK;
   1259       inst |= (immed << IMM_LOW) & IMM15_MASK;
   1260       break;
   1261 
   1262     case INST_TYPE_R1_RFSL:
   1263       if (strcmp (op_end, ""))
   1264         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
   1265       else
   1266 	{
   1267           as_fatal (_("Error in statement syntax"));
   1268           reg1 = 0;
   1269         }
   1270       if (strcmp (op_end, ""))
   1271         op_end = parse_reg (op_end + 1, &immed);  /* Get rfslN.  */
   1272       else
   1273 	{
   1274           as_fatal (_("Error in statement syntax"));
   1275           immed = 0;
   1276         }
   1277 
   1278       /* Check for spl registers.  */
   1279       if (check_spl_reg (&reg1))
   1280         as_fatal (_("Cannot use special register with this instruction"));
   1281 
   1282       inst |= (reg1 << RA_LOW) & RA_MASK;
   1283       inst |= (immed << IMM_LOW) & RFSL_MASK;
   1284       output = frag_more (isize);
   1285       break;
   1286 
   1287     case INST_TYPE_RFSL:
   1288       if (strcmp (op_end, ""))
   1289         op_end = parse_reg (op_end + 1, &immed);  /* Get rfslN.  */
   1290       else
   1291 	{
   1292           as_fatal (_("Error in statement syntax"));
   1293           immed = 0;
   1294         }
   1295       inst |= (immed << IMM_LOW) & RFSL_MASK;
   1296       output = frag_more (isize);
   1297       break;
   1298 
   1299     case INST_TYPE_R1:
   1300       if (strcmp (op_end, ""))
   1301         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
   1302       else
   1303 	{
   1304           as_fatal (_("Error in statement syntax"));
   1305           reg1 = 0;
   1306         }
   1307 
   1308       /* Check for spl registers.  */
   1309       if (check_spl_reg (&reg1))
   1310         as_fatal (_("Cannot use special register with this instruction"));
   1311 
   1312       inst |= (reg1 << RA_LOW) & RA_MASK;
   1313       output = frag_more (isize);
   1314       break;
   1315 
   1316       /* For tuqula insn...:) */
   1317     case INST_TYPE_RD:
   1318       if (strcmp (op_end, ""))
   1319         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1320       else
   1321 	{
   1322           as_fatal (_("Error in statement syntax"));
   1323           reg1 = 0;
   1324         }
   1325 
   1326       /* Check for spl registers.  */
   1327       if (check_spl_reg (&reg1))
   1328         as_fatal (_("Cannot use special register with this instruction"));
   1329 
   1330       inst |= (reg1 << RD_LOW) & RD_MASK;
   1331       output = frag_more (isize);
   1332       break;
   1333 
   1334     case INST_TYPE_RD_SPECIAL:
   1335       if (strcmp (op_end, ""))
   1336         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1337       else
   1338 	{
   1339           as_fatal (_("Error in statement syntax"));
   1340           reg1 = 0;
   1341         }
   1342       if (strcmp (op_end, ""))
   1343         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
   1344       else
   1345 	{
   1346           as_fatal (_("Error in statement syntax"));
   1347           reg2 = 0;
   1348         }
   1349 
   1350       if (reg2 == REG_MSR)
   1351         immed = opcode->immval_mask | REG_MSR_MASK;
   1352       else if (reg2 == REG_PC)
   1353         immed = opcode->immval_mask | REG_PC_MASK;
   1354       else if (reg2 == REG_EAR)
   1355         immed = opcode->immval_mask | REG_EAR_MASK;
   1356       else if (reg2 == REG_ESR)
   1357         immed = opcode->immval_mask | REG_ESR_MASK;
   1358       else if (reg2 == REG_FSR)
   1359         immed = opcode->immval_mask | REG_FSR_MASK;
   1360       else if (reg2 == REG_BTR)
   1361         immed = opcode->immval_mask | REG_BTR_MASK;
   1362       else if (reg2 == REG_EDR)
   1363         immed = opcode->immval_mask | REG_EDR_MASK;
   1364       else if (reg2 == REG_PID)
   1365         immed = opcode->immval_mask | REG_PID_MASK;
   1366       else if (reg2 == REG_ZPR)
   1367         immed = opcode->immval_mask | REG_ZPR_MASK;
   1368       else if (reg2 == REG_TLBX)
   1369         immed = opcode->immval_mask | REG_TLBX_MASK;
   1370       else if (reg2 == REG_TLBLO)
   1371         immed = opcode->immval_mask | REG_TLBLO_MASK;
   1372       else if (reg2 == REG_TLBHI)
   1373         immed = opcode->immval_mask | REG_TLBHI_MASK;
   1374       else if (reg2 == REG_SHR)
   1375         immed = opcode->immval_mask | REG_SHR_MASK;
   1376       else if (reg2 == REG_SLR)
   1377         immed = opcode->immval_mask | REG_SLR_MASK;
   1378       else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
   1379 	immed = opcode->immval_mask | REG_PVR_MASK | reg2;
   1380       else
   1381         as_fatal (_("invalid value for special purpose register"));
   1382       inst |= (reg1 << RD_LOW) & RD_MASK;
   1383       inst |= (immed << IMM_LOW) & IMM_MASK;
   1384       output = frag_more (isize);
   1385       break;
   1386 
   1387     case INST_TYPE_SPECIAL_R1:
   1388       if (strcmp (op_end, ""))
   1389         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1390       else
   1391 	{
   1392           as_fatal (_("Error in statement syntax"));
   1393           reg1 = 0;
   1394         }
   1395       if (strcmp (op_end, ""))
   1396         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
   1397       else
   1398 	{
   1399           as_fatal (_("Error in statement syntax"));
   1400           reg2 = 0;
   1401         }
   1402 
   1403       if (reg1 == REG_MSR)
   1404         immed = opcode->immval_mask | REG_MSR_MASK;
   1405       else if (reg1 == REG_PC)
   1406         immed = opcode->immval_mask | REG_PC_MASK;
   1407       else if (reg1 == REG_EAR)
   1408         immed = opcode->immval_mask | REG_EAR_MASK;
   1409       else if (reg1 == REG_ESR)
   1410         immed = opcode->immval_mask | REG_ESR_MASK;
   1411       else if (reg1 == REG_FSR)
   1412         immed = opcode->immval_mask | REG_FSR_MASK;
   1413       else if (reg1 == REG_BTR)
   1414         immed = opcode->immval_mask | REG_BTR_MASK;
   1415       else if (reg1 == REG_EDR)
   1416         immed = opcode->immval_mask | REG_EDR_MASK;
   1417       else if (reg1 == REG_PID)
   1418         immed = opcode->immval_mask | REG_PID_MASK;
   1419       else if (reg1 == REG_ZPR)
   1420         immed = opcode->immval_mask | REG_ZPR_MASK;
   1421       else if (reg1 == REG_TLBX)
   1422         immed = opcode->immval_mask | REG_TLBX_MASK;
   1423       else if (reg1 == REG_TLBLO)
   1424         immed = opcode->immval_mask | REG_TLBLO_MASK;
   1425       else if (reg1 == REG_TLBHI)
   1426         immed = opcode->immval_mask | REG_TLBHI_MASK;
   1427       else if (reg1 == REG_TLBSX)
   1428         immed = opcode->immval_mask | REG_TLBSX_MASK;
   1429       else if (reg1 == REG_SHR)
   1430         immed = opcode->immval_mask | REG_SHR_MASK;
   1431       else if (reg1 == REG_SLR)
   1432         immed = opcode->immval_mask | REG_SLR_MASK;
   1433       else
   1434         as_fatal (_("invalid value for special purpose register"));
   1435       inst |= (reg2 << RA_LOW) & RA_MASK;
   1436       inst |= (immed << IMM_LOW) & IMM_MASK;
   1437       output = frag_more (isize);
   1438       break;
   1439 
   1440     case INST_TYPE_R1_R2_SPECIAL:
   1441       if (strcmp (op_end, ""))
   1442         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
   1443       else
   1444 	{
   1445           as_fatal (_("Error in statement syntax"));
   1446           reg1 = 0;
   1447         }
   1448       if (strcmp (op_end, ""))
   1449         op_end = parse_reg (op_end + 1, &reg2);  /* Get r2.  */
   1450       else
   1451 	{
   1452           as_fatal (_("Error in statement syntax"));
   1453           reg2 =0;
   1454         }
   1455 
   1456       /* Check for spl registers.  */
   1457       if (check_spl_reg (&reg1))
   1458         as_fatal (_("Cannot use special register with this instruction"));
   1459       if (check_spl_reg (&reg2))
   1460         as_fatal (_("Cannot use special register with this instruction"));
   1461 
   1462       /* insn wic ra, rb => wic ra, ra, rb.  */
   1463       inst |= (reg1 << RA_LOW) & RA_MASK;
   1464       inst |= (reg2 << RB_LOW) & RB_MASK;
   1465 
   1466       output = frag_more (isize);
   1467       break;
   1468 
   1469     case INST_TYPE_RD_R2:
   1470       if (strcmp (op_end, ""))
   1471         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1472       else
   1473 	{
   1474           as_fatal (_("Error in statement syntax"));
   1475           reg1 = 0;
   1476         }
   1477       if (strcmp (op_end, ""))
   1478         op_end = parse_reg (op_end + 1, &reg2);  /* Get r2.  */
   1479       else
   1480 	{
   1481           as_fatal (_("Error in statement syntax"));
   1482           reg2 = 0;
   1483         }
   1484 
   1485       /* Check for spl registers.  */
   1486       if (check_spl_reg (&reg1))
   1487         as_fatal (_("Cannot use special register with this instruction"));
   1488       if (check_spl_reg (&reg2))
   1489         as_fatal (_("Cannot use special register with this instruction"));
   1490 
   1491       inst |= (reg1 << RD_LOW) & RD_MASK;
   1492       inst |= (reg2 << RB_LOW) & RB_MASK;
   1493       output = frag_more (isize);
   1494       break;
   1495 
   1496     case INST_TYPE_R1_IMM:
   1497       if (strcmp (op_end, ""))
   1498         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
   1499       else
   1500 	{
   1501           as_fatal (_("Error in statement syntax"));
   1502           reg1 = 0;
   1503         }
   1504       if (strcmp (op_end, ""))
   1505         op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
   1506       else
   1507         as_fatal (_("Error in statement syntax"));
   1508 
   1509       /* Check for spl registers.  */
   1510       if (check_spl_reg (&reg1))
   1511         as_fatal (_("Cannot use special register with this instruction"));
   1512 
   1513       if (exp.X_op != O_constant)
   1514 	{
   1515           char *opc = NULL;
   1516           relax_substateT subtype;
   1517 
   1518 	  if (exp.X_md != 0)
   1519 	    subtype = get_imm_otype(exp.X_md);
   1520 	  else
   1521 	    subtype = opcode->inst_offset_type;
   1522 
   1523 	  output = frag_var (rs_machine_dependent,
   1524 			     isize * 2, /* maxm of 2 words.  */
   1525 			     isize,     /* minm of 1 word.  */
   1526 			     subtype,   /* PC-relative or not.  */
   1527 			     exp.X_add_symbol,
   1528 			     exp.X_add_number,
   1529 			     opc);
   1530 	  immed = 0;
   1531 	}
   1532       else
   1533 	{
   1534           output = frag_more (isize);
   1535           immed = exp.X_add_number;
   1536         }
   1537 
   1538       temp = immed & 0xFFFF8000;
   1539       if ((temp != 0) && (temp != 0xFFFF8000))
   1540 	{
   1541           /* Needs an immediate inst.  */
   1542           opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
   1543           if (opcode1 == NULL)
   1544             {
   1545               as_bad (_("unknown opcode \"%s\""), "imm");
   1546 	      return;
   1547             }
   1548 
   1549           inst1 = opcode1->bit_sequence;
   1550           inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
   1551           output[0] = INST_BYTE0 (inst1);
   1552           output[1] = INST_BYTE1 (inst1);
   1553           output[2] = INST_BYTE2 (inst1);
   1554           output[3] = INST_BYTE3 (inst1);
   1555           output = frag_more (isize);
   1556         }
   1557 
   1558       inst |= (reg1 << RA_LOW) & RA_MASK;
   1559       inst |= (immed << IMM_LOW) & IMM_MASK;
   1560       break;
   1561 
   1562     case INST_TYPE_RD_IMM:
   1563       if (strcmp (op_end, ""))
   1564         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
   1565       else
   1566 	{
   1567           as_fatal (_("Error in statement syntax"));
   1568           reg1 = 0;
   1569         }
   1570       if (strcmp (op_end, ""))
   1571         op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
   1572       else
   1573         as_fatal (_("Error in statement syntax"));
   1574 
   1575       /* Check for spl registers.  */
   1576       if (check_spl_reg (&reg1))
   1577         as_fatal (_("Cannot use special register with this instruction"));
   1578 
   1579       if (exp.X_op != O_constant)
   1580 	{
   1581           char *opc = NULL;
   1582           relax_substateT subtype;
   1583 
   1584 	  if (exp.X_md != 0)
   1585 	    subtype = get_imm_otype(exp.X_md);
   1586 	  else
   1587 	    subtype = opcode->inst_offset_type;
   1588 
   1589           output = frag_var (rs_machine_dependent,
   1590 			     isize * 2, /* maxm of 2 words.  */
   1591 			     isize,     /* minm of 1 word.  */
   1592 			     subtype,   /* PC-relative or not.  */
   1593 			     exp.X_add_symbol,
   1594 			     exp.X_add_number,
   1595 			     opc);
   1596           immed = 0;
   1597 	}
   1598       else
   1599 	{
   1600           output = frag_more (isize);
   1601           immed = exp.X_add_number;
   1602         }
   1603 
   1604       temp = immed & 0xFFFF8000;
   1605       if ((temp != 0) && (temp != 0xFFFF8000))
   1606 	{
   1607           /* Needs an immediate inst.  */
   1608           opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
   1609           if (opcode1 == NULL)
   1610             {
   1611               as_bad (_("unknown opcode \"%s\""), "imm");
   1612               return;
   1613             }
   1614 
   1615           inst1 = opcode1->bit_sequence;
   1616           inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
   1617           output[0] = INST_BYTE0 (inst1);
   1618           output[1] = INST_BYTE1 (inst1);
   1619           output[2] = INST_BYTE2 (inst1);
   1620           output[3] = INST_BYTE3 (inst1);
   1621           output = frag_more (isize);
   1622         }
   1623 
   1624       inst |= (reg1 << RD_LOW) & RD_MASK;
   1625       inst |= (immed << IMM_LOW) & IMM_MASK;
   1626       break;
   1627 
   1628     case INST_TYPE_R2:
   1629       if (strcmp (op_end, ""))
   1630         op_end = parse_reg (op_end + 1, &reg2);  /* Get r2.  */
   1631       else
   1632 	{
   1633           as_fatal (_("Error in statement syntax"));
   1634           reg2 = 0;
   1635         }
   1636 
   1637       /* Check for spl registers.  */
   1638       if (check_spl_reg (&reg2))
   1639         as_fatal (_("Cannot use special register with this instruction"));
   1640 
   1641       inst |= (reg2 << RB_LOW) & RB_MASK;
   1642       output = frag_more (isize);
   1643       break;
   1644 
   1645     case INST_TYPE_IMM:
   1646       if (streq (name, "imm"))
   1647         as_fatal (_("An IMM instruction should not be present in the .s file"));
   1648 
   1649       op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
   1650 
   1651       if (exp.X_op != O_constant)
   1652 	{
   1653           char *opc = NULL;
   1654           relax_substateT subtype;
   1655 
   1656 	  if (exp.X_md != 0)
   1657 	    subtype = get_imm_otype(exp.X_md);
   1658 	  else
   1659 	    subtype = opcode->inst_offset_type;
   1660 
   1661           output = frag_var (rs_machine_dependent,
   1662 			     isize * 2, /* maxm of 2 words.  */
   1663 			     isize,     /* minm of 1 word.  */
   1664 			     subtype,   /* PC-relative or not.  */
   1665 			     exp.X_add_symbol,
   1666 			     exp.X_add_number,
   1667 			     opc);
   1668           immed = 0;
   1669         }
   1670       else
   1671 	{
   1672           output = frag_more (isize);
   1673           immed = exp.X_add_number;
   1674         }
   1675 
   1676 
   1677       temp = immed & 0xFFFF8000;
   1678       if ((temp != 0) && (temp != 0xFFFF8000))
   1679 	{
   1680           /* Needs an immediate inst.  */
   1681           opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
   1682           if (opcode1 == NULL)
   1683             {
   1684               as_bad (_("unknown opcode \"%s\""), "imm");
   1685               return;
   1686             }
   1687 
   1688           inst1 = opcode1->bit_sequence;
   1689           inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
   1690           output[0] = INST_BYTE0 (inst1);
   1691           output[1] = INST_BYTE1 (inst1);
   1692           output[2] = INST_BYTE2 (inst1);
   1693           output[3] = INST_BYTE3 (inst1);
   1694           output = frag_more (isize);
   1695         }
   1696       inst |= (immed << IMM_LOW) & IMM_MASK;
   1697       break;
   1698 
   1699     case INST_TYPE_NONE:
   1700       output = frag_more (isize);
   1701       break;
   1702 
   1703     case INST_TYPE_IMM5:
   1704       if (strcmp(op_end, ""))
   1705         op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5);
   1706       else
   1707         as_fatal(_("Error in statement syntax"));
   1708       if (exp.X_op != O_constant) {
   1709         as_warn(_("Symbol used as immediate for mbar instruction"));
   1710       } else {
   1711         output = frag_more (isize);
   1712         immed = exp.X_add_number;
   1713       }
   1714       if (immed != (immed % 32)) {
   1715         as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
   1716         immed = immed % 32;
   1717       }
   1718       inst |= (immed << IMM_MBAR);
   1719       break;
   1720 
   1721     default:
   1722       as_fatal (_("unimplemented opcode \"%s\""), name);
   1723     }
   1724 
   1725   /* Drop whitespace after all the operands have been parsed.  */
   1726   while (ISSPACE (* op_end))
   1727     op_end ++;
   1728 
   1729   /* Give warning message if the insn has more operands than required.  */
   1730   if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
   1731     as_warn (_("ignoring operands: %s "), op_end);
   1732 
   1733   output[0] = INST_BYTE0 (inst);
   1734   output[1] = INST_BYTE1 (inst);
   1735   output[2] = INST_BYTE2 (inst);
   1736   output[3] = INST_BYTE3 (inst);
   1737 
   1738 #ifdef OBJ_ELF
   1739   dwarf2_emit_insn (4);
   1740 #endif
   1741 }
   1742 
   1743 symbolS *
   1744 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
   1745 {
   1746   return NULL;
   1747 }
   1748 
   1749 /* Various routines to kill one day.  */
   1750 /* Equal to MAX_PRECISION in atof-ieee.c */
   1751 #define MAX_LITTLENUMS 6
   1752 
   1753 /* Turn a string in input_line_pointer into a floating point constant of type
   1754    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
   1755    emitted is stored in *sizeP.  An error message is returned, or NULL on OK.*/
   1756 char *
   1757 md_atof (int type, char * litP, int * sizeP)
   1758 {
   1759   int prec;
   1760   LITTLENUM_TYPE words[MAX_LITTLENUMS];
   1761   int    i;
   1762   char * t;
   1763 
   1764   switch (type)
   1765     {
   1766     case 'f':
   1767     case 'F':
   1768     case 's':
   1769     case 'S':
   1770       prec = 2;
   1771       break;
   1772 
   1773     case 'd':
   1774     case 'D':
   1775     case 'r':
   1776     case 'R':
   1777       prec = 4;
   1778       break;
   1779 
   1780     case 'x':
   1781     case 'X':
   1782       prec = 6;
   1783       break;
   1784 
   1785     case 'p':
   1786     case 'P':
   1787       prec = 6;
   1788       break;
   1789 
   1790     default:
   1791       *sizeP = 0;
   1792       return _("Bad call to MD_NTOF()");
   1793     }
   1794 
   1795   t = atof_ieee (input_line_pointer, type, words);
   1796 
   1797   if (t)
   1798     input_line_pointer = t;
   1799 
   1800   *sizeP = prec * sizeof (LITTLENUM_TYPE);
   1801 
   1802   if (! target_big_endian)
   1803     {
   1804       for (i = prec - 1; i >= 0; i--)
   1805         {
   1806           md_number_to_chars (litP, (valueT) words[i],
   1807                               sizeof (LITTLENUM_TYPE));
   1808           litP += sizeof (LITTLENUM_TYPE);
   1809         }
   1810     }
   1811   else
   1812     for (i = 0; i < prec; i++)
   1813       {
   1814         md_number_to_chars (litP, (valueT) words[i],
   1815                             sizeof (LITTLENUM_TYPE));
   1816         litP += sizeof (LITTLENUM_TYPE);
   1817       }
   1818 
   1819   return NULL;
   1820 }
   1821 
   1822 const char * md_shortopts = "";
   1824 
   1825 struct option md_longopts[] =
   1826 {
   1827   {"EB", no_argument, NULL, OPTION_EB},
   1828   {"EL", no_argument, NULL, OPTION_EL},
   1829   { NULL,          no_argument, NULL, 0}
   1830 };
   1831 
   1832 size_t md_longopts_size = sizeof (md_longopts);
   1833 
   1834 int md_short_jump_size;
   1835 
   1836 void
   1837 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
   1838 		      addressT from_Nddr ATTRIBUTE_UNUSED,
   1839 		      addressT to_Nddr ATTRIBUTE_UNUSED,
   1840 		      fragS * frag ATTRIBUTE_UNUSED,
   1841 		      symbolS * to_symbol ATTRIBUTE_UNUSED)
   1842 {
   1843   as_fatal (_("failed sanity check: short_jump"));
   1844 }
   1845 
   1846 void
   1847 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
   1848 		     addressT from_Nddr ATTRIBUTE_UNUSED,
   1849 		     addressT to_Nddr ATTRIBUTE_UNUSED,
   1850 		     fragS * frag ATTRIBUTE_UNUSED,
   1851 		     symbolS * to_symbol ATTRIBUTE_UNUSED)
   1852 {
   1853   as_fatal (_("failed sanity check: long_jump"));
   1854 }
   1855 
   1856 /* Called after relaxing, change the frags so they know how big they are.  */
   1857 
   1858 void
   1859 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
   1860 	         segT sec ATTRIBUTE_UNUSED,
   1861 		 fragS * fragP)
   1862 {
   1863   fixS *fixP;
   1864 
   1865   switch (fragP->fr_subtype)
   1866     {
   1867     case UNDEFINED_PC_OFFSET:
   1868       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1869 	       fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
   1870       fragP->fr_fix += INST_WORD_SIZE * 2;
   1871       fragP->fr_var = 0;
   1872       break;
   1873     case DEFINED_ABS_SEGMENT:
   1874       if (fragP->fr_symbol == GOT_symbol)
   1875         fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1876 	         fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
   1877       else
   1878         fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1879 	         fragP->fr_offset, FALSE, BFD_RELOC_64);
   1880       fragP->fr_fix += INST_WORD_SIZE * 2;
   1881       fragP->fr_var = 0;
   1882       break;
   1883     case DEFINED_RO_SEGMENT:
   1884       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
   1885 	       fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
   1886       fragP->fr_fix += INST_WORD_SIZE;
   1887       fragP->fr_var = 0;
   1888       break;
   1889     case DEFINED_RW_SEGMENT:
   1890       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
   1891 	       fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
   1892       fragP->fr_fix += INST_WORD_SIZE;
   1893       fragP->fr_var = 0;
   1894       break;
   1895     case DEFINED_PC_OFFSET:
   1896       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
   1897 	       fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
   1898       fragP->fr_fix += INST_WORD_SIZE;
   1899       fragP->fr_var = 0;
   1900       break;
   1901     case LARGE_DEFINED_PC_OFFSET:
   1902       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1903 	       fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
   1904       fragP->fr_fix += INST_WORD_SIZE * 2;
   1905       fragP->fr_var = 0;
   1906       break;
   1907     case GOT_OFFSET:
   1908       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1909 	       fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
   1910       fragP->fr_fix += INST_WORD_SIZE * 2;
   1911       fragP->fr_var = 0;
   1912       break;
   1913     case PLT_OFFSET:
   1914       fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1915 	              fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
   1916       /* fixP->fx_plt = 1; */
   1917       (void) fixP;
   1918       fragP->fr_fix += INST_WORD_SIZE * 2;
   1919       fragP->fr_var = 0;
   1920       break;
   1921     case GOTOFF_OFFSET:
   1922       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1923 	       fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
   1924       fragP->fr_fix += INST_WORD_SIZE * 2;
   1925       fragP->fr_var = 0;
   1926       break;
   1927     case TLSGD_OFFSET:
   1928       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1929 	       fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSGD);
   1930       fragP->fr_fix += INST_WORD_SIZE * 2;
   1931       fragP->fr_var = 0;
   1932       break;
   1933     case TLSLD_OFFSET:
   1934       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1935 	       fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSLD);
   1936       fragP->fr_fix += INST_WORD_SIZE * 2;
   1937       fragP->fr_var = 0;
   1938       break;
   1939     case TLSDTPREL_OFFSET:
   1940       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
   1941 	       fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSDTPREL);
   1942       fragP->fr_fix += INST_WORD_SIZE * 2;
   1943       fragP->fr_var = 0;
   1944       break;
   1945 
   1946     default:
   1947       abort ();
   1948     }
   1949 }
   1950 
   1951 /* Applies the desired value to the specified location.
   1952    Also sets up addends for 'rela' type relocations.  */
   1953 void
   1954 md_apply_fix (fixS *   fixP,
   1955 	      valueT * valp,
   1956 	      segT     segment)
   1957 {
   1958   char *       buf  = fixP->fx_where + fixP->fx_frag->fr_literal;
   1959   char *       file = fixP->fx_file ? fixP->fx_file : _("unknown");
   1960   const char * symname;
   1961   /* Note: use offsetT because it is signed, valueT is unsigned.  */
   1962   offsetT      val  = (offsetT) * valp;
   1963   int          i;
   1964   struct op_code_struct * opcode1;
   1965   unsigned long inst1;
   1966 
   1967   symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
   1968 
   1969   /* fixP->fx_offset is supposed to be set up correctly for all
   1970      symbol relocations.  */
   1971   if (fixP->fx_addsy == NULL)
   1972     {
   1973       if (!fixP->fx_pcrel)
   1974         fixP->fx_offset = val; /* Absolute relocation.  */
   1975       else
   1976         fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
   1977                  (unsigned int) fixP->fx_offset, (unsigned int) val);
   1978     }
   1979 
   1980   /* If we aren't adjusting this fixup to be against the section
   1981      symbol, we need to adjust the value.  */
   1982   if (fixP->fx_addsy != NULL)
   1983     {
   1984       if (S_IS_WEAK (fixP->fx_addsy)
   1985 	  || (symbol_used_in_reloc_p (fixP->fx_addsy)
   1986 	      && (((bfd_get_section_flags (stdoutput,
   1987 					   S_GET_SEGMENT (fixP->fx_addsy))
   1988 		    & SEC_LINK_ONCE) != 0)
   1989 		  || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
   1990 			       ".gnu.linkonce",
   1991 			       sizeof (".gnu.linkonce") - 1))))
   1992 	{
   1993 	  val -= S_GET_VALUE (fixP->fx_addsy);
   1994 	  if (val != 0 && ! fixP->fx_pcrel)
   1995             {
   1996               /* In this case, the bfd_install_relocation routine will
   1997                  incorrectly add the symbol value back in.  We just want
   1998                  the addend to appear in the object file.
   1999 	         FIXME: If this makes VALUE zero, we're toast.  */
   2000               val -= S_GET_VALUE (fixP->fx_addsy);
   2001             }
   2002 	}
   2003     }
   2004 
   2005   /* If the fix is relative to a symbol which is not defined, or not
   2006      in the same segment as the fix, we cannot resolve it here.  */
   2007   /* fixP->fx_addsy is NULL if valp contains the entire relocation.  */
   2008   if (fixP->fx_addsy != NULL
   2009       && (!S_IS_DEFINED (fixP->fx_addsy)
   2010           || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
   2011     {
   2012       fixP->fx_done = 0;
   2013 #ifdef OBJ_ELF
   2014       /* For ELF we can just return and let the reloc that will be generated
   2015          take care of everything.  For COFF we still have to insert 'val'
   2016          into the insn since the addend field will be ignored.  */
   2017       /* return; */
   2018 #endif
   2019     }
   2020   /* All fixups in the text section must be handled in the linker.  */
   2021   else if (segment->flags & SEC_CODE)
   2022     fixP->fx_done = 0;
   2023   else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
   2024     fixP->fx_done = 0;
   2025   else
   2026     fixP->fx_done = 1;
   2027 
   2028   switch (fixP->fx_r_type)
   2029     {
   2030     case BFD_RELOC_MICROBLAZE_32_LO:
   2031     case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
   2032       if (target_big_endian)
   2033 	{
   2034 	  buf[2] |= ((val >> 8) & 0xff);
   2035 	  buf[3] |= (val & 0xff);
   2036 	}
   2037       else
   2038 	{
   2039 	  buf[1] |= ((val >> 8) & 0xff);
   2040 	  buf[0] |= (val & 0xff);
   2041 	}
   2042       break;
   2043     case BFD_RELOC_MICROBLAZE_32_ROSDA:
   2044     case BFD_RELOC_MICROBLAZE_32_RWSDA:
   2045       /* Don't do anything if the symbol is not defined.  */
   2046       if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
   2047 	{
   2048 	  if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
   2049 	    as_bad_where (file, fixP->fx_line,
   2050 			  _("pcrel for branch to %s too far (0x%x)"),
   2051 			  symname, (int) val);
   2052 	  if (target_big_endian)
   2053 	    {
   2054 	      buf[2] |= ((val >> 8) & 0xff);
   2055 	      buf[3] |= (val & 0xff);
   2056 	    }
   2057 	  else
   2058 	    {
   2059 	      buf[1] |= ((val >> 8) & 0xff);
   2060 	      buf[0] |= (val & 0xff);
   2061 	    }
   2062 	}
   2063       break;
   2064     case BFD_RELOC_32:
   2065     case BFD_RELOC_RVA:
   2066     case BFD_RELOC_32_PCREL:
   2067     case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
   2068       /* Don't do anything if the symbol is not defined.  */
   2069       if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
   2070 	{
   2071 	  if (target_big_endian)
   2072 	    {
   2073 	      buf[0] |= ((val >> 24) & 0xff);
   2074 	      buf[1] |= ((val >> 16) & 0xff);
   2075 	      buf[2] |= ((val >> 8) & 0xff);
   2076 	      buf[3] |= (val & 0xff);
   2077 	    }
   2078 	  else
   2079 	    {
   2080 	      buf[3] |= ((val >> 24) & 0xff);
   2081 	      buf[2] |= ((val >> 16) & 0xff);
   2082 	      buf[1] |= ((val >> 8) & 0xff);
   2083 	      buf[0] |= (val & 0xff);
   2084 	    }
   2085 	}
   2086       break;
   2087     case BFD_RELOC_64_PCREL:
   2088     case BFD_RELOC_64:
   2089       /* Add an imm instruction.  First save the current instruction.  */
   2090       for (i = 0; i < INST_WORD_SIZE; i++)
   2091 	buf[i + INST_WORD_SIZE] = buf[i];
   2092 
   2093       /* Generate the imm instruction.  */
   2094       opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
   2095       if (opcode1 == NULL)
   2096 	{
   2097 	  as_bad (_("unknown opcode \"%s\""), "imm");
   2098 	  return;
   2099 	}
   2100 
   2101       inst1 = opcode1->bit_sequence;
   2102       if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
   2103 	inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
   2104 
   2105       buf[0] = INST_BYTE0 (inst1);
   2106       buf[1] = INST_BYTE1 (inst1);
   2107       buf[2] = INST_BYTE2 (inst1);
   2108       buf[3] = INST_BYTE3 (inst1);
   2109 
   2110       /* Add the value only if the symbol is defined.  */
   2111       if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
   2112 	{
   2113 	  if (target_big_endian)
   2114 	    {
   2115 	      buf[6] |= ((val >> 8) & 0xff);
   2116 	      buf[7] |= (val & 0xff);
   2117 	    }
   2118 	  else
   2119 	    {
   2120 	      buf[5] |= ((val >> 8) & 0xff);
   2121 	      buf[4] |= (val & 0xff);
   2122 	    }
   2123 	}
   2124       break;
   2125 
   2126     case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
   2127     case BFD_RELOC_MICROBLAZE_64_TLSGD:
   2128     case BFD_RELOC_MICROBLAZE_64_TLSLD:
   2129       S_SET_THREAD_LOCAL (fixP->fx_addsy);
   2130 
   2131     case BFD_RELOC_MICROBLAZE_64_GOTPC:
   2132     case BFD_RELOC_MICROBLAZE_64_GOT:
   2133     case BFD_RELOC_MICROBLAZE_64_PLT:
   2134     case BFD_RELOC_MICROBLAZE_64_GOTOFF:
   2135       /* Add an imm instruction.  First save the current instruction.  */
   2136       for (i = 0; i < INST_WORD_SIZE; i++)
   2137 	buf[i + INST_WORD_SIZE] = buf[i];
   2138 
   2139       /* Generate the imm instruction.  */
   2140       opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
   2141       if (opcode1 == NULL)
   2142 	{
   2143 	  as_bad (_("unknown opcode \"%s\""), "imm");
   2144 	  return;
   2145 	}
   2146 
   2147       inst1 = opcode1->bit_sequence;
   2148 
   2149       /* We can fixup call to a defined non-global address
   2150 	 within the same section only.  */
   2151       buf[0] = INST_BYTE0 (inst1);
   2152       buf[1] = INST_BYTE1 (inst1);
   2153       buf[2] = INST_BYTE2 (inst1);
   2154       buf[3] = INST_BYTE3 (inst1);
   2155       return;
   2156 
   2157     default:
   2158       break;
   2159     }
   2160 
   2161   if (fixP->fx_addsy == NULL)
   2162     {
   2163       /* This fixup has been resolved.  Create a reloc in case the linker
   2164 	 moves code around due to relaxing.  */
   2165       if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
   2166 	fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
   2167       else
   2168 	fixP->fx_r_type = BFD_RELOC_NONE;
   2169       fixP->fx_addsy = section_symbol (absolute_section);
   2170     }
   2171   return;
   2172 }
   2173 
   2174 void
   2175 md_operand (expressionS * expressionP)
   2176 {
   2177   /* Ignore leading hash symbol, if present.  */
   2178   if (*input_line_pointer == '#')
   2179     {
   2180       input_line_pointer ++;
   2181       expression (expressionP);
   2182     }
   2183 }
   2184 
   2185 /* Called just before address relaxation, return the length
   2186    by which a fragment must grow to reach it's destination.  */
   2187 
   2188 int
   2189 md_estimate_size_before_relax (fragS * fragP,
   2190 			       segT segment_type)
   2191 {
   2192   sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
   2193   sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
   2194   sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
   2195   sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
   2196 
   2197   switch (fragP->fr_subtype)
   2198     {
   2199     case INST_PC_OFFSET:
   2200       /* Used to be a PC-relative branch.  */
   2201       if (!fragP->fr_symbol)
   2202         {
   2203           /* We know the abs value: Should never happen.  */
   2204           as_bad (_("Absolute PC-relative value in relaxation code.  Assembler error....."));
   2205           abort ();
   2206         }
   2207       else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
   2208                !S_IS_WEAK (fragP->fr_symbol))
   2209         {
   2210           fragP->fr_subtype = DEFINED_PC_OFFSET;
   2211           /* Don't know now whether we need an imm instruction.  */
   2212           fragP->fr_var = INST_WORD_SIZE;
   2213         }
   2214       else if (S_IS_DEFINED (fragP->fr_symbol)
   2215 	       && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
   2216         {
   2217           /* Cannot have a PC-relative branch to a diff segment.  */
   2218           as_bad (_("PC relative branch to label %s which is not in the instruction space"),
   2219 		  S_GET_NAME (fragP->fr_symbol));
   2220           fragP->fr_subtype = UNDEFINED_PC_OFFSET;
   2221           fragP->fr_var = INST_WORD_SIZE*2;
   2222         }
   2223       else
   2224 	{
   2225 	  fragP->fr_subtype = UNDEFINED_PC_OFFSET;
   2226 	  fragP->fr_var = INST_WORD_SIZE*2;
   2227 	}
   2228       break;
   2229 
   2230     case INST_NO_OFFSET:
   2231       /* Used to be a reference to somewhere which was unknown.  */
   2232       if (fragP->fr_symbol)
   2233         {
   2234 	  if (fragP->fr_opcode == NULL)
   2235 	    {
   2236               /* Used as an absolute value.  */
   2237               fragP->fr_subtype = DEFINED_ABS_SEGMENT;
   2238               /* Variable part does not change.  */
   2239               fragP->fr_var = INST_WORD_SIZE*2;
   2240             }
   2241 	  else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
   2242 	    {
   2243               /* It is accessed using the small data read only anchor.  */
   2244               if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
   2245 		  || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
   2246 		  || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
   2247 		  || (! S_IS_DEFINED (fragP->fr_symbol)))
   2248 		{
   2249                   fragP->fr_subtype = DEFINED_RO_SEGMENT;
   2250                   fragP->fr_var = INST_WORD_SIZE;
   2251                 }
   2252 	      else
   2253 		{
   2254                   /* Variable not in small data read only segment accessed
   2255 		     using small data read only anchor.  */
   2256                   char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
   2257 
   2258                   as_bad_where (file, fragP->fr_line,
   2259                                 _("Variable is accessed using small data read "
   2260 				  "only anchor, but it is not in the small data "
   2261 			          "read only section"));
   2262                   fragP->fr_subtype = DEFINED_RO_SEGMENT;
   2263                   fragP->fr_var = INST_WORD_SIZE;
   2264                 }
   2265             }
   2266 	  else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
   2267 	    {
   2268               if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
   2269 		  || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
   2270 		  || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
   2271 		  || (!S_IS_DEFINED (fragP->fr_symbol)))
   2272 	        {
   2273                   /* It is accessed using the small data read write anchor.  */
   2274                   fragP->fr_subtype = DEFINED_RW_SEGMENT;
   2275                   fragP->fr_var = INST_WORD_SIZE;
   2276                 }
   2277 	      else
   2278 		{
   2279                   char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
   2280 
   2281                   as_bad_where (file, fragP->fr_line,
   2282                                 _("Variable is accessed using small data read "
   2283 				  "write anchor, but it is not in the small data "
   2284 				  "read write section"));
   2285                   fragP->fr_subtype = DEFINED_RW_SEGMENT;
   2286                   fragP->fr_var = INST_WORD_SIZE;
   2287                 }
   2288             }
   2289           else
   2290 	    {
   2291               as_bad (_("Incorrect fr_opcode value in frag.  Internal error....."));
   2292               abort ();
   2293             }
   2294 	}
   2295       else
   2296 	{
   2297 	  /* We know the abs value: Should never happen.  */
   2298 	  as_bad (_("Absolute value in relaxation code.  Assembler error....."));
   2299 	  abort ();
   2300 	}
   2301       break;
   2302 
   2303     case UNDEFINED_PC_OFFSET:
   2304     case LARGE_DEFINED_PC_OFFSET:
   2305     case DEFINED_ABS_SEGMENT:
   2306     case GOT_OFFSET:
   2307     case PLT_OFFSET:
   2308     case GOTOFF_OFFSET:
   2309     case TLSGD_OFFSET:
   2310     case TLSLD_OFFSET:
   2311     case TLSTPREL_OFFSET:
   2312     case TLSDTPREL_OFFSET:
   2313       fragP->fr_var = INST_WORD_SIZE*2;
   2314       break;
   2315     case DEFINED_RO_SEGMENT:
   2316     case DEFINED_RW_SEGMENT:
   2317     case DEFINED_PC_OFFSET:
   2318     case TLSDTPMOD_OFFSET:
   2319       fragP->fr_var = INST_WORD_SIZE;
   2320       break;
   2321     default:
   2322       abort ();
   2323     }
   2324 
   2325   return fragP->fr_var;
   2326 }
   2327 
   2328 /* Put number into target byte order.  */
   2329 
   2330 void
   2331 md_number_to_chars (char * ptr, valueT use, int nbytes)
   2332 {
   2333   if (target_big_endian)
   2334     number_to_chars_bigendian (ptr, use, nbytes);
   2335   else
   2336     number_to_chars_littleendian (ptr, use, nbytes);
   2337 }
   2338 
   2339 /* Round up a section size to the appropriate boundary.  */
   2340 
   2341 valueT
   2342 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
   2343 {
   2344   return size;			/* Byte alignment is fine.  */
   2345 }
   2346 
   2347 
   2348 /* The location from which a PC relative jump should be calculated,
   2349    given a PC relative reloc.  */
   2350 
   2351 long
   2352 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
   2353 {
   2354 #ifdef OBJ_ELF
   2355   /* If the symbol is undefined or defined in another section
   2356      we leave the add number alone for the linker to fix it later.
   2357      Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
   2358 
   2359   if (fixp->fx_addsy != (symbolS *) NULL
   2360       && (!S_IS_DEFINED (fixp->fx_addsy)
   2361           || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
   2362     return 0;
   2363   else
   2364     {
   2365       /* The case where we are going to resolve things... */
   2366       if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
   2367         return  fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
   2368       else
   2369         return  fixp->fx_where + fixp->fx_frag->fr_address;
   2370     }
   2371 #endif
   2372 }
   2373 
   2374 
   2375 #define F(SZ,PCREL)		(((SZ) << 1) + (PCREL))
   2376 #define MAP(SZ,PCREL,TYPE)	case F (SZ, PCREL): code = (TYPE); break
   2377 
   2378 arelent *
   2379 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
   2380 {
   2381   arelent * rel;
   2382   bfd_reloc_code_real_type code;
   2383 
   2384   switch (fixp->fx_r_type)
   2385     {
   2386     case BFD_RELOC_NONE:
   2387     case BFD_RELOC_MICROBLAZE_64_NONE:
   2388     case BFD_RELOC_32:
   2389     case BFD_RELOC_MICROBLAZE_32_LO:
   2390     case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
   2391     case BFD_RELOC_RVA:
   2392     case BFD_RELOC_64:
   2393     case BFD_RELOC_64_PCREL:
   2394     case BFD_RELOC_MICROBLAZE_32_ROSDA:
   2395     case BFD_RELOC_MICROBLAZE_32_RWSDA:
   2396     case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
   2397     case BFD_RELOC_MICROBLAZE_64_GOTPC:
   2398     case BFD_RELOC_MICROBLAZE_64_GOT:
   2399     case BFD_RELOC_MICROBLAZE_64_PLT:
   2400     case BFD_RELOC_MICROBLAZE_64_GOTOFF:
   2401     case BFD_RELOC_MICROBLAZE_32_GOTOFF:
   2402     case BFD_RELOC_MICROBLAZE_64_TLSGD:
   2403     case BFD_RELOC_MICROBLAZE_64_TLSLD:
   2404     case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
   2405     case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
   2406     case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
   2407     case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
   2408     case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
   2409       code = fixp->fx_r_type;
   2410       break;
   2411 
   2412     default:
   2413       switch (F (fixp->fx_size, fixp->fx_pcrel))
   2414         {
   2415           MAP (1, 0, BFD_RELOC_8);
   2416           MAP (2, 0, BFD_RELOC_16);
   2417           MAP (4, 0, BFD_RELOC_32);
   2418           MAP (1, 1, BFD_RELOC_8_PCREL);
   2419           MAP (2, 1, BFD_RELOC_16_PCREL);
   2420           MAP (4, 1, BFD_RELOC_32_PCREL);
   2421         default:
   2422           code = fixp->fx_r_type;
   2423           as_bad (_("Can not do %d byte %srelocation"),
   2424                   fixp->fx_size,
   2425                   fixp->fx_pcrel ? _("pc-relative") : "");
   2426         }
   2427       break;
   2428     }
   2429 
   2430   rel = (arelent *) xmalloc (sizeof (arelent));
   2431   rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
   2432 
   2433   if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
   2434     *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
   2435   else
   2436     *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   2437 
   2438   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
   2439   /* Always pass the addend along!  */
   2440   rel->addend = fixp->fx_offset;
   2441   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
   2442 
   2443   if (rel->howto == NULL)
   2444     {
   2445       as_bad_where (fixp->fx_file, fixp->fx_line,
   2446                     _("Cannot represent relocation type %s"),
   2447                     bfd_get_reloc_code_name (code));
   2448 
   2449       /* Set howto to a garbage value so that we can keep going.  */
   2450       rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
   2451       gas_assert (rel->howto != NULL);
   2452     }
   2453   return rel;
   2454 }
   2455 
   2456 int
   2457 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
   2458 {
   2459   switch (c)
   2460     {
   2461     case OPTION_EB:
   2462       target_big_endian = 1;
   2463       break;
   2464     case OPTION_EL:
   2465       target_big_endian = 0;
   2466       break;
   2467     default:
   2468       return 0;
   2469     }
   2470   return 1;
   2471 }
   2472 
   2473 void
   2474 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
   2475 {
   2476   /*  fprintf(stream, _("\
   2477       MicroBlaze options:\n\
   2478       -noSmall         Data in the comm and data sections do not go into the small data section\n")); */
   2479 }
   2480 
   2481 
   2482 /* Create a fixup for a cons expression.  If parse_cons_expression_microblaze
   2483    found a machine specific op in an expression,
   2484    then we create relocs accordingly.  */
   2485 
   2486 void
   2487 cons_fix_new_microblaze (fragS * frag,
   2488 			 int where,
   2489 			 int size,
   2490 			 expressionS *exp,
   2491 			 bfd_reloc_code_real_type r)
   2492 {
   2493   if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
   2494       (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
   2495       && (!S_IS_LOCAL (exp->X_op_symbol)))
   2496     r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
   2497   else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
   2498     {
   2499       exp->X_op = O_symbol;
   2500       r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
   2501     }
   2502   else
   2503     {
   2504       switch (size)
   2505         {
   2506         case 1:
   2507           r = BFD_RELOC_8;
   2508           break;
   2509         case 2:
   2510           r = BFD_RELOC_16;
   2511           break;
   2512         case 4:
   2513           r = BFD_RELOC_32;
   2514           break;
   2515         case 8:
   2516           r = BFD_RELOC_64;
   2517           break;
   2518         default:
   2519           as_bad (_("unsupported BFD relocation size %u"), size);
   2520           r = BFD_RELOC_32;
   2521           break;
   2522         }
   2523     }
   2524   fix_new_exp (frag, where, size, exp, 0, r);
   2525 }
   2526