1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright (C) 2009-2018 Free Software Foundation, Inc.
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)
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
27 #include "../opcodes/microblaze-opc.h"
28 #include "../opcodes/microblaze-opcm.h"
29 #include "safe-ctype.h"
31 #include <dwarf2dbg.h>
32 #include "aout/stab_gnu.h"
35 #define streq(a,b) (strcmp (a, b) == 0)
38 #define OPTION_EB (OPTION_MD_BASE + 0)
39 #define OPTION_EL (OPTION_MD_BASE + 1)
41 void microblaze_generate_symbol (char *sym);
42 static bfd_boolean check_spl_reg (unsigned *);
44 /* Several places in this file insert raw instructions into the
45 object. They should generate the instruction
46 and then use these four macros to crack the instruction value into
47 the appropriate byte values. */
48 #define INST_BYTE0(x) (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF))
49 #define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
50 #define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
51 #define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
53 /* This array holds the chars that always start a comment. If the
54 pre-processor is disabled, these aren't very useful. */
55 const char comment_chars[] = "#";
57 const char line_separator_chars[] = ";";
59 /* This array holds the chars that only start a comment at the beginning of
61 const char line_comment_chars[] = "#";
63 const int md_reloc_size = 8; /* Size of relocation record. */
65 /* Chars that can be used to separate mant
66 from exp in floating point numbers. */
67 const char EXP_CHARS[] = "eE";
69 /* Chars that mean this number is a floating point constant
72 const char FLT_CHARS[] = "rRsSfFdDxXpP";
74 /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1. */
75 #define UNDEFINED_PC_OFFSET 2
76 #define DEFINED_ABS_SEGMENT 3
77 #define DEFINED_PC_OFFSET 4
78 #define DEFINED_RO_SEGMENT 5
79 #define DEFINED_RW_SEGMENT 6
80 #define LARGE_DEFINED_PC_OFFSET 7
83 #define GOTOFF_OFFSET 10
84 #define TLSGD_OFFSET 11
85 #define TLSLD_OFFSET 12
86 #define TLSDTPMOD_OFFSET 13
87 #define TLSDTPREL_OFFSET 14
88 #define TLSGOTTPREL_OFFSET 15
89 #define TLSTPREL_OFFSET 16
90 #define TEXT_OFFSET 17
91 #define TEXT_PC_OFFSET 18
93 /* Initialize the relax table. */
94 const relax_typeS md_relax_table[] =
96 { 1, 1, 0, 0 }, /* 0: Unused. */
97 { 1, 1, 0, 0 }, /* 1: Unused. */
98 { 1, 1, 0, 0 }, /* 2: Unused. */
99 { 1, 1, 0, 0 }, /* 3: Unused. */
100 { 32767, -32768, INST_WORD_SIZE, LARGE_DEFINED_PC_OFFSET }, /* 4: DEFINED_PC_OFFSET. */
101 { 1, 1, 0, 0 }, /* 5: Unused. */
102 { 1, 1, 0, 0 }, /* 6: Unused. */
103 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
104 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */
105 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */
106 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */
107 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 11: TLSGD_OFFSET. */
108 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 12: TLSLD_OFFSET. */
109 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */
110 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 14: TLSDTPREL_OFFSET. */
111 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
112 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 16: TLSTPREL_OFFSET. */
113 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 17: TEXT_OFFSET. */
114 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 18: TEXT_PC_OFFSET. */
117 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
119 static segT sbss_segment = 0; /* Small bss section. */
120 static segT sbss2_segment = 0; /* Section not used. */
121 static segT sdata_segment = 0; /* Small data section. */
122 static segT sdata2_segment = 0; /* Small read-only section. */
123 static segT rodata_segment = 0; /* read-only section. */
125 /* Generate a symbol for stabs information. */
128 microblaze_generate_symbol (char *sym)
130 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
131 static int microblaze_label_count;
132 sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count);
133 ++microblaze_label_count;
136 /* Handle the section changing pseudo-ops. */
139 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
142 obj_elf_text (ignore);
149 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
152 obj_elf_change_section (".data", SHT_PROGBITS, 0, SHF_ALLOC+SHF_WRITE,
159 /* Things in the .sdata segment are always considered to be in the small data section. */
162 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
165 obj_elf_change_section (".sdata", SHT_PROGBITS, 0, SHF_ALLOC+SHF_WRITE,
172 /* Pseudo op to make file scope bss items. */
175 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
185 segT current_seg = now_seg;
186 subsegT current_subseg = now_subseg;
188 c = get_symbol_name (&name);
190 /* Just after name is now '\0'. */
191 p = input_line_pointer;
192 (void) restore_line_pointer (c);
194 if (*input_line_pointer != ',')
196 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
197 ignore_rest_of_line ();
201 input_line_pointer++; /* skip ',' */
202 if ((size = get_absolute_expression ()) < 0)
204 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
205 ignore_rest_of_line ();
209 /* The third argument to .lcomm is the alignment. */
210 if (*input_line_pointer != ',')
214 ++input_line_pointer;
215 align = get_absolute_expression ();
218 as_warn (_("ignoring bad alignment"));
224 symbolP = symbol_find_or_make (name);
227 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
229 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
230 S_GET_NAME (symbolP));
231 ignore_rest_of_line ();
235 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
237 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
238 S_GET_NAME (symbolP),
239 (long) S_GET_VALUE (symbolP),
242 ignore_rest_of_line ();
249 /* Convert to a power of 2 alignment. */
250 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
253 as_bad (_("Common alignment not a power of 2"));
254 ignore_rest_of_line ();
261 record_alignment (current_seg, align2);
262 subseg_set (current_seg, current_subseg);
264 frag_align (align2, 0, 0);
265 if (S_GET_SEGMENT (symbolP) == current_seg)
266 symbol_get_frag (symbolP)->fr_symbol = 0;
267 symbol_set_frag (symbolP, frag_now);
268 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
271 S_SET_SIZE (symbolP, size);
272 S_SET_SEGMENT (symbolP, current_seg);
273 subseg_set (current_seg, current_subseg);
274 demand_empty_rest_of_line ();
278 microblaze_s_rdata (int localvar)
284 obj_elf_change_section (".rodata", SHT_PROGBITS, 0, SHF_ALLOC,
286 if (rodata_segment == 0)
287 rodata_segment = subseg_new (".rodata", 0);
292 obj_elf_change_section (".sdata2", SHT_PROGBITS, 0, SHF_ALLOC,
301 microblaze_s_bss (int localvar)
304 if (localvar == 0) /* bss. */
305 obj_elf_change_section (".bss", SHT_NOBITS, 0, SHF_ALLOC+SHF_WRITE,
307 else if (localvar == 1)
310 obj_elf_change_section (".sbss", SHT_NOBITS, 0, SHF_ALLOC+SHF_WRITE,
312 if (sbss_segment == 0)
313 sbss_segment = subseg_new (".sbss", 0);
320 /* endp_p is always 1 as this func is called only for .end <funcname>
321 This func consumes the <funcname> and calls regular processing
322 s_func(1) with arg 1 (1 for end). */
325 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
328 restore_line_pointer (get_symbol_name (&name));
332 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
335 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
342 c = get_symbol_name (&name);
343 symbolP = symbol_find_or_make (name);
344 S_SET_WEAK (symbolP);
345 (void) restore_line_pointer (c);
349 if (!is_end_of_line[(unsigned char) *input_line_pointer])
351 if (S_IS_DEFINED (symbolP))
353 as_bad ("Ignoring attempt to redefine symbol `%s'.",
354 S_GET_NAME (symbolP));
355 ignore_rest_of_line ();
359 if (*input_line_pointer == ',')
361 ++input_line_pointer;
366 if (exp.X_op != O_symbol)
368 as_bad ("bad .weakext directive");
369 ignore_rest_of_line ();
372 symbol_set_value_expression (symbolP, &exp);
375 demand_empty_rest_of_line ();
378 /* This table describes all the machine specific pseudo-ops the assembler
379 has to support. The fields are:
380 Pseudo-op name without dot
381 Function to call to execute this pseudo-op
382 Integer arg to pass to the function. */
383 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
384 and then in the read.c table. */
385 const pseudo_typeS md_pseudo_table[] =
387 {"lcomm", microblaze_s_lcomm, 1},
388 {"data", microblaze_s_data, 0},
389 {"data8", cons, 1}, /* Same as byte. */
390 {"data16", cons, 2}, /* Same as hword. */
391 {"data32", cons, 4}, /* Same as word. */
392 {"ent", s_func, 0}, /* Treat ent as function entry point. */
393 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
394 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
395 {"weakext", microblaze_s_weakext, 0},
396 {"rodata", microblaze_s_rdata, 0},
397 {"sdata2", microblaze_s_rdata, 1},
398 {"sdata", microblaze_s_sdata, 0},
399 {"bss", microblaze_s_bss, 0},
400 {"sbss", microblaze_s_bss, 1},
401 {"text", microblaze_s_text, 0},
403 {"frame", s_ignore, 0},
404 {"mask", s_ignore, 0}, /* Emitted by gcc. */
408 /* This function is called once, at assembler startup time. This should
409 set up all the tables, etc that the MD part of the assembler needs. */
414 struct op_code_struct * opcode;
416 opcode_hash_control = hash_new ();
418 /* Insert unique names into hash table. */
419 for (opcode = opcodes; opcode->name; opcode ++)
420 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
423 /* Try to parse a reg name. */
426 parse_reg (char * s, unsigned * reg)
430 /* Strip leading whitespace. */
431 while (ISSPACE (* s))
434 if (strncasecmp (s, "rpc", 3) == 0)
439 else if (strncasecmp (s, "rmsr", 4) == 0)
444 else if (strncasecmp (s, "rear", 4) == 0)
449 else if (strncasecmp (s, "resr", 4) == 0)
454 else if (strncasecmp (s, "rfsr", 4) == 0)
459 else if (strncasecmp (s, "rbtr", 4) == 0)
464 else if (strncasecmp (s, "redr", 4) == 0)
469 /* MMU registers start. */
470 else if (strncasecmp (s, "rpid", 4) == 0)
475 else if (strncasecmp (s, "rzpr", 4) == 0)
480 else if (strncasecmp (s, "rtlbx", 5) == 0)
485 else if (strncasecmp (s, "rtlblo", 6) == 0)
490 else if (strncasecmp (s, "rtlbhi", 6) == 0)
495 else if (strncasecmp (s, "rtlbsx", 6) == 0)
500 /* MMU registers end. */
501 else if (strncasecmp (s, "rpvr", 4) == 0)
503 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
505 tmpreg = (s[4]-'0')*10 + s[5] - '0';
509 else if (ISDIGIT (s[4]))
515 as_bad (_("register expected, but saw '%.6s'"), s);
516 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
517 *reg = REG_PVR + tmpreg;
520 as_bad (_("Invalid register number at '%.6s'"), s);
525 else if (strncasecmp (s, "rsp", 3) == 0)
530 else if (strncasecmp (s, "rfsl", 4) == 0)
532 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
534 tmpreg = (s[4] - '0') * 10 + s[5] - '0';
537 else if (ISDIGIT (s[4]))
543 as_bad (_("register expected, but saw '%.6s'"), s);
545 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
549 as_bad (_("Invalid register number at '%.6s'"), s);
554 /* Stack protection registers. */
555 else if (strncasecmp (s, "rshr", 4) == 0)
560 else if (strncasecmp (s, "rslr", 4) == 0)
567 if (TOLOWER (s[0]) == 'r')
569 if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
571 tmpreg = (s[1] - '0') * 10 + s[2] - '0';
574 else if (ISDIGIT (s[1]))
580 as_bad (_("register expected, but saw '%.6s'"), s);
582 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
586 as_bad (_("Invalid register number at '%.6s'"), s);
592 as_bad (_("register expected, but saw '%.6s'"), s);
598 parse_exp (char *s, expressionS *e)
603 /* Skip whitespace. */
604 while (ISSPACE (* s))
607 save = input_line_pointer;
608 input_line_pointer = s;
612 if (e->X_op == O_absent)
613 as_fatal (_("missing operand"));
615 new_pointer = input_line_pointer;
616 input_line_pointer = save;
621 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
628 #define IMM_TLSDTPMOD 6
629 #define IMM_TLSDTPREL 7
630 #define IMM_TLSTPREL 8
632 #define IMM_TXTPCREL 10
636 const char *isuffix; /* Suffix String */
637 int itype; /* Suffix Type */
638 int otype; /* Offset Type */
641 /* These are NOT in ascending order of type, GOTOFF is ahead to make
642 sure @GOTOFF does not get matched with @GOT */
643 static struct imm_type imm_types[] = {
644 { "NONE", IMM_NONE , 0 },
645 { "GOTOFF", IMM_GOTOFF , GOTOFF_OFFSET },
646 { "GOT", IMM_GOT , GOT_OFFSET },
647 { "PLT", IMM_PLT , PLT_OFFSET },
648 { "TLSGD", IMM_TLSGD , TLSGD_OFFSET },
649 { "TLSLDM", IMM_TLSLD, TLSLD_OFFSET },
650 { "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET },
651 { "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET },
652 { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET },
653 { "TXTREL", IMM_TXTREL, TEXT_OFFSET },
654 { "TXTPCREL", IMM_TXTPCREL, TEXT_PC_OFFSET }
658 match_imm (const char *s, int *ilen)
663 /* Check for matching suffix */
664 for (i = 1; i < IMM_MAX; i++)
666 slen = strlen (imm_types[i].isuffix);
668 if (strncmp (imm_types[i].isuffix, s, slen) == 0)
671 return imm_types[i].itype;
679 get_imm_otype (int itype)
684 /* Check for matching itype */
685 for (i = 1; i < IMM_MAX; i++)
687 if (imm_types[i].itype == itype)
689 otype = imm_types[i].otype;
696 static symbolS * GOT_symbol;
698 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
701 parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
709 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
710 for (atp = s; *atp != '@'; atp++)
711 if (is_end_of_line[(unsigned char) *atp])
716 itype = match_imm (atp + 1, &ilen);
736 if (atp && !GOT_symbol)
738 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
741 new_pointer = parse_exp (s, e);
743 if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20))
745 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
748 if (e->X_op == O_absent)
749 ; /* An error message has already been emitted. */
750 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
751 as_fatal (_("operand must be a constant or a label"));
752 else if (e->X_op == O_constant)
754 /* Special case: sign extend negative 32-bit values to offsetT size. */
755 if ((e->X_add_number >> 31) == 1)
756 e->X_add_number |= -((addressT) (1U << 31));
758 if (e->X_add_number < min || e->X_add_number > max)
760 as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"),
761 (long) min, (long) max, (long) e->X_add_number);
767 *atp = '@'; /* restore back (needed?) */
768 if (new_pointer >= atp)
769 new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */
775 check_got (int * got_type, int * got_len)
783 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
784 for (atp = input_line_pointer; *atp != '@'; atp++)
785 if (is_end_of_line[(unsigned char) *atp])
788 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
791 *got_type = IMM_GOTOFF;
793 else if (strncmp (atp + 1, "GOT", 3) == 0)
798 else if (strncmp (atp + 1, "PLT", 3) == 0)
807 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
809 first = atp - input_line_pointer;
811 past_got = atp + *got_len + 1;
812 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
814 second = new_pointer - past_got;
815 /* One extra byte for ' ' and one for NUL. */
816 tmpbuf = XNEWVEC (char, first + second + 2);
817 memcpy (tmpbuf, input_line_pointer, first);
818 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
819 memcpy (tmpbuf + first + 1, past_got, second);
820 tmpbuf[first + second + 1] = '\0';
825 extern bfd_reloc_code_real_type
826 parse_cons_expression_microblaze (expressionS *exp, int size)
830 /* Handle @GOTOFF et.al. */
831 char *save, *gotfree_copy;
832 int got_len, got_type;
834 save = input_line_pointer;
835 gotfree_copy = check_got (& got_type, & got_len);
837 input_line_pointer = gotfree_copy;
843 exp->X_md = got_type;
844 input_line_pointer = save + (input_line_pointer - gotfree_copy)
851 return BFD_RELOC_NONE;
854 /* This is the guts of the machine-dependent assembler. STR points to a
855 machine dependent instruction. This function is supposed to emit
856 the frags/bytes it assembles to. */
858 static const char * str_microblaze_ro_anchor = "RO";
859 static const char * str_microblaze_rw_anchor = "RW";
862 check_spl_reg (unsigned * reg)
864 if ((*reg == REG_MSR) || (*reg == REG_PC)
865 || (*reg == REG_EAR) || (*reg == REG_ESR)
866 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
867 || (*reg == REG_PID) || (*reg == REG_ZPR)
868 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
869 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
870 || (*reg == REG_SHR) || (*reg == REG_SLR)
871 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
877 /* Here we decide which fixups can be adjusted to make them relative to
878 the beginning of the section instead of the symbol. Basically we need
879 to make sure that the dynamic relocations are done correctly, so in
880 some cases we force the original symbol to be used. */
883 tc_microblaze_fix_adjustable (struct fix *fixP)
885 if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
888 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
889 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
890 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
891 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT
892 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGD
893 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSLD
894 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
895 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPREL
896 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSDTPREL
897 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
898 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSTPREL)
905 md_assemble (char * str)
909 struct op_code_struct * opcode, *opcode1;
910 char * output = NULL;
913 unsigned long inst, inst1;
918 unsigned int immed, temp;
922 /* Drop leading whitespace. */
923 while (ISSPACE (* str))
926 /* Find the op code end. */
927 for (op_start = op_end = str;
928 *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
931 name[nlen] = op_start[nlen];
933 if (nlen == sizeof (name) - 1)
941 as_bad (_("can't find opcode "));
945 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
948 as_bad (_("unknown opcode \"%s\""), name);
952 inst = opcode->bit_sequence;
955 switch (opcode->inst_type)
957 case INST_TYPE_RD_R1_R2:
958 if (strcmp (op_end, ""))
959 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
962 as_fatal (_("Error in statement syntax"));
965 if (strcmp (op_end, ""))
966 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
969 as_fatal (_("Error in statement syntax"));
972 if (strcmp (op_end, ""))
973 op_end = parse_reg (op_end + 1, ®3); /* Get r2. */
976 as_fatal (_("Error in statement syntax"));
980 /* Check for spl registers. */
981 if (check_spl_reg (& reg1))
982 as_fatal (_("Cannot use special register with this instruction"));
983 if (check_spl_reg (& reg2))
984 as_fatal (_("Cannot use special register with this instruction"));
985 if (check_spl_reg (& reg3))
986 as_fatal (_("Cannot use special register with this instruction"));
988 if (streq (name, "sub"))
990 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
991 inst |= (reg1 << RD_LOW) & RD_MASK;
992 inst |= (reg3 << RA_LOW) & RA_MASK;
993 inst |= (reg2 << RB_LOW) & RB_MASK;
997 inst |= (reg1 << RD_LOW) & RD_MASK;
998 inst |= (reg2 << RA_LOW) & RA_MASK;
999 inst |= (reg3 << RB_LOW) & RB_MASK;
1001 output = frag_more (isize);
1004 case INST_TYPE_RD_R1_IMM:
1005 if (strcmp (op_end, ""))
1006 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1009 as_fatal (_("Error in statement syntax"));
1012 if (strcmp (op_end, ""))
1013 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1016 as_fatal (_("Error in statement syntax"));
1019 if (strcmp (op_end, ""))
1020 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1022 as_fatal (_("Error in statement syntax"));
1024 /* Check for spl registers. */
1025 if (check_spl_reg (& reg1))
1026 as_fatal (_("Cannot use special register with this instruction"));
1027 if (check_spl_reg (& reg2))
1028 as_fatal (_("Cannot use special register with this instruction"));
1030 if (exp.X_op != O_constant || exp.X_md == IMM_TXTPCREL)
1033 relax_substateT subtype;
1035 if (streq (name, "lmi"))
1036 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
1037 else if (streq (name, "smi"))
1038 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
1040 if (reg2 == REG_ROSDP)
1041 opc = str_microblaze_ro_anchor;
1042 else if (reg2 == REG_RWSDP)
1043 opc = str_microblaze_rw_anchor;
1047 subtype = get_imm_otype(exp.X_md);
1049 subtype = opcode->inst_offset_type;
1051 output = frag_var (rs_machine_dependent,
1052 isize * 2, /* maxm of 2 words. */
1053 isize, /* minm of 1 word. */
1054 subtype, /* PC-relative or not. */
1062 output = frag_more (isize);
1063 immed = exp.X_add_number;
1066 if (streq (name, "lmi") || streq (name, "smi"))
1068 /* Load/store 32-d consecutive registers. Used on exit/entry
1069 to subroutines to save and restore registers to stack.
1070 Generate 32-d insts. */
1074 if (streq (name, "lmi"))
1075 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
1077 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
1080 as_bad (_("unknown opcode \"%s\""), "lwi");
1083 inst = opcode->bit_sequence;
1084 inst |= (reg1 << RD_LOW) & RD_MASK;
1085 inst |= (reg2 << RA_LOW) & RA_MASK;
1086 inst |= (immed << IMM_LOW) & IMM_MASK;
1088 for (i = 0; i < count - 1; i++)
1090 output[0] = INST_BYTE0 (inst);
1091 output[1] = INST_BYTE1 (inst);
1092 output[2] = INST_BYTE2 (inst);
1093 output[3] = INST_BYTE3 (inst);
1094 output = frag_more (isize);
1097 inst = opcode->bit_sequence;
1098 inst |= (reg1 << RD_LOW) & RD_MASK;
1099 inst |= (reg2 << RA_LOW) & RA_MASK;
1100 inst |= (immed << IMM_LOW) & IMM_MASK;
1105 temp = immed & 0xFFFF8000;
1106 if ((temp != 0) && (temp != 0xFFFF8000))
1108 /* Needs an immediate inst. */
1109 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1110 if (opcode1 == NULL)
1112 as_bad (_("unknown opcode \"%s\""), "imm");
1116 inst1 = opcode1->bit_sequence;
1117 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1118 output[0] = INST_BYTE0 (inst1);
1119 output[1] = INST_BYTE1 (inst1);
1120 output[2] = INST_BYTE2 (inst1);
1121 output[3] = INST_BYTE3 (inst1);
1122 output = frag_more (isize);
1124 inst |= (reg1 << RD_LOW) & RD_MASK;
1125 inst |= (reg2 << RA_LOW) & RA_MASK;
1126 inst |= (immed << IMM_LOW) & IMM_MASK;
1130 case INST_TYPE_RD_R1_IMM5:
1131 if (strcmp (op_end, ""))
1132 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1135 as_fatal (_("Error in statement syntax"));
1138 if (strcmp (op_end, ""))
1139 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1142 as_fatal (_("Error in statement syntax"));
1145 if (strcmp (op_end, ""))
1146 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1148 as_fatal (_("Error in statement syntax"));
1150 /* Check for spl registers. */
1151 if (check_spl_reg (®1))
1152 as_fatal (_("Cannot use special register with this instruction"));
1153 if (check_spl_reg (®2))
1154 as_fatal (_("Cannot use special register with this instruction"));
1156 if (exp.X_op != O_constant)
1157 as_warn (_("Symbol used as immediate for shift instruction"));
1160 output = frag_more (isize);
1161 immed = exp.X_add_number;
1164 if (immed != (immed % 32))
1166 as_warn (_("Shift value > 32. using <value %% 32>"));
1169 inst |= (reg1 << RD_LOW) & RD_MASK;
1170 inst |= (reg2 << RA_LOW) & RA_MASK;
1171 inst |= (immed << IMM_LOW) & IMM5_MASK;
1174 case INST_TYPE_R1_R2:
1175 if (strcmp (op_end, ""))
1176 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1179 as_fatal (_("Error in statement syntax"));
1182 if (strcmp (op_end, ""))
1183 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1186 as_fatal (_("Error in statement syntax"));
1190 /* Check for spl registers. */
1191 if (check_spl_reg (& reg1))
1192 as_fatal (_("Cannot use special register with this instruction"));
1193 if (check_spl_reg (& reg2))
1194 as_fatal (_("Cannot use special register with this instruction"));
1196 inst |= (reg1 << RA_LOW) & RA_MASK;
1197 inst |= (reg2 << RB_LOW) & RB_MASK;
1198 output = frag_more (isize);
1201 case INST_TYPE_RD_R1:
1202 if (strcmp (op_end, ""))
1203 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1206 as_fatal (_("Error in statement syntax"));
1209 if (strcmp (op_end, ""))
1210 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1213 as_fatal (_("Error in statement syntax"));
1217 /* Check for spl registers. */
1218 if (check_spl_reg (®1))
1219 as_fatal (_("Cannot use special register with this instruction"));
1220 if (check_spl_reg (®2))
1221 as_fatal (_("Cannot use special register with this instruction"));
1223 inst |= (reg1 << RD_LOW) & RD_MASK;
1224 inst |= (reg2 << RA_LOW) & RA_MASK;
1225 output = frag_more (isize);
1228 case INST_TYPE_RD_RFSL:
1229 if (strcmp (op_end, ""))
1230 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1233 as_fatal (_("Error in statement syntax"));
1236 if (strcmp (op_end, ""))
1237 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1240 as_fatal (_("Error in statement syntax"));
1244 /* Check for spl registers. */
1245 if (check_spl_reg (®1))
1246 as_fatal (_("Cannot use special register with this instruction"));
1248 inst |= (reg1 << RD_LOW) & RD_MASK;
1249 inst |= (immed << IMM_LOW) & RFSL_MASK;
1250 output = frag_more (isize);
1253 case INST_TYPE_RD_IMM15:
1254 if (strcmp (op_end, ""))
1255 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1258 as_fatal (_("Error in statement syntax"));
1262 if (strcmp (op_end, ""))
1263 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1265 as_fatal (_("Error in statement syntax"));
1267 /* Check for spl registers. */
1268 if (check_spl_reg (®1))
1269 as_fatal (_("Cannot use special register with this instruction"));
1271 if (exp.X_op != O_constant)
1272 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1275 output = frag_more (isize);
1276 immed = exp.X_add_number;
1278 inst |= (reg1 << RD_LOW) & RD_MASK;
1279 inst |= (immed << IMM_LOW) & IMM15_MASK;
1282 case INST_TYPE_R1_RFSL:
1283 if (strcmp (op_end, ""))
1284 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1287 as_fatal (_("Error in statement syntax"));
1290 if (strcmp (op_end, ""))
1291 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1294 as_fatal (_("Error in statement syntax"));
1298 /* Check for spl registers. */
1299 if (check_spl_reg (®1))
1300 as_fatal (_("Cannot use special register with this instruction"));
1302 inst |= (reg1 << RA_LOW) & RA_MASK;
1303 inst |= (immed << IMM_LOW) & RFSL_MASK;
1304 output = frag_more (isize);
1307 case INST_TYPE_RFSL:
1308 if (strcmp (op_end, ""))
1309 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1312 as_fatal (_("Error in statement syntax"));
1315 inst |= (immed << IMM_LOW) & RFSL_MASK;
1316 output = frag_more (isize);
1320 if (strcmp (op_end, ""))
1321 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1324 as_fatal (_("Error in statement syntax"));
1328 /* Check for spl registers. */
1329 if (check_spl_reg (®1))
1330 as_fatal (_("Cannot use special register with this instruction"));
1332 inst |= (reg1 << RA_LOW) & RA_MASK;
1333 output = frag_more (isize);
1336 /* For tuqula insn...:) */
1338 if (strcmp (op_end, ""))
1339 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1342 as_fatal (_("Error in statement syntax"));
1346 /* Check for spl registers. */
1347 if (check_spl_reg (®1))
1348 as_fatal (_("Cannot use special register with this instruction"));
1350 inst |= (reg1 << RD_LOW) & RD_MASK;
1351 output = frag_more (isize);
1354 case INST_TYPE_RD_SPECIAL:
1355 if (strcmp (op_end, ""))
1356 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1359 as_fatal (_("Error in statement syntax"));
1362 if (strcmp (op_end, ""))
1363 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1366 as_fatal (_("Error in statement syntax"));
1370 if (reg2 == REG_MSR)
1371 immed = opcode->immval_mask | REG_MSR_MASK;
1372 else if (reg2 == REG_PC)
1373 immed = opcode->immval_mask | REG_PC_MASK;
1374 else if (reg2 == REG_EAR)
1375 immed = opcode->immval_mask | REG_EAR_MASK;
1376 else if (reg2 == REG_ESR)
1377 immed = opcode->immval_mask | REG_ESR_MASK;
1378 else if (reg2 == REG_FSR)
1379 immed = opcode->immval_mask | REG_FSR_MASK;
1380 else if (reg2 == REG_BTR)
1381 immed = opcode->immval_mask | REG_BTR_MASK;
1382 else if (reg2 == REG_EDR)
1383 immed = opcode->immval_mask | REG_EDR_MASK;
1384 else if (reg2 == REG_PID)
1385 immed = opcode->immval_mask | REG_PID_MASK;
1386 else if (reg2 == REG_ZPR)
1387 immed = opcode->immval_mask | REG_ZPR_MASK;
1388 else if (reg2 == REG_TLBX)
1389 immed = opcode->immval_mask | REG_TLBX_MASK;
1390 else if (reg2 == REG_TLBLO)
1391 immed = opcode->immval_mask | REG_TLBLO_MASK;
1392 else if (reg2 == REG_TLBHI)
1393 immed = opcode->immval_mask | REG_TLBHI_MASK;
1394 else if (reg2 == REG_SHR)
1395 immed = opcode->immval_mask | REG_SHR_MASK;
1396 else if (reg2 == REG_SLR)
1397 immed = opcode->immval_mask | REG_SLR_MASK;
1398 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1399 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1401 as_fatal (_("invalid value for special purpose register"));
1402 inst |= (reg1 << RD_LOW) & RD_MASK;
1403 inst |= (immed << IMM_LOW) & IMM_MASK;
1404 output = frag_more (isize);
1407 case INST_TYPE_SPECIAL_R1:
1408 if (strcmp (op_end, ""))
1409 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1412 as_fatal (_("Error in statement syntax"));
1415 if (strcmp (op_end, ""))
1416 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1419 as_fatal (_("Error in statement syntax"));
1423 if (reg1 == REG_MSR)
1424 immed = opcode->immval_mask | REG_MSR_MASK;
1425 else if (reg1 == REG_PC)
1426 immed = opcode->immval_mask | REG_PC_MASK;
1427 else if (reg1 == REG_EAR)
1428 immed = opcode->immval_mask | REG_EAR_MASK;
1429 else if (reg1 == REG_ESR)
1430 immed = opcode->immval_mask | REG_ESR_MASK;
1431 else if (reg1 == REG_FSR)
1432 immed = opcode->immval_mask | REG_FSR_MASK;
1433 else if (reg1 == REG_BTR)
1434 immed = opcode->immval_mask | REG_BTR_MASK;
1435 else if (reg1 == REG_EDR)
1436 immed = opcode->immval_mask | REG_EDR_MASK;
1437 else if (reg1 == REG_PID)
1438 immed = opcode->immval_mask | REG_PID_MASK;
1439 else if (reg1 == REG_ZPR)
1440 immed = opcode->immval_mask | REG_ZPR_MASK;
1441 else if (reg1 == REG_TLBX)
1442 immed = opcode->immval_mask | REG_TLBX_MASK;
1443 else if (reg1 == REG_TLBLO)
1444 immed = opcode->immval_mask | REG_TLBLO_MASK;
1445 else if (reg1 == REG_TLBHI)
1446 immed = opcode->immval_mask | REG_TLBHI_MASK;
1447 else if (reg1 == REG_TLBSX)
1448 immed = opcode->immval_mask | REG_TLBSX_MASK;
1449 else if (reg1 == REG_SHR)
1450 immed = opcode->immval_mask | REG_SHR_MASK;
1451 else if (reg1 == REG_SLR)
1452 immed = opcode->immval_mask | REG_SLR_MASK;
1454 as_fatal (_("invalid value for special purpose register"));
1455 inst |= (reg2 << RA_LOW) & RA_MASK;
1456 inst |= (immed << IMM_LOW) & IMM_MASK;
1457 output = frag_more (isize);
1460 case INST_TYPE_R1_R2_SPECIAL:
1461 if (strcmp (op_end, ""))
1462 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1465 as_fatal (_("Error in statement syntax"));
1468 if (strcmp (op_end, ""))
1469 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1472 as_fatal (_("Error in statement syntax"));
1476 /* Check for spl registers. */
1477 if (check_spl_reg (®1))
1478 as_fatal (_("Cannot use special register with this instruction"));
1479 if (check_spl_reg (®2))
1480 as_fatal (_("Cannot use special register with this instruction"));
1482 /* insn wic ra, rb => wic ra, ra, rb. */
1483 inst |= (reg1 << RA_LOW) & RA_MASK;
1484 inst |= (reg2 << RB_LOW) & RB_MASK;
1486 output = frag_more (isize);
1489 case INST_TYPE_RD_R2:
1490 if (strcmp (op_end, ""))
1491 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1494 as_fatal (_("Error in statement syntax"));
1497 if (strcmp (op_end, ""))
1498 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1501 as_fatal (_("Error in statement syntax"));
1505 /* Check for spl registers. */
1506 if (check_spl_reg (®1))
1507 as_fatal (_("Cannot use special register with this instruction"));
1508 if (check_spl_reg (®2))
1509 as_fatal (_("Cannot use special register with this instruction"));
1511 inst |= (reg1 << RD_LOW) & RD_MASK;
1512 inst |= (reg2 << RB_LOW) & RB_MASK;
1513 output = frag_more (isize);
1516 case INST_TYPE_R1_IMM:
1517 if (strcmp (op_end, ""))
1518 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1521 as_fatal (_("Error in statement syntax"));
1524 if (strcmp (op_end, ""))
1525 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1527 as_fatal (_("Error in statement syntax"));
1529 /* Check for spl registers. */
1530 if (check_spl_reg (®1))
1531 as_fatal (_("Cannot use special register with this instruction"));
1533 if (exp.X_op != O_constant)
1536 relax_substateT subtype;
1539 subtype = get_imm_otype(exp.X_md);
1541 subtype = opcode->inst_offset_type;
1543 output = frag_var (rs_machine_dependent,
1544 isize * 2, /* maxm of 2 words. */
1545 isize, /* minm of 1 word. */
1546 subtype, /* PC-relative or not. */
1554 output = frag_more (isize);
1555 immed = exp.X_add_number;
1558 temp = immed & 0xFFFF8000;
1559 if ((temp != 0) && (temp != 0xFFFF8000))
1561 /* Needs an immediate inst. */
1562 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1563 if (opcode1 == NULL)
1565 as_bad (_("unknown opcode \"%s\""), "imm");
1569 inst1 = opcode1->bit_sequence;
1570 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1571 output[0] = INST_BYTE0 (inst1);
1572 output[1] = INST_BYTE1 (inst1);
1573 output[2] = INST_BYTE2 (inst1);
1574 output[3] = INST_BYTE3 (inst1);
1575 output = frag_more (isize);
1578 inst |= (reg1 << RA_LOW) & RA_MASK;
1579 inst |= (immed << IMM_LOW) & IMM_MASK;
1582 case INST_TYPE_RD_IMM:
1583 if (strcmp (op_end, ""))
1584 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1587 as_fatal (_("Error in statement syntax"));
1590 if (strcmp (op_end, ""))
1591 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1593 as_fatal (_("Error in statement syntax"));
1595 /* Check for spl registers. */
1596 if (check_spl_reg (®1))
1597 as_fatal (_("Cannot use special register with this instruction"));
1599 if (exp.X_op != O_constant)
1602 relax_substateT subtype;
1605 subtype = get_imm_otype(exp.X_md);
1607 subtype = opcode->inst_offset_type;
1609 output = frag_var (rs_machine_dependent,
1610 isize * 2, /* maxm of 2 words. */
1611 isize, /* minm of 1 word. */
1612 subtype, /* PC-relative or not. */
1620 output = frag_more (isize);
1621 immed = exp.X_add_number;
1624 temp = immed & 0xFFFF8000;
1625 if ((temp != 0) && (temp != 0xFFFF8000))
1627 /* Needs an immediate inst. */
1628 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1629 if (opcode1 == NULL)
1631 as_bad (_("unknown opcode \"%s\""), "imm");
1635 inst1 = opcode1->bit_sequence;
1636 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1637 output[0] = INST_BYTE0 (inst1);
1638 output[1] = INST_BYTE1 (inst1);
1639 output[2] = INST_BYTE2 (inst1);
1640 output[3] = INST_BYTE3 (inst1);
1641 output = frag_more (isize);
1644 inst |= (reg1 << RD_LOW) & RD_MASK;
1645 inst |= (immed << IMM_LOW) & IMM_MASK;
1649 if (strcmp (op_end, ""))
1650 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1653 as_fatal (_("Error in statement syntax"));
1657 /* Check for spl registers. */
1658 if (check_spl_reg (®2))
1659 as_fatal (_("Cannot use special register with this instruction"));
1661 inst |= (reg2 << RB_LOW) & RB_MASK;
1662 output = frag_more (isize);
1666 if (streq (name, "imm"))
1667 as_fatal (_("An IMM instruction should not be present in the .s file"));
1669 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1671 if (exp.X_op != O_constant)
1674 relax_substateT subtype;
1677 subtype = get_imm_otype(exp.X_md);
1679 subtype = opcode->inst_offset_type;
1681 output = frag_var (rs_machine_dependent,
1682 isize * 2, /* maxm of 2 words. */
1683 isize, /* minm of 1 word. */
1684 subtype, /* PC-relative or not. */
1692 output = frag_more (isize);
1693 immed = exp.X_add_number;
1697 temp = immed & 0xFFFF8000;
1698 if ((temp != 0) && (temp != 0xFFFF8000))
1700 /* Needs an immediate inst. */
1701 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1702 if (opcode1 == NULL)
1704 as_bad (_("unknown opcode \"%s\""), "imm");
1708 inst1 = opcode1->bit_sequence;
1709 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1710 output[0] = INST_BYTE0 (inst1);
1711 output[1] = INST_BYTE1 (inst1);
1712 output[2] = INST_BYTE2 (inst1);
1713 output[3] = INST_BYTE3 (inst1);
1714 output = frag_more (isize);
1716 inst |= (immed << IMM_LOW) & IMM_MASK;
1719 case INST_TYPE_NONE:
1720 output = frag_more (isize);
1723 case INST_TYPE_IMM5:
1724 if (strcmp(op_end, ""))
1725 op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5);
1727 as_fatal(_("Error in statement syntax"));
1728 if (exp.X_op != O_constant) {
1729 as_warn(_("Symbol used as immediate for mbar instruction"));
1731 output = frag_more (isize);
1732 immed = exp.X_add_number;
1734 if (immed != (immed % 32)) {
1735 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1738 inst |= (immed << IMM_MBAR);
1742 as_fatal (_("unimplemented opcode \"%s\""), name);
1745 /* Drop whitespace after all the operands have been parsed. */
1746 while (ISSPACE (* op_end))
1749 /* Give warning message if the insn has more operands than required. */
1750 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1751 as_warn (_("ignoring operands: %s "), op_end);
1753 output[0] = INST_BYTE0 (inst);
1754 output[1] = INST_BYTE1 (inst);
1755 output[2] = INST_BYTE2 (inst);
1756 output[3] = INST_BYTE3 (inst);
1759 dwarf2_emit_insn (4);
1764 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1769 /* Various routines to kill one day. */
1770 /* Equal to MAX_PRECISION in atof-ieee.c */
1771 #define MAX_LITTLENUMS 6
1773 /* Turn a string in input_line_pointer into a floating point constant of type
1774 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1775 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1777 md_atof (int type, char * litP, int * sizeP)
1780 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1812 return _("Bad call to MD_NTOF()");
1815 t = atof_ieee (input_line_pointer, type, words);
1818 input_line_pointer = t;
1820 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1822 if (! target_big_endian)
1824 for (i = prec - 1; i >= 0; i--)
1826 md_number_to_chars (litP, (valueT) words[i],
1827 sizeof (LITTLENUM_TYPE));
1828 litP += sizeof (LITTLENUM_TYPE);
1832 for (i = 0; i < prec; i++)
1834 md_number_to_chars (litP, (valueT) words[i],
1835 sizeof (LITTLENUM_TYPE));
1836 litP += sizeof (LITTLENUM_TYPE);
1842 const char * md_shortopts = "";
1844 struct option md_longopts[] =
1846 {"EB", no_argument, NULL, OPTION_EB},
1847 {"EL", no_argument, NULL, OPTION_EL},
1848 { NULL, no_argument, NULL, 0}
1851 size_t md_longopts_size = sizeof (md_longopts);
1853 int md_short_jump_size;
1856 md_create_short_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)
1862 as_fatal (_("failed sanity check: short_jump"));
1866 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1867 addressT from_Nddr ATTRIBUTE_UNUSED,
1868 addressT to_Nddr ATTRIBUTE_UNUSED,
1869 fragS * frag ATTRIBUTE_UNUSED,
1870 symbolS * to_symbol ATTRIBUTE_UNUSED)
1872 as_fatal (_("failed sanity check: long_jump"));
1875 /* Called after relaxing, change the frags so they know how big they are. */
1878 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1879 segT sec ATTRIBUTE_UNUSED,
1884 switch (fragP->fr_subtype)
1886 case UNDEFINED_PC_OFFSET:
1887 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1888 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1889 fragP->fr_fix += INST_WORD_SIZE * 2;
1892 case DEFINED_ABS_SEGMENT:
1893 if (fragP->fr_symbol == GOT_symbol)
1894 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1895 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1897 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1898 fragP->fr_offset, FALSE, BFD_RELOC_64);
1899 fragP->fr_fix += INST_WORD_SIZE * 2;
1902 case DEFINED_RO_SEGMENT:
1903 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1904 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1905 fragP->fr_fix += INST_WORD_SIZE;
1908 case DEFINED_RW_SEGMENT:
1909 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1910 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1911 fragP->fr_fix += INST_WORD_SIZE;
1914 case DEFINED_PC_OFFSET:
1915 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1916 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1917 fragP->fr_fix += INST_WORD_SIZE;
1920 case LARGE_DEFINED_PC_OFFSET:
1921 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1922 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1923 fragP->fr_fix += INST_WORD_SIZE * 2;
1927 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1928 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1929 fragP->fr_fix += INST_WORD_SIZE * 2;
1933 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1934 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TEXTREL);
1935 fragP->fr_fix += INST_WORD_SIZE * 2;
1938 case TEXT_PC_OFFSET:
1939 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1940 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TEXTPCREL);
1941 fragP->fr_fix += INST_WORD_SIZE * 2;
1945 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1946 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1947 /* fixP->fx_plt = 1; */
1949 fragP->fr_fix += INST_WORD_SIZE * 2;
1953 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1954 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1955 fragP->fr_fix += INST_WORD_SIZE * 2;
1959 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1960 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSGD);
1961 fragP->fr_fix += INST_WORD_SIZE * 2;
1965 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1966 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSLD);
1967 fragP->fr_fix += INST_WORD_SIZE * 2;
1970 case TLSDTPREL_OFFSET:
1971 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1972 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSDTPREL);
1973 fragP->fr_fix += INST_WORD_SIZE * 2;
1982 /* Applies the desired value to the specified location.
1983 Also sets up addends for 'rela' type relocations. */
1985 md_apply_fix (fixS * fixP,
1989 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1990 const char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1991 const char * symname;
1992 /* Note: use offsetT because it is signed, valueT is unsigned. */
1993 offsetT val = (offsetT) * valp;
1995 struct op_code_struct * opcode1;
1996 unsigned long inst1;
1998 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
2000 /* fixP->fx_offset is supposed to be set up correctly for all
2001 symbol relocations. */
2002 if (fixP->fx_addsy == NULL)
2004 if (!fixP->fx_pcrel)
2005 fixP->fx_offset = val; /* Absolute relocation. */
2007 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
2008 (unsigned int) fixP->fx_offset, (unsigned int) val);
2011 /* If we aren't adjusting this fixup to be against the section
2012 symbol, we need to adjust the value. */
2013 if (fixP->fx_addsy != NULL)
2015 if (S_IS_WEAK (fixP->fx_addsy)
2016 || (symbol_used_in_reloc_p (fixP->fx_addsy)
2017 && (((bfd_get_section_flags (stdoutput,
2018 S_GET_SEGMENT (fixP->fx_addsy))
2019 & SEC_LINK_ONCE) != 0)
2020 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
2022 sizeof (".gnu.linkonce") - 1))))
2024 val -= S_GET_VALUE (fixP->fx_addsy);
2025 if (val != 0 && ! fixP->fx_pcrel)
2027 /* In this case, the bfd_install_relocation routine will
2028 incorrectly add the symbol value back in. We just want
2029 the addend to appear in the object file.
2030 FIXME: If this makes VALUE zero, we're toast. */
2031 val -= S_GET_VALUE (fixP->fx_addsy);
2036 /* If the fix is relative to a symbol which is not defined, or not
2037 in the same segment as the fix, we cannot resolve it here. */
2038 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
2039 if (fixP->fx_addsy != NULL
2040 && (!S_IS_DEFINED (fixP->fx_addsy)
2041 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
2045 /* For ELF we can just return and let the reloc that will be generated
2046 take care of everything. For COFF we still have to insert 'val'
2047 into the insn since the addend field will be ignored. */
2051 /* All fixups in the text section must be handled in the linker. */
2052 else if (segment->flags & SEC_CODE)
2054 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
2059 switch (fixP->fx_r_type)
2061 case BFD_RELOC_MICROBLAZE_32_LO:
2062 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2063 if (target_big_endian)
2065 buf[2] |= ((val >> 8) & 0xff);
2066 buf[3] |= (val & 0xff);
2070 buf[1] |= ((val >> 8) & 0xff);
2071 buf[0] |= (val & 0xff);
2074 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2075 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2076 /* Don't do anything if the symbol is not defined. */
2077 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2079 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
2080 as_bad_where (file, fixP->fx_line,
2081 _("pcrel for branch to %s too far (0x%x)"),
2082 symname, (int) val);
2083 if (target_big_endian)
2085 buf[2] |= ((val >> 8) & 0xff);
2086 buf[3] |= (val & 0xff);
2090 buf[1] |= ((val >> 8) & 0xff);
2091 buf[0] |= (val & 0xff);
2097 case BFD_RELOC_32_PCREL:
2098 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2099 /* Don't do anything if the symbol is not defined. */
2100 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2102 if (target_big_endian)
2104 buf[0] |= ((val >> 24) & 0xff);
2105 buf[1] |= ((val >> 16) & 0xff);
2106 buf[2] |= ((val >> 8) & 0xff);
2107 buf[3] |= (val & 0xff);
2111 buf[3] |= ((val >> 24) & 0xff);
2112 buf[2] |= ((val >> 16) & 0xff);
2113 buf[1] |= ((val >> 8) & 0xff);
2114 buf[0] |= (val & 0xff);
2118 case BFD_RELOC_64_PCREL:
2120 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
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];
2125 /* Generate the imm instruction. */
2126 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2127 if (opcode1 == NULL)
2129 as_bad (_("unknown opcode \"%s\""), "imm");
2133 inst1 = opcode1->bit_sequence;
2134 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2135 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
2137 buf[0] = INST_BYTE0 (inst1);
2138 buf[1] = INST_BYTE1 (inst1);
2139 buf[2] = INST_BYTE2 (inst1);
2140 buf[3] = INST_BYTE3 (inst1);
2142 /* Add the value only if the symbol is defined. */
2143 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2145 if (target_big_endian)
2147 buf[6] |= ((val >> 8) & 0xff);
2148 buf[7] |= (val & 0xff);
2152 buf[5] |= ((val >> 8) & 0xff);
2153 buf[4] |= (val & 0xff);
2158 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
2159 case BFD_RELOC_MICROBLAZE_64_TLSGD:
2160 case BFD_RELOC_MICROBLAZE_64_TLSLD:
2161 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2164 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2165 case BFD_RELOC_MICROBLAZE_64_GOT:
2166 case BFD_RELOC_MICROBLAZE_64_PLT:
2167 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2168 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
2169 /* Add an imm instruction. First save the current instruction. */
2170 for (i = 0; i < INST_WORD_SIZE; i++)
2171 buf[i + INST_WORD_SIZE] = buf[i];
2173 /* Generate the imm instruction. */
2174 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2175 if (opcode1 == NULL)
2177 as_bad (_("unknown opcode \"%s\""), "imm");
2181 inst1 = opcode1->bit_sequence;
2183 /* We can fixup call to a defined non-global address
2184 within the same section only. */
2185 buf[0] = INST_BYTE0 (inst1);
2186 buf[1] = INST_BYTE1 (inst1);
2187 buf[2] = INST_BYTE2 (inst1);
2188 buf[3] = INST_BYTE3 (inst1);
2195 if (fixP->fx_addsy == NULL)
2197 /* This fixup has been resolved. Create a reloc in case the linker
2198 moves code around due to relaxing. */
2199 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2200 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2202 fixP->fx_r_type = BFD_RELOC_NONE;
2203 fixP->fx_addsy = section_symbol (absolute_section);
2209 md_operand (expressionS * expressionP)
2211 /* Ignore leading hash symbol, if present. */
2212 if (*input_line_pointer == '#')
2214 input_line_pointer ++;
2215 expression (expressionP);
2219 /* Called just before address relaxation, return the length
2220 by which a fragment must grow to reach it's destination. */
2223 md_estimate_size_before_relax (fragS * fragP,
2226 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2227 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2228 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2229 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2231 switch (fragP->fr_subtype)
2233 case INST_PC_OFFSET:
2234 /* Used to be a PC-relative branch. */
2235 if (!fragP->fr_symbol)
2237 /* We know the abs value: Should never happen. */
2238 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2241 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
2242 !S_IS_WEAK (fragP->fr_symbol))
2244 fragP->fr_subtype = DEFINED_PC_OFFSET;
2245 /* Don't know now whether we need an imm instruction. */
2246 fragP->fr_var = INST_WORD_SIZE;
2248 else if (S_IS_DEFINED (fragP->fr_symbol)
2249 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2251 /* Cannot have a PC-relative branch to a diff segment. */
2252 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2253 S_GET_NAME (fragP->fr_symbol));
2254 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2255 fragP->fr_var = INST_WORD_SIZE*2;
2259 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2260 fragP->fr_var = INST_WORD_SIZE*2;
2264 case INST_NO_OFFSET:
2266 /* Used to be a reference to somewhere which was unknown. */
2267 if (fragP->fr_symbol)
2269 if (fragP->fr_opcode == NULL)
2271 /* Used as an absolute value. */
2272 if (fragP->fr_subtype == INST_NO_OFFSET)
2273 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2274 /* Variable part does not change. */
2275 fragP->fr_var = INST_WORD_SIZE*2;
2277 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2279 /* It is accessed using the small data read only anchor. */
2280 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2281 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2282 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2283 || (! S_IS_DEFINED (fragP->fr_symbol)))
2285 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2286 fragP->fr_var = INST_WORD_SIZE;
2290 /* Variable not in small data read only segment accessed
2291 using small data read only anchor. */
2292 const char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2294 as_bad_where (file, fragP->fr_line,
2295 _("Variable is accessed using small data read "
2296 "only anchor, but it is not in the small data "
2297 "read only section"));
2298 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2299 fragP->fr_var = INST_WORD_SIZE;
2302 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2304 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2305 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2306 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2307 || (!S_IS_DEFINED (fragP->fr_symbol)))
2309 /* It is accessed using the small data read write anchor. */
2310 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2311 fragP->fr_var = INST_WORD_SIZE;
2315 const char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2317 as_bad_where (file, fragP->fr_line,
2318 _("Variable is accessed using small data read "
2319 "write anchor, but it is not in the small data "
2320 "read write section"));
2321 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2322 fragP->fr_var = INST_WORD_SIZE;
2327 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2333 /* We know the abs value: Should never happen. */
2334 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2339 case UNDEFINED_PC_OFFSET:
2340 case LARGE_DEFINED_PC_OFFSET:
2341 case DEFINED_ABS_SEGMENT:
2345 case TEXT_PC_OFFSET:
2348 case TLSTPREL_OFFSET:
2349 case TLSDTPREL_OFFSET:
2350 fragP->fr_var = INST_WORD_SIZE*2;
2352 case DEFINED_RO_SEGMENT:
2353 case DEFINED_RW_SEGMENT:
2354 case DEFINED_PC_OFFSET:
2355 case TLSDTPMOD_OFFSET:
2356 fragP->fr_var = INST_WORD_SIZE;
2362 return fragP->fr_var;
2365 /* Put number into target byte order. */
2368 md_number_to_chars (char * ptr, valueT use, int nbytes)
2370 if (target_big_endian)
2371 number_to_chars_bigendian (ptr, use, nbytes);
2373 number_to_chars_littleendian (ptr, use, nbytes);
2376 /* Round up a section size to the appropriate boundary. */
2379 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2381 return size; /* Byte alignment is fine. */
2385 /* The location from which a PC relative jump should be calculated,
2386 given a PC relative reloc. */
2389 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2392 /* If the symbol is undefined or defined in another section
2393 we leave the add number alone for the linker to fix it later.
2394 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2396 if (fixp->fx_addsy != (symbolS *) NULL
2397 && (!S_IS_DEFINED (fixp->fx_addsy)
2398 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2402 /* The case where we are going to resolve things... */
2403 if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2404 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2406 return fixp->fx_where + fixp->fx_frag->fr_address;
2412 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2413 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2416 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2419 bfd_reloc_code_real_type code;
2421 switch (fixp->fx_r_type)
2423 case BFD_RELOC_NONE:
2424 case BFD_RELOC_MICROBLAZE_64_NONE:
2426 case BFD_RELOC_MICROBLAZE_32_LO:
2427 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2430 case BFD_RELOC_64_PCREL:
2431 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2432 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2433 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2434 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2435 case BFD_RELOC_MICROBLAZE_64_GOT:
2436 case BFD_RELOC_MICROBLAZE_64_PLT:
2437 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2438 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2439 case BFD_RELOC_MICROBLAZE_64_TLSGD:
2440 case BFD_RELOC_MICROBLAZE_64_TLSLD:
2441 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
2442 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
2443 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
2444 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
2445 case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
2446 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
2447 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
2448 code = fixp->fx_r_type;
2452 switch (F (fixp->fx_size, fixp->fx_pcrel))
2454 MAP (1, 0, BFD_RELOC_8);
2455 MAP (2, 0, BFD_RELOC_16);
2456 MAP (4, 0, BFD_RELOC_32);
2457 MAP (1, 1, BFD_RELOC_8_PCREL);
2458 MAP (2, 1, BFD_RELOC_16_PCREL);
2459 MAP (4, 1, BFD_RELOC_32_PCREL);
2461 code = fixp->fx_r_type;
2462 as_bad (_("Can not do %d byte %srelocation"),
2464 fixp->fx_pcrel ? _("pc-relative ") : "");
2469 rel = XNEW (arelent);
2470 rel->sym_ptr_ptr = XNEW (asymbol *);
2472 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2473 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2475 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2477 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2478 /* Always pass the addend along! */
2479 rel->addend = fixp->fx_offset;
2480 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2482 if (rel->howto == NULL)
2484 as_bad_where (fixp->fx_file, fixp->fx_line,
2485 _("Cannot represent relocation type %s"),
2486 bfd_get_reloc_code_name (code));
2488 /* Set howto to a garbage value so that we can keep going. */
2489 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2490 gas_assert (rel->howto != NULL);
2496 md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED)
2501 target_big_endian = 1;
2504 target_big_endian = 0;
2513 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2515 /* fprintf(stream, _("\
2516 MicroBlaze options:\n\
2517 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2521 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2522 found a machine specific op in an expression,
2523 then we create relocs accordingly. */
2526 cons_fix_new_microblaze (fragS * frag,
2530 bfd_reloc_code_real_type r)
2532 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2533 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2534 && (!S_IS_LOCAL (exp->X_op_symbol)))
2535 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2536 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2538 exp->X_op = O_symbol;
2539 r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2558 as_bad (_("unsupported BFD relocation size %u"), size);
2563 fix_new_exp (frag, where, size, exp, 0, r);