1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright 2009, 2010, 2012 Free Software Foundation.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
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 void microblaze_generate_symbol (char *sym);
39 static bfd_boolean check_spl_reg (unsigned *);
41 /* Several places in this file insert raw instructions into the
42 object. They should generate the instruction
43 and then use these four macros to crack the instruction value into
44 the appropriate byte values. */
45 #define INST_BYTE0(x) (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF))
46 #define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
47 #define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
48 #define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
50 /* This array holds the chars that always start a comment. If the
51 pre-processor is disabled, these aren't very useful. */
52 const char comment_chars[] = "#";
54 const char line_separator_chars[] = ";";
56 /* This array holds the chars that only start a comment at the beginning of
58 const char line_comment_chars[] = "#";
60 const int md_reloc_size = 8; /* Size of relocation record. */
62 /* Chars that can be used to separate mant
63 from exp in floating point numbers. */
64 const char EXP_CHARS[] = "eE";
66 /* Chars that mean this number is a floating point constant
69 const char FLT_CHARS[] = "rRsSfFdDxXpP";
71 /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1. */
72 #define UNDEFINED_PC_OFFSET 2
73 #define DEFINED_ABS_SEGMENT 3
74 #define DEFINED_PC_OFFSET 4
75 #define DEFINED_RO_SEGMENT 5
76 #define DEFINED_RW_SEGMENT 6
77 #define LARGE_DEFINED_PC_OFFSET 7
80 #define GOTOFF_OFFSET 10
83 /* Initialize the relax table. */
84 const relax_typeS md_relax_table[] =
86 { 1, 1, 0, 0 }, /* 0: Unused. */
87 { 1, 1, 0, 0 }, /* 1: Unused. */
88 { 1, 1, 0, 0 }, /* 2: Unused. */
89 { 1, 1, 0, 0 }, /* 3: Unused. */
90 { 32767, -32768, INST_WORD_SIZE, LARGE_DEFINED_PC_OFFSET }, /* 4: DEFINED_PC_OFFSET. */
91 { 1, 1, 0, 0 }, /* 5: Unused. */
92 { 1, 1, 0, 0 }, /* 6: Unused. */
93 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
94 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */
95 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */
96 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */
99 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
101 static segT sbss_segment = 0; /* Small bss section. */
102 static segT sbss2_segment = 0; /* Section not used. */
103 static segT sdata_segment = 0; /* Small data section. */
104 static segT sdata2_segment = 0; /* Small read-only section. */
105 static segT rodata_segment = 0; /* read-only section. */
107 /* Generate a symbol for stabs information. */
110 microblaze_generate_symbol (char *sym)
112 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
113 static int microblaze_label_count;
114 sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count);
115 ++microblaze_label_count;
118 /* Handle the section changing pseudo-ops. */
121 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
124 obj_elf_text (ignore);
131 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
134 obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
140 /* Things in the .sdata segment are always considered to be in the small data section. */
143 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
146 obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
152 /* Pseudo op to make file scope bss items. */
155 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
165 segT current_seg = now_seg;
166 subsegT current_subseg = now_subseg;
168 name = input_line_pointer;
169 c = get_symbol_end ();
171 /* Just after name is now '\0'. */
172 p = input_line_pointer;
175 if (*input_line_pointer != ',')
177 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
178 ignore_rest_of_line ();
182 input_line_pointer++; /* skip ',' */
183 if ((size = get_absolute_expression ()) < 0)
185 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
186 ignore_rest_of_line ();
190 /* The third argument to .lcomm is the alignment. */
191 if (*input_line_pointer != ',')
195 ++input_line_pointer;
196 align = get_absolute_expression ();
199 as_warn (_("ignoring bad alignment"));
205 symbolP = symbol_find_or_make (name);
208 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
210 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
211 S_GET_NAME (symbolP));
212 ignore_rest_of_line ();
216 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
218 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
219 S_GET_NAME (symbolP),
220 (long) S_GET_VALUE (symbolP),
223 ignore_rest_of_line ();
230 /* Convert to a power of 2 alignment. */
231 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
234 as_bad (_("Common alignment not a power of 2"));
235 ignore_rest_of_line ();
242 record_alignment (current_seg, align2);
243 subseg_set (current_seg, current_subseg);
245 frag_align (align2, 0, 0);
246 if (S_GET_SEGMENT (symbolP) == current_seg)
247 symbol_get_frag (symbolP)->fr_symbol = 0;
248 symbol_set_frag (symbolP, frag_now);
249 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
252 S_SET_SIZE (symbolP, size);
253 S_SET_SEGMENT (symbolP, current_seg);
254 subseg_set (current_seg, current_subseg);
255 demand_empty_rest_of_line ();
259 microblaze_s_rdata (int localvar)
265 obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
266 if (rodata_segment == 0)
267 rodata_segment = subseg_new (".rodata", 0);
272 obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
280 microblaze_s_bss (int localvar)
283 if (localvar == 0) /* bss. */
284 obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
285 else if (localvar == 1)
288 obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
289 if (sbss_segment == 0)
290 sbss_segment = subseg_new (".sbss", 0);
297 /* endp_p is always 1 as this func is called only for .end <funcname>
298 This func consumes the <funcname> and calls regular processing
299 s_func(1) with arg 1 (1 for end). */
302 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
304 *input_line_pointer = get_symbol_end ();
308 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
311 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
318 name = input_line_pointer;
319 c = get_symbol_end ();
320 symbolP = symbol_find_or_make (name);
321 S_SET_WEAK (symbolP);
322 *input_line_pointer = c;
326 if (!is_end_of_line[(unsigned char) *input_line_pointer])
328 if (S_IS_DEFINED (symbolP))
330 as_bad ("Ignoring attempt to redefine symbol `%s'.",
331 S_GET_NAME (symbolP));
332 ignore_rest_of_line ();
336 if (*input_line_pointer == ',')
338 ++input_line_pointer;
343 if (exp.X_op != O_symbol)
345 as_bad ("bad .weakext directive");
346 ignore_rest_of_line ();
349 symbol_set_value_expression (symbolP, &exp);
352 demand_empty_rest_of_line ();
355 /* This table describes all the machine specific pseudo-ops the assembler
356 has to support. The fields are:
357 Pseudo-op name without dot
358 Function to call to execute this pseudo-op
359 Integer arg to pass to the function. */
360 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
361 and then in the read.c table. */
362 const pseudo_typeS md_pseudo_table[] =
364 {"lcomm", microblaze_s_lcomm, 1},
365 {"data", microblaze_s_data, 0},
366 {"data8", cons, 1}, /* Same as byte. */
367 {"data16", cons, 2}, /* Same as hword. */
368 {"data32", cons, 4}, /* Same as word. */
369 {"ent", s_func, 0}, /* Treat ent as function entry point. */
370 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
371 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
372 {"weakext", microblaze_s_weakext, 0},
373 {"rodata", microblaze_s_rdata, 0},
374 {"sdata2", microblaze_s_rdata, 1},
375 {"sdata", microblaze_s_sdata, 0},
376 {"bss", microblaze_s_bss, 0},
377 {"sbss", microblaze_s_bss, 1},
378 {"text", microblaze_s_text, 0},
380 {"frame", s_ignore, 0},
381 {"mask", s_ignore, 0}, /* Emitted by gcc. */
385 /* This function is called once, at assembler startup time. This should
386 set up all the tables, etc that the MD part of the assembler needs. */
391 struct op_code_struct * opcode;
393 opcode_hash_control = hash_new ();
395 /* Insert unique names into hash table. */
396 for (opcode = opcodes; opcode->name; opcode ++)
397 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
400 /* Try to parse a reg name. */
403 parse_reg (char * s, unsigned * reg)
407 /* Strip leading whitespace. */
408 while (ISSPACE (* s))
411 if (strncasecmp (s, "rpc", 3) == 0)
416 else if (strncasecmp (s, "rmsr", 4) == 0)
422 else if (strncasecmp (s, "rear", 4) == 0)
427 else if (strncasecmp (s, "resr", 4) == 0)
432 else if (strncasecmp (s, "rfsr", 4) == 0)
437 else if (strncasecmp (s, "rbtr", 4) == 0)
442 else if (strncasecmp (s, "redr", 4) == 0)
447 /* MMU registers start. */
448 else if (strncasecmp (s, "rpid", 4) == 0)
453 else if (strncasecmp (s, "rzpr", 4) == 0)
458 else if (strncasecmp (s, "rtlbx", 5) == 0)
463 else if (strncasecmp (s, "rtlblo", 6) == 0)
468 else if (strncasecmp (s, "rtlbhi", 6) == 0)
473 else if (strncasecmp (s, "rtlbsx", 6) == 0)
478 /* MMU registers end. */
479 else if (strncasecmp (s, "rpvr", 4) == 0)
481 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
483 tmpreg = (s[4]-'0')*10 + s[5] - '0';
487 else if (ISDIGIT (s[4]))
493 as_bad (_("register expected, but saw '%.6s'"), s);
494 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
495 *reg = REG_PVR + tmpreg;
498 as_bad (_("Invalid register number at '%.6s'"), s);
503 else if (strncasecmp (s, "rsp", 3) == 0)
508 else if (strncasecmp (s, "rfsl", 4) == 0)
510 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
512 tmpreg = (s[4] - '0') * 10 + s[5] - '0';
515 else if (ISDIGIT (s[4]))
521 as_bad (_("register expected, but saw '%.6s'"), s);
523 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
527 as_bad (_("Invalid register number at '%.6s'"), s);
535 if (TOLOWER (s[0]) == 'r')
537 if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
539 tmpreg = (s[1] - '0') * 10 + s[2] - '0';
542 else if (ISDIGIT (s[1]))
548 as_bad (_("register expected, but saw '%.6s'"), s);
550 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
554 as_bad (_("Invalid register number at '%.6s'"), s);
560 as_bad (_("register expected, but saw '%.6s'"), s);
566 parse_exp (char *s, expressionS *e)
571 /* Skip whitespace. */
572 while (ISSPACE (* s))
575 save = input_line_pointer;
576 input_line_pointer = s;
580 if (e->X_op == O_absent)
581 as_fatal (_("missing operand"));
583 new_pointer = input_line_pointer;
584 input_line_pointer = save;
589 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
594 static symbolS * GOT_symbol;
596 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
599 parse_imm (char * s, expressionS * e, int min, int max)
604 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
605 for (atp = s; *atp != '@'; atp++)
606 if (is_end_of_line[(unsigned char) *atp])
611 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
614 e->X_md = IMM_GOTOFF;
616 else if (strncmp (atp + 1, "GOT", 3) == 0)
621 else if (strncmp (atp + 1, "PLT", 3) == 0)
639 if (atp && !GOT_symbol)
641 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
644 new_pointer = parse_exp (s, e);
646 if (e->X_op == O_absent)
647 ; /* An error message has already been emitted. */
648 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
649 as_fatal (_("operand must be a constant or a label"));
650 else if ((e->X_op == O_constant) && ((int) e->X_add_number < min
651 || (int) e->X_add_number > max))
653 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
654 min, max, (int) e->X_add_number);
659 *atp = '@'; /* restore back (needed?) */
660 if (new_pointer >= atp)
661 new_pointer += (e->X_md == IMM_GOTOFF)?7:4;
662 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
669 check_got (int * got_type, int * got_len)
677 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
678 for (atp = input_line_pointer; *atp != '@'; atp++)
679 if (is_end_of_line[(unsigned char) *atp])
682 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
685 *got_type = IMM_GOTOFF;
687 else if (strncmp (atp + 1, "GOT", 3) == 0)
692 else if (strncmp (atp + 1, "PLT", 3) == 0)
701 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
703 first = atp - input_line_pointer;
705 past_got = atp + *got_len + 1;
706 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
708 second = new_pointer - past_got;
709 tmpbuf = xmalloc (first + second + 2); /* One extra byte for ' ' and one for NUL. */
710 memcpy (tmpbuf, input_line_pointer, first);
711 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
712 memcpy (tmpbuf + first + 1, past_got, second);
713 tmpbuf[first + second + 1] = '\0';
719 parse_cons_expression_microblaze (expressionS *exp, int size)
723 /* Handle @GOTOFF et.al. */
724 char *save, *gotfree_copy;
725 int got_len, got_type;
727 save = input_line_pointer;
728 gotfree_copy = check_got (& got_type, & got_len);
730 input_line_pointer = gotfree_copy;
736 exp->X_md = got_type;
737 input_line_pointer = save + (input_line_pointer - gotfree_copy)
746 /* This is the guts of the machine-dependent assembler. STR points to a
747 machine dependent instruction. This function is supposed to emit
748 the frags/bytes it assembles to. */
750 static char * str_microblaze_ro_anchor = "RO";
751 static char * str_microblaze_rw_anchor = "RW";
754 check_spl_reg (unsigned * reg)
756 if ((*reg == REG_MSR) || (*reg == REG_PC)
758 || (*reg == REG_EAR) || (*reg == REG_ESR)
759 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
760 || (*reg == REG_PID) || (*reg == REG_ZPR)
761 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
762 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
763 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM)
771 /* Here we decide which fixups can be adjusted to make them relative to
772 the beginning of the section instead of the symbol. Basically we need
773 to make sure that the dynamic relocations are done correctly, so in
774 some cases we force the original symbol to be used. */
777 tc_microblaze_fix_adjustable (struct fix *fixP)
779 if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
782 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
783 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
784 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
785 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT)
792 md_assemble (char * str)
796 struct op_code_struct * opcode, *opcode1;
797 char * output = NULL;
800 unsigned long inst, inst1;
805 unsigned int immed, temp;
809 /* Drop leading whitespace. */
810 while (ISSPACE (* str))
813 /* Find the op code end. */
814 for (op_start = op_end = str;
815 *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
818 name[nlen] = op_start[nlen];
820 if (nlen == sizeof (name) - 1)
828 as_bad (_("can't find opcode "));
832 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
835 as_bad (_("unknown opcode \"%s\""), name);
839 inst = opcode->bit_sequence;
842 switch (opcode->inst_type)
844 case INST_TYPE_RD_R1_R2:
845 if (strcmp (op_end, ""))
846 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
849 as_fatal (_("Error in statement syntax"));
852 if (strcmp (op_end, ""))
853 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
856 as_fatal (_("Error in statement syntax"));
859 if (strcmp (op_end, ""))
860 op_end = parse_reg (op_end + 1, ®3); /* Get r2. */
863 as_fatal (_("Error in statement syntax"));
867 /* Check for spl registers. */
868 if (check_spl_reg (& reg1))
869 as_fatal (_("Cannot use special register with this instruction"));
870 if (check_spl_reg (& reg2))
871 as_fatal (_("Cannot use special register with this instruction"));
872 if (check_spl_reg (& reg3))
873 as_fatal (_("Cannot use special register with this instruction"));
875 if (streq (name, "sub"))
877 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
878 inst |= (reg1 << RD_LOW) & RD_MASK;
879 inst |= (reg3 << RA_LOW) & RA_MASK;
880 inst |= (reg2 << RB_LOW) & RB_MASK;
884 inst |= (reg1 << RD_LOW) & RD_MASK;
885 inst |= (reg2 << RA_LOW) & RA_MASK;
886 inst |= (reg3 << RB_LOW) & RB_MASK;
888 output = frag_more (isize);
891 case INST_TYPE_RD_R1_IMM:
892 if (strcmp (op_end, ""))
893 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
896 as_fatal (_("Error in statement syntax"));
899 if (strcmp (op_end, ""))
900 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
903 as_fatal (_("Error in statement syntax"));
906 if (strcmp (op_end, ""))
907 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
909 as_fatal (_("Error in statement syntax"));
911 /* Check for spl registers. */
912 if (check_spl_reg (& reg1))
913 as_fatal (_("Cannot use special register with this instruction"));
914 if (check_spl_reg (& reg2))
915 as_fatal (_("Cannot use special register with this instruction"));
917 if (exp.X_op != O_constant)
920 relax_substateT subtype;
922 if (streq (name, "lmi"))
923 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
924 else if (streq (name, "smi"))
925 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
927 if (reg2 == REG_ROSDP)
928 opc = str_microblaze_ro_anchor;
929 else if (reg2 == REG_RWSDP)
930 opc = str_microblaze_rw_anchor;
933 if (exp.X_md == IMM_GOT)
934 subtype = GOT_OFFSET;
935 else if (exp.X_md == IMM_PLT)
936 subtype = PLT_OFFSET;
937 else if (exp.X_md == IMM_GOTOFF)
938 subtype = GOTOFF_OFFSET;
940 subtype = opcode->inst_offset_type;
942 output = frag_var (rs_machine_dependent,
943 isize * 2, /* maxm of 2 words. */
944 isize, /* minm of 1 word. */
945 subtype, /* PC-relative or not. */
953 output = frag_more (isize);
954 immed = exp.X_add_number;
957 if (streq (name, "lmi") || streq (name, "smi"))
959 /* Load/store 32-d consecutive registers. Used on exit/entry
960 to subroutines to save and restore registers to stack.
961 Generate 32-d insts. */
965 if (streq (name, "lmi"))
966 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
968 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
971 as_bad (_("unknown opcode \"%s\""), "lwi");
974 inst = opcode->bit_sequence;
975 inst |= (reg1 << RD_LOW) & RD_MASK;
976 inst |= (reg2 << RA_LOW) & RA_MASK;
977 inst |= (immed << IMM_LOW) & IMM_MASK;
979 for (i = 0; i < count - 1; i++)
981 output[0] = INST_BYTE0 (inst);
982 output[1] = INST_BYTE1 (inst);
983 output[2] = INST_BYTE2 (inst);
984 output[3] = INST_BYTE3 (inst);
985 output = frag_more (isize);
988 inst = opcode->bit_sequence;
989 inst |= (reg1 << RD_LOW) & RD_MASK;
990 inst |= (reg2 << RA_LOW) & RA_MASK;
991 inst |= (immed << IMM_LOW) & IMM_MASK;
996 temp = immed & 0xFFFF8000;
997 if ((temp != 0) && (temp != 0xFFFF8000))
999 /* Needs an immediate inst. */
1000 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1001 if (opcode1 == NULL)
1003 as_bad (_("unknown opcode \"%s\""), "imm");
1007 inst1 = opcode1->bit_sequence;
1008 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1009 output[0] = INST_BYTE0 (inst1);
1010 output[1] = INST_BYTE1 (inst1);
1011 output[2] = INST_BYTE2 (inst1);
1012 output[3] = INST_BYTE3 (inst1);
1013 output = frag_more (isize);
1015 inst |= (reg1 << RD_LOW) & RD_MASK;
1016 inst |= (reg2 << RA_LOW) & RA_MASK;
1017 inst |= (immed << IMM_LOW) & IMM_MASK;
1021 case INST_TYPE_RD_R1_IMM5:
1022 if (strcmp (op_end, ""))
1023 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1026 as_fatal (_("Error in statement syntax"));
1029 if (strcmp (op_end, ""))
1030 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1033 as_fatal (_("Error in statement syntax"));
1036 if (strcmp (op_end, ""))
1037 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1039 as_fatal (_("Error in statement syntax"));
1041 /* Check for spl registers. */
1042 if (check_spl_reg (®1))
1043 as_fatal (_("Cannot use special register with this instruction"));
1044 if (check_spl_reg (®2))
1045 as_fatal (_("Cannot use special register with this instruction"));
1047 if (exp.X_op != O_constant)
1049 as_warn (_("Symbol used as immediate for shift instruction"));
1054 output = frag_more (isize);
1055 immed = exp.X_add_number;
1058 if (immed != (immed % 32))
1060 as_warn (_("Shift value > 32. using <value %% 32>"));
1063 inst |= (reg1 << RD_LOW) & RD_MASK;
1064 inst |= (reg2 << RA_LOW) & RA_MASK;
1065 inst |= (immed << IMM_LOW) & IMM5_MASK;
1068 case INST_TYPE_R1_R2:
1069 if (strcmp (op_end, ""))
1070 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1073 as_fatal (_("Error in statement syntax"));
1076 if (strcmp (op_end, ""))
1077 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1080 as_fatal (_("Error in statement syntax"));
1084 /* Check for spl registers. */
1085 if (check_spl_reg (& reg1))
1086 as_fatal (_("Cannot use special register with this instruction"));
1087 if (check_spl_reg (& reg2))
1088 as_fatal (_("Cannot use special register with this instruction"));
1090 inst |= (reg1 << RA_LOW) & RA_MASK;
1091 inst |= (reg2 << RB_LOW) & RB_MASK;
1092 output = frag_more (isize);
1095 case INST_TYPE_RD_R1:
1096 if (strcmp (op_end, ""))
1097 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1100 as_fatal (_("Error in statement syntax"));
1103 if (strcmp (op_end, ""))
1104 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1107 as_fatal (_("Error in statement syntax"));
1111 /* Check for spl registers. */
1112 if (check_spl_reg (®1))
1113 as_fatal (_("Cannot use special register with this instruction"));
1114 if (check_spl_reg (®2))
1115 as_fatal (_("Cannot use special register with this instruction"));
1117 inst |= (reg1 << RD_LOW) & RD_MASK;
1118 inst |= (reg2 << RA_LOW) & RA_MASK;
1119 output = frag_more (isize);
1122 #ifndef ARCH_mbtumbl
1123 case INST_TYPE_RD_RFSL:
1124 if (strcmp (op_end, ""))
1125 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1128 as_fatal (_("Error in statement syntax"));
1131 if (strcmp (op_end, ""))
1132 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1135 as_fatal (_("Error in statement syntax"));
1139 /* Check for spl registers. */
1140 if (check_spl_reg (®1))
1141 as_fatal (_("Cannot use special register with this instruction"));
1143 inst |= (reg1 << RD_LOW) & RD_MASK;
1144 inst |= (immed << IMM_LOW) & RFSL_MASK;
1145 output = frag_more (isize);
1148 case INST_TYPE_RD_IMM15:
1149 if (strcmp (op_end, ""))
1150 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1153 as_fatal (_("Error in statement syntax"));
1157 if (strcmp (op_end, ""))
1158 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1160 as_fatal (_("Error in statement syntax"));
1162 /* Check for spl registers. */
1163 if (check_spl_reg (®1))
1164 as_fatal (_("Cannot use special register with this instruction"));
1166 if (exp.X_op != O_constant)
1167 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1170 output = frag_more (isize);
1171 immed = exp.X_add_number;
1173 inst |= (reg1 << RD_LOW) & RD_MASK;
1174 inst |= (immed << IMM_LOW) & IMM15_MASK;
1177 case INST_TYPE_R1_RFSL:
1178 if (strcmp (op_end, ""))
1179 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1182 as_fatal (_("Error in statement syntax"));
1185 if (strcmp (op_end, ""))
1186 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1189 as_fatal (_("Error in statement syntax"));
1193 /* Check for spl registers. */
1194 if (check_spl_reg (®1))
1195 as_fatal (_("Cannot use special register with this instruction"));
1197 inst |= (reg1 << RA_LOW) & RA_MASK;
1198 inst |= (immed << IMM_LOW) & RFSL_MASK;
1199 output = frag_more (isize);
1202 case INST_TYPE_RFSL:
1203 if (strcmp (op_end, ""))
1204 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1207 as_fatal (_("Error in statement syntax"));
1210 /* Check for spl registers. */
1211 if (check_spl_reg (®1))
1212 as_fatal (_("Cannot use special register with this instruction"));
1213 inst |= (immed << IMM_LOW) & RFSL_MASK;
1214 output = frag_more (isize);
1219 if (strcmp (op_end, ""))
1220 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1223 as_fatal (_("Error in statement syntax"));
1227 /* Check for spl registers. */
1228 if (check_spl_reg (®1))
1229 as_fatal (_("Cannot use special register with this instruction"));
1231 inst |= (reg1 << RA_LOW) & RA_MASK;
1232 output = frag_more (isize);
1235 /* For tuqula insn...:) */
1236 #ifndef ARCH_mbtumbl
1238 if (strcmp (op_end, ""))
1239 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1242 as_fatal (_("Error in statement syntax"));
1246 /* Check for spl registers. */
1247 if (check_spl_reg (®1))
1248 as_fatal (_("Cannot use special register with this instruction"));
1250 inst |= (reg1 << RD_LOW) & RD_MASK;
1251 output = frag_more (isize);
1255 case INST_TYPE_RD_SPECIAL:
1256 if (strcmp (op_end, ""))
1257 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1260 as_fatal (_("Error in statement syntax"));
1263 if (strcmp (op_end, ""))
1264 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1267 as_fatal (_("Error in statement syntax"));
1271 if (reg2 == REG_MSR)
1272 immed = opcode->immval_mask | REG_MSR_MASK;
1273 else if (reg2 == REG_PC)
1274 immed = opcode->immval_mask | REG_PC_MASK;
1275 #ifndef ARCH_mbtumbl
1276 else if (reg2 == REG_EAR)
1277 immed = opcode->immval_mask | REG_EAR_MASK;
1278 else if (reg2 == REG_ESR)
1279 immed = opcode->immval_mask | REG_ESR_MASK;
1280 else if (reg2 == REG_FSR)
1281 immed = opcode->immval_mask | REG_FSR_MASK;
1282 else if (reg2 == REG_BTR)
1283 immed = opcode->immval_mask | REG_BTR_MASK;
1284 else if (reg2 == REG_EDR)
1285 immed = opcode->immval_mask | REG_EDR_MASK;
1286 else if (reg2 == REG_PID)
1287 immed = opcode->immval_mask | REG_PID_MASK;
1288 else if (reg2 == REG_ZPR)
1289 immed = opcode->immval_mask | REG_ZPR_MASK;
1290 else if (reg2 == REG_TLBX)
1291 immed = opcode->immval_mask | REG_TLBX_MASK;
1292 else if (reg2 == REG_TLBLO)
1293 immed = opcode->immval_mask | REG_TLBLO_MASK;
1294 else if (reg2 == REG_TLBHI)
1295 immed = opcode->immval_mask | REG_TLBHI_MASK;
1296 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1297 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1300 as_fatal (_("invalid value for special purpose register"));
1301 inst |= (reg1 << RD_LOW) & RD_MASK;
1302 inst |= (immed << IMM_LOW) & IMM_MASK;
1303 output = frag_more (isize);
1306 case INST_TYPE_SPECIAL_R1:
1307 if (strcmp (op_end, ""))
1308 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1311 as_fatal (_("Error in statement syntax"));
1314 if (strcmp (op_end, ""))
1315 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1318 as_fatal (_("Error in statement syntax"));
1322 if (reg1 == REG_MSR)
1323 immed = opcode->immval_mask | REG_MSR_MASK;
1324 else if (reg1 == REG_PC)
1325 immed = opcode->immval_mask | REG_PC_MASK;
1326 #ifndef ARCH_mbtumbl
1327 else if (reg1 == REG_EAR)
1328 immed = opcode->immval_mask | REG_EAR_MASK;
1329 else if (reg1 == REG_ESR)
1330 immed = opcode->immval_mask | REG_ESR_MASK;
1331 else if (reg1 == REG_FSR)
1332 immed = opcode->immval_mask | REG_FSR_MASK;
1333 else if (reg1 == REG_BTR)
1334 immed = opcode->immval_mask | REG_BTR_MASK;
1335 else if (reg1 == REG_EDR)
1336 immed = opcode->immval_mask | REG_EDR_MASK;
1337 else if (reg1 == REG_PID)
1338 immed = opcode->immval_mask | REG_PID_MASK;
1339 else if (reg1 == REG_ZPR)
1340 immed = opcode->immval_mask | REG_ZPR_MASK;
1341 else if (reg1 == REG_TLBX)
1342 immed = opcode->immval_mask | REG_TLBX_MASK;
1343 else if (reg1 == REG_TLBLO)
1344 immed = opcode->immval_mask | REG_TLBLO_MASK;
1345 else if (reg1 == REG_TLBHI)
1346 immed = opcode->immval_mask | REG_TLBHI_MASK;
1347 else if (reg1 == REG_TLBSX)
1348 immed = opcode->immval_mask | REG_TLBSX_MASK;
1351 as_fatal (_("invalid value for special purpose register"));
1352 inst |= (reg2 << RA_LOW) & RA_MASK;
1353 inst |= (immed << IMM_LOW) & IMM_MASK;
1354 output = frag_more (isize);
1357 case INST_TYPE_RD_R1_SPECIAL:
1358 if (strcmp (op_end, ""))
1359 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1362 as_fatal (_("Error in statement syntax"));
1365 if (strcmp (op_end, ""))
1366 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1369 as_fatal (_("Error in statement syntax"));
1373 /* Check for spl registers. */
1374 if (check_spl_reg (®1))
1375 as_fatal (_("Cannot use special register with this instruction"));
1376 if (check_spl_reg (®2))
1377 as_fatal (_("Cannot use special register with this instruction"));
1379 /* insn wic ra, rb => wic ra, ra, rb. */
1380 inst |= (reg1 << RD_LOW) & RD_MASK;
1381 inst |= (reg1 << RA_LOW) & RA_MASK;
1382 inst |= (reg2 << RB_LOW) & RB_MASK;
1384 output = frag_more (isize);
1387 case INST_TYPE_RD_R2:
1388 if (strcmp (op_end, ""))
1389 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1392 as_fatal (_("Error in statement syntax"));
1395 if (strcmp (op_end, ""))
1396 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1399 as_fatal (_("Error in statement syntax"));
1403 /* Check for spl registers. */
1404 if (check_spl_reg (®1))
1405 as_fatal (_("Cannot use special register with this instruction"));
1406 if (check_spl_reg (®2))
1407 as_fatal (_("Cannot use special register with this instruction"));
1409 inst |= (reg1 << RD_LOW) & RD_MASK;
1410 inst |= (reg2 << RB_LOW) & RB_MASK;
1411 output = frag_more (isize);
1414 case INST_TYPE_R1_IMM:
1415 if (strcmp (op_end, ""))
1416 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1419 as_fatal (_("Error in statement syntax"));
1422 if (strcmp (op_end, ""))
1423 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1425 as_fatal (_("Error in statement syntax"));
1427 /* Check for spl registers. */
1428 if (check_spl_reg (®1))
1429 as_fatal (_("Cannot use special register with this instruction"));
1431 if (exp.X_op != O_constant)
1434 relax_substateT subtype;
1436 if (exp.X_md == IMM_GOT)
1437 subtype = GOT_OFFSET;
1438 else if (exp.X_md == IMM_PLT)
1439 subtype = PLT_OFFSET;
1441 subtype = opcode->inst_offset_type;
1442 output = frag_var (rs_machine_dependent,
1443 isize * 2, /* maxm of 2 words. */
1444 isize, /* minm of 1 word. */
1445 subtype, /* PC-relative or not. */
1453 output = frag_more (isize);
1454 immed = exp.X_add_number;
1457 temp = immed & 0xFFFF8000;
1458 if ((temp != 0) && (temp != 0xFFFF8000))
1460 /* Needs an immediate inst. */
1461 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1462 if (opcode1 == NULL)
1464 as_bad (_("unknown opcode \"%s\""), "imm");
1468 inst1 = opcode1->bit_sequence;
1469 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1470 output[0] = INST_BYTE0 (inst1);
1471 output[1] = INST_BYTE1 (inst1);
1472 output[2] = INST_BYTE2 (inst1);
1473 output[3] = INST_BYTE3 (inst1);
1474 output = frag_more (isize);
1477 inst |= (reg1 << RA_LOW) & RA_MASK;
1478 inst |= (immed << IMM_LOW) & IMM_MASK;
1481 case INST_TYPE_RD_IMM:
1482 if (strcmp (op_end, ""))
1483 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1486 as_fatal (_("Error in statement syntax"));
1489 if (strcmp (op_end, ""))
1490 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1492 as_fatal (_("Error in statement syntax"));
1494 /* Check for spl registers. */
1495 if (check_spl_reg (®1))
1496 as_fatal (_("Cannot use special register with this instruction"));
1498 if (exp.X_op != O_constant)
1501 relax_substateT subtype;
1503 if (exp.X_md == IMM_GOT)
1504 subtype = GOT_OFFSET;
1505 else if (exp.X_md == IMM_PLT)
1506 subtype = PLT_OFFSET;
1508 subtype = opcode->inst_offset_type;
1509 output = frag_var (rs_machine_dependent,
1510 isize * 2, /* maxm of 2 words. */
1511 isize, /* minm of 1 word. */
1512 subtype, /* PC-relative or not. */
1520 output = frag_more (isize);
1521 immed = exp.X_add_number;
1524 temp = immed & 0xFFFF8000;
1525 if ((temp != 0) && (temp != 0xFFFF8000))
1527 /* Needs an immediate inst. */
1528 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1529 if (opcode1 == NULL)
1531 as_bad (_("unknown opcode \"%s\""), "imm");
1535 inst1 = opcode1->bit_sequence;
1536 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1537 output[0] = INST_BYTE0 (inst1);
1538 output[1] = INST_BYTE1 (inst1);
1539 output[2] = INST_BYTE2 (inst1);
1540 output[3] = INST_BYTE3 (inst1);
1541 output = frag_more (isize);
1544 inst |= (reg1 << RD_LOW) & RD_MASK;
1545 inst |= (immed << IMM_LOW) & IMM_MASK;
1549 if (strcmp (op_end, ""))
1550 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1553 as_fatal (_("Error in statement syntax"));
1557 /* Check for spl registers. */
1558 if (check_spl_reg (®2))
1559 as_fatal (_("Cannot use special register with this instruction"));
1561 inst |= (reg2 << RB_LOW) & RB_MASK;
1562 output = frag_more (isize);
1566 if (streq (name, "imm"))
1567 as_fatal (_("An IMM instruction should not be present in the .s file"));
1569 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1571 if (exp.X_op != O_constant)
1574 relax_substateT subtype;
1576 if (exp.X_md == IMM_GOT)
1577 subtype = GOT_OFFSET;
1578 else if (exp.X_md == IMM_PLT)
1579 subtype = PLT_OFFSET;
1581 subtype = opcode->inst_offset_type;
1582 output = frag_var (rs_machine_dependent,
1583 isize * 2, /* maxm of 2 words. */
1584 isize, /* minm of 1 word. */
1585 subtype, /* PC-relative or not. */
1593 output = frag_more (isize);
1594 immed = exp.X_add_number;
1598 temp = immed & 0xFFFF8000;
1599 if ((temp != 0) && (temp != 0xFFFF8000))
1601 /* Needs an immediate inst. */
1602 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1603 if (opcode1 == NULL)
1605 as_bad (_("unknown opcode \"%s\""), "imm");
1609 inst1 = opcode1->bit_sequence;
1610 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1611 output[0] = INST_BYTE0 (inst1);
1612 output[1] = INST_BYTE1 (inst1);
1613 output[2] = INST_BYTE2 (inst1);
1614 output[3] = INST_BYTE3 (inst1);
1615 output = frag_more (isize);
1617 inst |= (immed << IMM_LOW) & IMM_MASK;
1620 case INST_TYPE_NONE:
1621 output = frag_more (isize);
1625 as_fatal (_("unimplemented opcode \"%s\""), name);
1628 /* Drop whitespace after all the operands have been parsed. */
1629 while (ISSPACE (* op_end))
1632 /* Give warning message if the insn has more operands than required. */
1633 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1634 as_warn (_("ignoring operands: %s "), op_end);
1636 output[0] = INST_BYTE0 (inst);
1637 output[1] = INST_BYTE1 (inst);
1638 output[2] = INST_BYTE2 (inst);
1639 output[3] = INST_BYTE3 (inst);
1642 dwarf2_emit_insn (4);
1647 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1652 /* Various routines to kill one day. */
1653 /* Equal to MAX_PRECISION in atof-ieee.c */
1654 #define MAX_LITTLENUMS 6
1656 /* Turn a string in input_line_pointer into a floating point constant of type
1657 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1658 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1660 md_atof (int type, char * litP, int * sizeP)
1663 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1695 return _("Bad call to MD_NTOF()");
1698 t = atof_ieee (input_line_pointer, type, words);
1701 input_line_pointer = t;
1703 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1705 if (! target_big_endian)
1707 for (i = prec - 1; i >= 0; i--)
1709 md_number_to_chars (litP, (valueT) words[i],
1710 sizeof (LITTLENUM_TYPE));
1711 litP += sizeof (LITTLENUM_TYPE);
1715 for (i = 0; i < prec; i++)
1717 md_number_to_chars (litP, (valueT) words[i],
1718 sizeof (LITTLENUM_TYPE));
1719 litP += sizeof (LITTLENUM_TYPE);
1725 const char * md_shortopts = "";
1727 struct option md_longopts[] =
1729 { NULL, no_argument, NULL, 0}
1732 size_t md_longopts_size = sizeof (md_longopts);
1734 int md_short_jump_size;
1737 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1738 addressT from_Nddr ATTRIBUTE_UNUSED,
1739 addressT to_Nddr ATTRIBUTE_UNUSED,
1740 fragS * frag ATTRIBUTE_UNUSED,
1741 symbolS * to_symbol ATTRIBUTE_UNUSED)
1743 as_fatal (_("failed sanity check: short_jump"));
1747 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1748 addressT from_Nddr ATTRIBUTE_UNUSED,
1749 addressT to_Nddr ATTRIBUTE_UNUSED,
1750 fragS * frag ATTRIBUTE_UNUSED,
1751 symbolS * to_symbol ATTRIBUTE_UNUSED)
1753 as_fatal (_("failed sanity check: long_jump"));
1756 /* Called after relaxing, change the frags so they know how big they are. */
1759 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1760 segT sec ATTRIBUTE_UNUSED,
1765 switch (fragP->fr_subtype)
1767 case UNDEFINED_PC_OFFSET:
1768 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1769 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1770 fragP->fr_fix += INST_WORD_SIZE * 2;
1773 case DEFINED_ABS_SEGMENT:
1774 if (fragP->fr_symbol == GOT_symbol)
1775 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1776 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1778 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1779 fragP->fr_offset, FALSE, BFD_RELOC_64);
1780 fragP->fr_fix += INST_WORD_SIZE * 2;
1783 case DEFINED_RO_SEGMENT:
1784 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1785 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1786 fragP->fr_fix += INST_WORD_SIZE;
1789 case DEFINED_RW_SEGMENT:
1790 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1791 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1792 fragP->fr_fix += INST_WORD_SIZE;
1795 case DEFINED_PC_OFFSET:
1796 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1797 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1798 fragP->fr_fix += INST_WORD_SIZE;
1801 case LARGE_DEFINED_PC_OFFSET:
1802 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1803 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1804 fragP->fr_fix += INST_WORD_SIZE * 2;
1808 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1809 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1810 fragP->fr_fix += INST_WORD_SIZE * 2;
1814 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1815 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1816 /* fixP->fx_plt = 1; */
1818 fragP->fr_fix += INST_WORD_SIZE * 2;
1822 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1823 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1824 fragP->fr_fix += INST_WORD_SIZE * 2;
1833 /* Applies the desired value to the specified location.
1834 Also sets up addends for 'rela' type relocations. */
1836 md_apply_fix (fixS * fixP,
1840 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1841 char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1842 const char * symname;
1843 /* Note: use offsetT because it is signed, valueT is unsigned. */
1844 offsetT val = (offsetT) * valp;
1846 struct op_code_struct * opcode1;
1847 unsigned long inst1;
1849 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
1851 /* fixP->fx_offset is supposed to be set up correctly for all
1852 symbol relocations. */
1853 if (fixP->fx_addsy == NULL)
1855 if (!fixP->fx_pcrel)
1856 fixP->fx_offset = val; /* Absolute relocation. */
1858 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1859 (unsigned int) fixP->fx_offset, (unsigned int) val);
1862 /* If we aren't adjusting this fixup to be against the section
1863 symbol, we need to adjust the value. */
1864 if (fixP->fx_addsy != NULL)
1866 if (S_IS_WEAK (fixP->fx_addsy)
1867 || (symbol_used_in_reloc_p (fixP->fx_addsy)
1868 && (((bfd_get_section_flags (stdoutput,
1869 S_GET_SEGMENT (fixP->fx_addsy))
1870 & SEC_LINK_ONCE) != 0)
1871 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
1873 sizeof (".gnu.linkonce") - 1))))
1875 val -= S_GET_VALUE (fixP->fx_addsy);
1876 if (val != 0 && ! fixP->fx_pcrel)
1878 /* In this case, the bfd_install_relocation routine will
1879 incorrectly add the symbol value back in. We just want
1880 the addend to appear in the object file.
1881 FIXME: If this makes VALUE zero, we're toast. */
1882 val -= S_GET_VALUE (fixP->fx_addsy);
1887 /* If the fix is relative to a symbol which is not defined, or not
1888 in the same segment as the fix, we cannot resolve it here. */
1889 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1890 if (fixP->fx_addsy != NULL
1891 && (!S_IS_DEFINED (fixP->fx_addsy)
1892 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
1896 /* For ELF we can just return and let the reloc that will be generated
1897 take care of everything. For COFF we still have to insert 'val'
1898 into the insn since the addend field will be ignored. */
1902 /* All fixups in the text section must be handled in the linker. */
1903 else if (segment->flags & SEC_CODE)
1905 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
1910 switch (fixP->fx_r_type)
1912 case BFD_RELOC_MICROBLAZE_32_LO:
1913 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
1914 if (target_big_endian)
1916 buf[2] |= ((val >> 8) & 0xff);
1917 buf[3] |= (val & 0xff);
1921 buf[1] |= ((val >> 8) & 0xff);
1922 buf[0] |= (val & 0xff);
1925 case BFD_RELOC_MICROBLAZE_32_ROSDA:
1926 case BFD_RELOC_MICROBLAZE_32_RWSDA:
1927 /* Don't do anything if the symbol is not defined. */
1928 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1930 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
1931 as_bad_where (file, fixP->fx_line,
1932 _("pcrel for branch to %s too far (0x%x)"),
1933 symname, (int) val);
1934 if (target_big_endian)
1936 buf[2] |= ((val >> 8) & 0xff);
1937 buf[3] |= (val & 0xff);
1941 buf[1] |= ((val >> 8) & 0xff);
1942 buf[0] |= (val & 0xff);
1948 case BFD_RELOC_32_PCREL:
1949 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
1950 /* Don't do anything if the symbol is not defined. */
1951 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1953 if (target_big_endian)
1955 buf[0] |= ((val >> 24) & 0xff);
1956 buf[1] |= ((val >> 16) & 0xff);
1957 buf[2] |= ((val >> 8) & 0xff);
1958 buf[3] |= (val & 0xff);
1962 buf[3] |= ((val >> 24) & 0xff);
1963 buf[2] |= ((val >> 16) & 0xff);
1964 buf[1] |= ((val >> 8) & 0xff);
1965 buf[0] |= (val & 0xff);
1969 case BFD_RELOC_64_PCREL:
1971 /* Add an imm instruction. First save the current instruction. */
1972 for (i = 0; i < INST_WORD_SIZE; i++)
1973 buf[i + INST_WORD_SIZE] = buf[i];
1975 /* Generate the imm instruction. */
1976 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1977 if (opcode1 == NULL)
1979 as_bad (_("unknown opcode \"%s\""), "imm");
1983 inst1 = opcode1->bit_sequence;
1984 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1985 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
1987 buf[0] = INST_BYTE0 (inst1);
1988 buf[1] = INST_BYTE1 (inst1);
1989 buf[2] = INST_BYTE2 (inst1);
1990 buf[3] = INST_BYTE3 (inst1);
1992 /* Add the value only if the symbol is defined. */
1993 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1995 if (target_big_endian)
1997 buf[6] |= ((val >> 8) & 0xff);
1998 buf[7] |= (val & 0xff);
2002 buf[5] |= ((val >> 8) & 0xff);
2003 buf[4] |= (val & 0xff);
2008 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2009 case BFD_RELOC_MICROBLAZE_64_GOT:
2010 case BFD_RELOC_MICROBLAZE_64_PLT:
2011 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2012 /* Add an imm instruction. First save the current instruction. */
2013 for (i = 0; i < INST_WORD_SIZE; i++)
2014 buf[i + INST_WORD_SIZE] = buf[i];
2016 /* Generate the imm instruction. */
2017 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2018 if (opcode1 == NULL)
2020 as_bad (_("unknown opcode \"%s\""), "imm");
2024 inst1 = opcode1->bit_sequence;
2026 /* We can fixup call to a defined non-global address
2027 within the same section only. */
2028 buf[0] = INST_BYTE0 (inst1);
2029 buf[1] = INST_BYTE1 (inst1);
2030 buf[2] = INST_BYTE2 (inst1);
2031 buf[3] = INST_BYTE3 (inst1);
2038 if (fixP->fx_addsy == NULL)
2040 /* This fixup has been resolved. Create a reloc in case the linker
2041 moves code around due to relaxing. */
2042 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2043 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2045 fixP->fx_r_type = BFD_RELOC_NONE;
2046 fixP->fx_addsy = section_symbol (absolute_section);
2052 md_operand (expressionS * expressionP)
2054 /* Ignore leading hash symbol, if present. */
2055 if (*input_line_pointer == '#')
2057 input_line_pointer ++;
2058 expression (expressionP);
2062 /* Called just before address relaxation, return the length
2063 by which a fragment must grow to reach it's destination. */
2066 md_estimate_size_before_relax (fragS * fragP,
2069 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2070 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2071 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2072 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2074 switch (fragP->fr_subtype)
2076 case INST_PC_OFFSET:
2077 /* Used to be a PC-relative branch. */
2078 if (!fragP->fr_symbol)
2080 /* We know the abs value: Should never happen. */
2081 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2084 else if ((S_GET_SEGMENT (fragP->fr_symbol) == segment_type))
2086 fragP->fr_subtype = DEFINED_PC_OFFSET;
2087 /* Don't know now whether we need an imm instruction. */
2088 fragP->fr_var = INST_WORD_SIZE;
2090 else if (S_IS_DEFINED (fragP->fr_symbol)
2091 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2093 /* Cannot have a PC-relative branch to a diff segment. */
2094 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2095 S_GET_NAME (fragP->fr_symbol));
2096 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2097 fragP->fr_var = INST_WORD_SIZE*2;
2101 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2102 fragP->fr_var = INST_WORD_SIZE*2;
2106 case INST_NO_OFFSET:
2107 /* Used to be a reference to somewhere which was unknown. */
2108 if (fragP->fr_symbol)
2110 if (fragP->fr_opcode == NULL)
2112 /* Used as an absolute value. */
2113 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2114 /* Variable part does not change. */
2115 fragP->fr_var = INST_WORD_SIZE*2;
2117 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2119 /* It is accessed using the small data read only anchor. */
2120 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2121 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2122 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2123 || (! S_IS_DEFINED (fragP->fr_symbol)))
2125 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2126 fragP->fr_var = INST_WORD_SIZE;
2130 /* Variable not in small data read only segment accessed
2131 using small data read only anchor. */
2132 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2134 as_bad_where (file, fragP->fr_line,
2135 _("Variable is accessed using small data read "
2136 "only anchor, but it is not in the small data "
2137 "read only section"));
2138 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2139 fragP->fr_var = INST_WORD_SIZE;
2142 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2144 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2145 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2146 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2147 || (!S_IS_DEFINED (fragP->fr_symbol)))
2149 /* It is accessed using the small data read write anchor. */
2150 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2151 fragP->fr_var = INST_WORD_SIZE;
2155 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2157 as_bad_where (file, fragP->fr_line,
2158 _("Variable is accessed using small data read "
2159 "write anchor, but it is not in the small data "
2160 "read write section"));
2161 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2162 fragP->fr_var = INST_WORD_SIZE;
2167 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2173 /* We know the abs value: Should never happen. */
2174 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2179 case UNDEFINED_PC_OFFSET:
2180 case LARGE_DEFINED_PC_OFFSET:
2181 case DEFINED_ABS_SEGMENT:
2185 fragP->fr_var = INST_WORD_SIZE*2;
2187 case DEFINED_RO_SEGMENT:
2188 case DEFINED_RW_SEGMENT:
2189 case DEFINED_PC_OFFSET:
2190 fragP->fr_var = INST_WORD_SIZE;
2196 return fragP->fr_var;
2199 /* Put number into target byte order. */
2202 md_number_to_chars (char * ptr, valueT use, int nbytes)
2204 if (target_big_endian)
2205 number_to_chars_bigendian (ptr, use, nbytes);
2207 number_to_chars_littleendian (ptr, use, nbytes);
2210 /* Round up a section size to the appropriate boundary. */
2213 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2215 return size; /* Byte alignment is fine. */
2219 /* The location from which a PC relative jump should be calculated,
2220 given a PC relative reloc. */
2223 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2226 /* If the symbol is undefined or defined in another section
2227 we leave the add number alone for the linker to fix it later.
2228 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2230 if (fixp->fx_addsy != (symbolS *) NULL
2231 && (!S_IS_DEFINED (fixp->fx_addsy)
2232 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2236 /* The case where we are going to resolve things... */
2237 if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2238 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2240 return fixp->fx_where + fixp->fx_frag->fr_address;
2246 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2247 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2250 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2253 bfd_reloc_code_real_type code;
2255 switch (fixp->fx_r_type)
2257 case BFD_RELOC_NONE:
2258 case BFD_RELOC_MICROBLAZE_64_NONE:
2260 case BFD_RELOC_MICROBLAZE_32_LO:
2261 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2264 case BFD_RELOC_64_PCREL:
2265 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2266 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2267 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2268 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2269 case BFD_RELOC_MICROBLAZE_64_GOT:
2270 case BFD_RELOC_MICROBLAZE_64_PLT:
2271 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2272 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2273 code = fixp->fx_r_type;
2277 switch (F (fixp->fx_size, fixp->fx_pcrel))
2279 MAP (1, 0, BFD_RELOC_8);
2280 MAP (2, 0, BFD_RELOC_16);
2281 MAP (4, 0, BFD_RELOC_32);
2282 MAP (1, 1, BFD_RELOC_8_PCREL);
2283 MAP (2, 1, BFD_RELOC_16_PCREL);
2284 MAP (4, 1, BFD_RELOC_32_PCREL);
2286 code = fixp->fx_r_type;
2287 as_bad (_("Can not do %d byte %srelocation"),
2289 fixp->fx_pcrel ? _("pc-relative") : "");
2294 rel = (arelent *) xmalloc (sizeof (arelent));
2295 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2297 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2298 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2300 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2302 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2303 /* Always pass the addend along! */
2304 rel->addend = fixp->fx_offset;
2305 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2307 if (rel->howto == NULL)
2309 as_bad_where (fixp->fx_file, fixp->fx_line,
2310 _("Cannot represent relocation type %s"),
2311 bfd_get_reloc_code_name (code));
2313 /* Set howto to a garbage value so that we can keep going. */
2314 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2315 gas_assert (rel->howto != NULL);
2321 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
2332 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2334 /* fprintf(stream, _("\
2335 MicroBlaze options:\n\
2336 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2340 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2341 found a machine specific op in an expression,
2342 then we create relocs accordingly. */
2345 cons_fix_new_microblaze (fragS * frag,
2351 bfd_reloc_code_real_type r;
2353 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2354 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2355 && (!S_IS_LOCAL (exp->X_op_symbol)))
2356 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2357 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2359 exp->X_op = O_symbol;
2360 r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2379 as_bad (_("unsupported BFD relocation size %u"), size);
2384 fix_new_exp (frag, where, size, exp, 0, r);