]> Git Repo - binutils.git/blob - gas/config/tc-microblaze.c
Automatic date update in version.in
[binutils.git] / gas / config / tc-microblaze.c
1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
2
3    Copyright (C) 2009-2022 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 bool 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 htab_t  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, 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, 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, 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, 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, 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, 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   const struct op_code_struct * opcode;
415
416   opcode_hash_control = str_htab_create ();
417
418   /* Insert unique names into hash table.  */
419   for (opcode = microblaze_opcodes; opcode->name; opcode ++)
420     str_hash_insert (opcode_hash_control, opcode->name, opcode, 0);
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 && startswith (s, GOT_SYMBOL_NAME))
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 (startswith (atp + 1, "GOTOFF"))
789     {
790       *got_len = 6;
791       *got_type = IMM_GOTOFF;
792     }
793   else if (startswith (atp + 1, "GOT"))
794     {
795       *got_len = 3;
796       *got_type = IMM_GOT;
797     }
798   else if (startswith (atp + 1, "PLT"))
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 bool
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 = 0, 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 *) str_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
1076               = (struct op_code_struct *) str_hash_find (opcode_hash_control,
1077                                                          "lwi");
1078           else
1079             opcode
1080               = (struct op_code_struct *) str_hash_find (opcode_hash_control,
1081                                                          "swi");
1082           if (opcode == NULL)
1083             {
1084               as_bad (_("unknown opcode \"%s\""), "lwi");
1085               return;
1086             }
1087           inst  = opcode->bit_sequence;
1088           inst |= (reg1 << RD_LOW) & RD_MASK;
1089           inst |= (reg2 << RA_LOW) & RA_MASK;
1090           inst |= (immed << IMM_LOW) & IMM_MASK;
1091
1092           for (i = 0; i < count - 1; i++)
1093             {
1094               output[0] = INST_BYTE0 (inst);
1095               output[1] = INST_BYTE1 (inst);
1096               output[2] = INST_BYTE2 (inst);
1097               output[3] = INST_BYTE3 (inst);
1098               output = frag_more (isize);
1099               immed = immed + 4;
1100               reg1++;
1101               inst = opcode->bit_sequence;
1102               inst |= (reg1 << RD_LOW) & RD_MASK;
1103               inst |= (reg2 << RA_LOW) & RA_MASK;
1104               inst |= (immed << IMM_LOW) & IMM_MASK;
1105             }
1106         }
1107       else
1108         {
1109           temp = immed & 0xFFFF8000;
1110           if ((temp != 0) && (temp != 0xFFFF8000))
1111             {
1112               /* Needs an immediate inst.  */
1113               opcode1
1114                 = (struct op_code_struct *) str_hash_find (opcode_hash_control,
1115                                                            "imm");
1116               if (opcode1 == NULL)
1117                 {
1118                   as_bad (_("unknown opcode \"%s\""), "imm");
1119                   return;
1120                 }
1121
1122               inst1 = opcode1->bit_sequence;
1123               inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1124               output[0] = INST_BYTE0 (inst1);
1125               output[1] = INST_BYTE1 (inst1);
1126               output[2] = INST_BYTE2 (inst1);
1127               output[3] = INST_BYTE3 (inst1);
1128               output = frag_more (isize);
1129             }
1130           inst |= (reg1 << RD_LOW) & RD_MASK;
1131           inst |= (reg2 << RA_LOW) & RA_MASK;
1132           inst |= (immed << IMM_LOW) & IMM_MASK;
1133         }
1134       break;
1135
1136     case INST_TYPE_RD_R1_IMM5:
1137       if (strcmp (op_end, ""))
1138         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1139       else
1140         {
1141           as_fatal (_("Error in statement syntax"));
1142           reg1 = 0;
1143         }
1144       if (strcmp (op_end, ""))
1145         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
1146       else
1147         {
1148           as_fatal (_("Error in statement syntax"));
1149           reg2 = 0;
1150         }
1151       if (strcmp (op_end, ""))
1152         op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1153       else
1154         as_fatal (_("Error in statement syntax"));
1155
1156       /* Check for spl registers.  */
1157       if (check_spl_reg (&reg1))
1158         as_fatal (_("Cannot use special register with this instruction"));
1159       if (check_spl_reg (&reg2))
1160         as_fatal (_("Cannot use special register with this instruction"));
1161
1162       if (exp.X_op != O_constant)
1163         as_warn (_("Symbol used as immediate for shift instruction"));
1164       else
1165         {
1166           output = frag_more (isize);
1167           immed = exp.X_add_number;
1168         }
1169
1170       if (immed != (immed % 32))
1171         {
1172           as_warn (_("Shift value > 32. using <value %% 32>"));
1173           immed = immed % 32;
1174         }
1175       inst |= (reg1 << RD_LOW) & RD_MASK;
1176       inst |= (reg2 << RA_LOW) & RA_MASK;
1177       inst |= (immed << IMM_LOW) & IMM5_MASK;
1178       break;
1179
1180     case INST_TYPE_R1_R2:
1181       if (strcmp (op_end, ""))
1182         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
1183       else
1184         {
1185           as_fatal (_("Error in statement syntax"));
1186           reg1 = 0;
1187         }
1188       if (strcmp (op_end, ""))
1189         op_end = parse_reg (op_end + 1, &reg2);  /* Get r2.  */
1190       else
1191         {
1192           as_fatal (_("Error in statement syntax"));
1193           reg2 = 0;
1194         }
1195
1196       /* Check for spl registers.  */
1197       if (check_spl_reg (& reg1))
1198         as_fatal (_("Cannot use special register with this instruction"));
1199       if (check_spl_reg (& reg2))
1200         as_fatal (_("Cannot use special register with this instruction"));
1201
1202       inst |= (reg1 << RA_LOW) & RA_MASK;
1203       inst |= (reg2 << RB_LOW) & RB_MASK;
1204       output = frag_more (isize);
1205       break;
1206
1207     case INST_TYPE_RD_R1:
1208       if (strcmp (op_end, ""))
1209         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1210       else
1211         {
1212           as_fatal (_("Error in statement syntax"));
1213           reg1 = 0;
1214         }
1215       if (strcmp (op_end, ""))
1216         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
1217       else
1218         {
1219           as_fatal (_("Error in statement syntax"));
1220           reg2 =0;
1221         }
1222
1223       /* Check for spl registers.  */
1224       if (check_spl_reg (&reg1))
1225         as_fatal (_("Cannot use special register with this instruction"));
1226       if (check_spl_reg (&reg2))
1227         as_fatal (_("Cannot use special register with this instruction"));
1228
1229       inst |= (reg1 << RD_LOW) & RD_MASK;
1230       inst |= (reg2 << RA_LOW) & RA_MASK;
1231       output = frag_more (isize);
1232       break;
1233
1234     case INST_TYPE_RD_RFSL:
1235       if (strcmp (op_end, ""))
1236         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1237       else
1238         {
1239           as_fatal (_("Error in statement syntax"));
1240           reg1 = 0;
1241         }
1242       if (strcmp (op_end, ""))
1243         op_end = parse_reg (op_end + 1, &immed);  /* Get rfslN.  */
1244       else
1245         {
1246           as_fatal (_("Error in statement syntax"));
1247           immed = 0;
1248         }
1249
1250       /* Check for spl registers.  */
1251       if (check_spl_reg (&reg1))
1252         as_fatal (_("Cannot use special register with this instruction"));
1253
1254       inst |= (reg1 << RD_LOW) & RD_MASK;
1255       inst |= (immed << IMM_LOW) & RFSL_MASK;
1256       output = frag_more (isize);
1257       break;
1258
1259     case INST_TYPE_RD_IMM15:
1260       if (strcmp (op_end, ""))
1261         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1262       else
1263         {
1264           as_fatal (_("Error in statement syntax"));
1265           reg1 = 0;
1266         }
1267
1268       if (strcmp (op_end, ""))
1269         op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1270       else
1271         as_fatal (_("Error in statement syntax"));
1272
1273       /* Check for spl registers. */
1274       if (check_spl_reg (&reg1))
1275         as_fatal (_("Cannot use special register with this instruction"));
1276
1277       if (exp.X_op != O_constant)
1278         as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1279       else
1280         {
1281           output = frag_more (isize);
1282           immed = exp.X_add_number;
1283         }
1284       inst |= (reg1 << RD_LOW) & RD_MASK;
1285       inst |= (immed << IMM_LOW) & IMM15_MASK;
1286       break;
1287
1288     case INST_TYPE_R1_RFSL:
1289       if (strcmp (op_end, ""))
1290         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
1291       else
1292         {
1293           as_fatal (_("Error in statement syntax"));
1294           reg1 = 0;
1295         }
1296       if (strcmp (op_end, ""))
1297         op_end = parse_reg (op_end + 1, &immed);  /* Get rfslN.  */
1298       else
1299         {
1300           as_fatal (_("Error in statement syntax"));
1301           immed = 0;
1302         }
1303
1304       /* Check for spl registers.  */
1305       if (check_spl_reg (&reg1))
1306         as_fatal (_("Cannot use special register with this instruction"));
1307
1308       inst |= (reg1 << RA_LOW) & RA_MASK;
1309       inst |= (immed << IMM_LOW) & RFSL_MASK;
1310       output = frag_more (isize);
1311       break;
1312
1313     case INST_TYPE_RFSL:
1314       if (strcmp (op_end, ""))
1315         op_end = parse_reg (op_end + 1, &immed);  /* Get rfslN.  */
1316       else
1317         {
1318           as_fatal (_("Error in statement syntax"));
1319           immed = 0;
1320         }
1321       inst |= (immed << IMM_LOW) & RFSL_MASK;
1322       output = frag_more (isize);
1323       break;
1324
1325     case INST_TYPE_R1:
1326       if (strcmp (op_end, ""))
1327         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
1328       else
1329         {
1330           as_fatal (_("Error in statement syntax"));
1331           reg1 = 0;
1332         }
1333
1334       /* Check for spl registers.  */
1335       if (check_spl_reg (&reg1))
1336         as_fatal (_("Cannot use special register with this instruction"));
1337
1338       inst |= (reg1 << RA_LOW) & RA_MASK;
1339       output = frag_more (isize);
1340       break;
1341
1342       /* For tuqula insn...:) */
1343     case INST_TYPE_RD:
1344       if (strcmp (op_end, ""))
1345         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1346       else
1347         {
1348           as_fatal (_("Error in statement syntax"));
1349           reg1 = 0;
1350         }
1351
1352       /* Check for spl registers.  */
1353       if (check_spl_reg (&reg1))
1354         as_fatal (_("Cannot use special register with this instruction"));
1355
1356       inst |= (reg1 << RD_LOW) & RD_MASK;
1357       output = frag_more (isize);
1358       break;
1359
1360     case INST_TYPE_RD_SPECIAL:
1361       if (strcmp (op_end, ""))
1362         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1363       else
1364         {
1365           as_fatal (_("Error in statement syntax"));
1366           reg1 = 0;
1367         }
1368       if (strcmp (op_end, ""))
1369         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
1370       else
1371         {
1372           as_fatal (_("Error in statement syntax"));
1373           reg2 = 0;
1374         }
1375
1376       if (reg2 == REG_MSR)
1377         immed = opcode->immval_mask | REG_MSR_MASK;
1378       else if (reg2 == REG_PC)
1379         immed = opcode->immval_mask | REG_PC_MASK;
1380       else if (reg2 == REG_EAR)
1381         immed = opcode->immval_mask | REG_EAR_MASK;
1382       else if (reg2 == REG_ESR)
1383         immed = opcode->immval_mask | REG_ESR_MASK;
1384       else if (reg2 == REG_FSR)
1385         immed = opcode->immval_mask | REG_FSR_MASK;
1386       else if (reg2 == REG_BTR)
1387         immed = opcode->immval_mask | REG_BTR_MASK;
1388       else if (reg2 == REG_EDR)
1389         immed = opcode->immval_mask | REG_EDR_MASK;
1390       else if (reg2 == REG_PID)
1391         immed = opcode->immval_mask | REG_PID_MASK;
1392       else if (reg2 == REG_ZPR)
1393         immed = opcode->immval_mask | REG_ZPR_MASK;
1394       else if (reg2 == REG_TLBX)
1395         immed = opcode->immval_mask | REG_TLBX_MASK;
1396       else if (reg2 == REG_TLBLO)
1397         immed = opcode->immval_mask | REG_TLBLO_MASK;
1398       else if (reg2 == REG_TLBHI)
1399         immed = opcode->immval_mask | REG_TLBHI_MASK;
1400       else if (reg2 == REG_SHR)
1401         immed = opcode->immval_mask | REG_SHR_MASK;
1402       else if (reg2 == REG_SLR)
1403         immed = opcode->immval_mask | REG_SLR_MASK;
1404       else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1405         immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1406       else
1407         as_fatal (_("invalid value for special purpose register"));
1408       inst |= (reg1 << RD_LOW) & RD_MASK;
1409       inst |= (immed << IMM_LOW) & IMM_MASK;
1410       output = frag_more (isize);
1411       break;
1412
1413     case INST_TYPE_SPECIAL_R1:
1414       if (strcmp (op_end, ""))
1415         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1416       else
1417         {
1418           as_fatal (_("Error in statement syntax"));
1419           reg1 = 0;
1420         }
1421       if (strcmp (op_end, ""))
1422         op_end = parse_reg (op_end + 1, &reg2);  /* Get r1.  */
1423       else
1424         {
1425           as_fatal (_("Error in statement syntax"));
1426           reg2 = 0;
1427         }
1428
1429       if (reg1 == REG_MSR)
1430         immed = opcode->immval_mask | REG_MSR_MASK;
1431       else if (reg1 == REG_PC)
1432         immed = opcode->immval_mask | REG_PC_MASK;
1433       else if (reg1 == REG_EAR)
1434         immed = opcode->immval_mask | REG_EAR_MASK;
1435       else if (reg1 == REG_ESR)
1436         immed = opcode->immval_mask | REG_ESR_MASK;
1437       else if (reg1 == REG_FSR)
1438         immed = opcode->immval_mask | REG_FSR_MASK;
1439       else if (reg1 == REG_BTR)
1440         immed = opcode->immval_mask | REG_BTR_MASK;
1441       else if (reg1 == REG_EDR)
1442         immed = opcode->immval_mask | REG_EDR_MASK;
1443       else if (reg1 == REG_PID)
1444         immed = opcode->immval_mask | REG_PID_MASK;
1445       else if (reg1 == REG_ZPR)
1446         immed = opcode->immval_mask | REG_ZPR_MASK;
1447       else if (reg1 == REG_TLBX)
1448         immed = opcode->immval_mask | REG_TLBX_MASK;
1449       else if (reg1 == REG_TLBLO)
1450         immed = opcode->immval_mask | REG_TLBLO_MASK;
1451       else if (reg1 == REG_TLBHI)
1452         immed = opcode->immval_mask | REG_TLBHI_MASK;
1453       else if (reg1 == REG_TLBSX)
1454         immed = opcode->immval_mask | REG_TLBSX_MASK;
1455       else if (reg1 == REG_SHR)
1456         immed = opcode->immval_mask | REG_SHR_MASK;
1457       else if (reg1 == REG_SLR)
1458         immed = opcode->immval_mask | REG_SLR_MASK;
1459       else
1460         as_fatal (_("invalid value for special purpose register"));
1461       inst |= (reg2 << RA_LOW) & RA_MASK;
1462       inst |= (immed << IMM_LOW) & IMM_MASK;
1463       output = frag_more (isize);
1464       break;
1465
1466     case INST_TYPE_R1_R2_SPECIAL:
1467       if (strcmp (op_end, ""))
1468         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
1469       else
1470         {
1471           as_fatal (_("Error in statement syntax"));
1472           reg1 = 0;
1473         }
1474       if (strcmp (op_end, ""))
1475         op_end = parse_reg (op_end + 1, &reg2);  /* Get r2.  */
1476       else
1477         {
1478           as_fatal (_("Error in statement syntax"));
1479           reg2 =0;
1480         }
1481
1482       /* Check for spl registers.  */
1483       if (check_spl_reg (&reg1))
1484         as_fatal (_("Cannot use special register with this instruction"));
1485       if (check_spl_reg (&reg2))
1486         as_fatal (_("Cannot use special register with this instruction"));
1487
1488       /* insn wic ra, rb => wic ra, ra, rb.  */
1489       inst |= (reg1 << RA_LOW) & RA_MASK;
1490       inst |= (reg2 << RB_LOW) & RB_MASK;
1491
1492       output = frag_more (isize);
1493       break;
1494
1495     case INST_TYPE_RD_R2:
1496       if (strcmp (op_end, ""))
1497         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1498       else
1499         {
1500           as_fatal (_("Error in statement syntax"));
1501           reg1 = 0;
1502         }
1503       if (strcmp (op_end, ""))
1504         op_end = parse_reg (op_end + 1, &reg2);  /* Get r2.  */
1505       else
1506         {
1507           as_fatal (_("Error in statement syntax"));
1508           reg2 = 0;
1509         }
1510
1511       /* Check for spl registers.  */
1512       if (check_spl_reg (&reg1))
1513         as_fatal (_("Cannot use special register with this instruction"));
1514       if (check_spl_reg (&reg2))
1515         as_fatal (_("Cannot use special register with this instruction"));
1516
1517       inst |= (reg1 << RD_LOW) & RD_MASK;
1518       inst |= (reg2 << RB_LOW) & RB_MASK;
1519       output = frag_more (isize);
1520       break;
1521
1522     case INST_TYPE_R1_IMM:
1523       if (strcmp (op_end, ""))
1524         op_end = parse_reg (op_end + 1, &reg1);  /* Get r1.  */
1525       else
1526         {
1527           as_fatal (_("Error in statement syntax"));
1528           reg1 = 0;
1529         }
1530       if (strcmp (op_end, ""))
1531         op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1532       else
1533         as_fatal (_("Error in statement syntax"));
1534
1535       /* Check for spl registers.  */
1536       if (check_spl_reg (&reg1))
1537         as_fatal (_("Cannot use special register with this instruction"));
1538
1539       if (exp.X_op != O_constant)
1540         {
1541           char *opc = NULL;
1542           relax_substateT subtype;
1543
1544           if (exp.X_md != 0)
1545             subtype = get_imm_otype(exp.X_md);
1546           else
1547             subtype = opcode->inst_offset_type;
1548
1549           output = frag_var (rs_machine_dependent,
1550                              isize * 2, /* maxm of 2 words.  */
1551                              isize,     /* minm of 1 word.  */
1552                              subtype,   /* PC-relative or not.  */
1553                              exp.X_add_symbol,
1554                              exp.X_add_number,
1555                              opc);
1556           immed = 0;
1557         }
1558       else
1559         {
1560           output = frag_more (isize);
1561           immed = exp.X_add_number;
1562         }
1563
1564       temp = immed & 0xFFFF8000;
1565       if ((temp != 0) && (temp != 0xFFFF8000))
1566         {
1567           /* Needs an immediate inst.  */
1568           opcode1
1569             = (struct op_code_struct *) str_hash_find (opcode_hash_control,
1570                                                        "imm");
1571           if (opcode1 == NULL)
1572             {
1573               as_bad (_("unknown opcode \"%s\""), "imm");
1574               return;
1575             }
1576
1577           inst1 = opcode1->bit_sequence;
1578           inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1579           output[0] = INST_BYTE0 (inst1);
1580           output[1] = INST_BYTE1 (inst1);
1581           output[2] = INST_BYTE2 (inst1);
1582           output[3] = INST_BYTE3 (inst1);
1583           output = frag_more (isize);
1584         }
1585
1586       inst |= (reg1 << RA_LOW) & RA_MASK;
1587       inst |= (immed << IMM_LOW) & IMM_MASK;
1588       break;
1589
1590     case INST_TYPE_RD_IMM:
1591       if (strcmp (op_end, ""))
1592         op_end = parse_reg (op_end + 1, &reg1);  /* Get rd.  */
1593       else
1594         {
1595           as_fatal (_("Error in statement syntax"));
1596           reg1 = 0;
1597         }
1598       if (strcmp (op_end, ""))
1599         op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1600       else
1601         as_fatal (_("Error in statement syntax"));
1602
1603       /* Check for spl registers.  */
1604       if (check_spl_reg (&reg1))
1605         as_fatal (_("Cannot use special register with this instruction"));
1606
1607       if (exp.X_op != O_constant)
1608         {
1609           char *opc = NULL;
1610           relax_substateT subtype;
1611
1612           if (exp.X_md != 0)
1613             subtype = get_imm_otype(exp.X_md);
1614           else
1615             subtype = opcode->inst_offset_type;
1616
1617           output = frag_var (rs_machine_dependent,
1618                              isize * 2, /* maxm of 2 words.  */
1619                              isize,     /* minm of 1 word.  */
1620                              subtype,   /* PC-relative or not.  */
1621                              exp.X_add_symbol,
1622                              exp.X_add_number,
1623                              opc);
1624           immed = 0;
1625         }
1626       else
1627         {
1628           output = frag_more (isize);
1629           immed = exp.X_add_number;
1630         }
1631
1632       temp = immed & 0xFFFF8000;
1633       if ((temp != 0) && (temp != 0xFFFF8000))
1634         {
1635           /* Needs an immediate inst.  */
1636           opcode1
1637             = (struct op_code_struct *) str_hash_find (opcode_hash_control,
1638                                                        "imm");
1639           if (opcode1 == NULL)
1640             {
1641               as_bad (_("unknown opcode \"%s\""), "imm");
1642               return;
1643             }
1644
1645           inst1 = opcode1->bit_sequence;
1646           inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1647           output[0] = INST_BYTE0 (inst1);
1648           output[1] = INST_BYTE1 (inst1);
1649           output[2] = INST_BYTE2 (inst1);
1650           output[3] = INST_BYTE3 (inst1);
1651           output = frag_more (isize);
1652         }
1653
1654       inst |= (reg1 << RD_LOW) & RD_MASK;
1655       inst |= (immed << IMM_LOW) & IMM_MASK;
1656       break;
1657
1658     case INST_TYPE_R2:
1659       if (strcmp (op_end, ""))
1660         op_end = parse_reg (op_end + 1, &reg2);  /* Get r2.  */
1661       else
1662         {
1663           as_fatal (_("Error in statement syntax"));
1664           reg2 = 0;
1665         }
1666
1667       /* Check for spl registers.  */
1668       if (check_spl_reg (&reg2))
1669         as_fatal (_("Cannot use special register with this instruction"));
1670
1671       inst |= (reg2 << RB_LOW) & RB_MASK;
1672       output = frag_more (isize);
1673       break;
1674
1675     case INST_TYPE_IMM:
1676       if (streq (name, "imm"))
1677         as_fatal (_("An IMM instruction should not be present in the .s file"));
1678
1679       op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1680
1681       if (exp.X_op != O_constant)
1682         {
1683           char *opc = NULL;
1684           relax_substateT subtype;
1685
1686           if (exp.X_md != 0)
1687             subtype = get_imm_otype(exp.X_md);
1688           else
1689             subtype = opcode->inst_offset_type;
1690
1691           output = frag_var (rs_machine_dependent,
1692                              isize * 2, /* maxm of 2 words.  */
1693                              isize,     /* minm of 1 word.  */
1694                              subtype,   /* PC-relative or not.  */
1695                              exp.X_add_symbol,
1696                              exp.X_add_number,
1697                              opc);
1698           immed = 0;
1699         }
1700       else
1701         {
1702           output = frag_more (isize);
1703           immed = exp.X_add_number;
1704         }
1705
1706
1707       temp = immed & 0xFFFF8000;
1708       if ((temp != 0) && (temp != 0xFFFF8000))
1709         {
1710           /* Needs an immediate inst.  */
1711           opcode1
1712             = (struct op_code_struct *) str_hash_find (opcode_hash_control,
1713                                                        "imm");
1714           if (opcode1 == NULL)
1715             {
1716               as_bad (_("unknown opcode \"%s\""), "imm");
1717               return;
1718             }
1719
1720           inst1 = opcode1->bit_sequence;
1721           inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1722           output[0] = INST_BYTE0 (inst1);
1723           output[1] = INST_BYTE1 (inst1);
1724           output[2] = INST_BYTE2 (inst1);
1725           output[3] = INST_BYTE3 (inst1);
1726           output = frag_more (isize);
1727         }
1728       inst |= (immed << IMM_LOW) & IMM_MASK;
1729       break;
1730
1731     case INST_TYPE_NONE:
1732       output = frag_more (isize);
1733       break;
1734
1735     case INST_TYPE_IMM5:
1736       if (strcmp(op_end, ""))
1737         op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5);
1738       else
1739         as_fatal(_("Error in statement syntax"));
1740       if (exp.X_op != O_constant) {
1741         as_warn(_("Symbol used as immediate for mbar instruction"));
1742       } else {
1743         output = frag_more (isize);
1744         immed = exp.X_add_number;
1745       }
1746       if (immed != (immed % 32)) {
1747         as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1748         immed = immed % 32;
1749       }
1750       inst |= (immed << IMM_MBAR);
1751       break;
1752
1753     default:
1754       as_fatal (_("unimplemented opcode \"%s\""), name);
1755     }
1756
1757   /* Drop whitespace after all the operands have been parsed.  */
1758   while (ISSPACE (* op_end))
1759     op_end ++;
1760
1761   /* Give warning message if the insn has more operands than required.  */
1762   if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1763     as_warn (_("ignoring operands: %s "), op_end);
1764
1765   output[0] = INST_BYTE0 (inst);
1766   output[1] = INST_BYTE1 (inst);
1767   output[2] = INST_BYTE2 (inst);
1768   output[3] = INST_BYTE3 (inst);
1769
1770 #ifdef OBJ_ELF
1771   dwarf2_emit_insn (4);
1772 #endif
1773 }
1774
1775 symbolS *
1776 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1777 {
1778   return NULL;
1779 }
1780
1781 /* Turn a string in input_line_pointer into a floating point constant of type
1782    type, and store the appropriate bytes in *litP.  The number of LITTLENUMS
1783    emitted is stored in *sizeP.  An error message is returned, or NULL on OK.*/
1784
1785 const char *
1786 md_atof (int type, char * litP, int * sizeP)
1787 {
1788   int prec;
1789   LITTLENUM_TYPE words[MAX_LITTLENUMS];
1790   int    i;
1791   char * t;
1792
1793   switch (type)
1794     {
1795     case 'f':
1796     case 'F':
1797     case 's':
1798     case 'S':
1799       prec = 2;
1800       break;
1801
1802     case 'd':
1803     case 'D':
1804     case 'r':
1805     case 'R':
1806       prec = 4;
1807       break;
1808
1809     case 'x':
1810     case 'X':
1811       prec = 6;
1812       break;
1813
1814     case 'p':
1815     case 'P':
1816       prec = 6;
1817       break;
1818
1819     default:
1820       *sizeP = 0;
1821       return _("Bad call to MD_NTOF()");
1822     }
1823
1824   t = atof_ieee (input_line_pointer, type, words);
1825
1826   if (t)
1827     input_line_pointer = t;
1828
1829   *sizeP = prec * sizeof (LITTLENUM_TYPE);
1830
1831   if (! target_big_endian)
1832     {
1833       for (i = prec - 1; i >= 0; i--)
1834         {
1835           md_number_to_chars (litP, (valueT) words[i],
1836                               sizeof (LITTLENUM_TYPE));
1837           litP += sizeof (LITTLENUM_TYPE);
1838         }
1839     }
1840   else
1841     for (i = 0; i < prec; i++)
1842       {
1843         md_number_to_chars (litP, (valueT) words[i],
1844                             sizeof (LITTLENUM_TYPE));
1845         litP += sizeof (LITTLENUM_TYPE);
1846       }
1847
1848   return NULL;
1849 }
1850 \f
1851 const char * md_shortopts = "";
1852
1853 struct option md_longopts[] =
1854 {
1855   {"EB", no_argument, NULL, OPTION_EB},
1856   {"EL", no_argument, NULL, OPTION_EL},
1857   { NULL,          no_argument, NULL, 0}
1858 };
1859
1860 size_t md_longopts_size = sizeof (md_longopts);
1861
1862 int md_short_jump_size;
1863
1864 void
1865 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1866                       addressT from_Nddr ATTRIBUTE_UNUSED,
1867                       addressT to_Nddr ATTRIBUTE_UNUSED,
1868                       fragS * frag ATTRIBUTE_UNUSED,
1869                       symbolS * to_symbol ATTRIBUTE_UNUSED)
1870 {
1871   as_fatal (_("failed sanity check: short_jump"));
1872 }
1873
1874 void
1875 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1876                      addressT from_Nddr ATTRIBUTE_UNUSED,
1877                      addressT to_Nddr ATTRIBUTE_UNUSED,
1878                      fragS * frag ATTRIBUTE_UNUSED,
1879                      symbolS * to_symbol ATTRIBUTE_UNUSED)
1880 {
1881   as_fatal (_("failed sanity check: long_jump"));
1882 }
1883
1884 /* Called after relaxing, change the frags so they know how big they are.  */
1885
1886 void
1887 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1888                  segT sec ATTRIBUTE_UNUSED,
1889                  fragS * fragP)
1890 {
1891   fixS *fixP;
1892
1893   switch (fragP->fr_subtype)
1894     {
1895     case UNDEFINED_PC_OFFSET:
1896       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1897                fragP->fr_offset, true, BFD_RELOC_64_PCREL);
1898       fragP->fr_fix += INST_WORD_SIZE * 2;
1899       fragP->fr_var = 0;
1900       break;
1901     case DEFINED_ABS_SEGMENT:
1902       if (fragP->fr_symbol == GOT_symbol)
1903         fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1904                  fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_GOTPC);
1905       else
1906         fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1907                  fragP->fr_offset, false, BFD_RELOC_64);
1908       fragP->fr_fix += INST_WORD_SIZE * 2;
1909       fragP->fr_var = 0;
1910       break;
1911     case DEFINED_RO_SEGMENT:
1912       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1913                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_32_ROSDA);
1914       fragP->fr_fix += INST_WORD_SIZE;
1915       fragP->fr_var = 0;
1916       break;
1917     case DEFINED_RW_SEGMENT:
1918       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1919                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_32_RWSDA);
1920       fragP->fr_fix += INST_WORD_SIZE;
1921       fragP->fr_var = 0;
1922       break;
1923     case DEFINED_PC_OFFSET:
1924       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1925                fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1926       fragP->fr_fix += INST_WORD_SIZE;
1927       fragP->fr_var = 0;
1928       break;
1929     case LARGE_DEFINED_PC_OFFSET:
1930       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1931                fragP->fr_offset, true, BFD_RELOC_64_PCREL);
1932       fragP->fr_fix += INST_WORD_SIZE * 2;
1933       fragP->fr_var = 0;
1934       break;
1935     case GOT_OFFSET:
1936       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1937                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_GOT);
1938       fragP->fr_fix += INST_WORD_SIZE * 2;
1939       fragP->fr_var = 0;
1940       break;
1941     case TEXT_OFFSET:
1942       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1943                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TEXTREL);
1944       fragP->fr_fix += INST_WORD_SIZE * 2;
1945       fragP->fr_var = 0;
1946       break;
1947     case TEXT_PC_OFFSET:
1948       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1949                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TEXTPCREL);
1950       fragP->fr_fix += INST_WORD_SIZE * 2;
1951       fragP->fr_var = 0;
1952       break;
1953     case PLT_OFFSET:
1954       fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1955                       fragP->fr_offset, true, BFD_RELOC_MICROBLAZE_64_PLT);
1956       /* fixP->fx_plt = 1; */
1957       (void) fixP;
1958       fragP->fr_fix += INST_WORD_SIZE * 2;
1959       fragP->fr_var = 0;
1960       break;
1961     case GOTOFF_OFFSET:
1962       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1963                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1964       fragP->fr_fix += INST_WORD_SIZE * 2;
1965       fragP->fr_var = 0;
1966       break;
1967     case TLSGD_OFFSET:
1968       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1969                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TLSGD);
1970       fragP->fr_fix += INST_WORD_SIZE * 2;
1971       fragP->fr_var = 0;
1972       break;
1973     case TLSLD_OFFSET:
1974       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1975                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TLSLD);
1976       fragP->fr_fix += INST_WORD_SIZE * 2;
1977       fragP->fr_var = 0;
1978       break;
1979     case TLSDTPREL_OFFSET:
1980       fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1981                fragP->fr_offset, false, BFD_RELOC_MICROBLAZE_64_TLSDTPREL);
1982       fragP->fr_fix += INST_WORD_SIZE * 2;
1983       fragP->fr_var = 0;
1984       break;
1985
1986     default:
1987       abort ();
1988     }
1989 }
1990
1991 /* Applies the desired value to the specified location.
1992    Also sets up addends for 'rela' type relocations.  */
1993 void
1994 md_apply_fix (fixS *   fixP,
1995               valueT * valp,
1996               segT     segment)
1997 {
1998   char *       buf  = fixP->fx_where + &fixP->fx_frag->fr_literal[0];
1999   const char *       file = fixP->fx_file ? fixP->fx_file : _("unknown");
2000   const char * symname;
2001   /* Note: use offsetT because it is signed, valueT is unsigned.  */
2002   offsetT      val  = (offsetT) * valp;
2003   int          i;
2004   struct op_code_struct * opcode1;
2005   unsigned long inst1;
2006
2007   symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
2008
2009   /* fixP->fx_offset is supposed to be set up correctly for all
2010      symbol relocations.  */
2011   if (fixP->fx_addsy == NULL)
2012     {
2013       if (!fixP->fx_pcrel)
2014         fixP->fx_offset = val; /* Absolute relocation.  */
2015       else
2016         fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
2017                  (unsigned int) fixP->fx_offset, (unsigned int) val);
2018     }
2019
2020   /* If we aren't adjusting this fixup to be against the section
2021      symbol, we need to adjust the value.  */
2022   if (fixP->fx_addsy != NULL)
2023     {
2024       if (S_IS_WEAK (fixP->fx_addsy)
2025           || (symbol_used_in_reloc_p (fixP->fx_addsy)
2026               && (((bfd_section_flags (S_GET_SEGMENT (fixP->fx_addsy))
2027                     & SEC_LINK_ONCE) != 0)
2028                   || startswith (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
2029                                  ".gnu.linkonce"))))
2030         {
2031           val -= S_GET_VALUE (fixP->fx_addsy);
2032           if (val != 0 && ! fixP->fx_pcrel)
2033             {
2034               /* In this case, the bfd_install_relocation routine will
2035                  incorrectly add the symbol value back in.  We just want
2036                  the addend to appear in the object file.
2037                  FIXME: If this makes VALUE zero, we're toast.  */
2038               val -= S_GET_VALUE (fixP->fx_addsy);
2039             }
2040         }
2041     }
2042
2043   /* If the fix is relative to a symbol which is not defined, or not
2044      in the same segment as the fix, we cannot resolve it here.  */
2045   /* fixP->fx_addsy is NULL if valp contains the entire relocation.  */
2046   if (fixP->fx_addsy != NULL
2047       && (!S_IS_DEFINED (fixP->fx_addsy)
2048           || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
2049     {
2050       fixP->fx_done = 0;
2051 #ifdef OBJ_ELF
2052       /* For ELF we can just return and let the reloc that will be generated
2053          take care of everything.  For COFF we still have to insert 'val'
2054          into the insn since the addend field will be ignored.  */
2055       /* return; */
2056 #endif
2057     }
2058   /* All fixups in the text section must be handled in the linker.  */
2059   else if (segment->flags & SEC_CODE)
2060     fixP->fx_done = 0;
2061   else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
2062     fixP->fx_done = 0;
2063   else
2064     fixP->fx_done = 1;
2065
2066   switch (fixP->fx_r_type)
2067     {
2068     case BFD_RELOC_MICROBLAZE_32_LO:
2069     case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2070       if (target_big_endian)
2071         {
2072           buf[2] |= ((val >> 8) & 0xff);
2073           buf[3] |= (val & 0xff);
2074         }
2075       else
2076         {
2077           buf[1] |= ((val >> 8) & 0xff);
2078           buf[0] |= (val & 0xff);
2079         }
2080       break;
2081     case BFD_RELOC_MICROBLAZE_32_ROSDA:
2082     case BFD_RELOC_MICROBLAZE_32_RWSDA:
2083       /* Don't do anything if the symbol is not defined.  */
2084       if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2085         {
2086           if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
2087             as_bad_where (file, fixP->fx_line,
2088                           _("pcrel for branch to %s too far (0x%x)"),
2089                           symname, (int) val);
2090           if (target_big_endian)
2091             {
2092               buf[2] |= ((val >> 8) & 0xff);
2093               buf[3] |= (val & 0xff);
2094             }
2095           else
2096             {
2097               buf[1] |= ((val >> 8) & 0xff);
2098               buf[0] |= (val & 0xff);
2099             }
2100         }
2101       break;
2102     case BFD_RELOC_32:
2103     case BFD_RELOC_RVA:
2104     case BFD_RELOC_32_PCREL:
2105     case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2106       /* Don't do anything if the symbol is not defined.  */
2107       if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2108         {
2109           if (target_big_endian)
2110             {
2111               buf[0] |= ((val >> 24) & 0xff);
2112               buf[1] |= ((val >> 16) & 0xff);
2113               buf[2] |= ((val >> 8) & 0xff);
2114               buf[3] |= (val & 0xff);
2115             }
2116           else
2117             {
2118               buf[3] |= ((val >> 24) & 0xff);
2119               buf[2] |= ((val >> 16) & 0xff);
2120               buf[1] |= ((val >> 8) & 0xff);
2121               buf[0] |= (val & 0xff);
2122             }
2123         }
2124       break;
2125     case BFD_RELOC_64_PCREL:
2126     case BFD_RELOC_64:
2127     case BFD_RELOC_MICROBLAZE_64_TEXTREL:
2128       /* Add an imm instruction.  First save the current instruction.  */
2129       for (i = 0; i < INST_WORD_SIZE; i++)
2130         buf[i + INST_WORD_SIZE] = buf[i];
2131
2132       /* Generate the imm instruction.  */
2133       opcode1
2134         = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
2135       if (opcode1 == NULL)
2136         {
2137           as_bad (_("unknown opcode \"%s\""), "imm");
2138           return;
2139         }
2140
2141       inst1 = opcode1->bit_sequence;
2142       if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2143         inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
2144
2145       buf[0] = INST_BYTE0 (inst1);
2146       buf[1] = INST_BYTE1 (inst1);
2147       buf[2] = INST_BYTE2 (inst1);
2148       buf[3] = INST_BYTE3 (inst1);
2149
2150       /* Add the value only if the symbol is defined.  */
2151       if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2152         {
2153           if (target_big_endian)
2154             {
2155               buf[6] |= ((val >> 8) & 0xff);
2156               buf[7] |= (val & 0xff);
2157             }
2158           else
2159             {
2160               buf[5] |= ((val >> 8) & 0xff);
2161               buf[4] |= (val & 0xff);
2162             }
2163         }
2164       break;
2165
2166     case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
2167     case BFD_RELOC_MICROBLAZE_64_TLSGD:
2168     case BFD_RELOC_MICROBLAZE_64_TLSLD:
2169       S_SET_THREAD_LOCAL (fixP->fx_addsy);
2170       /* Fall through.  */
2171
2172     case BFD_RELOC_MICROBLAZE_64_GOTPC:
2173     case BFD_RELOC_MICROBLAZE_64_GOT:
2174     case BFD_RELOC_MICROBLAZE_64_PLT:
2175     case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2176     case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
2177       /* Add an imm instruction.  First save the current instruction.  */
2178       for (i = 0; i < INST_WORD_SIZE; i++)
2179         buf[i + INST_WORD_SIZE] = buf[i];
2180
2181       /* Generate the imm instruction.  */
2182       opcode1
2183         = (struct op_code_struct *) str_hash_find (opcode_hash_control, "imm");
2184       if (opcode1 == NULL)
2185         {
2186           as_bad (_("unknown opcode \"%s\""), "imm");
2187           return;
2188         }
2189
2190       inst1 = opcode1->bit_sequence;
2191
2192       /* We can fixup call to a defined non-global address
2193          within the same section only.  */
2194       buf[0] = INST_BYTE0 (inst1);
2195       buf[1] = INST_BYTE1 (inst1);
2196       buf[2] = INST_BYTE2 (inst1);
2197       buf[3] = INST_BYTE3 (inst1);
2198       return;
2199
2200     default:
2201       break;
2202     }
2203
2204   if (fixP->fx_addsy == NULL)
2205     {
2206       /* This fixup has been resolved.  Create a reloc in case the linker
2207          moves code around due to relaxing.  */
2208       if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2209         fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2210       else
2211         fixP->fx_r_type = BFD_RELOC_NONE;
2212       fixP->fx_addsy = section_symbol (absolute_section);
2213     }
2214   return;
2215 }
2216
2217 void
2218 md_operand (expressionS * expressionP)
2219 {
2220   /* Ignore leading hash symbol, if present.  */
2221   if (*input_line_pointer == '#')
2222     {
2223       input_line_pointer ++;
2224       expression (expressionP);
2225     }
2226 }
2227
2228 /* Called just before address relaxation, return the length
2229    by which a fragment must grow to reach it's destination.  */
2230
2231 int
2232 md_estimate_size_before_relax (fragS * fragP,
2233                                segT segment_type)
2234 {
2235   sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2236   sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2237   sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2238   sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2239
2240   switch (fragP->fr_subtype)
2241     {
2242     case INST_PC_OFFSET:
2243       /* Used to be a PC-relative branch.  */
2244       if (!fragP->fr_symbol)
2245         {
2246           /* We know the abs value: Should never happen.  */
2247           as_bad (_("Absolute PC-relative value in relaxation code.  Assembler error....."));
2248           abort ();
2249         }
2250       else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
2251                !S_IS_WEAK (fragP->fr_symbol))
2252         {
2253           fragP->fr_subtype = DEFINED_PC_OFFSET;
2254           /* Don't know now whether we need an imm instruction.  */
2255           fragP->fr_var = INST_WORD_SIZE;
2256         }
2257       else if (S_IS_DEFINED (fragP->fr_symbol)
2258                && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2259         {
2260           /* Cannot have a PC-relative branch to a diff segment.  */
2261           as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2262                   S_GET_NAME (fragP->fr_symbol));
2263           fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2264           fragP->fr_var = INST_WORD_SIZE*2;
2265         }
2266       else
2267         {
2268           fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2269           fragP->fr_var = INST_WORD_SIZE*2;
2270         }
2271       break;
2272
2273     case INST_NO_OFFSET:
2274     case TEXT_OFFSET:
2275       /* Used to be a reference to somewhere which was unknown.  */
2276       if (fragP->fr_symbol)
2277         {
2278           if (fragP->fr_opcode == NULL)
2279             {
2280               /* Used as an absolute value.  */
2281               if (fragP->fr_subtype == INST_NO_OFFSET)
2282                 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2283               /* Variable part does not change.  */
2284               fragP->fr_var = INST_WORD_SIZE*2;
2285             }
2286           else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2287             {
2288               /* It is accessed using the small data read only anchor.  */
2289               if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2290                   || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2291                   || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2292                   || (! S_IS_DEFINED (fragP->fr_symbol)))
2293                 {
2294                   fragP->fr_subtype = DEFINED_RO_SEGMENT;
2295                   fragP->fr_var = INST_WORD_SIZE;
2296                 }
2297               else
2298                 {
2299                   /* Variable not in small data read only segment accessed
2300                      using small data read only anchor.  */
2301                   const char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2302
2303                   as_bad_where (file, fragP->fr_line,
2304                                 _("Variable is accessed using small data read "
2305                                   "only anchor, but it is not in the small data "
2306                                   "read only section"));
2307                   fragP->fr_subtype = DEFINED_RO_SEGMENT;
2308                   fragP->fr_var = INST_WORD_SIZE;
2309                 }
2310             }
2311           else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2312             {
2313               if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2314                   || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2315                   || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2316                   || (!S_IS_DEFINED (fragP->fr_symbol)))
2317                 {
2318                   /* It is accessed using the small data read write anchor.  */
2319                   fragP->fr_subtype = DEFINED_RW_SEGMENT;
2320                   fragP->fr_var = INST_WORD_SIZE;
2321                 }
2322               else
2323                 {
2324                   const char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2325
2326                   as_bad_where (file, fragP->fr_line,
2327                                 _("Variable is accessed using small data read "
2328                                   "write anchor, but it is not in the small data "
2329                                   "read write section"));
2330                   fragP->fr_subtype = DEFINED_RW_SEGMENT;
2331                   fragP->fr_var = INST_WORD_SIZE;
2332                 }
2333             }
2334           else
2335             {
2336               as_bad (_("Incorrect fr_opcode value in frag.  Internal error....."));
2337               abort ();
2338             }
2339         }
2340       else
2341         {
2342           /* We know the abs value: Should never happen.  */
2343           as_bad (_("Absolute value in relaxation code.  Assembler error....."));
2344           abort ();
2345         }
2346       break;
2347
2348     case UNDEFINED_PC_OFFSET:
2349     case LARGE_DEFINED_PC_OFFSET:
2350     case DEFINED_ABS_SEGMENT:
2351     case GOT_OFFSET:
2352     case PLT_OFFSET:
2353     case GOTOFF_OFFSET:
2354     case TEXT_PC_OFFSET:
2355     case TLSGD_OFFSET:
2356     case TLSLD_OFFSET:
2357     case TLSTPREL_OFFSET:
2358     case TLSDTPREL_OFFSET:
2359       fragP->fr_var = INST_WORD_SIZE*2;
2360       break;
2361     case DEFINED_RO_SEGMENT:
2362     case DEFINED_RW_SEGMENT:
2363     case DEFINED_PC_OFFSET:
2364     case TLSDTPMOD_OFFSET:
2365       fragP->fr_var = INST_WORD_SIZE;
2366       break;
2367     default:
2368       abort ();
2369     }
2370
2371   return fragP->fr_var;
2372 }
2373
2374 /* Put number into target byte order.  */
2375
2376 void
2377 md_number_to_chars (char * ptr, valueT use, int nbytes)
2378 {
2379   if (target_big_endian)
2380     number_to_chars_bigendian (ptr, use, nbytes);
2381   else
2382     number_to_chars_littleendian (ptr, use, nbytes);
2383 }
2384
2385 /* Round up a section size to the appropriate boundary.  */
2386
2387 valueT
2388 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2389 {
2390   return size;                  /* Byte alignment is fine.  */
2391 }
2392
2393
2394 /* The location from which a PC relative jump should be calculated,
2395    given a PC relative reloc.  */
2396
2397 long
2398 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2399 {
2400 #ifdef OBJ_ELF
2401   /* If the symbol is undefined or defined in another section
2402      we leave the add number alone for the linker to fix it later.
2403      Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2404
2405   if (fixp->fx_addsy != (symbolS *) NULL
2406       && (!S_IS_DEFINED (fixp->fx_addsy)
2407           || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2408     return 0;
2409   else
2410     {
2411       /* The case where we are going to resolve things... */
2412       if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2413         return  fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2414       else
2415         return  fixp->fx_where + fixp->fx_frag->fr_address;
2416     }
2417 #endif
2418 }
2419
2420
2421 #define F(SZ,PCREL)             (((SZ) << 1) + (PCREL))
2422 #define MAP(SZ,PCREL,TYPE)      case F (SZ, PCREL): code = (TYPE); break
2423
2424 arelent *
2425 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2426 {
2427   arelent * rel;
2428   bfd_reloc_code_real_type code;
2429
2430   switch (fixp->fx_r_type)
2431     {
2432     case BFD_RELOC_NONE:
2433     case BFD_RELOC_MICROBLAZE_64_NONE:
2434     case BFD_RELOC_32:
2435     case BFD_RELOC_MICROBLAZE_32_LO:
2436     case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2437     case BFD_RELOC_RVA:
2438     case BFD_RELOC_64:
2439     case BFD_RELOC_64_PCREL:
2440     case BFD_RELOC_MICROBLAZE_32_ROSDA:
2441     case BFD_RELOC_MICROBLAZE_32_RWSDA:
2442     case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2443     case BFD_RELOC_MICROBLAZE_64_GOTPC:
2444     case BFD_RELOC_MICROBLAZE_64_GOT:
2445     case BFD_RELOC_MICROBLAZE_64_PLT:
2446     case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2447     case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2448     case BFD_RELOC_MICROBLAZE_64_TLSGD:
2449     case BFD_RELOC_MICROBLAZE_64_TLSLD:
2450     case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
2451     case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
2452     case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
2453     case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
2454     case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
2455     case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
2456     case BFD_RELOC_MICROBLAZE_64_TEXTREL:
2457       code = fixp->fx_r_type;
2458       break;
2459
2460     default:
2461       switch (F (fixp->fx_size, fixp->fx_pcrel))
2462         {
2463           MAP (1, 0, BFD_RELOC_8);
2464           MAP (2, 0, BFD_RELOC_16);
2465           MAP (4, 0, BFD_RELOC_32);
2466           MAP (1, 1, BFD_RELOC_8_PCREL);
2467           MAP (2, 1, BFD_RELOC_16_PCREL);
2468           MAP (4, 1, BFD_RELOC_32_PCREL);
2469         default:
2470           code = fixp->fx_r_type;
2471           as_bad (_("Can not do %d byte %srelocation"),
2472                   fixp->fx_size,
2473                   fixp->fx_pcrel ? _("pc-relative ") : "");
2474         }
2475       break;
2476     }
2477
2478   rel = XNEW (arelent);
2479   rel->sym_ptr_ptr = XNEW (asymbol *);
2480
2481   if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2482     *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2483   else
2484     *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2485
2486   rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2487   /* Always pass the addend along!  */
2488   rel->addend = fixp->fx_offset;
2489   rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2490
2491   if (rel->howto == NULL)
2492     {
2493       as_bad_where (fixp->fx_file, fixp->fx_line,
2494                     _("Cannot represent relocation type %s"),
2495                     bfd_get_reloc_code_name (code));
2496
2497       /* Set howto to a garbage value so that we can keep going.  */
2498       rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2499       gas_assert (rel->howto != NULL);
2500     }
2501   return rel;
2502 }
2503
2504 int
2505 md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
2506 {
2507   switch (c)
2508     {
2509     case OPTION_EB:
2510       target_big_endian = 1;
2511       break;
2512     case OPTION_EL:
2513       target_big_endian = 0;
2514       break;
2515     default:
2516       return 0;
2517     }
2518   return 1;
2519 }
2520
2521 void
2522 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2523 {
2524   /*  fprintf(stream, _("\
2525       MicroBlaze options:\n\
2526       -noSmall         Data in the comm and data sections do not go into the small data section\n")); */
2527 }
2528
2529
2530 /* Create a fixup for a cons expression.  If parse_cons_expression_microblaze
2531    found a machine specific op in an expression,
2532    then we create relocs accordingly.  */
2533
2534 void
2535 cons_fix_new_microblaze (fragS * frag,
2536                          int where,
2537                          int size,
2538                          expressionS *exp,
2539                          bfd_reloc_code_real_type r)
2540 {
2541   if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2542       (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2543       && (!S_IS_LOCAL (exp->X_op_symbol)))
2544     r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2545   else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2546     {
2547       exp->X_op = O_symbol;
2548       r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2549     }
2550   else
2551     {
2552       switch (size)
2553         {
2554         case 1:
2555           r = BFD_RELOC_8;
2556           break;
2557         case 2:
2558           r = BFD_RELOC_16;
2559           break;
2560         case 4:
2561           r = BFD_RELOC_32;
2562           break;
2563         case 8:
2564           r = BFD_RELOC_64;
2565           break;
2566         default:
2567           as_bad (_("unsupported BFD relocation size %u"), size);
2568           r = BFD_RELOC_32;
2569           break;
2570         }
2571     }
2572   fix_new_exp (frag, where, size, exp, 0, r);
2573 }
This page took 0.16308 seconds and 4 git commands to generate.