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