2010-06-01 Rafael Espindola <espindola@google.com>
[binutils.git] / gas / config / tc-microblaze.c
blob88b4dda6c924db3a3ae3d585f570e3952635fc42
1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright 2009 Free Software Foundation.
5 This file is part of GAS, the GNU Assembler.
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.
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.
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. */
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"
34 #ifndef streq
35 #define streq(a,b) (strcmp (a, b) == 0)
36 #endif
38 void microblaze_generate_symbol (char *sym);
39 static bfd_boolean check_spl_reg (unsigned *);
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))
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[] = "#";
54 const char line_separator_chars[] = ";";
56 /* This array holds the chars that only start a comment at the beginning of
57 a line. */
58 const char line_comment_chars[] = "#";
60 const int md_reloc_size = 8; /* Size of relocation record. */
62 /* Chars that can be used to separate mant
63 from exp in floating point numbers. */
64 const char EXP_CHARS[] = "eE";
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";
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
83 /* Initialize the relax table. */
84 const relax_typeS md_relax_table[] =
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. */
99 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
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. */
107 /* Generate a symbol for stabs information. */
109 void
110 microblaze_generate_symbol (char *sym)
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;
118 /* Handle the section changing pseudo-ops. */
120 static void
121 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
123 #ifdef OBJ_ELF
124 obj_elf_text (ignore);
125 #else
126 s_text (ignore);
127 #endif
130 static void
131 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
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
140 /* Things in the .sdata segment are always considered to be in the small data section. */
142 static void
143 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
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
152 /* Pseudo op to make file scope bss items. */
154 static void
155 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
157 char *name;
158 char c;
159 char *p;
160 offsetT size;
161 symbolS *symbolP;
162 offsetT align;
163 segT old_sec;
164 int old_subsec;
165 char *pfrag;
166 int align2;
167 segT current_seg = now_seg;
168 subsegT current_subseg = now_subseg;
170 name = input_line_pointer;
171 c = get_symbol_end ();
173 /* Just after name is now '\0'. */
174 p = input_line_pointer;
175 *p = c;
176 SKIP_WHITESPACE ();
177 if (*input_line_pointer != ',')
179 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
180 ignore_rest_of_line ();
181 return;
184 input_line_pointer++; /* skip ',' */
185 if ((size = get_absolute_expression ()) < 0)
187 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
188 ignore_rest_of_line ();
189 return;
192 /* The third argument to .lcomm is the alignment. */
193 if (*input_line_pointer != ',')
194 align = 8;
195 else
197 ++input_line_pointer;
198 align = get_absolute_expression ();
199 if (align <= 0)
201 as_warn (_("ignoring bad alignment"));
202 align = 8;
206 *p = 0;
207 symbolP = symbol_find_or_make (name);
208 *p = c;
210 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
212 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
213 S_GET_NAME (symbolP));
214 ignore_rest_of_line ();
215 return;
218 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
220 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
221 S_GET_NAME (symbolP),
222 (long) S_GET_VALUE (symbolP),
223 (long) size);
225 ignore_rest_of_line ();
226 return;
229 /* Allocate_bss. */
230 old_sec = now_seg;
231 old_subsec = now_subseg;
232 if (align)
234 /* Convert to a power of 2 alignment. */
235 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
236 if (align != 1)
238 as_bad (_("Common alignment not a power of 2"));
239 ignore_rest_of_line ();
240 return;
243 else
244 align2 = 0;
246 record_alignment (current_seg, align2);
247 subseg_set (current_seg, current_subseg);
248 if (align2)
249 frag_align (align2, 0, 0);
250 if (S_GET_SEGMENT (symbolP) == current_seg)
251 symbol_get_frag (symbolP)->fr_symbol = 0;
252 symbol_set_frag (symbolP, frag_now);
253 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
254 (char *) 0);
255 *pfrag = 0;
256 S_SET_SIZE (symbolP, size);
257 S_SET_SEGMENT (symbolP, current_seg);
258 subseg_set (current_seg, current_subseg);
259 demand_empty_rest_of_line ();
262 static void
263 microblaze_s_rdata (int localvar)
265 #ifdef OBJ_ELF
266 if (localvar == 0)
268 /* rodata. */
269 obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
270 if (rodata_segment == 0)
271 rodata_segment = subseg_new (".rodata", 0);
273 else
275 /* 1 .sdata2. */
276 obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
278 #else
279 s_data (ignore);
280 #endif
283 static void
284 microblaze_s_bss (int localvar)
286 #ifdef OBJ_ELF
287 if (localvar == 0) /* bss. */
288 obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
289 else if (localvar == 1)
291 /* sbss. */
292 obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
293 if (sbss_segment == 0)
294 sbss_segment = subseg_new (".sbss", 0);
296 #else
297 s_data (ignore);
298 #endif
301 /* endp_p is always 1 as this func is called only for .end <funcname>
302 This func consumes the <funcname> and calls regular processing
303 s_func(1) with arg 1 (1 for end). */
305 static void
306 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
308 *input_line_pointer = get_symbol_end ();
309 s_func (1);
312 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
314 static void
315 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
317 char *name;
318 int c;
319 symbolS *symbolP;
320 expressionS exp;
322 name = input_line_pointer;
323 c = get_symbol_end ();
324 symbolP = symbol_find_or_make (name);
325 S_SET_WEAK (symbolP);
326 *input_line_pointer = c;
328 SKIP_WHITESPACE ();
330 if (!is_end_of_line[(unsigned char) *input_line_pointer])
332 if (S_IS_DEFINED (symbolP))
334 as_bad ("Ignoring attempt to redefine symbol `%s'.",
335 S_GET_NAME (symbolP));
336 ignore_rest_of_line ();
337 return;
340 if (*input_line_pointer == ',')
342 ++input_line_pointer;
343 SKIP_WHITESPACE ();
346 expression (&exp);
347 if (exp.X_op != O_symbol)
349 as_bad ("bad .weakext directive");
350 ignore_rest_of_line ();
351 return;
353 symbol_set_value_expression (symbolP, &exp);
356 demand_empty_rest_of_line ();
359 /* This table describes all the machine specific pseudo-ops the assembler
360 has to support. The fields are:
361 Pseudo-op name without dot
362 Function to call to execute this pseudo-op
363 Integer arg to pass to the function. */
364 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
365 and then in the read.c table. */
366 const pseudo_typeS md_pseudo_table[] =
368 {"lcomm", microblaze_s_lcomm, 1},
369 {"data", microblaze_s_data, 0},
370 {"data8", cons, 1}, /* Same as byte. */
371 {"data16", cons, 2}, /* Same as hword. */
372 {"data32", cons, 4}, /* Same as word. */
373 {"ent", s_func, 0}, /* Treat ent as function entry point. */
374 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
375 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
376 {"weakext", microblaze_s_weakext, 0},
377 {"rodata", microblaze_s_rdata, 0},
378 {"sdata2", microblaze_s_rdata, 1},
379 {"sdata", microblaze_s_sdata, 0},
380 {"bss", microblaze_s_bss, 0},
381 {"sbss", microblaze_s_bss, 1},
382 {"text", microblaze_s_text, 0},
383 {"word", cons, 4},
384 {"frame", s_ignore, 0},
385 {"mask", s_ignore, 0}, /* Emitted by gcc. */
386 {NULL, NULL, 0}
389 /* This function is called once, at assembler startup time. This should
390 set up all the tables, etc that the MD part of the assembler needs. */
392 void
393 md_begin (void)
395 struct op_code_struct * opcode;
397 opcode_hash_control = hash_new ();
399 /* Insert unique names into hash table. */
400 for (opcode = opcodes; opcode->name; opcode ++)
401 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
404 /* Try to parse a reg name. */
406 static char *
407 parse_reg (char * s, unsigned * reg)
409 unsigned tmpreg = 0;
411 /* Strip leading whitespace. */
412 while (ISSPACE (* s))
413 ++ s;
415 if (strncasecmp (s, "rpc", 3) == 0)
417 *reg = REG_PC;
418 return s + 3;
420 else if (strncasecmp (s, "rmsr", 4) == 0)
422 *reg = REG_MSR;
423 return s + 4;
425 else if (strncasecmp (s, "rear", 4) == 0)
427 *reg = REG_EAR;
428 return s + 4;
430 else if (strncasecmp (s, "resr", 4) == 0)
432 *reg = REG_ESR;
433 return s + 4;
435 else if (strncasecmp (s, "rfsr", 4) == 0)
437 *reg = REG_FSR;
438 return s + 4;
440 else if (strncasecmp (s, "rbtr", 4) == 0)
442 *reg = REG_BTR;
443 return s + 4;
445 else if (strncasecmp (s, "redr", 4) == 0)
447 *reg = REG_EDR;
448 return s + 4;
450 /* MMU registers start. */
451 else if (strncasecmp (s, "rpid", 4) == 0)
453 *reg = REG_PID;
454 return s + 4;
456 else if (strncasecmp (s, "rzpr", 4) == 0)
458 *reg = REG_ZPR;
459 return s + 4;
461 else if (strncasecmp (s, "rtlbx", 5) == 0)
463 *reg = REG_TLBX;
464 return s + 5;
466 else if (strncasecmp (s, "rtlblo", 6) == 0)
468 *reg = REG_TLBLO;
469 return s + 6;
471 else if (strncasecmp (s, "rtlbhi", 6) == 0)
473 *reg = REG_TLBHI;
474 return s + 6;
476 else if (strncasecmp (s, "rtlbsx", 6) == 0)
478 *reg = REG_TLBSX;
479 return s + 6;
481 /* MMU registers end. */
482 else if (strncasecmp (s, "rpvr", 4) == 0)
484 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
486 tmpreg = (s[4]-'0')*10 + s[5] - '0';
487 s += 6;
490 else if (ISDIGIT (s[4]))
492 tmpreg = s[4] - '0';
493 s += 5;
495 else
496 as_bad (_("register expected, but saw '%.6s'"), s);
497 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
498 *reg = REG_PVR + tmpreg;
499 else
501 as_bad (_("Invalid register number at '%.6s'"), s);
502 *reg = REG_PVR;
504 return s;
506 else if (strncasecmp (s, "rsp", 3) == 0)
508 *reg = REG_SP;
509 return s + 3;
511 else if (strncasecmp (s, "rfsl", 4) == 0)
513 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
515 tmpreg = (s[4] - '0') * 10 + s[5] - '0';
516 s += 6;
518 else if (ISDIGIT (s[4]))
520 tmpreg = s[4] - '0';
521 s += 5;
523 else
524 as_bad (_("register expected, but saw '%.6s'"), s);
526 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
527 *reg = tmpreg;
528 else
530 as_bad (_("Invalid register number at '%.6s'"), s);
531 *reg = 0;
533 return s;
535 else
537 if (TOLOWER (s[0]) == 'r')
539 if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
541 tmpreg = (s[1] - '0') * 10 + s[2] - '0';
542 s += 3;
544 else if (ISDIGIT (s[1]))
546 tmpreg = s[1] - '0';
547 s += 2;
549 else
550 as_bad (_("register expected, but saw '%.6s'"), s);
552 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
553 *reg = tmpreg;
554 else
556 as_bad (_("Invalid register number at '%.6s'"), s);
557 *reg = 0;
559 return s;
562 as_bad (_("register expected, but saw '%.6s'"), s);
563 *reg = 0;
564 return s;
567 static char *
568 parse_exp (char *s, expressionS *e)
570 char *save;
571 char *new_pointer;
573 /* Skip whitespace. */
574 while (ISSPACE (* s))
575 ++ s;
577 save = input_line_pointer;
578 input_line_pointer = s;
580 expression (e);
582 if (e->X_op == O_absent)
583 as_fatal (_("missing operand"));
585 new_pointer = input_line_pointer;
586 input_line_pointer = save;
588 return new_pointer;
591 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
592 #define IMM_GOT 1
593 #define IMM_PLT 2
594 #define IMM_GOTOFF 3
596 static symbolS * GOT_symbol;
598 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
600 static char *
601 parse_imm (char * s, expressionS * e, int min, int max)
603 char *new_pointer;
604 char *atp;
606 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
607 for (atp = s; *atp != '@'; atp++)
608 if (is_end_of_line[(unsigned char) *atp])
609 break;
611 if (*atp == '@')
613 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
615 *atp = 0;
616 e->X_md = IMM_GOTOFF;
618 else if (strncmp (atp + 1, "GOT", 3) == 0)
620 *atp = 0;
621 e->X_md = IMM_GOT;
623 else if (strncmp (atp + 1, "PLT", 3) == 0)
625 *atp = 0;
626 e->X_md = IMM_PLT;
628 else
630 atp = NULL;
631 e->X_md = 0;
633 *atp = 0;
635 else
637 atp = NULL;
638 e->X_md = 0;
641 if (atp && !GOT_symbol)
643 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
646 new_pointer = parse_exp (s, e);
648 if (e->X_op == O_absent)
649 ; /* An error message has already been emitted. */
650 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
651 as_fatal (_("operand must be a constant or a label"));
652 else if ((e->X_op == O_constant) && ((int) e->X_add_number < min
653 || (int) e->X_add_number > max))
655 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
656 min, max, (int) e->X_add_number);
659 if (atp)
661 *atp = '@'; /* restore back (needed?) */
662 if (new_pointer >= atp)
663 new_pointer += (e->X_md == IMM_GOTOFF)?7:4;
664 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
667 return new_pointer;
670 static char *
671 check_got (int * got_type, int * got_len)
673 char *new_pointer;
674 char *atp;
675 char *past_got;
676 int first, second;
677 char *tmpbuf;
679 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
680 for (atp = input_line_pointer; *atp != '@'; atp++)
681 if (is_end_of_line[(unsigned char) *atp])
682 return NULL;
684 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
686 *got_len = 6;
687 *got_type = IMM_GOTOFF;
689 else if (strncmp (atp + 1, "GOT", 3) == 0)
691 *got_len = 3;
692 *got_type = IMM_GOT;
694 else if (strncmp (atp + 1, "PLT", 3) == 0)
696 *got_len = 3;
697 *got_type = IMM_PLT;
699 else
700 return NULL;
702 if (!GOT_symbol)
703 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
705 first = atp - input_line_pointer;
707 past_got = atp + *got_len + 1;
708 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
710 second = new_pointer - past_got;
711 tmpbuf = xmalloc (first + second + 2); /* One extra byte for ' ' and one for NUL. */
712 memcpy (tmpbuf, input_line_pointer, first);
713 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
714 memcpy (tmpbuf + first + 1, past_got, second);
715 tmpbuf[first + second + 1] = '\0';
717 return tmpbuf;
720 extern void
721 parse_cons_expression_microblaze (expressionS *exp, int size)
723 if (size == 4)
725 /* Handle @GOTOFF et.al. */
726 char *save, *gotfree_copy;
727 int got_len, got_type;
729 save = input_line_pointer;
730 gotfree_copy = check_got (& got_type, & got_len);
731 if (gotfree_copy)
732 input_line_pointer = gotfree_copy;
734 expression (exp);
736 if (gotfree_copy)
738 exp->X_md = got_type;
739 input_line_pointer = save + (input_line_pointer - gotfree_copy)
740 + got_len;
741 free (gotfree_copy);
744 else
745 expression (exp);
748 /* This is the guts of the machine-dependent assembler. STR points to a
749 machine dependent instruction. This function is supposed to emit
750 the frags/bytes it assembles to. */
752 static char * str_microblaze_ro_anchor = "RO";
753 static char * str_microblaze_rw_anchor = "RW";
755 static bfd_boolean
756 check_spl_reg (unsigned * reg)
758 if ((*reg == REG_MSR) || (*reg == REG_PC)
759 || (*reg == REG_EAR) || (*reg == REG_ESR)
760 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
761 || (*reg == REG_PID) || (*reg == REG_ZPR)
762 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
763 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
764 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
765 return TRUE;
767 return FALSE;
770 /* Here we decide which fixups can be adjusted to make them relative to
771 the beginning of the section instead of the symbol. Basically we need
772 to make sure that the dynamic relocations are done correctly, so in
773 some cases we force the original symbol to be used. */
776 tc_microblaze_fix_adjustable (struct fix *fixP)
778 if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
779 return 0;
781 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
782 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
783 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
784 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT)
785 return 0;
787 return 1;
790 void
791 md_assemble (char * str)
793 char * op_start;
794 char * op_end;
795 struct op_code_struct * opcode, *opcode1;
796 char * output = NULL;
797 int nlen = 0;
798 int i;
799 unsigned long inst, inst1;
800 unsigned reg1;
801 unsigned reg2;
802 unsigned reg3;
803 unsigned isize;
804 unsigned int immed, temp;
805 expressionS exp;
806 char name[20];
808 /* Drop leading whitespace. */
809 while (ISSPACE (* str))
810 str ++;
812 /* Find the op code end. */
813 for (op_start = op_end = str;
814 * op_end && nlen < 20 && !is_end_of_line [(int)*op_end] && *op_end != ' ';
815 op_end++)
817 name[nlen] = op_start[nlen];
818 nlen++;
821 name [nlen] = 0;
823 if (nlen == 0)
825 as_bad (_("can't find opcode "));
826 return;
829 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
830 if (opcode == NULL)
832 as_bad (_("unknown opcode \"%s\""), name);
833 return;
836 inst = opcode->bit_sequence;
837 isize = 4;
839 switch (opcode->inst_type)
841 case INST_TYPE_RD_R1_R2:
842 if (strcmp (op_end, ""))
843 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
844 else
846 as_fatal (_("Error in statement syntax"));
847 reg1 = 0;
849 if (strcmp (op_end, ""))
850 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
851 else
853 as_fatal (_("Error in statement syntax"));
854 reg2 = 0;
856 if (strcmp (op_end, ""))
857 op_end = parse_reg (op_end + 1, &reg3); /* Get r2. */
858 else
860 as_fatal (_("Error in statement syntax"));
861 reg3 = 0;
864 /* Check for spl registers. */
865 if (check_spl_reg (& reg1))
866 as_fatal (_("Cannot use special register with this instruction"));
867 if (check_spl_reg (& reg2))
868 as_fatal (_("Cannot use special register with this instruction"));
869 if (check_spl_reg (& reg3))
870 as_fatal (_("Cannot use special register with this instruction"));
872 if (streq (name, "sub"))
874 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
875 inst |= (reg1 << RD_LOW) & RD_MASK;
876 inst |= (reg3 << RA_LOW) & RA_MASK;
877 inst |= (reg2 << RB_LOW) & RB_MASK;
879 else
881 inst |= (reg1 << RD_LOW) & RD_MASK;
882 inst |= (reg2 << RA_LOW) & RA_MASK;
883 inst |= (reg3 << RB_LOW) & RB_MASK;
885 output = frag_more (isize);
886 break;
888 case INST_TYPE_RD_R1_IMM:
889 if (strcmp (op_end, ""))
890 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
891 else
893 as_fatal (_("Error in statement syntax"));
894 reg1 = 0;
896 if (strcmp (op_end, ""))
897 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
898 else
900 as_fatal (_("Error in statement syntax"));
901 reg2 = 0;
903 if (strcmp (op_end, ""))
904 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
905 else
906 as_fatal (_("Error in statement syntax"));
908 /* Check for spl registers. */
909 if (check_spl_reg (& reg1))
910 as_fatal (_("Cannot use special register with this instruction"));
911 if (check_spl_reg (& reg2))
912 as_fatal (_("Cannot use special register with this instruction"));
914 if (exp.X_op != O_constant)
916 char *opc;
917 relax_substateT subtype;
919 if (streq (name, "lmi"))
920 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
921 else if (streq (name, "smi"))
922 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
924 if (reg2 == REG_ROSDP)
925 opc = str_microblaze_ro_anchor;
926 else if (reg2 == REG_RWSDP)
927 opc = str_microblaze_rw_anchor;
928 else
929 opc = NULL;
930 if (exp.X_md == IMM_GOT)
931 subtype = GOT_OFFSET;
932 else if (exp.X_md == IMM_PLT)
933 subtype = PLT_OFFSET;
934 else if (exp.X_md == IMM_GOTOFF)
935 subtype = GOTOFF_OFFSET;
936 else
937 subtype = opcode->inst_offset_type;
939 output = frag_var (rs_machine_dependent,
940 isize * 2, /* maxm of 2 words. */
941 isize, /* minm of 1 word. */
942 subtype, /* PC-relative or not. */
943 exp.X_add_symbol,
944 exp.X_add_number,
945 opc);
946 immed = 0;
948 else
950 output = frag_more (isize);
951 immed = exp.X_add_number;
954 if (streq (name, "lmi") || streq (name, "smi"))
956 /* Load/store 32-d consecutive registers. Used on exit/entry
957 to subroutines to save and restore registers to stack.
958 Generate 32-d insts. */
959 int count;
961 count = 32 - reg1;
962 if (streq (name, "lmi"))
963 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
964 else
965 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
966 if (opcode == NULL)
968 as_bad (_("unknown opcode \"%s\""), "lwi");
969 return;
971 inst = opcode->bit_sequence;
972 inst |= (reg1 << RD_LOW) & RD_MASK;
973 inst |= (reg2 << RA_LOW) & RA_MASK;
974 inst |= (immed << IMM_LOW) & IMM_MASK;
976 for (i = 0; i < count - 1; i++)
978 output[0] = INST_BYTE0 (inst);
979 output[1] = INST_BYTE1 (inst);
980 output[2] = INST_BYTE2 (inst);
981 output[3] = INST_BYTE3 (inst);
982 output = frag_more (isize);
983 immed = immed + 4;
984 reg1++;
985 inst = opcode->bit_sequence;
986 inst |= (reg1 << RD_LOW) & RD_MASK;
987 inst |= (reg2 << RA_LOW) & RA_MASK;
988 inst |= (immed << IMM_LOW) & IMM_MASK;
991 else
993 temp = immed & 0xFFFF8000;
994 if ((temp != 0) && (temp != 0xFFFF8000))
996 /* Needs an immediate inst. */
997 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
998 if (opcode1 == NULL)
1000 as_bad (_("unknown opcode \"%s\""), "imm");
1001 return;
1004 inst1 = opcode1->bit_sequence;
1005 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1006 output[0] = INST_BYTE0 (inst1);
1007 output[1] = INST_BYTE1 (inst1);
1008 output[2] = INST_BYTE2 (inst1);
1009 output[3] = INST_BYTE3 (inst1);
1010 output = frag_more (isize);
1012 inst |= (reg1 << RD_LOW) & RD_MASK;
1013 inst |= (reg2 << RA_LOW) & RA_MASK;
1014 inst |= (immed << IMM_LOW) & IMM_MASK;
1016 break;
1018 case INST_TYPE_RD_R1_IMM5:
1019 if (strcmp (op_end, ""))
1020 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1021 else
1023 as_fatal (_("Error in statement syntax"));
1024 reg1 = 0;
1026 if (strcmp (op_end, ""))
1027 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1028 else
1030 as_fatal (_("Error in statement syntax"));
1031 reg2 = 0;
1033 if (strcmp (op_end, ""))
1034 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1035 else
1036 as_fatal (_("Error in statement syntax"));
1038 /* Check for spl registers. */
1039 if (check_spl_reg (&reg1))
1040 as_fatal (_("Cannot use special register with this instruction"));
1041 if (check_spl_reg (&reg2))
1042 as_fatal (_("Cannot use special register with this instruction"));
1044 if (exp.X_op != O_constant)
1045 as_warn (_("Symbol used as immediate for shift instruction"));
1046 else
1048 output = frag_more (isize);
1049 immed = exp.X_add_number;
1052 if (immed != (immed % 32))
1054 as_warn (_("Shift value > 32. using <value %% 32>"));
1055 immed = immed % 32;
1057 inst |= (reg1 << RD_LOW) & RD_MASK;
1058 inst |= (reg2 << RA_LOW) & RA_MASK;
1059 inst |= (immed << IMM_LOW) & IMM5_MASK;
1060 break;
1062 case INST_TYPE_R1_R2:
1063 if (strcmp (op_end, ""))
1064 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1065 else
1067 as_fatal (_("Error in statement syntax"));
1068 reg1 = 0;
1070 if (strcmp (op_end, ""))
1071 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1072 else
1074 as_fatal (_("Error in statement syntax"));
1075 reg2 = 0;
1078 /* Check for spl registers. */
1079 if (check_spl_reg (& reg1))
1080 as_fatal (_("Cannot use special register with this instruction"));
1081 if (check_spl_reg (& reg2))
1082 as_fatal (_("Cannot use special register with this instruction"));
1084 inst |= (reg1 << RA_LOW) & RA_MASK;
1085 inst |= (reg2 << RB_LOW) & RB_MASK;
1086 output = frag_more (isize);
1087 break;
1089 case INST_TYPE_RD_R1:
1090 if (strcmp (op_end, ""))
1091 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1092 else
1094 as_fatal (_("Error in statement syntax"));
1095 reg1 = 0;
1097 if (strcmp (op_end, ""))
1098 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1099 else
1101 as_fatal (_("Error in statement syntax"));
1102 reg2 =0;
1105 /* Check for spl registers. */
1106 if (check_spl_reg (&reg1))
1107 as_fatal (_("Cannot use special register with this instruction"));
1108 if (check_spl_reg (&reg2))
1109 as_fatal (_("Cannot use special register with this instruction"));
1111 inst |= (reg1 << RD_LOW) & RD_MASK;
1112 inst |= (reg2 << RA_LOW) & RA_MASK;
1113 output = frag_more (isize);
1114 break;
1116 case INST_TYPE_RD_RFSL:
1117 if (strcmp (op_end, ""))
1118 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1119 else
1121 as_fatal (_("Error in statement syntax"));
1122 reg1 = 0;
1124 if (strcmp (op_end, ""))
1125 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1126 else
1128 as_fatal (_("Error in statement syntax"));
1129 immed = 0;
1132 /* Check for spl registers. */
1133 if (check_spl_reg (&reg1))
1134 as_fatal (_("Cannot use special register with this instruction"));
1136 inst |= (reg1 << RD_LOW) & RD_MASK;
1137 inst |= (immed << IMM_LOW) & RFSL_MASK;
1138 output = frag_more (isize);
1139 break;
1141 case INST_TYPE_RD_IMM15:
1142 if (strcmp (op_end, ""))
1143 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1144 else
1146 as_fatal (_("Error in statement syntax"));
1147 reg1 = 0;
1150 if (strcmp (op_end, ""))
1151 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1152 else
1153 as_fatal (_("Error in statement syntax"));
1155 /* Check for spl registers. */
1156 if (check_spl_reg (&reg1))
1157 as_fatal (_("Cannot use special register with this instruction"));
1159 if (exp.X_op != O_constant)
1160 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1161 else
1163 output = frag_more (isize);
1164 immed = exp.X_add_number;
1166 inst |= (reg1 << RD_LOW) & RD_MASK;
1167 inst |= (immed << IMM_LOW) & IMM15_MASK;
1168 break;
1170 case INST_TYPE_R1_RFSL:
1171 if (strcmp (op_end, ""))
1172 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1173 else
1175 as_fatal (_("Error in statement syntax"));
1176 reg1 = 0;
1178 if (strcmp (op_end, ""))
1179 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1180 else
1182 as_fatal (_("Error in statement syntax"));
1183 immed = 0;
1186 /* Check for spl registers. */
1187 if (check_spl_reg (&reg1))
1188 as_fatal (_("Cannot use special register with this instruction"));
1190 inst |= (reg1 << RA_LOW) & RA_MASK;
1191 inst |= (immed << IMM_LOW) & RFSL_MASK;
1192 output = frag_more (isize);
1193 break;
1195 case INST_TYPE_RFSL:
1196 if (strcmp (op_end, ""))
1197 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1198 else
1200 as_fatal (_("Error in statement syntax"));
1201 immed = 0;
1203 /* Check for spl registers. */
1204 if (check_spl_reg (&reg1))
1205 as_fatal (_("Cannot use special register with this instruction"));
1206 inst |= (immed << IMM_LOW) & RFSL_MASK;
1207 output = frag_more (isize);
1208 break;
1210 case INST_TYPE_R1:
1211 if (strcmp (op_end, ""))
1212 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1213 else
1215 as_fatal (_("Error in statement syntax"));
1216 reg1 = 0;
1219 /* Check for spl registers. */
1220 if (check_spl_reg (&reg1))
1221 as_fatal (_("Cannot use special register with this instruction"));
1223 inst |= (reg1 << RA_LOW) & RA_MASK;
1224 output = frag_more (isize);
1225 break;
1227 /* For tuqula insn...:) */
1228 case INST_TYPE_RD:
1229 if (strcmp (op_end, ""))
1230 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1231 else
1233 as_fatal (_("Error in statement syntax"));
1234 reg1 = 0;
1237 /* Check for spl registers. */
1238 if (check_spl_reg (&reg1))
1239 as_fatal (_("Cannot use special register with this instruction"));
1241 inst |= (reg1 << RD_LOW) & RD_MASK;
1242 output = frag_more (isize);
1243 break;
1245 case INST_TYPE_RD_SPECIAL:
1246 if (strcmp (op_end, ""))
1247 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1248 else
1250 as_fatal (_("Error in statement syntax"));
1251 reg1 = 0;
1253 if (strcmp (op_end, ""))
1254 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1255 else
1257 as_fatal (_("Error in statement syntax"));
1258 reg2 = 0;
1261 if (reg2 == REG_MSR)
1262 immed = opcode->immval_mask | REG_MSR_MASK;
1263 else if (reg2 == REG_PC)
1264 immed = opcode->immval_mask | REG_PC_MASK;
1265 else if (reg2 == REG_EAR)
1266 immed = opcode->immval_mask | REG_EAR_MASK;
1267 else if (reg2 == REG_ESR)
1268 immed = opcode->immval_mask | REG_ESR_MASK;
1269 else if (reg2 == REG_FSR)
1270 immed = opcode->immval_mask | REG_FSR_MASK;
1271 else if (reg2 == REG_BTR)
1272 immed = opcode->immval_mask | REG_BTR_MASK;
1273 else if (reg2 == REG_EDR)
1274 immed = opcode->immval_mask | REG_EDR_MASK;
1275 else if (reg2 == REG_PID)
1276 immed = opcode->immval_mask | REG_PID_MASK;
1277 else if (reg2 == REG_ZPR)
1278 immed = opcode->immval_mask | REG_ZPR_MASK;
1279 else if (reg2 == REG_TLBX)
1280 immed = opcode->immval_mask | REG_TLBX_MASK;
1281 else if (reg2 == REG_TLBLO)
1282 immed = opcode->immval_mask | REG_TLBLO_MASK;
1283 else if (reg2 == REG_TLBHI)
1284 immed = opcode->immval_mask | REG_TLBHI_MASK;
1285 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1286 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1287 else
1288 as_fatal (_("invalid value for special purpose register"));
1289 inst |= (reg1 << RD_LOW) & RD_MASK;
1290 inst |= (immed << IMM_LOW) & IMM_MASK;
1291 output = frag_more (isize);
1292 break;
1294 case INST_TYPE_SPECIAL_R1:
1295 if (strcmp (op_end, ""))
1296 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1297 else
1299 as_fatal (_("Error in statement syntax"));
1300 reg1 = 0;
1302 if (strcmp (op_end, ""))
1303 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1304 else
1306 as_fatal (_("Error in statement syntax"));
1307 reg2 = 0;
1310 if (reg1 == REG_MSR)
1311 immed = opcode->immval_mask | REG_MSR_MASK;
1312 else if (reg1 == REG_PC)
1313 immed = opcode->immval_mask | REG_PC_MASK;
1314 else if (reg1 == REG_EAR)
1315 immed = opcode->immval_mask | REG_EAR_MASK;
1316 else if (reg1 == REG_ESR)
1317 immed = opcode->immval_mask | REG_ESR_MASK;
1318 else if (reg1 == REG_FSR)
1319 immed = opcode->immval_mask | REG_FSR_MASK;
1320 else if (reg1 == REG_BTR)
1321 immed = opcode->immval_mask | REG_BTR_MASK;
1322 else if (reg1 == REG_EDR)
1323 immed = opcode->immval_mask | REG_EDR_MASK;
1324 else if (reg1 == REG_PID)
1325 immed = opcode->immval_mask | REG_PID_MASK;
1326 else if (reg1 == REG_ZPR)
1327 immed = opcode->immval_mask | REG_ZPR_MASK;
1328 else if (reg1 == REG_TLBX)
1329 immed = opcode->immval_mask | REG_TLBX_MASK;
1330 else if (reg1 == REG_TLBLO)
1331 immed = opcode->immval_mask | REG_TLBLO_MASK;
1332 else if (reg1 == REG_TLBHI)
1333 immed = opcode->immval_mask | REG_TLBHI_MASK;
1334 else if (reg1 == REG_TLBSX)
1335 immed = opcode->immval_mask | REG_TLBSX_MASK;
1336 else
1337 as_fatal (_("invalid value for special purpose register"));
1338 inst |= (reg2 << RA_LOW) & RA_MASK;
1339 inst |= (immed << IMM_LOW) & IMM_MASK;
1340 output = frag_more (isize);
1341 break;
1343 case INST_TYPE_RD_R1_SPECIAL:
1344 if (strcmp (op_end, ""))
1345 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1346 else
1348 as_fatal (_("Error in statement syntax"));
1349 reg1 = 0;
1351 if (strcmp (op_end, ""))
1352 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1353 else
1355 as_fatal (_("Error in statement syntax"));
1356 reg2 =0;
1359 /* Check for spl registers. */
1360 if (check_spl_reg (&reg1))
1361 as_fatal (_("Cannot use special register with this instruction"));
1362 if (check_spl_reg (&reg2))
1363 as_fatal (_("Cannot use special register with this instruction"));
1365 /* insn wic ra, rb => wic ra, ra, rb. */
1366 inst |= (reg1 << RD_LOW) & RD_MASK;
1367 inst |= (reg1 << RA_LOW) & RA_MASK;
1368 inst |= (reg2 << RB_LOW) & RB_MASK;
1370 output = frag_more (isize);
1371 break;
1373 case INST_TYPE_RD_R2:
1374 if (strcmp (op_end, ""))
1375 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1376 else
1378 as_fatal (_("Error in statement syntax"));
1379 reg1 = 0;
1381 if (strcmp (op_end, ""))
1382 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1383 else
1385 as_fatal (_("Error in statement syntax"));
1386 reg2 = 0;
1389 /* Check for spl registers. */
1390 if (check_spl_reg (&reg1))
1391 as_fatal (_("Cannot use special register with this instruction"));
1392 if (check_spl_reg (&reg2))
1393 as_fatal (_("Cannot use special register with this instruction"));
1395 inst |= (reg1 << RD_LOW) & RD_MASK;
1396 inst |= (reg2 << RB_LOW) & RB_MASK;
1397 output = frag_more (isize);
1398 break;
1400 case INST_TYPE_R1_IMM:
1401 if (strcmp (op_end, ""))
1402 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1403 else
1405 as_fatal (_("Error in statement syntax"));
1406 reg1 = 0;
1408 if (strcmp (op_end, ""))
1409 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1410 else
1411 as_fatal (_("Error in statement syntax"));
1413 /* Check for spl registers. */
1414 if (check_spl_reg (&reg1))
1415 as_fatal (_("Cannot use special register with this instruction"));
1417 if (exp.X_op != O_constant)
1419 char *opc = NULL;
1420 relax_substateT subtype;
1422 if (exp.X_md == IMM_GOT)
1423 subtype = GOT_OFFSET;
1424 else if (exp.X_md == IMM_PLT)
1425 subtype = PLT_OFFSET;
1426 else
1427 subtype = opcode->inst_offset_type;
1428 output = frag_var (rs_machine_dependent,
1429 isize * 2, /* maxm of 2 words. */
1430 isize, /* minm of 1 word. */
1431 subtype, /* PC-relative or not. */
1432 exp.X_add_symbol,
1433 exp.X_add_number,
1434 opc);
1435 immed = 0;
1437 else
1439 output = frag_more (isize);
1440 immed = exp.X_add_number;
1443 temp = immed & 0xFFFF8000;
1444 if ((temp != 0) && (temp != 0xFFFF8000))
1446 /* Needs an immediate inst. */
1447 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1448 if (opcode1 == NULL)
1450 as_bad (_("unknown opcode \"%s\""), "imm");
1451 return;
1454 inst1 = opcode1->bit_sequence;
1455 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1456 output[0] = INST_BYTE0 (inst1);
1457 output[1] = INST_BYTE1 (inst1);
1458 output[2] = INST_BYTE2 (inst1);
1459 output[3] = INST_BYTE3 (inst1);
1460 output = frag_more (isize);
1463 inst |= (reg1 << RA_LOW) & RA_MASK;
1464 inst |= (immed << IMM_LOW) & IMM_MASK;
1465 break;
1467 case INST_TYPE_RD_IMM:
1468 if (strcmp (op_end, ""))
1469 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1470 else
1472 as_fatal (_("Error in statement syntax"));
1473 reg1 = 0;
1475 if (strcmp (op_end, ""))
1476 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1477 else
1478 as_fatal (_("Error in statement syntax"));
1480 /* Check for spl registers. */
1481 if (check_spl_reg (&reg1))
1482 as_fatal (_("Cannot use special register with this instruction"));
1484 if (exp.X_op != O_constant)
1486 char *opc = NULL;
1487 relax_substateT subtype;
1489 if (exp.X_md == IMM_GOT)
1490 subtype = GOT_OFFSET;
1491 else if (exp.X_md == IMM_PLT)
1492 subtype = PLT_OFFSET;
1493 else
1494 subtype = opcode->inst_offset_type;
1495 output = frag_var (rs_machine_dependent,
1496 isize * 2, /* maxm of 2 words. */
1497 isize, /* minm of 1 word. */
1498 subtype, /* PC-relative or not. */
1499 exp.X_add_symbol,
1500 exp.X_add_number,
1501 opc);
1502 immed = 0;
1504 else
1506 output = frag_more (isize);
1507 immed = exp.X_add_number;
1510 temp = immed & 0xFFFF8000;
1511 if ((temp != 0) && (temp != 0xFFFF8000))
1513 /* Needs an immediate inst. */
1514 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1515 if (opcode1 == NULL)
1517 as_bad (_("unknown opcode \"%s\""), "imm");
1518 return;
1521 inst1 = opcode1->bit_sequence;
1522 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1523 output[0] = INST_BYTE0 (inst1);
1524 output[1] = INST_BYTE1 (inst1);
1525 output[2] = INST_BYTE2 (inst1);
1526 output[3] = INST_BYTE3 (inst1);
1527 output = frag_more (isize);
1530 inst |= (reg1 << RD_LOW) & RD_MASK;
1531 inst |= (immed << IMM_LOW) & IMM_MASK;
1532 break;
1534 case INST_TYPE_R2:
1535 if (strcmp (op_end, ""))
1536 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1537 else
1539 as_fatal (_("Error in statement syntax"));
1540 reg2 = 0;
1543 /* Check for spl registers. */
1544 if (check_spl_reg (&reg2))
1545 as_fatal (_("Cannot use special register with this instruction"));
1547 inst |= (reg2 << RB_LOW) & RB_MASK;
1548 output = frag_more (isize);
1549 break;
1551 case INST_TYPE_IMM:
1552 if (streq (name, "imm"))
1553 as_fatal (_("An IMM instruction should not be present in the .s file"));
1555 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1557 if (exp.X_op != O_constant)
1559 char *opc = NULL;
1560 relax_substateT subtype;
1562 if (exp.X_md == IMM_GOT)
1563 subtype = GOT_OFFSET;
1564 else if (exp.X_md == IMM_PLT)
1565 subtype = PLT_OFFSET;
1566 else
1567 subtype = opcode->inst_offset_type;
1568 output = frag_var (rs_machine_dependent,
1569 isize * 2, /* maxm of 2 words. */
1570 isize, /* minm of 1 word. */
1571 subtype, /* PC-relative or not. */
1572 exp.X_add_symbol,
1573 exp.X_add_number,
1574 opc);
1575 immed = 0;
1577 else
1579 output = frag_more (isize);
1580 immed = exp.X_add_number;
1584 temp = immed & 0xFFFF8000;
1585 if ((temp != 0) && (temp != 0xFFFF8000))
1587 /* Needs an immediate inst. */
1588 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1589 if (opcode1 == NULL)
1591 as_bad (_("unknown opcode \"%s\""), "imm");
1592 return;
1595 inst1 = opcode1->bit_sequence;
1596 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1597 output[0] = INST_BYTE0 (inst1);
1598 output[1] = INST_BYTE1 (inst1);
1599 output[2] = INST_BYTE2 (inst1);
1600 output[3] = INST_BYTE3 (inst1);
1601 output = frag_more (isize);
1603 inst |= (immed << IMM_LOW) & IMM_MASK;
1604 break;
1606 case INST_TYPE_NONE:
1607 output = frag_more (isize);
1608 break;
1610 default:
1611 as_fatal (_("unimplemented opcode \"%s\""), name);
1614 /* Drop whitespace after all the operands have been parsed. */
1615 while (ISSPACE (* op_end))
1616 op_end ++;
1618 /* Give warning message if the insn has more operands than required. */
1619 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1620 as_warn (_("ignoring operands: %s "), op_end);
1622 output[0] = INST_BYTE0 (inst);
1623 output[1] = INST_BYTE1 (inst);
1624 output[2] = INST_BYTE2 (inst);
1625 output[3] = INST_BYTE3 (inst);
1627 #ifdef OBJ_ELF
1628 dwarf2_emit_insn (4);
1629 #endif
1632 symbolS *
1633 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1635 return NULL;
1638 /* Various routines to kill one day. */
1639 /* Equal to MAX_PRECISION in atof-ieee.c */
1640 #define MAX_LITTLENUMS 6
1642 /* Turn a string in input_line_pointer into a floating point constant of type
1643 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1644 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1645 char *
1646 md_atof (int type, char * litP, int * sizeP)
1648 int prec;
1649 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1650 int i;
1651 char * t;
1653 switch (type)
1655 case 'f':
1656 case 'F':
1657 case 's':
1658 case 'S':
1659 prec = 2;
1660 break;
1662 case 'd':
1663 case 'D':
1664 case 'r':
1665 case 'R':
1666 prec = 4;
1667 break;
1669 case 'x':
1670 case 'X':
1671 prec = 6;
1672 break;
1674 case 'p':
1675 case 'P':
1676 prec = 6;
1677 break;
1679 default:
1680 *sizeP = 0;
1681 return _("Bad call to MD_NTOF()");
1684 t = atof_ieee (input_line_pointer, type, words);
1686 if (t)
1687 input_line_pointer = t;
1689 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1691 if (! target_big_endian)
1693 for (i = prec - 1; i >= 0; i--)
1695 md_number_to_chars (litP, (valueT) words[i],
1696 sizeof (LITTLENUM_TYPE));
1697 litP += sizeof (LITTLENUM_TYPE);
1700 else
1701 for (i = 0; i < prec; i++)
1703 md_number_to_chars (litP, (valueT) words[i],
1704 sizeof (LITTLENUM_TYPE));
1705 litP += sizeof (LITTLENUM_TYPE);
1708 return NULL;
1711 const char * md_shortopts = "";
1713 struct option md_longopts[] =
1715 { NULL, no_argument, NULL, 0}
1718 size_t md_longopts_size = sizeof (md_longopts);
1720 int md_short_jump_size;
1722 void
1723 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1724 addressT from_Nddr ATTRIBUTE_UNUSED,
1725 addressT to_Nddr ATTRIBUTE_UNUSED,
1726 fragS * frag ATTRIBUTE_UNUSED,
1727 symbolS * to_symbol ATTRIBUTE_UNUSED)
1729 as_fatal (_("failed sanity check: short_jump"));
1732 void
1733 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1734 addressT from_Nddr ATTRIBUTE_UNUSED,
1735 addressT to_Nddr ATTRIBUTE_UNUSED,
1736 fragS * frag ATTRIBUTE_UNUSED,
1737 symbolS * to_symbol ATTRIBUTE_UNUSED)
1739 as_fatal (_("failed sanity check: long_jump"));
1742 /* Called after relaxing, change the frags so they know how big they are. */
1744 void
1745 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1746 segT sec ATTRIBUTE_UNUSED,
1747 fragS * fragP)
1749 fixS *fixP;
1751 switch (fragP->fr_subtype)
1753 case UNDEFINED_PC_OFFSET:
1754 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1755 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1756 fragP->fr_fix += INST_WORD_SIZE * 2;
1757 fragP->fr_var = 0;
1758 break;
1759 case DEFINED_ABS_SEGMENT:
1760 if (fragP->fr_symbol == GOT_symbol)
1761 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1762 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1763 else
1764 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1765 fragP->fr_offset, FALSE, BFD_RELOC_64);
1766 fragP->fr_fix += INST_WORD_SIZE * 2;
1767 fragP->fr_var = 0;
1768 break;
1769 case DEFINED_RO_SEGMENT:
1770 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1771 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1772 fragP->fr_fix += INST_WORD_SIZE;
1773 fragP->fr_var = 0;
1774 break;
1775 case DEFINED_RW_SEGMENT:
1776 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1777 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1778 fragP->fr_fix += INST_WORD_SIZE;
1779 fragP->fr_var = 0;
1780 break;
1781 case DEFINED_PC_OFFSET:
1782 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1783 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1784 fragP->fr_fix += INST_WORD_SIZE;
1785 fragP->fr_var = 0;
1786 break;
1787 case LARGE_DEFINED_PC_OFFSET:
1788 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1789 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1790 fragP->fr_fix += INST_WORD_SIZE * 2;
1791 fragP->fr_var = 0;
1792 break;
1793 case GOT_OFFSET:
1794 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1795 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1796 fragP->fr_fix += INST_WORD_SIZE * 2;
1797 fragP->fr_var = 0;
1798 break;
1799 case PLT_OFFSET:
1800 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1801 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1802 /* fixP->fx_plt = 1; */
1803 fragP->fr_fix += INST_WORD_SIZE * 2;
1804 fragP->fr_var = 0;
1805 break;
1806 case GOTOFF_OFFSET:
1807 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1808 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1809 fragP->fr_fix += INST_WORD_SIZE * 2;
1810 fragP->fr_var = 0;
1811 break;
1813 default:
1814 abort ();
1818 /* Applies the desired value to the specified location.
1819 Also sets up addends for 'rela' type relocations. */
1820 void
1821 md_apply_fix (fixS * fixP,
1822 valueT * valp,
1823 segT segment)
1825 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1826 char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1827 const char * symname;
1828 /* Note: use offsetT because it is signed, valueT is unsigned. */
1829 offsetT val = (offsetT) * valp;
1830 int i;
1831 struct op_code_struct * opcode1;
1832 unsigned long inst1;
1834 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
1836 /* fixP->fx_offset is supposed to be set up correctly for all
1837 symbol relocations. */
1838 if (fixP->fx_addsy == NULL)
1840 if (!fixP->fx_pcrel)
1841 fixP->fx_offset = val; /* Absolute relocation. */
1842 else
1843 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1844 (unsigned int) fixP->fx_offset, (unsigned int) val);
1847 /* If we aren't adjusting this fixup to be against the section
1848 symbol, we need to adjust the value. */
1849 if (fixP->fx_addsy != NULL)
1851 if (S_IS_WEAK (fixP->fx_addsy)
1852 || (symbol_used_in_reloc_p (fixP->fx_addsy)
1853 && (((bfd_get_section_flags (stdoutput,
1854 S_GET_SEGMENT (fixP->fx_addsy))
1855 & SEC_LINK_ONCE) != 0)
1856 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
1857 ".gnu.linkonce",
1858 sizeof (".gnu.linkonce") - 1))))
1860 val -= S_GET_VALUE (fixP->fx_addsy);
1861 if (val != 0 && ! fixP->fx_pcrel)
1863 /* In this case, the bfd_install_relocation routine will
1864 incorrectly add the symbol value back in. We just want
1865 the addend to appear in the object file.
1866 FIXME: If this makes VALUE zero, we're toast. */
1867 val -= S_GET_VALUE (fixP->fx_addsy);
1872 /* If the fix is relative to a symbol which is not defined, or not
1873 in the same segment as the fix, we cannot resolve it here. */
1874 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1875 if (fixP->fx_addsy != NULL
1876 && (!S_IS_DEFINED (fixP->fx_addsy)
1877 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
1879 fixP->fx_done = 0;
1880 #ifdef OBJ_ELF
1881 /* For ELF we can just return and let the reloc that will be generated
1882 take care of everything. For COFF we still have to insert 'val'
1883 into the insn since the addend field will be ignored. */
1884 /* return; */
1885 #endif
1887 /* All fixups in the text section must be handled in the linker. */
1888 else if (segment->flags & SEC_CODE)
1889 fixP->fx_done = 0;
1890 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
1891 fixP->fx_done = 0;
1892 else
1893 fixP->fx_done = 1;
1895 switch (fixP->fx_r_type)
1897 case BFD_RELOC_MICROBLAZE_32_LO:
1898 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
1899 if (target_big_endian)
1901 buf[2] |= ((val >> 8) & 0xff);
1902 buf[3] |= (val & 0xff);
1904 else
1906 buf[1] |= ((val >> 8) & 0xff);
1907 buf[0] |= (val & 0xff);
1909 break;
1910 case BFD_RELOC_MICROBLAZE_32_ROSDA:
1911 case BFD_RELOC_MICROBLAZE_32_RWSDA:
1912 /* Don't do anything if the symbol is not defined. */
1913 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1915 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
1916 as_bad_where (file, fixP->fx_line,
1917 _("pcrel for branch to %s too far (0x%x)"),
1918 symname, (int) val);
1919 if (target_big_endian)
1921 buf[2] |= ((val >> 8) & 0xff);
1922 buf[3] |= (val & 0xff);
1924 else
1926 buf[1] |= ((val >> 8) & 0xff);
1927 buf[0] |= (val & 0xff);
1930 break;
1931 case BFD_RELOC_32:
1932 case BFD_RELOC_RVA:
1933 case BFD_RELOC_32_PCREL:
1934 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
1935 /* Don't do anything if the symbol is not defined. */
1936 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1938 if (target_big_endian)
1940 buf[0] |= ((val >> 24) & 0xff);
1941 buf[1] |= ((val >> 16) & 0xff);
1942 buf[2] |= ((val >> 8) & 0xff);
1943 buf[3] |= (val & 0xff);
1945 else
1947 buf[3] |= ((val >> 24) & 0xff);
1948 buf[2] |= ((val >> 16) & 0xff);
1949 buf[1] |= ((val >> 8) & 0xff);
1950 buf[0] |= (val & 0xff);
1953 break;
1954 case BFD_RELOC_64_PCREL:
1955 case BFD_RELOC_64:
1956 /* Add an imm instruction. First save the current instruction. */
1957 for (i = 0; i < INST_WORD_SIZE; i++)
1958 buf[i + INST_WORD_SIZE] = buf[i];
1960 /* Generate the imm instruction. */
1961 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1962 if (opcode1 == NULL)
1964 as_bad (_("unknown opcode \"%s\""), "imm");
1965 return;
1968 inst1 = opcode1->bit_sequence;
1969 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1970 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
1972 buf[0] = INST_BYTE0 (inst1);
1973 buf[1] = INST_BYTE1 (inst1);
1974 buf[2] = INST_BYTE2 (inst1);
1975 buf[3] = INST_BYTE3 (inst1);
1977 /* Add the value only if the symbol is defined. */
1978 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1980 if (target_big_endian)
1982 buf[6] |= ((val >> 8) & 0xff);
1983 buf[7] |= (val & 0xff);
1985 else
1987 buf[5] |= ((val >> 8) & 0xff);
1988 buf[4] |= (val & 0xff);
1991 break;
1993 case BFD_RELOC_MICROBLAZE_64_GOTPC:
1994 case BFD_RELOC_MICROBLAZE_64_GOT:
1995 case BFD_RELOC_MICROBLAZE_64_PLT:
1996 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
1997 /* Add an imm instruction. First save the current instruction. */
1998 for (i = 0; i < INST_WORD_SIZE; i++)
1999 buf[i + INST_WORD_SIZE] = buf[i];
2001 /* Generate the imm instruction. */
2002 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2003 if (opcode1 == NULL)
2005 as_bad (_("unknown opcode \"%s\""), "imm");
2006 return;
2009 inst1 = opcode1->bit_sequence;
2011 /* We can fixup call to a defined non-global address
2012 within the same section only. */
2013 buf[0] = INST_BYTE0 (inst1);
2014 buf[1] = INST_BYTE1 (inst1);
2015 buf[2] = INST_BYTE2 (inst1);
2016 buf[3] = INST_BYTE3 (inst1);
2017 return;
2019 default:
2020 break;
2023 if (fixP->fx_addsy == NULL)
2025 /* This fixup has been resolved. Create a reloc in case the linker
2026 moves code around due to relaxing. */
2027 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2028 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2029 else
2030 fixP->fx_r_type = BFD_RELOC_NONE;
2031 fixP->fx_addsy = section_symbol (absolute_section);
2033 return;
2036 void
2037 md_operand (expressionS * expressionP)
2039 /* Ignore leading hash symbol, if present. */
2040 if (*input_line_pointer == '#')
2042 input_line_pointer ++;
2043 expression (expressionP);
2047 /* Called just before address relaxation, return the length
2048 by which a fragment must grow to reach it's destination. */
2051 md_estimate_size_before_relax (fragS * fragP,
2052 segT segment_type)
2054 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2055 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2056 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2057 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2059 switch (fragP->fr_subtype)
2061 case INST_PC_OFFSET:
2062 /* Used to be a PC-relative branch. */
2063 if (!fragP->fr_symbol)
2065 /* We know the abs value: Should never happen. */
2066 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2067 abort ();
2069 else if ((S_GET_SEGMENT (fragP->fr_symbol) == segment_type))
2071 fragP->fr_subtype = DEFINED_PC_OFFSET;
2072 /* Don't know now whether we need an imm instruction. */
2073 fragP->fr_var = INST_WORD_SIZE;
2075 else if (S_IS_DEFINED (fragP->fr_symbol)
2076 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2078 /* Cannot have a PC-relative branch to a diff segment. */
2079 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2080 S_GET_NAME (fragP->fr_symbol));
2081 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2082 fragP->fr_var = INST_WORD_SIZE*2;
2084 else
2086 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2087 fragP->fr_var = INST_WORD_SIZE*2;
2089 break;
2091 case INST_NO_OFFSET:
2092 /* Used to be a reference to somewhere which was unknown. */
2093 if (fragP->fr_symbol)
2095 if (fragP->fr_opcode == NULL)
2097 /* Used as an absolute value. */
2098 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2099 /* Variable part does not change. */
2100 fragP->fr_var = INST_WORD_SIZE*2;
2102 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2104 /* It is accessed using the small data read only anchor. */
2105 if ((S_GET_SEGMENT (fragP->fr_symbol) == &bfd_com_section)
2106 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2107 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2108 || (! S_IS_DEFINED (fragP->fr_symbol)))
2110 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2111 fragP->fr_var = INST_WORD_SIZE;
2113 else
2115 /* Variable not in small data read only segment accessed
2116 using small data read only anchor. */
2117 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2119 as_bad_where (file, fragP->fr_line,
2120 _("Variable is accessed using small data read "
2121 "only anchor, but it is not in the small data "
2122 "read only section"));
2123 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2124 fragP->fr_var = INST_WORD_SIZE;
2127 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2129 if ((S_GET_SEGMENT (fragP->fr_symbol) == &bfd_com_section)
2130 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2131 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2132 || (!S_IS_DEFINED (fragP->fr_symbol)))
2134 /* It is accessed using the small data read write anchor. */
2135 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2136 fragP->fr_var = INST_WORD_SIZE;
2138 else
2140 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2142 as_bad_where (file, fragP->fr_line,
2143 _("Variable is accessed using small data read "
2144 "write anchor, but it is not in the small data "
2145 "read write section"));
2146 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2147 fragP->fr_var = INST_WORD_SIZE;
2150 else
2152 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2153 abort ();
2156 else
2158 /* We know the abs value: Should never happen. */
2159 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2160 abort ();
2162 break;
2164 case UNDEFINED_PC_OFFSET:
2165 case LARGE_DEFINED_PC_OFFSET:
2166 case DEFINED_ABS_SEGMENT:
2167 case GOT_OFFSET:
2168 case PLT_OFFSET:
2169 case GOTOFF_OFFSET:
2170 fragP->fr_var = INST_WORD_SIZE*2;
2171 break;
2172 case DEFINED_RO_SEGMENT:
2173 case DEFINED_RW_SEGMENT:
2174 case DEFINED_PC_OFFSET:
2175 fragP->fr_var = INST_WORD_SIZE;
2176 break;
2177 default:
2178 abort ();
2181 return fragP->fr_var;
2184 /* Put number into target byte order. */
2186 void
2187 md_number_to_chars (char * ptr, valueT use, int nbytes)
2189 if (target_big_endian)
2190 number_to_chars_bigendian (ptr, use, nbytes);
2191 else
2192 number_to_chars_littleendian (ptr, use, nbytes);
2195 /* Round up a section size to the appropriate boundary. */
2197 valueT
2198 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2200 return size; /* Byte alignment is fine. */
2204 /* The location from which a PC relative jump should be calculated,
2205 given a PC relative reloc. */
2207 long
2208 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2210 #ifdef OBJ_ELF
2211 /* If the symbol is undefined or defined in another section
2212 we leave the add number alone for the linker to fix it later.
2213 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2215 if (fixp->fx_addsy != (symbolS *) NULL
2216 && (!S_IS_DEFINED (fixp->fx_addsy)
2217 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2218 return 0;
2219 else
2221 /* The case where we are going to resolve things... */
2222 if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2223 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2224 else
2225 return fixp->fx_where + fixp->fx_frag->fr_address;
2227 #endif
2231 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2232 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2234 arelent *
2235 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2237 arelent * rel;
2238 bfd_reloc_code_real_type code;
2240 switch (fixp->fx_r_type)
2242 case BFD_RELOC_NONE:
2243 case BFD_RELOC_MICROBLAZE_64_NONE:
2244 case BFD_RELOC_32:
2245 case BFD_RELOC_MICROBLAZE_32_LO:
2246 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2247 case BFD_RELOC_RVA:
2248 case BFD_RELOC_64:
2249 case BFD_RELOC_64_PCREL:
2250 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2251 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2252 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2253 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2254 case BFD_RELOC_MICROBLAZE_64_GOT:
2255 case BFD_RELOC_MICROBLAZE_64_PLT:
2256 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2257 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2258 code = fixp->fx_r_type;
2259 break;
2261 default:
2262 switch (F (fixp->fx_size, fixp->fx_pcrel))
2264 MAP (1, 0, BFD_RELOC_8);
2265 MAP (2, 0, BFD_RELOC_16);
2266 MAP (4, 0, BFD_RELOC_32);
2267 MAP (1, 1, BFD_RELOC_8_PCREL);
2268 MAP (2, 1, BFD_RELOC_16_PCREL);
2269 MAP (4, 1, BFD_RELOC_32_PCREL);
2270 default:
2271 code = fixp->fx_r_type;
2272 as_bad (_("Can not do %d byte %srelocation"),
2273 fixp->fx_size,
2274 fixp->fx_pcrel ? _("pc-relative") : "");
2276 break;
2279 rel = (arelent *) xmalloc (sizeof (arelent));
2280 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2282 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2283 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2284 else
2285 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2287 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2288 /* Always pass the addend along! */
2289 rel->addend = fixp->fx_offset;
2290 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2292 if (rel->howto == NULL)
2294 as_bad_where (fixp->fx_file, fixp->fx_line,
2295 _("Cannot represent relocation type %s"),
2296 bfd_get_reloc_code_name (code));
2298 /* Set howto to a garbage value so that we can keep going. */
2299 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2300 gas_assert (rel->howto != NULL);
2302 return rel;
2306 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
2308 switch (c)
2310 default:
2311 return 0;
2313 return 1;
2316 void
2317 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2319 /* fprintf(stream, _("\
2320 MicroBlaze options:\n\
2321 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2325 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2326 found a machine specific op in an expression,
2327 then we create relocs accordingly. */
2329 void
2330 cons_fix_new_microblaze (fragS * frag,
2331 int where,
2332 int size,
2333 expressionS *exp)
2336 bfd_reloc_code_real_type r;
2338 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2339 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2340 && (!S_IS_LOCAL (exp->X_op_symbol)))
2341 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2342 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2344 exp->X_op = O_symbol;
2345 r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2347 else
2349 switch (size)
2351 case 1:
2352 r = BFD_RELOC_8;
2353 break;
2354 case 2:
2355 r = BFD_RELOC_16;
2356 break;
2357 case 4:
2358 r = BFD_RELOC_32;
2359 break;
2360 case 8:
2361 r = BFD_RELOC_64;
2362 break;
2363 default:
2364 as_bad (_("unsupported BFD relocation size %u"), size);
2365 r = BFD_RELOC_32;
2366 break;
2369 fix_new_exp (frag, where, size, exp, 0, r);