Upload Tizen:Base source
[external/binutils.git] / gas / config / tc-microblaze.c
1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
2
3    Copyright 2009, 2010 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 <stdio.h>
23 #include "as.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 \f
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)
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)
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 }