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