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