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 #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
86 /* Initialize the relax table. */
87 const relax_typeS md_relax_table[] =
89 { 1, 1, 0, 0 }, /* 0: Unused. */
90 { 1, 1, 0, 0 }, /* 1: Unused. */
91 { 1, 1, 0, 0 }, /* 2: Unused. */
92 { 1, 1, 0, 0 }, /* 3: Unused. */
93 { 32767, -32768, INST_WORD_SIZE, LARGE_DEFINED_PC_OFFSET }, /* 4: DEFINED_PC_OFFSET. */
94 { 1, 1, 0, 0 }, /* 5: Unused. */
95 { 1, 1, 0, 0 }, /* 6: Unused. */
96 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
97 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */
98 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */
99 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */
102 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
104 static segT sbss_segment = 0; /* Small bss section. */
105 static segT sbss2_segment = 0; /* Section not used. */
106 static segT sdata_segment = 0; /* Small data section. */
107 static segT sdata2_segment = 0; /* Small read-only section. */
108 static segT rodata_segment = 0; /* read-only section. */
110 /* Generate a symbol for stabs information. */
113 microblaze_generate_symbol (char *sym)
115 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
116 static int microblaze_label_count;
117 sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count);
118 ++microblaze_label_count;
121 /* Handle the section changing pseudo-ops. */
124 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
127 obj_elf_text (ignore);
134 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
137 obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
143 /* Things in the .sdata segment are always considered to be in the small data section. */
146 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
149 obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
155 /* Pseudo op to make file scope bss items. */
158 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
168 segT current_seg = now_seg;
169 subsegT current_subseg = now_subseg;
171 name = input_line_pointer;
172 c = get_symbol_end ();
174 /* Just after name is now '\0'. */
175 p = input_line_pointer;
178 if (*input_line_pointer != ',')
180 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
181 ignore_rest_of_line ();
185 input_line_pointer++; /* skip ',' */
186 if ((size = get_absolute_expression ()) < 0)
188 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
189 ignore_rest_of_line ();
193 /* The third argument to .lcomm is the alignment. */
194 if (*input_line_pointer != ',')
198 ++input_line_pointer;
199 align = get_absolute_expression ();
202 as_warn (_("ignoring bad alignment"));
208 symbolP = symbol_find_or_make (name);
211 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
213 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
214 S_GET_NAME (symbolP));
215 ignore_rest_of_line ();
219 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
221 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
222 S_GET_NAME (symbolP),
223 (long) S_GET_VALUE (symbolP),
226 ignore_rest_of_line ();
233 /* Convert to a power of 2 alignment. */
234 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
237 as_bad (_("Common alignment not a power of 2"));
238 ignore_rest_of_line ();
245 record_alignment (current_seg, align2);
246 subseg_set (current_seg, current_subseg);
248 frag_align (align2, 0, 0);
249 if (S_GET_SEGMENT (symbolP) == current_seg)
250 symbol_get_frag (symbolP)->fr_symbol = 0;
251 symbol_set_frag (symbolP, frag_now);
252 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
255 S_SET_SIZE (symbolP, size);
256 S_SET_SEGMENT (symbolP, current_seg);
257 subseg_set (current_seg, current_subseg);
258 demand_empty_rest_of_line ();
262 microblaze_s_rdata (int localvar)
268 obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
269 if (rodata_segment == 0)
270 rodata_segment = subseg_new (".rodata", 0);
275 obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
283 microblaze_s_bss (int localvar)
286 if (localvar == 0) /* bss. */
287 obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
288 else if (localvar == 1)
291 obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
292 if (sbss_segment == 0)
293 sbss_segment = subseg_new (".sbss", 0);
300 /* endp_p is always 1 as this func is called only for .end <funcname>
301 This func consumes the <funcname> and calls regular processing
302 s_func(1) with arg 1 (1 for end). */
305 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
307 *input_line_pointer = get_symbol_end ();
311 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
314 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
321 name = input_line_pointer;
322 c = get_symbol_end ();
323 symbolP = symbol_find_or_make (name);
324 S_SET_WEAK (symbolP);
325 *input_line_pointer = c;
329 if (!is_end_of_line[(unsigned char) *input_line_pointer])
331 if (S_IS_DEFINED (symbolP))
333 as_bad ("Ignoring attempt to redefine symbol `%s'.",
334 S_GET_NAME (symbolP));
335 ignore_rest_of_line ();
339 if (*input_line_pointer == ',')
341 ++input_line_pointer;
346 if (exp.X_op != O_symbol)
348 as_bad ("bad .weakext directive");
349 ignore_rest_of_line ();
352 symbol_set_value_expression (symbolP, &exp);
355 demand_empty_rest_of_line ();
358 /* This table describes all the machine specific pseudo-ops the assembler
359 has to support. The fields are:
360 Pseudo-op name without dot
361 Function to call to execute this pseudo-op
362 Integer arg to pass to the function. */
363 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
364 and then in the read.c table. */
365 const pseudo_typeS md_pseudo_table[] =
367 {"lcomm", microblaze_s_lcomm, 1},
368 {"data", microblaze_s_data, 0},
369 {"data8", cons, 1}, /* Same as byte. */
370 {"data16", cons, 2}, /* Same as hword. */
371 {"data32", cons, 4}, /* Same as word. */
372 {"ent", s_func, 0}, /* Treat ent as function entry point. */
373 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
374 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
375 {"weakext", microblaze_s_weakext, 0},
376 {"rodata", microblaze_s_rdata, 0},
377 {"sdata2", microblaze_s_rdata, 1},
378 {"sdata", microblaze_s_sdata, 0},
379 {"bss", microblaze_s_bss, 0},
380 {"sbss", microblaze_s_bss, 1},
381 {"text", microblaze_s_text, 0},
383 {"frame", s_ignore, 0},
384 {"mask", s_ignore, 0}, /* Emitted by gcc. */
388 /* This function is called once, at assembler startup time. This should
389 set up all the tables, etc that the MD part of the assembler needs. */
394 struct op_code_struct * opcode;
396 opcode_hash_control = hash_new ();
398 /* Insert unique names into hash table. */
399 for (opcode = opcodes; opcode->name; opcode ++)
400 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
403 /* Try to parse a reg name. */
406 parse_reg (char * s, unsigned * reg)
410 /* Strip leading whitespace. */
411 while (ISSPACE (* s))
414 if (strncasecmp (s, "rpc", 3) == 0)
419 else if (strncasecmp (s, "rmsr", 4) == 0)
424 else if (strncasecmp (s, "rear", 4) == 0)
429 else if (strncasecmp (s, "resr", 4) == 0)
434 else if (strncasecmp (s, "rfsr", 4) == 0)
439 else if (strncasecmp (s, "rbtr", 4) == 0)
444 else if (strncasecmp (s, "redr", 4) == 0)
449 /* MMU registers start. */
450 else if (strncasecmp (s, "rpid", 4) == 0)
455 else if (strncasecmp (s, "rzpr", 4) == 0)
460 else if (strncasecmp (s, "rtlbx", 5) == 0)
465 else if (strncasecmp (s, "rtlblo", 6) == 0)
470 else if (strncasecmp (s, "rtlbhi", 6) == 0)
475 else if (strncasecmp (s, "rtlbsx", 6) == 0)
480 /* MMU registers end. */
481 else if (strncasecmp (s, "rpvr", 4) == 0)
483 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
485 tmpreg = (s[4]-'0')*10 + s[5] - '0';
489 else if (ISDIGIT (s[4]))
495 as_bad (_("register expected, but saw '%.6s'"), s);
496 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
497 *reg = REG_PVR + tmpreg;
500 as_bad (_("Invalid register number at '%.6s'"), s);
505 else if (strncasecmp (s, "rsp", 3) == 0)
510 else if (strncasecmp (s, "rfsl", 4) == 0)
512 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
514 tmpreg = (s[4] - '0') * 10 + s[5] - '0';
517 else if (ISDIGIT (s[4]))
523 as_bad (_("register expected, but saw '%.6s'"), s);
525 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
529 as_bad (_("Invalid register number at '%.6s'"), s);
534 /* Stack protection registers. */
535 else if (strncasecmp (s, "rshr", 4) == 0)
540 else if (strncasecmp (s, "rslr", 4) == 0)
547 if (TOLOWER (s[0]) == 'r')
549 if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
551 tmpreg = (s[1] - '0') * 10 + s[2] - '0';
554 else if (ISDIGIT (s[1]))
560 as_bad (_("register expected, but saw '%.6s'"), s);
562 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
566 as_bad (_("Invalid register number at '%.6s'"), s);
572 as_bad (_("register expected, but saw '%.6s'"), s);
578 parse_exp (char *s, expressionS *e)
583 /* Skip whitespace. */
584 while (ISSPACE (* s))
587 save = input_line_pointer;
588 input_line_pointer = s;
592 if (e->X_op == O_absent)
593 as_fatal (_("missing operand"));
595 new_pointer = input_line_pointer;
596 input_line_pointer = save;
601 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
606 static symbolS * GOT_symbol;
608 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
611 parse_imm (char * s, expressionS * e, int min, int max)
616 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
617 for (atp = s; *atp != '@'; atp++)
618 if (is_end_of_line[(unsigned char) *atp])
623 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
626 e->X_md = IMM_GOTOFF;
628 else if (strncmp (atp + 1, "GOT", 3) == 0)
633 else if (strncmp (atp + 1, "PLT", 3) == 0)
651 if (atp && !GOT_symbol)
653 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
656 new_pointer = parse_exp (s, e);
658 if (e->X_op == O_absent)
659 ; /* An error message has already been emitted. */
660 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
661 as_fatal (_("operand must be a constant or a label"));
662 else if ((e->X_op == O_constant) && ((int) e->X_add_number < min
663 || (int) e->X_add_number > max))
665 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
666 min, max, (int) e->X_add_number);
671 *atp = '@'; /* restore back (needed?) */
672 if (new_pointer >= atp)
673 new_pointer += (e->X_md == IMM_GOTOFF)?7:4;
674 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
681 check_got (int * got_type, int * got_len)
689 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
690 for (atp = input_line_pointer; *atp != '@'; atp++)
691 if (is_end_of_line[(unsigned char) *atp])
694 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
697 *got_type = IMM_GOTOFF;
699 else if (strncmp (atp + 1, "GOT", 3) == 0)
704 else if (strncmp (atp + 1, "PLT", 3) == 0)
713 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
715 first = atp - input_line_pointer;
717 past_got = atp + *got_len + 1;
718 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
720 second = new_pointer - past_got;
721 tmpbuf = xmalloc (first + second + 2); /* One extra byte for ' ' and one for NUL. */
722 memcpy (tmpbuf, input_line_pointer, first);
723 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
724 memcpy (tmpbuf + first + 1, past_got, second);
725 tmpbuf[first + second + 1] = '\0';
731 parse_cons_expression_microblaze (expressionS *exp, int size)
735 /* Handle @GOTOFF et.al. */
736 char *save, *gotfree_copy;
737 int got_len, got_type;
739 save = input_line_pointer;
740 gotfree_copy = check_got (& got_type, & got_len);
742 input_line_pointer = gotfree_copy;
748 exp->X_md = got_type;
749 input_line_pointer = save + (input_line_pointer - gotfree_copy)
758 /* This is the guts of the machine-dependent assembler. STR points to a
759 machine dependent instruction. This function is supposed to emit
760 the frags/bytes it assembles to. */
762 static char * str_microblaze_ro_anchor = "RO";
763 static char * str_microblaze_rw_anchor = "RW";
766 check_spl_reg (unsigned * reg)
768 if ((*reg == REG_MSR) || (*reg == REG_PC)
769 || (*reg == REG_EAR) || (*reg == REG_ESR)
770 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
771 || (*reg == REG_PID) || (*reg == REG_ZPR)
772 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
773 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
774 || (*reg == REG_SHR) || (*reg == REG_SLR)
775 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
781 /* Here we decide which fixups can be adjusted to make them relative to
782 the beginning of the section instead of the symbol. Basically we need
783 to make sure that the dynamic relocations are done correctly, so in
784 some cases we force the original symbol to be used. */
787 tc_microblaze_fix_adjustable (struct fix *fixP)
789 if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
792 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
793 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
794 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
795 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT)
802 md_assemble (char * str)
806 struct op_code_struct * opcode, *opcode1;
807 char * output = NULL;
810 unsigned long inst, inst1;
815 unsigned int immed, temp;
819 /* Drop leading whitespace. */
820 while (ISSPACE (* str))
823 /* Find the op code end. */
824 for (op_start = op_end = str;
825 *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
828 name[nlen] = op_start[nlen];
830 if (nlen == sizeof (name) - 1)
838 as_bad (_("can't find opcode "));
842 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
845 as_bad (_("unknown opcode \"%s\""), name);
849 inst = opcode->bit_sequence;
852 switch (opcode->inst_type)
854 case INST_TYPE_RD_R1_R2:
855 if (strcmp (op_end, ""))
856 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
859 as_fatal (_("Error in statement syntax"));
862 if (strcmp (op_end, ""))
863 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
866 as_fatal (_("Error in statement syntax"));
869 if (strcmp (op_end, ""))
870 op_end = parse_reg (op_end + 1, ®3); /* Get r2. */
873 as_fatal (_("Error in statement syntax"));
877 /* Check for spl registers. */
878 if (check_spl_reg (& reg1))
879 as_fatal (_("Cannot use special register with this instruction"));
880 if (check_spl_reg (& reg2))
881 as_fatal (_("Cannot use special register with this instruction"));
882 if (check_spl_reg (& reg3))
883 as_fatal (_("Cannot use special register with this instruction"));
885 if (streq (name, "sub"))
887 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
888 inst |= (reg1 << RD_LOW) & RD_MASK;
889 inst |= (reg3 << RA_LOW) & RA_MASK;
890 inst |= (reg2 << RB_LOW) & RB_MASK;
894 inst |= (reg1 << RD_LOW) & RD_MASK;
895 inst |= (reg2 << RA_LOW) & RA_MASK;
896 inst |= (reg3 << RB_LOW) & RB_MASK;
898 output = frag_more (isize);
901 case INST_TYPE_RD_R1_IMM:
902 if (strcmp (op_end, ""))
903 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
906 as_fatal (_("Error in statement syntax"));
909 if (strcmp (op_end, ""))
910 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
913 as_fatal (_("Error in statement syntax"));
916 if (strcmp (op_end, ""))
917 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
919 as_fatal (_("Error in statement syntax"));
921 /* Check for spl registers. */
922 if (check_spl_reg (& reg1))
923 as_fatal (_("Cannot use special register with this instruction"));
924 if (check_spl_reg (& reg2))
925 as_fatal (_("Cannot use special register with this instruction"));
927 if (exp.X_op != O_constant)
930 relax_substateT subtype;
932 if (streq (name, "lmi"))
933 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
934 else if (streq (name, "smi"))
935 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
937 if (reg2 == REG_ROSDP)
938 opc = str_microblaze_ro_anchor;
939 else if (reg2 == REG_RWSDP)
940 opc = str_microblaze_rw_anchor;
943 if (exp.X_md == IMM_GOT)
944 subtype = GOT_OFFSET;
945 else if (exp.X_md == IMM_PLT)
946 subtype = PLT_OFFSET;
947 else if (exp.X_md == IMM_GOTOFF)
948 subtype = GOTOFF_OFFSET;
950 subtype = opcode->inst_offset_type;
952 output = frag_var (rs_machine_dependent,
953 isize * 2, /* maxm of 2 words. */
954 isize, /* minm of 1 word. */
955 subtype, /* PC-relative or not. */
963 output = frag_more (isize);
964 immed = exp.X_add_number;
967 if (streq (name, "lmi") || streq (name, "smi"))
969 /* Load/store 32-d consecutive registers. Used on exit/entry
970 to subroutines to save and restore registers to stack.
971 Generate 32-d insts. */
975 if (streq (name, "lmi"))
976 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
978 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
981 as_bad (_("unknown opcode \"%s\""), "lwi");
984 inst = opcode->bit_sequence;
985 inst |= (reg1 << RD_LOW) & RD_MASK;
986 inst |= (reg2 << RA_LOW) & RA_MASK;
987 inst |= (immed << IMM_LOW) & IMM_MASK;
989 for (i = 0; i < count - 1; i++)
991 output[0] = INST_BYTE0 (inst);
992 output[1] = INST_BYTE1 (inst);
993 output[2] = INST_BYTE2 (inst);
994 output[3] = INST_BYTE3 (inst);
995 output = frag_more (isize);
998 inst = opcode->bit_sequence;
999 inst |= (reg1 << RD_LOW) & RD_MASK;
1000 inst |= (reg2 << RA_LOW) & RA_MASK;
1001 inst |= (immed << IMM_LOW) & IMM_MASK;
1006 temp = immed & 0xFFFF8000;
1007 if ((temp != 0) && (temp != 0xFFFF8000))
1009 /* Needs an immediate inst. */
1010 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1011 if (opcode1 == NULL)
1013 as_bad (_("unknown opcode \"%s\""), "imm");
1017 inst1 = opcode1->bit_sequence;
1018 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1019 output[0] = INST_BYTE0 (inst1);
1020 output[1] = INST_BYTE1 (inst1);
1021 output[2] = INST_BYTE2 (inst1);
1022 output[3] = INST_BYTE3 (inst1);
1023 output = frag_more (isize);
1025 inst |= (reg1 << RD_LOW) & RD_MASK;
1026 inst |= (reg2 << RA_LOW) & RA_MASK;
1027 inst |= (immed << IMM_LOW) & IMM_MASK;
1031 case INST_TYPE_RD_R1_IMM5:
1032 if (strcmp (op_end, ""))
1033 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1036 as_fatal (_("Error in statement syntax"));
1039 if (strcmp (op_end, ""))
1040 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1043 as_fatal (_("Error in statement syntax"));
1046 if (strcmp (op_end, ""))
1047 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1049 as_fatal (_("Error in statement syntax"));
1051 /* Check for spl registers. */
1052 if (check_spl_reg (®1))
1053 as_fatal (_("Cannot use special register with this instruction"));
1054 if (check_spl_reg (®2))
1055 as_fatal (_("Cannot use special register with this instruction"));
1057 if (exp.X_op != O_constant)
1058 as_warn (_("Symbol used as immediate for shift instruction"));
1061 output = frag_more (isize);
1062 immed = exp.X_add_number;
1065 if (immed != (immed % 32))
1067 as_warn (_("Shift value > 32. using <value %% 32>"));
1070 inst |= (reg1 << RD_LOW) & RD_MASK;
1071 inst |= (reg2 << RA_LOW) & RA_MASK;
1072 inst |= (immed << IMM_LOW) & IMM5_MASK;
1075 case INST_TYPE_R1_R2:
1076 if (strcmp (op_end, ""))
1077 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1080 as_fatal (_("Error in statement syntax"));
1083 if (strcmp (op_end, ""))
1084 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1087 as_fatal (_("Error in statement syntax"));
1091 /* Check for spl registers. */
1092 if (check_spl_reg (& reg1))
1093 as_fatal (_("Cannot use special register with this instruction"));
1094 if (check_spl_reg (& reg2))
1095 as_fatal (_("Cannot use special register with this instruction"));
1097 inst |= (reg1 << RA_LOW) & RA_MASK;
1098 inst |= (reg2 << RB_LOW) & RB_MASK;
1099 output = frag_more (isize);
1102 case INST_TYPE_RD_R1:
1103 if (strcmp (op_end, ""))
1104 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1107 as_fatal (_("Error in statement syntax"));
1110 if (strcmp (op_end, ""))
1111 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1114 as_fatal (_("Error in statement syntax"));
1118 /* Check for spl registers. */
1119 if (check_spl_reg (®1))
1120 as_fatal (_("Cannot use special register with this instruction"));
1121 if (check_spl_reg (®2))
1122 as_fatal (_("Cannot use special register with this instruction"));
1124 inst |= (reg1 << RD_LOW) & RD_MASK;
1125 inst |= (reg2 << RA_LOW) & RA_MASK;
1126 output = frag_more (isize);
1129 case INST_TYPE_RD_RFSL:
1130 if (strcmp (op_end, ""))
1131 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1134 as_fatal (_("Error in statement syntax"));
1137 if (strcmp (op_end, ""))
1138 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1141 as_fatal (_("Error in statement syntax"));
1145 /* Check for spl registers. */
1146 if (check_spl_reg (®1))
1147 as_fatal (_("Cannot use special register with this instruction"));
1149 inst |= (reg1 << RD_LOW) & RD_MASK;
1150 inst |= (immed << IMM_LOW) & RFSL_MASK;
1151 output = frag_more (isize);
1154 case INST_TYPE_RD_IMM15:
1155 if (strcmp (op_end, ""))
1156 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1159 as_fatal (_("Error in statement syntax"));
1163 if (strcmp (op_end, ""))
1164 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1166 as_fatal (_("Error in statement syntax"));
1168 /* Check for spl registers. */
1169 if (check_spl_reg (®1))
1170 as_fatal (_("Cannot use special register with this instruction"));
1172 if (exp.X_op != O_constant)
1173 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1176 output = frag_more (isize);
1177 immed = exp.X_add_number;
1179 inst |= (reg1 << RD_LOW) & RD_MASK;
1180 inst |= (immed << IMM_LOW) & IMM15_MASK;
1183 case INST_TYPE_R1_RFSL:
1184 if (strcmp (op_end, ""))
1185 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1188 as_fatal (_("Error in statement syntax"));
1191 if (strcmp (op_end, ""))
1192 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1195 as_fatal (_("Error in statement syntax"));
1199 /* Check for spl registers. */
1200 if (check_spl_reg (®1))
1201 as_fatal (_("Cannot use special register with this instruction"));
1203 inst |= (reg1 << RA_LOW) & RA_MASK;
1204 inst |= (immed << IMM_LOW) & RFSL_MASK;
1205 output = frag_more (isize);
1208 case INST_TYPE_RFSL:
1209 if (strcmp (op_end, ""))
1210 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1213 as_fatal (_("Error in statement syntax"));
1216 inst |= (immed << IMM_LOW) & RFSL_MASK;
1217 output = frag_more (isize);
1221 if (strcmp (op_end, ""))
1222 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
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 << RA_LOW) & RA_MASK;
1234 output = frag_more (isize);
1237 /* For tuqula insn...:) */
1239 if (strcmp (op_end, ""))
1240 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1243 as_fatal (_("Error in statement syntax"));
1247 /* Check for spl registers. */
1248 if (check_spl_reg (®1))
1249 as_fatal (_("Cannot use special register with this instruction"));
1251 inst |= (reg1 << RD_LOW) & RD_MASK;
1252 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 else if (reg2 == REG_EAR)
1276 immed = opcode->immval_mask | REG_EAR_MASK;
1277 else if (reg2 == REG_ESR)
1278 immed = opcode->immval_mask | REG_ESR_MASK;
1279 else if (reg2 == REG_FSR)
1280 immed = opcode->immval_mask | REG_FSR_MASK;
1281 else if (reg2 == REG_BTR)
1282 immed = opcode->immval_mask | REG_BTR_MASK;
1283 else if (reg2 == REG_EDR)
1284 immed = opcode->immval_mask | REG_EDR_MASK;
1285 else if (reg2 == REG_PID)
1286 immed = opcode->immval_mask | REG_PID_MASK;
1287 else if (reg2 == REG_ZPR)
1288 immed = opcode->immval_mask | REG_ZPR_MASK;
1289 else if (reg2 == REG_TLBX)
1290 immed = opcode->immval_mask | REG_TLBX_MASK;
1291 else if (reg2 == REG_TLBLO)
1292 immed = opcode->immval_mask | REG_TLBLO_MASK;
1293 else if (reg2 == REG_TLBHI)
1294 immed = opcode->immval_mask | REG_TLBHI_MASK;
1295 else if (reg2 == REG_SHR)
1296 immed = opcode->immval_mask | REG_SHR_MASK;
1297 else if (reg2 == REG_SLR)
1298 immed = opcode->immval_mask | REG_SLR_MASK;
1299 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1300 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1302 as_fatal (_("invalid value for special purpose register"));
1303 inst |= (reg1 << RD_LOW) & RD_MASK;
1304 inst |= (immed << IMM_LOW) & IMM_MASK;
1305 output = frag_more (isize);
1308 case INST_TYPE_SPECIAL_R1:
1309 if (strcmp (op_end, ""))
1310 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1313 as_fatal (_("Error in statement syntax"));
1316 if (strcmp (op_end, ""))
1317 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1320 as_fatal (_("Error in statement syntax"));
1324 if (reg1 == REG_MSR)
1325 immed = opcode->immval_mask | REG_MSR_MASK;
1326 else if (reg1 == REG_PC)
1327 immed = opcode->immval_mask | REG_PC_MASK;
1328 else if (reg1 == REG_EAR)
1329 immed = opcode->immval_mask | REG_EAR_MASK;
1330 else if (reg1 == REG_ESR)
1331 immed = opcode->immval_mask | REG_ESR_MASK;
1332 else if (reg1 == REG_FSR)
1333 immed = opcode->immval_mask | REG_FSR_MASK;
1334 else if (reg1 == REG_BTR)
1335 immed = opcode->immval_mask | REG_BTR_MASK;
1336 else if (reg1 == REG_EDR)
1337 immed = opcode->immval_mask | REG_EDR_MASK;
1338 else if (reg1 == REG_PID)
1339 immed = opcode->immval_mask | REG_PID_MASK;
1340 else if (reg1 == REG_ZPR)
1341 immed = opcode->immval_mask | REG_ZPR_MASK;
1342 else if (reg1 == REG_TLBX)
1343 immed = opcode->immval_mask | REG_TLBX_MASK;
1344 else if (reg1 == REG_TLBLO)
1345 immed = opcode->immval_mask | REG_TLBLO_MASK;
1346 else if (reg1 == REG_TLBHI)
1347 immed = opcode->immval_mask | REG_TLBHI_MASK;
1348 else if (reg1 == REG_TLBSX)
1349 immed = opcode->immval_mask | REG_TLBSX_MASK;
1350 else if (reg1 == REG_SHR)
1351 immed = opcode->immval_mask | REG_SHR_MASK;
1352 else if (reg1 == REG_SLR)
1353 immed = opcode->immval_mask | REG_SLR_MASK;
1355 as_fatal (_("invalid value for special purpose register"));
1356 inst |= (reg2 << RA_LOW) & RA_MASK;
1357 inst |= (immed << IMM_LOW) & IMM_MASK;
1358 output = frag_more (isize);
1361 case INST_TYPE_R1_R2_SPECIAL:
1362 if (strcmp (op_end, ""))
1363 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1366 as_fatal (_("Error in statement syntax"));
1369 if (strcmp (op_end, ""))
1370 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1373 as_fatal (_("Error in statement syntax"));
1377 /* Check for spl registers. */
1378 if (check_spl_reg (®1))
1379 as_fatal (_("Cannot use special register with this instruction"));
1380 if (check_spl_reg (®2))
1381 as_fatal (_("Cannot use special register with this instruction"));
1383 /* insn wic ra, rb => wic ra, ra, rb. */
1384 inst |= (reg1 << RA_LOW) & RA_MASK;
1385 inst |= (reg2 << RB_LOW) & RB_MASK;
1387 output = frag_more (isize);
1390 case INST_TYPE_RD_R2:
1391 if (strcmp (op_end, ""))
1392 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1395 as_fatal (_("Error in statement syntax"));
1398 if (strcmp (op_end, ""))
1399 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1402 as_fatal (_("Error in statement syntax"));
1406 /* Check for spl registers. */
1407 if (check_spl_reg (®1))
1408 as_fatal (_("Cannot use special register with this instruction"));
1409 if (check_spl_reg (®2))
1410 as_fatal (_("Cannot use special register with this instruction"));
1412 inst |= (reg1 << RD_LOW) & RD_MASK;
1413 inst |= (reg2 << RB_LOW) & RB_MASK;
1414 output = frag_more (isize);
1417 case INST_TYPE_R1_IMM:
1418 if (strcmp (op_end, ""))
1419 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1422 as_fatal (_("Error in statement syntax"));
1425 if (strcmp (op_end, ""))
1426 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1428 as_fatal (_("Error in statement syntax"));
1430 /* Check for spl registers. */
1431 if (check_spl_reg (®1))
1432 as_fatal (_("Cannot use special register with this instruction"));
1434 if (exp.X_op != O_constant)
1437 relax_substateT subtype;
1439 if (exp.X_md == IMM_GOT)
1440 subtype = GOT_OFFSET;
1441 else if (exp.X_md == IMM_PLT)
1442 subtype = PLT_OFFSET;
1444 subtype = opcode->inst_offset_type;
1445 output = frag_var (rs_machine_dependent,
1446 isize * 2, /* maxm of 2 words. */
1447 isize, /* minm of 1 word. */
1448 subtype, /* PC-relative or not. */
1456 output = frag_more (isize);
1457 immed = exp.X_add_number;
1460 temp = immed & 0xFFFF8000;
1461 if ((temp != 0) && (temp != 0xFFFF8000))
1463 /* Needs an immediate inst. */
1464 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1465 if (opcode1 == NULL)
1467 as_bad (_("unknown opcode \"%s\""), "imm");
1471 inst1 = opcode1->bit_sequence;
1472 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1473 output[0] = INST_BYTE0 (inst1);
1474 output[1] = INST_BYTE1 (inst1);
1475 output[2] = INST_BYTE2 (inst1);
1476 output[3] = INST_BYTE3 (inst1);
1477 output = frag_more (isize);
1480 inst |= (reg1 << RA_LOW) & RA_MASK;
1481 inst |= (immed << IMM_LOW) & IMM_MASK;
1484 case INST_TYPE_RD_IMM:
1485 if (strcmp (op_end, ""))
1486 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1489 as_fatal (_("Error in statement syntax"));
1492 if (strcmp (op_end, ""))
1493 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1495 as_fatal (_("Error in statement syntax"));
1497 /* Check for spl registers. */
1498 if (check_spl_reg (®1))
1499 as_fatal (_("Cannot use special register with this instruction"));
1501 if (exp.X_op != O_constant)
1504 relax_substateT subtype;
1506 if (exp.X_md == IMM_GOT)
1507 subtype = GOT_OFFSET;
1508 else if (exp.X_md == IMM_PLT)
1509 subtype = PLT_OFFSET;
1511 subtype = opcode->inst_offset_type;
1512 output = frag_var (rs_machine_dependent,
1513 isize * 2, /* maxm of 2 words. */
1514 isize, /* minm of 1 word. */
1515 subtype, /* PC-relative or not. */
1523 output = frag_more (isize);
1524 immed = exp.X_add_number;
1527 temp = immed & 0xFFFF8000;
1528 if ((temp != 0) && (temp != 0xFFFF8000))
1530 /* Needs an immediate inst. */
1531 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1532 if (opcode1 == NULL)
1534 as_bad (_("unknown opcode \"%s\""), "imm");
1538 inst1 = opcode1->bit_sequence;
1539 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1540 output[0] = INST_BYTE0 (inst1);
1541 output[1] = INST_BYTE1 (inst1);
1542 output[2] = INST_BYTE2 (inst1);
1543 output[3] = INST_BYTE3 (inst1);
1544 output = frag_more (isize);
1547 inst |= (reg1 << RD_LOW) & RD_MASK;
1548 inst |= (immed << IMM_LOW) & IMM_MASK;
1552 if (strcmp (op_end, ""))
1553 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1556 as_fatal (_("Error in statement syntax"));
1560 /* Check for spl registers. */
1561 if (check_spl_reg (®2))
1562 as_fatal (_("Cannot use special register with this instruction"));
1564 inst |= (reg2 << RB_LOW) & RB_MASK;
1565 output = frag_more (isize);
1569 if (streq (name, "imm"))
1570 as_fatal (_("An IMM instruction should not be present in the .s file"));
1572 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1574 if (exp.X_op != O_constant)
1577 relax_substateT subtype;
1579 if (exp.X_md == IMM_GOT)
1580 subtype = GOT_OFFSET;
1581 else if (exp.X_md == IMM_PLT)
1582 subtype = PLT_OFFSET;
1584 subtype = opcode->inst_offset_type;
1585 output = frag_var (rs_machine_dependent,
1586 isize * 2, /* maxm of 2 words. */
1587 isize, /* minm of 1 word. */
1588 subtype, /* PC-relative or not. */
1596 output = frag_more (isize);
1597 immed = exp.X_add_number;
1601 temp = immed & 0xFFFF8000;
1602 if ((temp != 0) && (temp != 0xFFFF8000))
1604 /* Needs an immediate inst. */
1605 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1606 if (opcode1 == NULL)
1608 as_bad (_("unknown opcode \"%s\""), "imm");
1612 inst1 = opcode1->bit_sequence;
1613 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1614 output[0] = INST_BYTE0 (inst1);
1615 output[1] = INST_BYTE1 (inst1);
1616 output[2] = INST_BYTE2 (inst1);
1617 output[3] = INST_BYTE3 (inst1);
1618 output = frag_more (isize);
1620 inst |= (immed << IMM_LOW) & IMM_MASK;
1623 case INST_TYPE_NONE:
1624 output = frag_more (isize);
1627 case INST_TYPE_IMM5:
1628 if (strcmp(op_end, ""))
1629 op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5);
1631 as_fatal(_("Error in statement syntax"));
1632 if (exp.X_op != O_constant) {
1633 as_warn(_("Symbol used as immediate for mbar instruction"));
1635 output = frag_more (isize);
1636 immed = exp.X_add_number;
1638 if (immed != (immed % 32)) {
1639 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1642 inst |= (immed << IMM_MBAR);
1646 as_fatal (_("unimplemented opcode \"%s\""), name);
1649 /* Drop whitespace after all the operands have been parsed. */
1650 while (ISSPACE (* op_end))
1653 /* Give warning message if the insn has more operands than required. */
1654 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1655 as_warn (_("ignoring operands: %s "), op_end);
1657 output[0] = INST_BYTE0 (inst);
1658 output[1] = INST_BYTE1 (inst);
1659 output[2] = INST_BYTE2 (inst);
1660 output[3] = INST_BYTE3 (inst);
1663 dwarf2_emit_insn (4);
1668 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1673 /* Various routines to kill one day. */
1674 /* Equal to MAX_PRECISION in atof-ieee.c */
1675 #define MAX_LITTLENUMS 6
1677 /* Turn a string in input_line_pointer into a floating point constant of type
1678 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1679 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1681 md_atof (int type, char * litP, int * sizeP)
1684 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1716 return _("Bad call to MD_NTOF()");
1719 t = atof_ieee (input_line_pointer, type, words);
1722 input_line_pointer = t;
1724 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1726 if (! target_big_endian)
1728 for (i = prec - 1; i >= 0; i--)
1730 md_number_to_chars (litP, (valueT) words[i],
1731 sizeof (LITTLENUM_TYPE));
1732 litP += sizeof (LITTLENUM_TYPE);
1736 for (i = 0; i < prec; i++)
1738 md_number_to_chars (litP, (valueT) words[i],
1739 sizeof (LITTLENUM_TYPE));
1740 litP += sizeof (LITTLENUM_TYPE);
1746 const char * md_shortopts = "";
1748 struct option md_longopts[] =
1750 {"EB", no_argument, NULL, OPTION_EB},
1751 {"EL", no_argument, NULL, OPTION_EL},
1752 { NULL, no_argument, NULL, 0}
1755 size_t md_longopts_size = sizeof (md_longopts);
1757 int md_short_jump_size;
1760 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1761 addressT from_Nddr ATTRIBUTE_UNUSED,
1762 addressT to_Nddr ATTRIBUTE_UNUSED,
1763 fragS * frag ATTRIBUTE_UNUSED,
1764 symbolS * to_symbol ATTRIBUTE_UNUSED)
1766 as_fatal (_("failed sanity check: short_jump"));
1770 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1771 addressT from_Nddr ATTRIBUTE_UNUSED,
1772 addressT to_Nddr ATTRIBUTE_UNUSED,
1773 fragS * frag ATTRIBUTE_UNUSED,
1774 symbolS * to_symbol ATTRIBUTE_UNUSED)
1776 as_fatal (_("failed sanity check: long_jump"));
1779 /* Called after relaxing, change the frags so they know how big they are. */
1782 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1783 segT sec ATTRIBUTE_UNUSED,
1788 switch (fragP->fr_subtype)
1790 case UNDEFINED_PC_OFFSET:
1791 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1792 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1793 fragP->fr_fix += INST_WORD_SIZE * 2;
1796 case DEFINED_ABS_SEGMENT:
1797 if (fragP->fr_symbol == GOT_symbol)
1798 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1799 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1801 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1802 fragP->fr_offset, FALSE, BFD_RELOC_64);
1803 fragP->fr_fix += INST_WORD_SIZE * 2;
1806 case DEFINED_RO_SEGMENT:
1807 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1808 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1809 fragP->fr_fix += INST_WORD_SIZE;
1812 case DEFINED_RW_SEGMENT:
1813 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1814 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1815 fragP->fr_fix += INST_WORD_SIZE;
1818 case DEFINED_PC_OFFSET:
1819 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1820 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1821 fragP->fr_fix += INST_WORD_SIZE;
1824 case LARGE_DEFINED_PC_OFFSET:
1825 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1826 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1827 fragP->fr_fix += INST_WORD_SIZE * 2;
1831 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1832 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1833 fragP->fr_fix += INST_WORD_SIZE * 2;
1837 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1838 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1839 /* fixP->fx_plt = 1; */
1841 fragP->fr_fix += INST_WORD_SIZE * 2;
1845 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1846 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1847 fragP->fr_fix += INST_WORD_SIZE * 2;
1856 /* Applies the desired value to the specified location.
1857 Also sets up addends for 'rela' type relocations. */
1859 md_apply_fix (fixS * fixP,
1863 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1864 char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1865 const char * symname;
1866 /* Note: use offsetT because it is signed, valueT is unsigned. */
1867 offsetT val = (offsetT) * valp;
1869 struct op_code_struct * opcode1;
1870 unsigned long inst1;
1872 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
1874 /* fixP->fx_offset is supposed to be set up correctly for all
1875 symbol relocations. */
1876 if (fixP->fx_addsy == NULL)
1878 if (!fixP->fx_pcrel)
1879 fixP->fx_offset = val; /* Absolute relocation. */
1881 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1882 (unsigned int) fixP->fx_offset, (unsigned int) val);
1885 /* If we aren't adjusting this fixup to be against the section
1886 symbol, we need to adjust the value. */
1887 if (fixP->fx_addsy != NULL)
1889 if (S_IS_WEAK (fixP->fx_addsy)
1890 || (symbol_used_in_reloc_p (fixP->fx_addsy)
1891 && (((bfd_get_section_flags (stdoutput,
1892 S_GET_SEGMENT (fixP->fx_addsy))
1893 & SEC_LINK_ONCE) != 0)
1894 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
1896 sizeof (".gnu.linkonce") - 1))))
1898 val -= S_GET_VALUE (fixP->fx_addsy);
1899 if (val != 0 && ! fixP->fx_pcrel)
1901 /* In this case, the bfd_install_relocation routine will
1902 incorrectly add the symbol value back in. We just want
1903 the addend to appear in the object file.
1904 FIXME: If this makes VALUE zero, we're toast. */
1905 val -= S_GET_VALUE (fixP->fx_addsy);
1910 /* If the fix is relative to a symbol which is not defined, or not
1911 in the same segment as the fix, we cannot resolve it here. */
1912 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1913 if (fixP->fx_addsy != NULL
1914 && (!S_IS_DEFINED (fixP->fx_addsy)
1915 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
1919 /* For ELF we can just return and let the reloc that will be generated
1920 take care of everything. For COFF we still have to insert 'val'
1921 into the insn since the addend field will be ignored. */
1925 /* All fixups in the text section must be handled in the linker. */
1926 else if (segment->flags & SEC_CODE)
1928 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
1933 switch (fixP->fx_r_type)
1935 case BFD_RELOC_MICROBLAZE_32_LO:
1936 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
1937 if (target_big_endian)
1939 buf[2] |= ((val >> 8) & 0xff);
1940 buf[3] |= (val & 0xff);
1944 buf[1] |= ((val >> 8) & 0xff);
1945 buf[0] |= (val & 0xff);
1948 case BFD_RELOC_MICROBLAZE_32_ROSDA:
1949 case BFD_RELOC_MICROBLAZE_32_RWSDA:
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 (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
1954 as_bad_where (file, fixP->fx_line,
1955 _("pcrel for branch to %s too far (0x%x)"),
1956 symname, (int) val);
1957 if (target_big_endian)
1959 buf[2] |= ((val >> 8) & 0xff);
1960 buf[3] |= (val & 0xff);
1964 buf[1] |= ((val >> 8) & 0xff);
1965 buf[0] |= (val & 0xff);
1971 case BFD_RELOC_32_PCREL:
1972 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
1973 /* Don't do anything if the symbol is not defined. */
1974 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1976 if (target_big_endian)
1978 buf[0] |= ((val >> 24) & 0xff);
1979 buf[1] |= ((val >> 16) & 0xff);
1980 buf[2] |= ((val >> 8) & 0xff);
1981 buf[3] |= (val & 0xff);
1985 buf[3] |= ((val >> 24) & 0xff);
1986 buf[2] |= ((val >> 16) & 0xff);
1987 buf[1] |= ((val >> 8) & 0xff);
1988 buf[0] |= (val & 0xff);
1992 case BFD_RELOC_64_PCREL:
1994 /* Add an imm instruction. First save the current instruction. */
1995 for (i = 0; i < INST_WORD_SIZE; i++)
1996 buf[i + INST_WORD_SIZE] = buf[i];
1998 /* Generate the imm instruction. */
1999 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2000 if (opcode1 == NULL)
2002 as_bad (_("unknown opcode \"%s\""), "imm");
2006 inst1 = opcode1->bit_sequence;
2007 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2008 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
2010 buf[0] = INST_BYTE0 (inst1);
2011 buf[1] = INST_BYTE1 (inst1);
2012 buf[2] = INST_BYTE2 (inst1);
2013 buf[3] = INST_BYTE3 (inst1);
2015 /* Add the value only if the symbol is defined. */
2016 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2018 if (target_big_endian)
2020 buf[6] |= ((val >> 8) & 0xff);
2021 buf[7] |= (val & 0xff);
2025 buf[5] |= ((val >> 8) & 0xff);
2026 buf[4] |= (val & 0xff);
2031 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2032 case BFD_RELOC_MICROBLAZE_64_GOT:
2033 case BFD_RELOC_MICROBLAZE_64_PLT:
2034 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2035 /* Add an imm instruction. First save the current instruction. */
2036 for (i = 0; i < INST_WORD_SIZE; i++)
2037 buf[i + INST_WORD_SIZE] = buf[i];
2039 /* Generate the imm instruction. */
2040 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2041 if (opcode1 == NULL)
2043 as_bad (_("unknown opcode \"%s\""), "imm");
2047 inst1 = opcode1->bit_sequence;
2049 /* We can fixup call to a defined non-global address
2050 within the same section only. */
2051 buf[0] = INST_BYTE0 (inst1);
2052 buf[1] = INST_BYTE1 (inst1);
2053 buf[2] = INST_BYTE2 (inst1);
2054 buf[3] = INST_BYTE3 (inst1);
2061 if (fixP->fx_addsy == NULL)
2063 /* This fixup has been resolved. Create a reloc in case the linker
2064 moves code around due to relaxing. */
2065 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2066 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2068 fixP->fx_r_type = BFD_RELOC_NONE;
2069 fixP->fx_addsy = section_symbol (absolute_section);
2075 md_operand (expressionS * expressionP)
2077 /* Ignore leading hash symbol, if present. */
2078 if (*input_line_pointer == '#')
2080 input_line_pointer ++;
2081 expression (expressionP);
2085 /* Called just before address relaxation, return the length
2086 by which a fragment must grow to reach it's destination. */
2089 md_estimate_size_before_relax (fragS * fragP,
2092 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2093 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2094 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2095 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2097 switch (fragP->fr_subtype)
2099 case INST_PC_OFFSET:
2100 /* Used to be a PC-relative branch. */
2101 if (!fragP->fr_symbol)
2103 /* We know the abs value: Should never happen. */
2104 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2107 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
2108 !S_IS_WEAK (fragP->fr_symbol))
2110 fragP->fr_subtype = DEFINED_PC_OFFSET;
2111 /* Don't know now whether we need an imm instruction. */
2112 fragP->fr_var = INST_WORD_SIZE;
2114 else if (S_IS_DEFINED (fragP->fr_symbol)
2115 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2117 /* Cannot have a PC-relative branch to a diff segment. */
2118 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2119 S_GET_NAME (fragP->fr_symbol));
2120 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2121 fragP->fr_var = INST_WORD_SIZE*2;
2125 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2126 fragP->fr_var = INST_WORD_SIZE*2;
2130 case INST_NO_OFFSET:
2131 /* Used to be a reference to somewhere which was unknown. */
2132 if (fragP->fr_symbol)
2134 if (fragP->fr_opcode == NULL)
2136 /* Used as an absolute value. */
2137 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2138 /* Variable part does not change. */
2139 fragP->fr_var = INST_WORD_SIZE*2;
2141 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2143 /* It is accessed using the small data read only anchor. */
2144 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2145 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2146 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2147 || (! S_IS_DEFINED (fragP->fr_symbol)))
2149 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2150 fragP->fr_var = INST_WORD_SIZE;
2154 /* Variable not in small data read only segment accessed
2155 using small data read only anchor. */
2156 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2158 as_bad_where (file, fragP->fr_line,
2159 _("Variable is accessed using small data read "
2160 "only anchor, but it is not in the small data "
2161 "read only section"));
2162 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2163 fragP->fr_var = INST_WORD_SIZE;
2166 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2168 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2169 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2170 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2171 || (!S_IS_DEFINED (fragP->fr_symbol)))
2173 /* It is accessed using the small data read write anchor. */
2174 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2175 fragP->fr_var = INST_WORD_SIZE;
2179 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2181 as_bad_where (file, fragP->fr_line,
2182 _("Variable is accessed using small data read "
2183 "write anchor, but it is not in the small data "
2184 "read write section"));
2185 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2186 fragP->fr_var = INST_WORD_SIZE;
2191 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2197 /* We know the abs value: Should never happen. */
2198 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2203 case UNDEFINED_PC_OFFSET:
2204 case LARGE_DEFINED_PC_OFFSET:
2205 case DEFINED_ABS_SEGMENT:
2209 fragP->fr_var = INST_WORD_SIZE*2;
2211 case DEFINED_RO_SEGMENT:
2212 case DEFINED_RW_SEGMENT:
2213 case DEFINED_PC_OFFSET:
2214 fragP->fr_var = INST_WORD_SIZE;
2220 return fragP->fr_var;
2223 /* Put number into target byte order. */
2226 md_number_to_chars (char * ptr, valueT use, int nbytes)
2228 if (target_big_endian)
2229 number_to_chars_bigendian (ptr, use, nbytes);
2231 number_to_chars_littleendian (ptr, use, nbytes);
2234 /* Round up a section size to the appropriate boundary. */
2237 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2239 return size; /* Byte alignment is fine. */
2243 /* The location from which a PC relative jump should be calculated,
2244 given a PC relative reloc. */
2247 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2250 /* If the symbol is undefined or defined in another section
2251 we leave the add number alone for the linker to fix it later.
2252 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2254 if (fixp->fx_addsy != (symbolS *) NULL
2255 && (!S_IS_DEFINED (fixp->fx_addsy)
2256 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2260 /* The case where we are going to resolve things... */
2261 if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2262 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2264 return fixp->fx_where + fixp->fx_frag->fr_address;
2270 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2271 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2274 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2277 bfd_reloc_code_real_type code;
2279 switch (fixp->fx_r_type)
2281 case BFD_RELOC_NONE:
2282 case BFD_RELOC_MICROBLAZE_64_NONE:
2284 case BFD_RELOC_MICROBLAZE_32_LO:
2285 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2288 case BFD_RELOC_64_PCREL:
2289 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2290 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2291 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2292 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2293 case BFD_RELOC_MICROBLAZE_64_GOT:
2294 case BFD_RELOC_MICROBLAZE_64_PLT:
2295 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2296 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2297 code = fixp->fx_r_type;
2301 switch (F (fixp->fx_size, fixp->fx_pcrel))
2303 MAP (1, 0, BFD_RELOC_8);
2304 MAP (2, 0, BFD_RELOC_16);
2305 MAP (4, 0, BFD_RELOC_32);
2306 MAP (1, 1, BFD_RELOC_8_PCREL);
2307 MAP (2, 1, BFD_RELOC_16_PCREL);
2308 MAP (4, 1, BFD_RELOC_32_PCREL);
2310 code = fixp->fx_r_type;
2311 as_bad (_("Can not do %d byte %srelocation"),
2313 fixp->fx_pcrel ? _("pc-relative") : "");
2318 rel = (arelent *) xmalloc (sizeof (arelent));
2319 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2321 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2322 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2324 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2326 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2327 /* Always pass the addend along! */
2328 rel->addend = fixp->fx_offset;
2329 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2331 if (rel->howto == NULL)
2333 as_bad_where (fixp->fx_file, fixp->fx_line,
2334 _("Cannot represent relocation type %s"),
2335 bfd_get_reloc_code_name (code));
2337 /* Set howto to a garbage value so that we can keep going. */
2338 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2339 gas_assert (rel->howto != NULL);
2345 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
2350 target_big_endian = 1;
2353 target_big_endian = 0;
2362 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2364 /* fprintf(stream, _("\
2365 MicroBlaze options:\n\
2366 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2370 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2371 found a machine specific op in an expression,
2372 then we create relocs accordingly. */
2375 cons_fix_new_microblaze (fragS * frag,
2381 bfd_reloc_code_real_type r;
2383 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2384 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2385 && (!S_IS_LOCAL (exp->X_op_symbol)))
2386 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2387 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2389 exp->X_op = O_symbol;
2390 r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2409 as_bad (_("unsupported BFD relocation size %u"), size);
2414 fix_new_exp (frag, where, size, exp, 0, r);