1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright (C) 2009-2016 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
91 /* Initialize the relax table. */
92 const relax_typeS md_relax_table[] =
94 { 1, 1, 0, 0 }, /* 0: Unused. */
95 { 1, 1, 0, 0 }, /* 1: Unused. */
96 { 1, 1, 0, 0 }, /* 2: Unused. */
97 { 1, 1, 0, 0 }, /* 3: Unused. */
98 { 32767, -32768, INST_WORD_SIZE, LARGE_DEFINED_PC_OFFSET }, /* 4: DEFINED_PC_OFFSET. */
99 { 1, 1, 0, 0 }, /* 5: Unused. */
100 { 1, 1, 0, 0 }, /* 6: Unused. */
101 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
102 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */
103 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */
104 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */
105 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 11: TLSGD_OFFSET. */
106 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 12: TLSLD_OFFSET. */
107 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */
108 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 14: TLSDTPREL_OFFSET. */
109 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
110 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */
113 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
115 static segT sbss_segment = 0; /* Small bss section. */
116 static segT sbss2_segment = 0; /* Section not used. */
117 static segT sdata_segment = 0; /* Small data section. */
118 static segT sdata2_segment = 0; /* Small read-only section. */
119 static segT rodata_segment = 0; /* read-only section. */
121 /* Generate a symbol for stabs information. */
124 microblaze_generate_symbol (char *sym)
126 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
127 static int microblaze_label_count;
128 sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count);
129 ++microblaze_label_count;
132 /* Handle the section changing pseudo-ops. */
135 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
138 obj_elf_text (ignore);
145 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
148 obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
154 /* Things in the .sdata segment are always considered to be in the small data section. */
157 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
160 obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
166 /* Pseudo op to make file scope bss items. */
169 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
179 segT current_seg = now_seg;
180 subsegT current_subseg = now_subseg;
182 c = get_symbol_name (&name);
184 /* Just after name is now '\0'. */
185 p = input_line_pointer;
186 (void) restore_line_pointer (c);
188 if (*input_line_pointer != ',')
190 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
191 ignore_rest_of_line ();
195 input_line_pointer++; /* skip ',' */
196 if ((size = get_absolute_expression ()) < 0)
198 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
199 ignore_rest_of_line ();
203 /* The third argument to .lcomm is the alignment. */
204 if (*input_line_pointer != ',')
208 ++input_line_pointer;
209 align = get_absolute_expression ();
212 as_warn (_("ignoring bad alignment"));
218 symbolP = symbol_find_or_make (name);
221 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
223 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
224 S_GET_NAME (symbolP));
225 ignore_rest_of_line ();
229 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
231 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
232 S_GET_NAME (symbolP),
233 (long) S_GET_VALUE (symbolP),
236 ignore_rest_of_line ();
243 /* Convert to a power of 2 alignment. */
244 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
247 as_bad (_("Common alignment not a power of 2"));
248 ignore_rest_of_line ();
255 record_alignment (current_seg, align2);
256 subseg_set (current_seg, current_subseg);
258 frag_align (align2, 0, 0);
259 if (S_GET_SEGMENT (symbolP) == current_seg)
260 symbol_get_frag (symbolP)->fr_symbol = 0;
261 symbol_set_frag (symbolP, frag_now);
262 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
265 S_SET_SIZE (symbolP, size);
266 S_SET_SEGMENT (symbolP, current_seg);
267 subseg_set (current_seg, current_subseg);
268 demand_empty_rest_of_line ();
272 microblaze_s_rdata (int localvar)
278 obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
279 if (rodata_segment == 0)
280 rodata_segment = subseg_new (".rodata", 0);
285 obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
293 microblaze_s_bss (int localvar)
296 if (localvar == 0) /* bss. */
297 obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
298 else if (localvar == 1)
301 obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
302 if (sbss_segment == 0)
303 sbss_segment = subseg_new (".sbss", 0);
310 /* endp_p is always 1 as this func is called only for .end <funcname>
311 This func consumes the <funcname> and calls regular processing
312 s_func(1) with arg 1 (1 for end). */
315 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
318 restore_line_pointer (get_symbol_name (&name));
322 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
325 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
332 c = get_symbol_name (&name);
333 symbolP = symbol_find_or_make (name);
334 S_SET_WEAK (symbolP);
335 (void) restore_line_pointer (c);
339 if (!is_end_of_line[(unsigned char) *input_line_pointer])
341 if (S_IS_DEFINED (symbolP))
343 as_bad ("Ignoring attempt to redefine symbol `%s'.",
344 S_GET_NAME (symbolP));
345 ignore_rest_of_line ();
349 if (*input_line_pointer == ',')
351 ++input_line_pointer;
356 if (exp.X_op != O_symbol)
358 as_bad ("bad .weakext directive");
359 ignore_rest_of_line ();
362 symbol_set_value_expression (symbolP, &exp);
365 demand_empty_rest_of_line ();
368 /* This table describes all the machine specific pseudo-ops the assembler
369 has to support. The fields are:
370 Pseudo-op name without dot
371 Function to call to execute this pseudo-op
372 Integer arg to pass to the function. */
373 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
374 and then in the read.c table. */
375 const pseudo_typeS md_pseudo_table[] =
377 {"lcomm", microblaze_s_lcomm, 1},
378 {"data", microblaze_s_data, 0},
379 {"data8", cons, 1}, /* Same as byte. */
380 {"data16", cons, 2}, /* Same as hword. */
381 {"data32", cons, 4}, /* Same as word. */
382 {"ent", s_func, 0}, /* Treat ent as function entry point. */
383 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
384 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
385 {"weakext", microblaze_s_weakext, 0},
386 {"rodata", microblaze_s_rdata, 0},
387 {"sdata2", microblaze_s_rdata, 1},
388 {"sdata", microblaze_s_sdata, 0},
389 {"bss", microblaze_s_bss, 0},
390 {"sbss", microblaze_s_bss, 1},
391 {"text", microblaze_s_text, 0},
393 {"frame", s_ignore, 0},
394 {"mask", s_ignore, 0}, /* Emitted by gcc. */
398 /* This function is called once, at assembler startup time. This should
399 set up all the tables, etc that the MD part of the assembler needs. */
404 struct op_code_struct * opcode;
406 opcode_hash_control = hash_new ();
408 /* Insert unique names into hash table. */
409 for (opcode = opcodes; opcode->name; opcode ++)
410 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
413 /* Try to parse a reg name. */
416 parse_reg (char * s, unsigned * reg)
420 /* Strip leading whitespace. */
421 while (ISSPACE (* s))
424 if (strncasecmp (s, "rpc", 3) == 0)
429 else if (strncasecmp (s, "rmsr", 4) == 0)
434 else if (strncasecmp (s, "rear", 4) == 0)
439 else if (strncasecmp (s, "resr", 4) == 0)
444 else if (strncasecmp (s, "rfsr", 4) == 0)
449 else if (strncasecmp (s, "rbtr", 4) == 0)
454 else if (strncasecmp (s, "redr", 4) == 0)
459 /* MMU registers start. */
460 else if (strncasecmp (s, "rpid", 4) == 0)
465 else if (strncasecmp (s, "rzpr", 4) == 0)
470 else if (strncasecmp (s, "rtlbx", 5) == 0)
475 else if (strncasecmp (s, "rtlblo", 6) == 0)
480 else if (strncasecmp (s, "rtlbhi", 6) == 0)
485 else if (strncasecmp (s, "rtlbsx", 6) == 0)
490 /* MMU registers end. */
491 else if (strncasecmp (s, "rpvr", 4) == 0)
493 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
495 tmpreg = (s[4]-'0')*10 + s[5] - '0';
499 else if (ISDIGIT (s[4]))
505 as_bad (_("register expected, but saw '%.6s'"), s);
506 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
507 *reg = REG_PVR + tmpreg;
510 as_bad (_("Invalid register number at '%.6s'"), s);
515 else if (strncasecmp (s, "rsp", 3) == 0)
520 else if (strncasecmp (s, "rfsl", 4) == 0)
522 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
524 tmpreg = (s[4] - '0') * 10 + s[5] - '0';
527 else if (ISDIGIT (s[4]))
533 as_bad (_("register expected, but saw '%.6s'"), s);
535 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
539 as_bad (_("Invalid register number at '%.6s'"), s);
544 /* Stack protection registers. */
545 else if (strncasecmp (s, "rshr", 4) == 0)
550 else if (strncasecmp (s, "rslr", 4) == 0)
557 if (TOLOWER (s[0]) == 'r')
559 if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
561 tmpreg = (s[1] - '0') * 10 + s[2] - '0';
564 else if (ISDIGIT (s[1]))
570 as_bad (_("register expected, but saw '%.6s'"), s);
572 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
576 as_bad (_("Invalid register number at '%.6s'"), s);
582 as_bad (_("register expected, but saw '%.6s'"), s);
588 parse_exp (char *s, expressionS *e)
593 /* Skip whitespace. */
594 while (ISSPACE (* s))
597 save = input_line_pointer;
598 input_line_pointer = s;
602 if (e->X_op == O_absent)
603 as_fatal (_("missing operand"));
605 new_pointer = input_line_pointer;
606 input_line_pointer = save;
611 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
618 #define IMM_TLSDTPMOD 6
619 #define IMM_TLSDTPREL 7
620 #define IMM_TLSTPREL 8
624 const char *isuffix; /* Suffix String */
625 int itype; /* Suffix Type */
626 int otype; /* Offset Type */
629 /* These are NOT in assending order of type, GOTOFF is ahead to make
630 sure @GOTOFF does not get matched with @GOT */
631 static struct imm_type imm_types[] = {
632 { "NONE", IMM_NONE , 0 },
633 { "GOTOFF", IMM_GOTOFF , GOTOFF_OFFSET },
634 { "GOT", IMM_GOT , GOT_OFFSET },
635 { "PLT", IMM_PLT , PLT_OFFSET },
636 { "TLSGD", IMM_TLSGD , TLSGD_OFFSET },
637 { "TLSLDM", IMM_TLSLD, TLSLD_OFFSET },
638 { "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET },
639 { "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET },
640 { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET }
644 match_imm (const char *s, int *ilen)
649 /* Check for matching suffix */
650 for (i = 1; i < IMM_MAX; i++)
652 slen = strlen (imm_types[i].isuffix);
654 if (strncmp (imm_types[i].isuffix, s, slen) == 0)
657 return imm_types[i].itype;
665 get_imm_otype (int itype)
670 /* Check for matching itype */
671 for (i = 1; i < IMM_MAX; i++)
673 if (imm_types[i].itype == itype)
675 otype = imm_types[i].otype;
682 static symbolS * GOT_symbol;
684 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
687 parse_imm (char * s, expressionS * e, offsetT min, offsetT max)
695 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
696 for (atp = s; *atp != '@'; atp++)
697 if (is_end_of_line[(unsigned char) *atp])
702 itype = match_imm (atp + 1, &ilen);
722 if (atp && !GOT_symbol)
724 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
727 new_pointer = parse_exp (s, e);
729 if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20))
731 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
734 if (e->X_op == O_absent)
735 ; /* An error message has already been emitted. */
736 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
737 as_fatal (_("operand must be a constant or a label"));
738 else if (e->X_op == O_constant)
740 /* Special case: sign extend negative 32-bit values to offsetT size. */
741 if ((e->X_add_number >> 31) == 1)
742 e->X_add_number |= -((addressT) (1U << 31));
744 if (e->X_add_number < min || e->X_add_number > max)
746 as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"),
747 (long) min, (long) max, (long) e->X_add_number);
753 *atp = '@'; /* restore back (needed?) */
754 if (new_pointer >= atp)
755 new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */
761 check_got (int * got_type, int * got_len)
769 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
770 for (atp = input_line_pointer; *atp != '@'; atp++)
771 if (is_end_of_line[(unsigned char) *atp])
774 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
777 *got_type = IMM_GOTOFF;
779 else if (strncmp (atp + 1, "GOT", 3) == 0)
784 else if (strncmp (atp + 1, "PLT", 3) == 0)
793 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
795 first = atp - input_line_pointer;
797 past_got = atp + *got_len + 1;
798 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
800 second = new_pointer - past_got;
801 tmpbuf = xmalloc (first + second + 2); /* One extra byte for ' ' and one for NUL. */
802 memcpy (tmpbuf, input_line_pointer, first);
803 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
804 memcpy (tmpbuf + first + 1, past_got, second);
805 tmpbuf[first + second + 1] = '\0';
810 extern bfd_reloc_code_real_type
811 parse_cons_expression_microblaze (expressionS *exp, int size)
815 /* Handle @GOTOFF et.al. */
816 char *save, *gotfree_copy;
817 int got_len, got_type;
819 save = input_line_pointer;
820 gotfree_copy = check_got (& got_type, & got_len);
822 input_line_pointer = gotfree_copy;
828 exp->X_md = got_type;
829 input_line_pointer = save + (input_line_pointer - gotfree_copy)
836 return BFD_RELOC_NONE;
839 /* This is the guts of the machine-dependent assembler. STR points to a
840 machine dependent instruction. This function is supposed to emit
841 the frags/bytes it assembles to. */
843 static char * str_microblaze_ro_anchor = "RO";
844 static char * str_microblaze_rw_anchor = "RW";
847 check_spl_reg (unsigned * reg)
849 if ((*reg == REG_MSR) || (*reg == REG_PC)
850 || (*reg == REG_EAR) || (*reg == REG_ESR)
851 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
852 || (*reg == REG_PID) || (*reg == REG_ZPR)
853 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
854 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
855 || (*reg == REG_SHR) || (*reg == REG_SLR)
856 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
862 /* Here we decide which fixups can be adjusted to make them relative to
863 the beginning of the section instead of the symbol. Basically we need
864 to make sure that the dynamic relocations are done correctly, so in
865 some cases we force the original symbol to be used. */
868 tc_microblaze_fix_adjustable (struct fix *fixP)
870 if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
873 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
874 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
875 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
876 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT
877 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGD
878 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSLD
879 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
880 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPREL
881 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSDTPREL
882 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
883 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSTPREL)
890 md_assemble (char * str)
894 struct op_code_struct * opcode, *opcode1;
895 char * output = NULL;
898 unsigned long inst, inst1;
903 unsigned int immed, temp;
907 /* Drop leading whitespace. */
908 while (ISSPACE (* str))
911 /* Find the op code end. */
912 for (op_start = op_end = str;
913 *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
916 name[nlen] = op_start[nlen];
918 if (nlen == sizeof (name) - 1)
926 as_bad (_("can't find opcode "));
930 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
933 as_bad (_("unknown opcode \"%s\""), name);
937 inst = opcode->bit_sequence;
940 switch (opcode->inst_type)
942 case INST_TYPE_RD_R1_R2:
943 if (strcmp (op_end, ""))
944 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
947 as_fatal (_("Error in statement syntax"));
950 if (strcmp (op_end, ""))
951 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
954 as_fatal (_("Error in statement syntax"));
957 if (strcmp (op_end, ""))
958 op_end = parse_reg (op_end + 1, ®3); /* Get r2. */
961 as_fatal (_("Error in statement syntax"));
965 /* Check for spl registers. */
966 if (check_spl_reg (& reg1))
967 as_fatal (_("Cannot use special register with this instruction"));
968 if (check_spl_reg (& reg2))
969 as_fatal (_("Cannot use special register with this instruction"));
970 if (check_spl_reg (& reg3))
971 as_fatal (_("Cannot use special register with this instruction"));
973 if (streq (name, "sub"))
975 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
976 inst |= (reg1 << RD_LOW) & RD_MASK;
977 inst |= (reg3 << RA_LOW) & RA_MASK;
978 inst |= (reg2 << RB_LOW) & RB_MASK;
982 inst |= (reg1 << RD_LOW) & RD_MASK;
983 inst |= (reg2 << RA_LOW) & RA_MASK;
984 inst |= (reg3 << RB_LOW) & RB_MASK;
986 output = frag_more (isize);
989 case INST_TYPE_RD_R1_IMM:
990 if (strcmp (op_end, ""))
991 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
994 as_fatal (_("Error in statement syntax"));
997 if (strcmp (op_end, ""))
998 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1001 as_fatal (_("Error in statement syntax"));
1004 if (strcmp (op_end, ""))
1005 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1007 as_fatal (_("Error in statement syntax"));
1009 /* Check for spl registers. */
1010 if (check_spl_reg (& reg1))
1011 as_fatal (_("Cannot use special register with this instruction"));
1012 if (check_spl_reg (& reg2))
1013 as_fatal (_("Cannot use special register with this instruction"));
1015 if (exp.X_op != O_constant)
1018 relax_substateT subtype;
1020 if (streq (name, "lmi"))
1021 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
1022 else if (streq (name, "smi"))
1023 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
1025 if (reg2 == REG_ROSDP)
1026 opc = str_microblaze_ro_anchor;
1027 else if (reg2 == REG_RWSDP)
1028 opc = str_microblaze_rw_anchor;
1032 subtype = get_imm_otype(exp.X_md);
1034 subtype = opcode->inst_offset_type;
1036 output = frag_var (rs_machine_dependent,
1037 isize * 2, /* maxm of 2 words. */
1038 isize, /* minm of 1 word. */
1039 subtype, /* PC-relative or not. */
1047 output = frag_more (isize);
1048 immed = exp.X_add_number;
1051 if (streq (name, "lmi") || streq (name, "smi"))
1053 /* Load/store 32-d consecutive registers. Used on exit/entry
1054 to subroutines to save and restore registers to stack.
1055 Generate 32-d insts. */
1059 if (streq (name, "lmi"))
1060 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
1062 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
1065 as_bad (_("unknown opcode \"%s\""), "lwi");
1068 inst = opcode->bit_sequence;
1069 inst |= (reg1 << RD_LOW) & RD_MASK;
1070 inst |= (reg2 << RA_LOW) & RA_MASK;
1071 inst |= (immed << IMM_LOW) & IMM_MASK;
1073 for (i = 0; i < count - 1; i++)
1075 output[0] = INST_BYTE0 (inst);
1076 output[1] = INST_BYTE1 (inst);
1077 output[2] = INST_BYTE2 (inst);
1078 output[3] = INST_BYTE3 (inst);
1079 output = frag_more (isize);
1082 inst = opcode->bit_sequence;
1083 inst |= (reg1 << RD_LOW) & RD_MASK;
1084 inst |= (reg2 << RA_LOW) & RA_MASK;
1085 inst |= (immed << IMM_LOW) & IMM_MASK;
1090 temp = immed & 0xFFFF8000;
1091 if ((temp != 0) && (temp != 0xFFFF8000))
1093 /* Needs an immediate inst. */
1094 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1095 if (opcode1 == NULL)
1097 as_bad (_("unknown opcode \"%s\""), "imm");
1101 inst1 = opcode1->bit_sequence;
1102 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1103 output[0] = INST_BYTE0 (inst1);
1104 output[1] = INST_BYTE1 (inst1);
1105 output[2] = INST_BYTE2 (inst1);
1106 output[3] = INST_BYTE3 (inst1);
1107 output = frag_more (isize);
1109 inst |= (reg1 << RD_LOW) & RD_MASK;
1110 inst |= (reg2 << RA_LOW) & RA_MASK;
1111 inst |= (immed << IMM_LOW) & IMM_MASK;
1115 case INST_TYPE_RD_R1_IMM5:
1116 if (strcmp (op_end, ""))
1117 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1120 as_fatal (_("Error in statement syntax"));
1123 if (strcmp (op_end, ""))
1124 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1127 as_fatal (_("Error in statement syntax"));
1130 if (strcmp (op_end, ""))
1131 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1133 as_fatal (_("Error in statement syntax"));
1135 /* Check for spl registers. */
1136 if (check_spl_reg (®1))
1137 as_fatal (_("Cannot use special register with this instruction"));
1138 if (check_spl_reg (®2))
1139 as_fatal (_("Cannot use special register with this instruction"));
1141 if (exp.X_op != O_constant)
1142 as_warn (_("Symbol used as immediate for shift instruction"));
1145 output = frag_more (isize);
1146 immed = exp.X_add_number;
1149 if (immed != (immed % 32))
1151 as_warn (_("Shift value > 32. using <value %% 32>"));
1154 inst |= (reg1 << RD_LOW) & RD_MASK;
1155 inst |= (reg2 << RA_LOW) & RA_MASK;
1156 inst |= (immed << IMM_LOW) & IMM5_MASK;
1159 case INST_TYPE_R1_R2:
1160 if (strcmp (op_end, ""))
1161 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1164 as_fatal (_("Error in statement syntax"));
1167 if (strcmp (op_end, ""))
1168 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1171 as_fatal (_("Error in statement syntax"));
1175 /* Check for spl registers. */
1176 if (check_spl_reg (& reg1))
1177 as_fatal (_("Cannot use special register with this instruction"));
1178 if (check_spl_reg (& reg2))
1179 as_fatal (_("Cannot use special register with this instruction"));
1181 inst |= (reg1 << RA_LOW) & RA_MASK;
1182 inst |= (reg2 << RB_LOW) & RB_MASK;
1183 output = frag_more (isize);
1186 case INST_TYPE_RD_R1:
1187 if (strcmp (op_end, ""))
1188 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1191 as_fatal (_("Error in statement syntax"));
1194 if (strcmp (op_end, ""))
1195 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1198 as_fatal (_("Error in statement syntax"));
1202 /* Check for spl registers. */
1203 if (check_spl_reg (®1))
1204 as_fatal (_("Cannot use special register with this instruction"));
1205 if (check_spl_reg (®2))
1206 as_fatal (_("Cannot use special register with this instruction"));
1208 inst |= (reg1 << RD_LOW) & RD_MASK;
1209 inst |= (reg2 << RA_LOW) & RA_MASK;
1210 output = frag_more (isize);
1213 case INST_TYPE_RD_RFSL:
1214 if (strcmp (op_end, ""))
1215 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1218 as_fatal (_("Error in statement syntax"));
1221 if (strcmp (op_end, ""))
1222 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1225 as_fatal (_("Error in statement syntax"));
1229 /* Check for spl registers. */
1230 if (check_spl_reg (®1))
1231 as_fatal (_("Cannot use special register with this instruction"));
1233 inst |= (reg1 << RD_LOW) & RD_MASK;
1234 inst |= (immed << IMM_LOW) & RFSL_MASK;
1235 output = frag_more (isize);
1238 case INST_TYPE_RD_IMM15:
1239 if (strcmp (op_end, ""))
1240 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1243 as_fatal (_("Error in statement syntax"));
1247 if (strcmp (op_end, ""))
1248 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1250 as_fatal (_("Error in statement syntax"));
1252 /* Check for spl registers. */
1253 if (check_spl_reg (®1))
1254 as_fatal (_("Cannot use special register with this instruction"));
1256 if (exp.X_op != O_constant)
1257 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1260 output = frag_more (isize);
1261 immed = exp.X_add_number;
1263 inst |= (reg1 << RD_LOW) & RD_MASK;
1264 inst |= (immed << IMM_LOW) & IMM15_MASK;
1267 case INST_TYPE_R1_RFSL:
1268 if (strcmp (op_end, ""))
1269 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1272 as_fatal (_("Error in statement syntax"));
1275 if (strcmp (op_end, ""))
1276 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1279 as_fatal (_("Error in statement syntax"));
1283 /* Check for spl registers. */
1284 if (check_spl_reg (®1))
1285 as_fatal (_("Cannot use special register with this instruction"));
1287 inst |= (reg1 << RA_LOW) & RA_MASK;
1288 inst |= (immed << IMM_LOW) & RFSL_MASK;
1289 output = frag_more (isize);
1292 case INST_TYPE_RFSL:
1293 if (strcmp (op_end, ""))
1294 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1297 as_fatal (_("Error in statement syntax"));
1300 inst |= (immed << IMM_LOW) & RFSL_MASK;
1301 output = frag_more (isize);
1305 if (strcmp (op_end, ""))
1306 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1309 as_fatal (_("Error in statement syntax"));
1313 /* Check for spl registers. */
1314 if (check_spl_reg (®1))
1315 as_fatal (_("Cannot use special register with this instruction"));
1317 inst |= (reg1 << RA_LOW) & RA_MASK;
1318 output = frag_more (isize);
1321 /* For tuqula insn...:) */
1323 if (strcmp (op_end, ""))
1324 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1327 as_fatal (_("Error in statement syntax"));
1331 /* Check for spl registers. */
1332 if (check_spl_reg (®1))
1333 as_fatal (_("Cannot use special register with this instruction"));
1335 inst |= (reg1 << RD_LOW) & RD_MASK;
1336 output = frag_more (isize);
1339 case INST_TYPE_RD_SPECIAL:
1340 if (strcmp (op_end, ""))
1341 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1344 as_fatal (_("Error in statement syntax"));
1347 if (strcmp (op_end, ""))
1348 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1351 as_fatal (_("Error in statement syntax"));
1355 if (reg2 == REG_MSR)
1356 immed = opcode->immval_mask | REG_MSR_MASK;
1357 else if (reg2 == REG_PC)
1358 immed = opcode->immval_mask | REG_PC_MASK;
1359 else if (reg2 == REG_EAR)
1360 immed = opcode->immval_mask | REG_EAR_MASK;
1361 else if (reg2 == REG_ESR)
1362 immed = opcode->immval_mask | REG_ESR_MASK;
1363 else if (reg2 == REG_FSR)
1364 immed = opcode->immval_mask | REG_FSR_MASK;
1365 else if (reg2 == REG_BTR)
1366 immed = opcode->immval_mask | REG_BTR_MASK;
1367 else if (reg2 == REG_EDR)
1368 immed = opcode->immval_mask | REG_EDR_MASK;
1369 else if (reg2 == REG_PID)
1370 immed = opcode->immval_mask | REG_PID_MASK;
1371 else if (reg2 == REG_ZPR)
1372 immed = opcode->immval_mask | REG_ZPR_MASK;
1373 else if (reg2 == REG_TLBX)
1374 immed = opcode->immval_mask | REG_TLBX_MASK;
1375 else if (reg2 == REG_TLBLO)
1376 immed = opcode->immval_mask | REG_TLBLO_MASK;
1377 else if (reg2 == REG_TLBHI)
1378 immed = opcode->immval_mask | REG_TLBHI_MASK;
1379 else if (reg2 == REG_SHR)
1380 immed = opcode->immval_mask | REG_SHR_MASK;
1381 else if (reg2 == REG_SLR)
1382 immed = opcode->immval_mask | REG_SLR_MASK;
1383 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1384 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1386 as_fatal (_("invalid value for special purpose register"));
1387 inst |= (reg1 << RD_LOW) & RD_MASK;
1388 inst |= (immed << IMM_LOW) & IMM_MASK;
1389 output = frag_more (isize);
1392 case INST_TYPE_SPECIAL_R1:
1393 if (strcmp (op_end, ""))
1394 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1397 as_fatal (_("Error in statement syntax"));
1400 if (strcmp (op_end, ""))
1401 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1404 as_fatal (_("Error in statement syntax"));
1408 if (reg1 == REG_MSR)
1409 immed = opcode->immval_mask | REG_MSR_MASK;
1410 else if (reg1 == REG_PC)
1411 immed = opcode->immval_mask | REG_PC_MASK;
1412 else if (reg1 == REG_EAR)
1413 immed = opcode->immval_mask | REG_EAR_MASK;
1414 else if (reg1 == REG_ESR)
1415 immed = opcode->immval_mask | REG_ESR_MASK;
1416 else if (reg1 == REG_FSR)
1417 immed = opcode->immval_mask | REG_FSR_MASK;
1418 else if (reg1 == REG_BTR)
1419 immed = opcode->immval_mask | REG_BTR_MASK;
1420 else if (reg1 == REG_EDR)
1421 immed = opcode->immval_mask | REG_EDR_MASK;
1422 else if (reg1 == REG_PID)
1423 immed = opcode->immval_mask | REG_PID_MASK;
1424 else if (reg1 == REG_ZPR)
1425 immed = opcode->immval_mask | REG_ZPR_MASK;
1426 else if (reg1 == REG_TLBX)
1427 immed = opcode->immval_mask | REG_TLBX_MASK;
1428 else if (reg1 == REG_TLBLO)
1429 immed = opcode->immval_mask | REG_TLBLO_MASK;
1430 else if (reg1 == REG_TLBHI)
1431 immed = opcode->immval_mask | REG_TLBHI_MASK;
1432 else if (reg1 == REG_TLBSX)
1433 immed = opcode->immval_mask | REG_TLBSX_MASK;
1434 else if (reg1 == REG_SHR)
1435 immed = opcode->immval_mask | REG_SHR_MASK;
1436 else if (reg1 == REG_SLR)
1437 immed = opcode->immval_mask | REG_SLR_MASK;
1439 as_fatal (_("invalid value for special purpose register"));
1440 inst |= (reg2 << RA_LOW) & RA_MASK;
1441 inst |= (immed << IMM_LOW) & IMM_MASK;
1442 output = frag_more (isize);
1445 case INST_TYPE_R1_R2_SPECIAL:
1446 if (strcmp (op_end, ""))
1447 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1450 as_fatal (_("Error in statement syntax"));
1453 if (strcmp (op_end, ""))
1454 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1457 as_fatal (_("Error in statement syntax"));
1461 /* Check for spl registers. */
1462 if (check_spl_reg (®1))
1463 as_fatal (_("Cannot use special register with this instruction"));
1464 if (check_spl_reg (®2))
1465 as_fatal (_("Cannot use special register with this instruction"));
1467 /* insn wic ra, rb => wic ra, ra, rb. */
1468 inst |= (reg1 << RA_LOW) & RA_MASK;
1469 inst |= (reg2 << RB_LOW) & RB_MASK;
1471 output = frag_more (isize);
1474 case INST_TYPE_RD_R2:
1475 if (strcmp (op_end, ""))
1476 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1479 as_fatal (_("Error in statement syntax"));
1482 if (strcmp (op_end, ""))
1483 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1486 as_fatal (_("Error in statement syntax"));
1490 /* Check for spl registers. */
1491 if (check_spl_reg (®1))
1492 as_fatal (_("Cannot use special register with this instruction"));
1493 if (check_spl_reg (®2))
1494 as_fatal (_("Cannot use special register with this instruction"));
1496 inst |= (reg1 << RD_LOW) & RD_MASK;
1497 inst |= (reg2 << RB_LOW) & RB_MASK;
1498 output = frag_more (isize);
1501 case INST_TYPE_R1_IMM:
1502 if (strcmp (op_end, ""))
1503 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1506 as_fatal (_("Error in statement syntax"));
1509 if (strcmp (op_end, ""))
1510 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1512 as_fatal (_("Error in statement syntax"));
1514 /* Check for spl registers. */
1515 if (check_spl_reg (®1))
1516 as_fatal (_("Cannot use special register with this instruction"));
1518 if (exp.X_op != O_constant)
1521 relax_substateT subtype;
1524 subtype = get_imm_otype(exp.X_md);
1526 subtype = opcode->inst_offset_type;
1528 output = frag_var (rs_machine_dependent,
1529 isize * 2, /* maxm of 2 words. */
1530 isize, /* minm of 1 word. */
1531 subtype, /* PC-relative or not. */
1539 output = frag_more (isize);
1540 immed = exp.X_add_number;
1543 temp = immed & 0xFFFF8000;
1544 if ((temp != 0) && (temp != 0xFFFF8000))
1546 /* Needs an immediate inst. */
1547 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1548 if (opcode1 == NULL)
1550 as_bad (_("unknown opcode \"%s\""), "imm");
1554 inst1 = opcode1->bit_sequence;
1555 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1556 output[0] = INST_BYTE0 (inst1);
1557 output[1] = INST_BYTE1 (inst1);
1558 output[2] = INST_BYTE2 (inst1);
1559 output[3] = INST_BYTE3 (inst1);
1560 output = frag_more (isize);
1563 inst |= (reg1 << RA_LOW) & RA_MASK;
1564 inst |= (immed << IMM_LOW) & IMM_MASK;
1567 case INST_TYPE_RD_IMM:
1568 if (strcmp (op_end, ""))
1569 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1572 as_fatal (_("Error in statement syntax"));
1575 if (strcmp (op_end, ""))
1576 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1578 as_fatal (_("Error in statement syntax"));
1580 /* Check for spl registers. */
1581 if (check_spl_reg (®1))
1582 as_fatal (_("Cannot use special register with this instruction"));
1584 if (exp.X_op != O_constant)
1587 relax_substateT subtype;
1590 subtype = get_imm_otype(exp.X_md);
1592 subtype = opcode->inst_offset_type;
1594 output = frag_var (rs_machine_dependent,
1595 isize * 2, /* maxm of 2 words. */
1596 isize, /* minm of 1 word. */
1597 subtype, /* PC-relative or not. */
1605 output = frag_more (isize);
1606 immed = exp.X_add_number;
1609 temp = immed & 0xFFFF8000;
1610 if ((temp != 0) && (temp != 0xFFFF8000))
1612 /* Needs an immediate inst. */
1613 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1614 if (opcode1 == NULL)
1616 as_bad (_("unknown opcode \"%s\""), "imm");
1620 inst1 = opcode1->bit_sequence;
1621 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1622 output[0] = INST_BYTE0 (inst1);
1623 output[1] = INST_BYTE1 (inst1);
1624 output[2] = INST_BYTE2 (inst1);
1625 output[3] = INST_BYTE3 (inst1);
1626 output = frag_more (isize);
1629 inst |= (reg1 << RD_LOW) & RD_MASK;
1630 inst |= (immed << IMM_LOW) & IMM_MASK;
1634 if (strcmp (op_end, ""))
1635 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1638 as_fatal (_("Error in statement syntax"));
1642 /* Check for spl registers. */
1643 if (check_spl_reg (®2))
1644 as_fatal (_("Cannot use special register with this instruction"));
1646 inst |= (reg2 << RB_LOW) & RB_MASK;
1647 output = frag_more (isize);
1651 if (streq (name, "imm"))
1652 as_fatal (_("An IMM instruction should not be present in the .s file"));
1654 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1656 if (exp.X_op != O_constant)
1659 relax_substateT subtype;
1662 subtype = get_imm_otype(exp.X_md);
1664 subtype = opcode->inst_offset_type;
1666 output = frag_var (rs_machine_dependent,
1667 isize * 2, /* maxm of 2 words. */
1668 isize, /* minm of 1 word. */
1669 subtype, /* PC-relative or not. */
1677 output = frag_more (isize);
1678 immed = exp.X_add_number;
1682 temp = immed & 0xFFFF8000;
1683 if ((temp != 0) && (temp != 0xFFFF8000))
1685 /* Needs an immediate inst. */
1686 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1687 if (opcode1 == NULL)
1689 as_bad (_("unknown opcode \"%s\""), "imm");
1693 inst1 = opcode1->bit_sequence;
1694 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1695 output[0] = INST_BYTE0 (inst1);
1696 output[1] = INST_BYTE1 (inst1);
1697 output[2] = INST_BYTE2 (inst1);
1698 output[3] = INST_BYTE3 (inst1);
1699 output = frag_more (isize);
1701 inst |= (immed << IMM_LOW) & IMM_MASK;
1704 case INST_TYPE_NONE:
1705 output = frag_more (isize);
1708 case INST_TYPE_IMM5:
1709 if (strcmp(op_end, ""))
1710 op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5);
1712 as_fatal(_("Error in statement syntax"));
1713 if (exp.X_op != O_constant) {
1714 as_warn(_("Symbol used as immediate for mbar instruction"));
1716 output = frag_more (isize);
1717 immed = exp.X_add_number;
1719 if (immed != (immed % 32)) {
1720 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1723 inst |= (immed << IMM_MBAR);
1727 as_fatal (_("unimplemented opcode \"%s\""), name);
1730 /* Drop whitespace after all the operands have been parsed. */
1731 while (ISSPACE (* op_end))
1734 /* Give warning message if the insn has more operands than required. */
1735 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1736 as_warn (_("ignoring operands: %s "), op_end);
1738 output[0] = INST_BYTE0 (inst);
1739 output[1] = INST_BYTE1 (inst);
1740 output[2] = INST_BYTE2 (inst);
1741 output[3] = INST_BYTE3 (inst);
1744 dwarf2_emit_insn (4);
1749 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1754 /* Various routines to kill one day. */
1755 /* Equal to MAX_PRECISION in atof-ieee.c */
1756 #define MAX_LITTLENUMS 6
1758 /* Turn a string in input_line_pointer into a floating point constant of type
1759 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1760 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1762 md_atof (int type, char * litP, int * sizeP)
1765 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1797 return _("Bad call to MD_NTOF()");
1800 t = atof_ieee (input_line_pointer, type, words);
1803 input_line_pointer = t;
1805 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1807 if (! target_big_endian)
1809 for (i = prec - 1; i >= 0; i--)
1811 md_number_to_chars (litP, (valueT) words[i],
1812 sizeof (LITTLENUM_TYPE));
1813 litP += sizeof (LITTLENUM_TYPE);
1817 for (i = 0; i < prec; i++)
1819 md_number_to_chars (litP, (valueT) words[i],
1820 sizeof (LITTLENUM_TYPE));
1821 litP += sizeof (LITTLENUM_TYPE);
1827 const char * md_shortopts = "";
1829 struct option md_longopts[] =
1831 {"EB", no_argument, NULL, OPTION_EB},
1832 {"EL", no_argument, NULL, OPTION_EL},
1833 { NULL, no_argument, NULL, 0}
1836 size_t md_longopts_size = sizeof (md_longopts);
1838 int md_short_jump_size;
1841 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1842 addressT from_Nddr ATTRIBUTE_UNUSED,
1843 addressT to_Nddr ATTRIBUTE_UNUSED,
1844 fragS * frag ATTRIBUTE_UNUSED,
1845 symbolS * to_symbol ATTRIBUTE_UNUSED)
1847 as_fatal (_("failed sanity check: short_jump"));
1851 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1852 addressT from_Nddr ATTRIBUTE_UNUSED,
1853 addressT to_Nddr ATTRIBUTE_UNUSED,
1854 fragS * frag ATTRIBUTE_UNUSED,
1855 symbolS * to_symbol ATTRIBUTE_UNUSED)
1857 as_fatal (_("failed sanity check: long_jump"));
1860 /* Called after relaxing, change the frags so they know how big they are. */
1863 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1864 segT sec ATTRIBUTE_UNUSED,
1869 switch (fragP->fr_subtype)
1871 case UNDEFINED_PC_OFFSET:
1872 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1873 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1874 fragP->fr_fix += INST_WORD_SIZE * 2;
1877 case DEFINED_ABS_SEGMENT:
1878 if (fragP->fr_symbol == GOT_symbol)
1879 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1880 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1882 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1883 fragP->fr_offset, FALSE, BFD_RELOC_64);
1884 fragP->fr_fix += INST_WORD_SIZE * 2;
1887 case DEFINED_RO_SEGMENT:
1888 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1889 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1890 fragP->fr_fix += INST_WORD_SIZE;
1893 case DEFINED_RW_SEGMENT:
1894 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1895 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1896 fragP->fr_fix += INST_WORD_SIZE;
1899 case DEFINED_PC_OFFSET:
1900 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1901 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1902 fragP->fr_fix += INST_WORD_SIZE;
1905 case LARGE_DEFINED_PC_OFFSET:
1906 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1907 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1908 fragP->fr_fix += INST_WORD_SIZE * 2;
1912 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1913 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1914 fragP->fr_fix += INST_WORD_SIZE * 2;
1918 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1919 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1920 /* fixP->fx_plt = 1; */
1922 fragP->fr_fix += INST_WORD_SIZE * 2;
1926 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1927 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1928 fragP->fr_fix += INST_WORD_SIZE * 2;
1932 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1933 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSGD);
1934 fragP->fr_fix += INST_WORD_SIZE * 2;
1938 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1939 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSLD);
1940 fragP->fr_fix += INST_WORD_SIZE * 2;
1943 case TLSDTPREL_OFFSET:
1944 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1945 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSDTPREL);
1946 fragP->fr_fix += INST_WORD_SIZE * 2;
1955 /* Applies the desired value to the specified location.
1956 Also sets up addends for 'rela' type relocations. */
1958 md_apply_fix (fixS * fixP,
1962 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1963 const char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1964 const char * symname;
1965 /* Note: use offsetT because it is signed, valueT is unsigned. */
1966 offsetT val = (offsetT) * valp;
1968 struct op_code_struct * opcode1;
1969 unsigned long inst1;
1971 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
1973 /* fixP->fx_offset is supposed to be set up correctly for all
1974 symbol relocations. */
1975 if (fixP->fx_addsy == NULL)
1977 if (!fixP->fx_pcrel)
1978 fixP->fx_offset = val; /* Absolute relocation. */
1980 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1981 (unsigned int) fixP->fx_offset, (unsigned int) val);
1984 /* If we aren't adjusting this fixup to be against the section
1985 symbol, we need to adjust the value. */
1986 if (fixP->fx_addsy != NULL)
1988 if (S_IS_WEAK (fixP->fx_addsy)
1989 || (symbol_used_in_reloc_p (fixP->fx_addsy)
1990 && (((bfd_get_section_flags (stdoutput,
1991 S_GET_SEGMENT (fixP->fx_addsy))
1992 & SEC_LINK_ONCE) != 0)
1993 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
1995 sizeof (".gnu.linkonce") - 1))))
1997 val -= S_GET_VALUE (fixP->fx_addsy);
1998 if (val != 0 && ! fixP->fx_pcrel)
2000 /* In this case, the bfd_install_relocation routine will
2001 incorrectly add the symbol value back in. We just want
2002 the addend to appear in the object file.
2003 FIXME: If this makes VALUE zero, we're toast. */
2004 val -= S_GET_VALUE (fixP->fx_addsy);
2009 /* If the fix is relative to a symbol which is not defined, or not
2010 in the same segment as the fix, we cannot resolve it here. */
2011 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
2012 if (fixP->fx_addsy != NULL
2013 && (!S_IS_DEFINED (fixP->fx_addsy)
2014 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
2018 /* For ELF we can just return and let the reloc that will be generated
2019 take care of everything. For COFF we still have to insert 'val'
2020 into the insn since the addend field will be ignored. */
2024 /* All fixups in the text section must be handled in the linker. */
2025 else if (segment->flags & SEC_CODE)
2027 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
2032 switch (fixP->fx_r_type)
2034 case BFD_RELOC_MICROBLAZE_32_LO:
2035 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2036 if (target_big_endian)
2038 buf[2] |= ((val >> 8) & 0xff);
2039 buf[3] |= (val & 0xff);
2043 buf[1] |= ((val >> 8) & 0xff);
2044 buf[0] |= (val & 0xff);
2047 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2048 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2049 /* Don't do anything if the symbol is not defined. */
2050 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2052 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
2053 as_bad_where (file, fixP->fx_line,
2054 _("pcrel for branch to %s too far (0x%x)"),
2055 symname, (int) val);
2056 if (target_big_endian)
2058 buf[2] |= ((val >> 8) & 0xff);
2059 buf[3] |= (val & 0xff);
2063 buf[1] |= ((val >> 8) & 0xff);
2064 buf[0] |= (val & 0xff);
2070 case BFD_RELOC_32_PCREL:
2071 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2072 /* Don't do anything if the symbol is not defined. */
2073 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2075 if (target_big_endian)
2077 buf[0] |= ((val >> 24) & 0xff);
2078 buf[1] |= ((val >> 16) & 0xff);
2079 buf[2] |= ((val >> 8) & 0xff);
2080 buf[3] |= (val & 0xff);
2084 buf[3] |= ((val >> 24) & 0xff);
2085 buf[2] |= ((val >> 16) & 0xff);
2086 buf[1] |= ((val >> 8) & 0xff);
2087 buf[0] |= (val & 0xff);
2091 case BFD_RELOC_64_PCREL:
2093 /* Add an imm instruction. First save the current instruction. */
2094 for (i = 0; i < INST_WORD_SIZE; i++)
2095 buf[i + INST_WORD_SIZE] = buf[i];
2097 /* Generate the imm instruction. */
2098 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2099 if (opcode1 == NULL)
2101 as_bad (_("unknown opcode \"%s\""), "imm");
2105 inst1 = opcode1->bit_sequence;
2106 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2107 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
2109 buf[0] = INST_BYTE0 (inst1);
2110 buf[1] = INST_BYTE1 (inst1);
2111 buf[2] = INST_BYTE2 (inst1);
2112 buf[3] = INST_BYTE3 (inst1);
2114 /* Add the value only if the symbol is defined. */
2115 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2117 if (target_big_endian)
2119 buf[6] |= ((val >> 8) & 0xff);
2120 buf[7] |= (val & 0xff);
2124 buf[5] |= ((val >> 8) & 0xff);
2125 buf[4] |= (val & 0xff);
2130 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
2131 case BFD_RELOC_MICROBLAZE_64_TLSGD:
2132 case BFD_RELOC_MICROBLAZE_64_TLSLD:
2133 S_SET_THREAD_LOCAL (fixP->fx_addsy);
2135 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2136 case BFD_RELOC_MICROBLAZE_64_GOT:
2137 case BFD_RELOC_MICROBLAZE_64_PLT:
2138 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2139 /* Add an imm instruction. First save the current instruction. */
2140 for (i = 0; i < INST_WORD_SIZE; i++)
2141 buf[i + INST_WORD_SIZE] = buf[i];
2143 /* Generate the imm instruction. */
2144 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2145 if (opcode1 == NULL)
2147 as_bad (_("unknown opcode \"%s\""), "imm");
2151 inst1 = opcode1->bit_sequence;
2153 /* We can fixup call to a defined non-global address
2154 within the same section only. */
2155 buf[0] = INST_BYTE0 (inst1);
2156 buf[1] = INST_BYTE1 (inst1);
2157 buf[2] = INST_BYTE2 (inst1);
2158 buf[3] = INST_BYTE3 (inst1);
2165 if (fixP->fx_addsy == NULL)
2167 /* This fixup has been resolved. Create a reloc in case the linker
2168 moves code around due to relaxing. */
2169 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2170 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2172 fixP->fx_r_type = BFD_RELOC_NONE;
2173 fixP->fx_addsy = section_symbol (absolute_section);
2179 md_operand (expressionS * expressionP)
2181 /* Ignore leading hash symbol, if present. */
2182 if (*input_line_pointer == '#')
2184 input_line_pointer ++;
2185 expression (expressionP);
2189 /* Called just before address relaxation, return the length
2190 by which a fragment must grow to reach it's destination. */
2193 md_estimate_size_before_relax (fragS * fragP,
2196 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2197 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2198 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2199 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2201 switch (fragP->fr_subtype)
2203 case INST_PC_OFFSET:
2204 /* Used to be a PC-relative branch. */
2205 if (!fragP->fr_symbol)
2207 /* We know the abs value: Should never happen. */
2208 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2211 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
2212 !S_IS_WEAK (fragP->fr_symbol))
2214 fragP->fr_subtype = DEFINED_PC_OFFSET;
2215 /* Don't know now whether we need an imm instruction. */
2216 fragP->fr_var = INST_WORD_SIZE;
2218 else if (S_IS_DEFINED (fragP->fr_symbol)
2219 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2221 /* Cannot have a PC-relative branch to a diff segment. */
2222 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2223 S_GET_NAME (fragP->fr_symbol));
2224 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2225 fragP->fr_var = INST_WORD_SIZE*2;
2229 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2230 fragP->fr_var = INST_WORD_SIZE*2;
2234 case INST_NO_OFFSET:
2235 /* Used to be a reference to somewhere which was unknown. */
2236 if (fragP->fr_symbol)
2238 if (fragP->fr_opcode == NULL)
2240 /* Used as an absolute value. */
2241 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2242 /* Variable part does not change. */
2243 fragP->fr_var = INST_WORD_SIZE*2;
2245 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2247 /* It is accessed using the small data read only anchor. */
2248 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2249 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2250 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2251 || (! S_IS_DEFINED (fragP->fr_symbol)))
2253 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2254 fragP->fr_var = INST_WORD_SIZE;
2258 /* Variable not in small data read only segment accessed
2259 using small data read only anchor. */
2260 const char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2262 as_bad_where (file, fragP->fr_line,
2263 _("Variable is accessed using small data read "
2264 "only anchor, but it is not in the small data "
2265 "read only section"));
2266 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2267 fragP->fr_var = INST_WORD_SIZE;
2270 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2272 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2273 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2274 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2275 || (!S_IS_DEFINED (fragP->fr_symbol)))
2277 /* It is accessed using the small data read write anchor. */
2278 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2279 fragP->fr_var = INST_WORD_SIZE;
2283 const char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2285 as_bad_where (file, fragP->fr_line,
2286 _("Variable is accessed using small data read "
2287 "write anchor, but it is not in the small data "
2288 "read write section"));
2289 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2290 fragP->fr_var = INST_WORD_SIZE;
2295 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2301 /* We know the abs value: Should never happen. */
2302 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2307 case UNDEFINED_PC_OFFSET:
2308 case LARGE_DEFINED_PC_OFFSET:
2309 case DEFINED_ABS_SEGMENT:
2315 case TLSTPREL_OFFSET:
2316 case TLSDTPREL_OFFSET:
2317 fragP->fr_var = INST_WORD_SIZE*2;
2319 case DEFINED_RO_SEGMENT:
2320 case DEFINED_RW_SEGMENT:
2321 case DEFINED_PC_OFFSET:
2322 case TLSDTPMOD_OFFSET:
2323 fragP->fr_var = INST_WORD_SIZE;
2329 return fragP->fr_var;
2332 /* Put number into target byte order. */
2335 md_number_to_chars (char * ptr, valueT use, int nbytes)
2337 if (target_big_endian)
2338 number_to_chars_bigendian (ptr, use, nbytes);
2340 number_to_chars_littleendian (ptr, use, nbytes);
2343 /* Round up a section size to the appropriate boundary. */
2346 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2348 return size; /* Byte alignment is fine. */
2352 /* The location from which a PC relative jump should be calculated,
2353 given a PC relative reloc. */
2356 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2359 /* If the symbol is undefined or defined in another section
2360 we leave the add number alone for the linker to fix it later.
2361 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2363 if (fixp->fx_addsy != (symbolS *) NULL
2364 && (!S_IS_DEFINED (fixp->fx_addsy)
2365 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2369 /* The case where we are going to resolve things... */
2370 if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2371 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2373 return fixp->fx_where + fixp->fx_frag->fr_address;
2379 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2380 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2383 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2386 bfd_reloc_code_real_type code;
2388 switch (fixp->fx_r_type)
2390 case BFD_RELOC_NONE:
2391 case BFD_RELOC_MICROBLAZE_64_NONE:
2393 case BFD_RELOC_MICROBLAZE_32_LO:
2394 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2397 case BFD_RELOC_64_PCREL:
2398 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2399 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2400 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2401 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2402 case BFD_RELOC_MICROBLAZE_64_GOT:
2403 case BFD_RELOC_MICROBLAZE_64_PLT:
2404 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2405 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2406 case BFD_RELOC_MICROBLAZE_64_TLSGD:
2407 case BFD_RELOC_MICROBLAZE_64_TLSLD:
2408 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
2409 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
2410 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
2411 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
2412 case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
2413 code = fixp->fx_r_type;
2417 switch (F (fixp->fx_size, fixp->fx_pcrel))
2419 MAP (1, 0, BFD_RELOC_8);
2420 MAP (2, 0, BFD_RELOC_16);
2421 MAP (4, 0, BFD_RELOC_32);
2422 MAP (1, 1, BFD_RELOC_8_PCREL);
2423 MAP (2, 1, BFD_RELOC_16_PCREL);
2424 MAP (4, 1, BFD_RELOC_32_PCREL);
2426 code = fixp->fx_r_type;
2427 as_bad (_("Can not do %d byte %srelocation"),
2429 fixp->fx_pcrel ? _("pc-relative") : "");
2434 rel = (arelent *) xmalloc (sizeof (arelent));
2435 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2437 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2438 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2440 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2442 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2443 /* Always pass the addend along! */
2444 rel->addend = fixp->fx_offset;
2445 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2447 if (rel->howto == NULL)
2449 as_bad_where (fixp->fx_file, fixp->fx_line,
2450 _("Cannot represent relocation type %s"),
2451 bfd_get_reloc_code_name (code));
2453 /* Set howto to a garbage value so that we can keep going. */
2454 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2455 gas_assert (rel->howto != NULL);
2461 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
2466 target_big_endian = 1;
2469 target_big_endian = 0;
2478 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2480 /* fprintf(stream, _("\
2481 MicroBlaze options:\n\
2482 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2486 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2487 found a machine specific op in an expression,
2488 then we create relocs accordingly. */
2491 cons_fix_new_microblaze (fragS * frag,
2495 bfd_reloc_code_real_type r)
2497 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2498 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2499 && (!S_IS_LOCAL (exp->X_op_symbol)))
2500 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2501 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2503 exp->X_op = O_symbol;
2504 r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2523 as_bad (_("unsupported BFD relocation size %u"), size);
2528 fix_new_exp (frag, where, size, exp, 0, r);