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