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 /* Previous instruction (for pseudo instructions) */
108 static char * last_output;
109 static int last_inst;
110 static int last_pseudo;
112 /* Generate a symbol for stabs information. */
115 microblaze_generate_symbol (char *sym)
117 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
118 static int microblaze_label_count;
119 sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count);
120 ++microblaze_label_count;
123 /* Handle the section changing pseudo-ops. */
126 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
129 obj_elf_text (ignore);
136 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
139 obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
145 /* Things in the .sdata segment are always considered to be in the small data section. */
148 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
151 obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
157 /* Pseudo op to make file scope bss items. */
160 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
170 segT current_seg = now_seg;
171 subsegT current_subseg = now_subseg;
173 name = input_line_pointer;
174 c = get_symbol_end ();
176 /* Just after name is now '\0'. */
177 p = input_line_pointer;
180 if (*input_line_pointer != ',')
182 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
183 ignore_rest_of_line ();
187 input_line_pointer++; /* skip ',' */
188 if ((size = get_absolute_expression ()) < 0)
190 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
191 ignore_rest_of_line ();
195 /* The third argument to .lcomm is the alignment. */
196 if (*input_line_pointer != ',')
200 ++input_line_pointer;
201 align = get_absolute_expression ();
204 as_warn (_("ignoring bad alignment"));
210 symbolP = symbol_find_or_make (name);
213 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
215 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
216 S_GET_NAME (symbolP));
217 ignore_rest_of_line ();
221 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
223 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
224 S_GET_NAME (symbolP),
225 (long) S_GET_VALUE (symbolP),
228 ignore_rest_of_line ();
235 /* Convert to a power of 2 alignment. */
236 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
239 as_bad (_("Common alignment not a power of 2"));
240 ignore_rest_of_line ();
247 record_alignment (current_seg, align2);
248 subseg_set (current_seg, current_subseg);
250 frag_align (align2, 0, 0);
251 if (S_GET_SEGMENT (symbolP) == current_seg)
252 symbol_get_frag (symbolP)->fr_symbol = 0;
253 symbol_set_frag (symbolP, frag_now);
254 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
257 S_SET_SIZE (symbolP, size);
258 S_SET_SEGMENT (symbolP, current_seg);
259 subseg_set (current_seg, current_subseg);
260 demand_empty_rest_of_line ();
264 microblaze_s_rdata (int localvar)
270 obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
271 if (rodata_segment == 0)
272 rodata_segment = subseg_new (".rodata", 0);
277 obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
285 microblaze_s_bss (int localvar)
288 if (localvar == 0) /* bss. */
289 obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
290 else if (localvar == 1)
293 obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
294 if (sbss_segment == 0)
295 sbss_segment = subseg_new (".sbss", 0);
302 /* endp_p is always 1 as this func is called only for .end <funcname>
303 This func consumes the <funcname> and calls regular processing
304 s_func(1) with arg 1 (1 for end). */
307 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
309 *input_line_pointer = get_symbol_end ();
313 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
316 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
323 name = input_line_pointer;
324 c = get_symbol_end ();
325 symbolP = symbol_find_or_make (name);
326 S_SET_WEAK (symbolP);
327 *input_line_pointer = c;
331 if (!is_end_of_line[(unsigned char) *input_line_pointer])
333 if (S_IS_DEFINED (symbolP))
335 as_bad ("Ignoring attempt to redefine symbol `%s'.",
336 S_GET_NAME (symbolP));
337 ignore_rest_of_line ();
341 if (*input_line_pointer == ',')
343 ++input_line_pointer;
348 if (exp.X_op != O_symbol)
350 as_bad ("bad .weakext directive");
351 ignore_rest_of_line ();
354 symbol_set_value_expression (symbolP, &exp);
357 demand_empty_rest_of_line ();
360 /* This table describes all the machine specific pseudo-ops the assembler
361 has to support. The fields are:
362 Pseudo-op name without dot
363 Function to call to execute this pseudo-op
364 Integer arg to pass to the function. */
365 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
366 and then in the read.c table. */
367 const pseudo_typeS md_pseudo_table[] =
369 {"lcomm", microblaze_s_lcomm, 1},
370 {"data", microblaze_s_data, 0},
371 {"data8", cons, 1}, /* Same as byte. */
372 {"data16", cons, 2}, /* Same as hword. */
373 {"data32", cons, 4}, /* Same as word. */
374 {"ent", s_func, 0}, /* Treat ent as function entry point. */
375 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
376 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
377 {"weakext", microblaze_s_weakext, 0},
378 {"rodata", microblaze_s_rdata, 0},
379 {"sdata2", microblaze_s_rdata, 1},
380 {"sdata", microblaze_s_sdata, 0},
381 {"bss", microblaze_s_bss, 0},
382 {"sbss", microblaze_s_bss, 1},
383 {"text", microblaze_s_text, 0},
385 {"frame", s_ignore, 0},
386 {"mask", s_ignore, 0}, /* Emitted by gcc. */
390 /* This function is called once, at assembler startup time. This should
391 set up all the tables, etc that the MD part of the assembler needs. */
396 struct op_code_struct * opcode;
398 opcode_hash_control = hash_new ();
400 /* Insert unique names into hash table. */
401 for (opcode = opcodes; opcode->name; opcode ++)
402 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
405 /* Try to parse a reg name. */
408 parse_reg (char * s, unsigned * reg)
412 /* Strip leading whitespace. */
413 while (ISSPACE (* s))
416 if (strncasecmp (s, "rpc", 3) == 0)
421 else if (strncasecmp (s, "rmsr", 4) == 0)
427 else if (strncasecmp (s, "rear", 4) == 0)
432 else if (strncasecmp (s, "resr", 4) == 0)
437 else if (strncasecmp (s, "rfsr", 4) == 0)
442 else if (strncasecmp (s, "rbtr", 4) == 0)
447 else if (strncasecmp (s, "redr", 4) == 0)
452 /* MMU registers start. */
453 else if (strncasecmp (s, "rpid", 4) == 0)
458 else if (strncasecmp (s, "rzpr", 4) == 0)
463 else if (strncasecmp (s, "rtlbx", 5) == 0)
468 else if (strncasecmp (s, "rtlblo", 6) == 0)
473 else if (strncasecmp (s, "rtlbhi", 6) == 0)
478 else if (strncasecmp (s, "rtlbsx", 6) == 0)
483 /* MMU registers end. */
484 else if (strncasecmp (s, "rpvr", 4) == 0)
486 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
488 tmpreg = (s[4]-'0')*10 + s[5] - '0';
492 else if (ISDIGIT (s[4]))
498 as_bad (_("register expected, but saw '%.6s'"), s);
499 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
500 *reg = REG_PVR + tmpreg;
503 as_bad (_("Invalid register number at '%.6s'"), s);
508 else if (strncasecmp (s, "rsp", 3) == 0)
513 else if (strncasecmp (s, "rfsl", 4) == 0)
515 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
517 tmpreg = (s[4] - '0') * 10 + s[5] - '0';
520 else if (ISDIGIT (s[4]))
526 as_bad (_("register expected, but saw '%.6s'"), s);
528 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
532 as_bad (_("Invalid register number at '%.6s'"), s);
540 if (TOLOWER (s[0]) == 'r')
542 if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
544 tmpreg = (s[1] - '0') * 10 + s[2] - '0';
547 else if (ISDIGIT (s[1]))
553 as_bad (_("register expected, but saw '%.6s'"), s);
555 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
559 as_bad (_("Invalid register number at '%.6s'"), s);
565 as_bad (_("register expected, but saw '%.6s'"), s);
570 /* Try to parse a cond name. */
573 parse_cond (char * s, unsigned * cond)
575 /* Strip leading whitespace. */
576 while (ISSPACE (* s))
579 if (strncasecmp (s, "eq", 2) == 0)
584 else if (strncasecmp (s, "ne", 2) == 0)
589 else if (strncasecmp (s, "lt", 2) == 0)
594 else if (strncasecmp (s, "le", 2) == 0)
599 else if (strncasecmp (s, "gt", 2) == 0)
604 else if (strncasecmp (s, "ge", 2) == 0)
611 as_bad (_("condition expected, but saw '%.6s'"), s);
618 parse_exp (char *s, expressionS *e)
623 /* Skip whitespace. */
624 while (ISSPACE (* s))
627 save = input_line_pointer;
628 input_line_pointer = s;
632 if (e->X_op == O_absent)
633 as_fatal (_("missing operand"));
635 new_pointer = input_line_pointer;
636 input_line_pointer = save;
641 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
646 static symbolS * GOT_symbol;
648 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
651 parse_imm (char * s, expressionS * e, int min, int max)
656 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
657 for (atp = s; *atp != '@'; atp++)
658 if (is_end_of_line[(unsigned char) *atp])
663 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
666 e->X_md = IMM_GOTOFF;
668 else if (strncmp (atp + 1, "GOT", 3) == 0)
673 else if (strncmp (atp + 1, "PLT", 3) == 0)
691 if (atp && !GOT_symbol)
693 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
696 new_pointer = parse_exp (s, e);
698 if (e->X_op == O_absent)
699 ; /* An error message has already been emitted. */
700 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
701 as_fatal (_("operand must be a constant or a label"));
702 else if ((e->X_op == O_constant) && ((int) e->X_add_number < min
703 || (int) e->X_add_number > max))
705 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
706 min, max, (int) e->X_add_number);
711 *atp = '@'; /* restore back (needed?) */
712 if (new_pointer >= atp)
713 new_pointer += (e->X_md == IMM_GOTOFF)?7:4;
714 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
721 check_got (int * got_type, int * got_len)
729 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
730 for (atp = input_line_pointer; *atp != '@'; atp++)
731 if (is_end_of_line[(unsigned char) *atp])
734 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
737 *got_type = IMM_GOTOFF;
739 else if (strncmp (atp + 1, "GOT", 3) == 0)
744 else if (strncmp (atp + 1, "PLT", 3) == 0)
753 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
755 first = atp - input_line_pointer;
757 past_got = atp + *got_len + 1;
758 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
760 second = new_pointer - past_got;
761 tmpbuf = xmalloc (first + second + 2); /* One extra byte for ' ' and one for NUL. */
762 memcpy (tmpbuf, input_line_pointer, first);
763 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
764 memcpy (tmpbuf + first + 1, past_got, second);
765 tmpbuf[first + second + 1] = '\0';
771 parse_cons_expression_microblaze (expressionS *exp, int size)
775 /* Handle @GOTOFF et.al. */
776 char *save, *gotfree_copy;
777 int got_len, got_type;
779 save = input_line_pointer;
780 gotfree_copy = check_got (& got_type, & got_len);
782 input_line_pointer = gotfree_copy;
788 exp->X_md = got_type;
789 input_line_pointer = save + (input_line_pointer - gotfree_copy)
798 /* This is the guts of the machine-dependent assembler. STR points to a
799 machine dependent instruction. This function is supposed to emit
800 the frags/bytes it assembles to. */
802 static char * str_microblaze_ro_anchor = "RO";
803 static char * str_microblaze_rw_anchor = "RW";
806 check_spl_reg (unsigned * reg)
808 if ((*reg == REG_MSR) || (*reg == REG_PC)
810 || (*reg == REG_EAR) || (*reg == REG_ESR)
811 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
812 || (*reg == REG_PID) || (*reg == REG_ZPR)
813 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
814 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
815 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM)
823 /* Here we decide which fixups can be adjusted to make them relative to
824 the beginning of the section instead of the symbol. Basically we need
825 to make sure that the dynamic relocations are done correctly, so in
826 some cases we force the original symbol to be used. */
829 tc_microblaze_fix_adjustable (struct fix *fixP)
831 if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
834 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
835 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
836 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
837 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT)
844 md_assemble (char * str)
848 struct op_code_struct * opcode, *opcode1;
849 char * output = NULL;
853 unsigned long inst, inst1;
858 unsigned int immed, temp;
862 /* Drop leading whitespace. */
863 while (ISSPACE (* str))
866 /* Find the op code end. */
867 for (op_start = op_end = str;
868 *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
871 name[nlen] = op_start[nlen];
873 if (nlen == sizeof (name) - 1)
881 as_bad (_("can't find opcode "));
885 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
888 as_bad (_("unknown opcode \"%s\""), name);
892 inst = opcode->bit_sequence;
895 switch (opcode->inst_type)
897 case INST_TYPE_RD_R1_R2:
898 if (strcmp (op_end, ""))
899 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
902 as_fatal (_("Error in statement syntax"));
905 if (strcmp (op_end, ""))
906 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
909 as_fatal (_("Error in statement syntax"));
912 if (strcmp (op_end, ""))
913 op_end = parse_reg (op_end + 1, ®3); /* Get r2. */
916 as_fatal (_("Error in statement syntax"));
920 /* Check for spl registers. */
921 if (check_spl_reg (& reg1))
922 as_fatal (_("Cannot use special register with this instruction"));
923 if (check_spl_reg (& reg2))
924 as_fatal (_("Cannot use special register with this instruction"));
925 if (check_spl_reg (& reg3))
926 as_fatal (_("Cannot use special register with this instruction"));
928 if (streq (name, "sub"))
930 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
931 inst |= (reg1 << RD_LOW) & RD_MASK;
932 inst |= (reg3 << RA_LOW) & RA_MASK;
933 inst |= (reg2 << RB_LOW) & RB_MASK;
937 inst |= (reg1 << RD_LOW) & RD_MASK;
938 inst |= (reg2 << RA_LOW) & RA_MASK;
939 inst |= (reg3 << RB_LOW) & RB_MASK;
941 output = frag_more (isize);
944 case INST_TYPE_RD_R1_IMM:
945 if (strcmp (op_end, ""))
946 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
949 as_fatal (_("Error in statement syntax"));
952 if (strcmp (op_end, ""))
953 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
956 as_fatal (_("Error in statement syntax"));
959 if (strcmp (op_end, ""))
960 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
962 as_fatal (_("Error in statement syntax"));
964 /* Check for spl registers. */
965 if (check_spl_reg (& reg1))
966 as_fatal (_("Cannot use special register with this instruction"));
967 if (check_spl_reg (& reg2))
968 as_fatal (_("Cannot use special register with this instruction"));
970 if (exp.X_op != O_constant)
973 relax_substateT subtype;
975 if (streq (name, "lmi"))
976 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
977 else if (streq (name, "smi"))
978 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
980 if (reg2 == REG_ROSDP)
981 opc = str_microblaze_ro_anchor;
982 else if (reg2 == REG_RWSDP)
983 opc = str_microblaze_rw_anchor;
986 if (exp.X_md == IMM_GOT)
987 subtype = GOT_OFFSET;
988 else if (exp.X_md == IMM_PLT)
989 subtype = PLT_OFFSET;
990 else if (exp.X_md == IMM_GOTOFF)
991 subtype = GOTOFF_OFFSET;
993 subtype = opcode->inst_offset_type;
995 output = frag_var (rs_machine_dependent,
996 isize * 2, /* maxm of 2 words. */
997 isize, /* minm of 1 word. */
998 subtype, /* PC-relative or not. */
1006 output = frag_more (isize);
1007 immed = exp.X_add_number;
1010 if (streq (name, "lmi") || streq (name, "smi"))
1012 /* Load/store 32-d consecutive registers. Used on exit/entry
1013 to subroutines to save and restore registers to stack.
1014 Generate 32-d insts. */
1018 if (streq (name, "lmi"))
1019 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
1021 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
1024 as_bad (_("unknown opcode \"%s\""), "lwi");
1027 inst = opcode->bit_sequence;
1028 inst |= (reg1 << RD_LOW) & RD_MASK;
1029 inst |= (reg2 << RA_LOW) & RA_MASK;
1030 inst |= (immed << IMM_LOW) & IMM_MASK;
1032 for (i = 0; i < count - 1; i++)
1034 output[0] = INST_BYTE0 (inst);
1035 output[1] = INST_BYTE1 (inst);
1036 output[2] = INST_BYTE2 (inst);
1037 output[3] = INST_BYTE3 (inst);
1038 output = frag_more (isize);
1041 inst = opcode->bit_sequence;
1042 inst |= (reg1 << RD_LOW) & RD_MASK;
1043 inst |= (reg2 << RA_LOW) & RA_MASK;
1044 inst |= (immed << IMM_LOW) & IMM_MASK;
1049 temp = immed & 0xFFFF8000;
1050 if ((temp != 0) && (temp != 0xFFFF8000))
1052 /* Needs an immediate inst. */
1053 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1054 if (opcode1 == NULL)
1056 as_bad (_("unknown opcode \"%s\""), "imm");
1060 inst1 = opcode1->bit_sequence;
1061 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1062 output[0] = INST_BYTE0 (inst1);
1063 output[1] = INST_BYTE1 (inst1);
1064 output[2] = INST_BYTE2 (inst1);
1065 output[3] = INST_BYTE3 (inst1);
1066 output = frag_more (isize);
1068 inst |= (reg1 << RD_LOW) & RD_MASK;
1069 inst |= (reg2 << RA_LOW) & RA_MASK;
1070 inst |= (immed << IMM_LOW) & IMM_MASK;
1074 case INST_TYPE_RD_R1_IMM5:
1075 if (strcmp (op_end, ""))
1076 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1079 as_fatal (_("Error in statement syntax"));
1082 if (strcmp (op_end, ""))
1083 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1086 as_fatal (_("Error in statement syntax"));
1089 if (strcmp (op_end, ""))
1090 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1092 as_fatal (_("Error in statement syntax"));
1094 /* Check for spl registers. */
1095 if (check_spl_reg (®1))
1096 as_fatal (_("Cannot use special register with this instruction"));
1097 if (check_spl_reg (®2))
1098 as_fatal (_("Cannot use special register with this instruction"));
1100 if (exp.X_op != O_constant)
1102 as_warn (_("Symbol used as immediate for shift instruction"));
1107 output = frag_more (isize);
1108 immed = exp.X_add_number;
1111 if (immed != (immed % 32))
1113 as_warn (_("Shift value > 32. using <value %% 32>"));
1116 inst |= (reg1 << RD_LOW) & RD_MASK;
1117 inst |= (reg2 << RA_LOW) & RA_MASK;
1118 inst |= (immed << IMM_LOW) & IMM5_MASK;
1121 case INST_TYPE_R1_R2:
1122 if (strcmp (op_end, ""))
1123 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1126 as_fatal (_("Error in statement syntax"));
1129 if (strcmp (op_end, ""))
1130 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1133 as_fatal (_("Error in statement syntax"));
1137 /* Check for spl registers. */
1138 if (check_spl_reg (& reg1))
1139 as_fatal (_("Cannot use special register with this instruction"));
1140 if (check_spl_reg (& reg2))
1141 as_fatal (_("Cannot use special register with this instruction"));
1143 inst |= (reg1 << RA_LOW) & RA_MASK;
1144 inst |= (reg2 << RB_LOW) & RB_MASK;
1145 output = frag_more (isize);
1148 case INST_TYPE_RD_R1:
1149 if (strcmp (op_end, ""))
1150 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1153 as_fatal (_("Error in statement syntax"));
1156 if (strcmp (op_end, ""))
1157 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1160 as_fatal (_("Error in statement syntax"));
1164 /* Check for spl registers. */
1165 if (check_spl_reg (®1))
1166 as_fatal (_("Cannot use special register with this instruction"));
1167 if (check_spl_reg (®2))
1168 as_fatal (_("Cannot use special register with this instruction"));
1170 inst |= (reg1 << RD_LOW) & RD_MASK;
1171 inst |= (reg2 << RA_LOW) & RA_MASK;
1172 output = frag_more (isize);
1175 #ifndef ARCH_mbtumbl
1176 case INST_TYPE_RD_RFSL:
1177 if (strcmp (op_end, ""))
1178 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1181 as_fatal (_("Error in statement syntax"));
1184 if (strcmp (op_end, ""))
1185 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1188 as_fatal (_("Error in statement syntax"));
1192 /* Check for spl registers. */
1193 if (check_spl_reg (®1))
1194 as_fatal (_("Cannot use special register with this instruction"));
1196 inst |= (reg1 << RD_LOW) & RD_MASK;
1197 inst |= (immed << IMM_LOW) & RFSL_MASK;
1198 output = frag_more (isize);
1201 case INST_TYPE_RD_IMM15:
1202 if (strcmp (op_end, ""))
1203 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1206 as_fatal (_("Error in statement syntax"));
1210 if (strcmp (op_end, ""))
1211 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1213 as_fatal (_("Error in statement syntax"));
1215 /* Check for spl registers. */
1216 if (check_spl_reg (®1))
1217 as_fatal (_("Cannot use special register with this instruction"));
1219 if (exp.X_op != O_constant)
1220 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1223 output = frag_more (isize);
1224 immed = exp.X_add_number;
1226 inst |= (reg1 << RD_LOW) & RD_MASK;
1227 inst |= (immed << IMM_LOW) & IMM15_MASK;
1230 case INST_TYPE_R1_RFSL:
1231 if (strcmp (op_end, ""))
1232 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1235 as_fatal (_("Error in statement syntax"));
1238 if (strcmp (op_end, ""))
1239 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
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 << RA_LOW) & RA_MASK;
1251 inst |= (immed << IMM_LOW) & RFSL_MASK;
1252 output = frag_more (isize);
1255 case INST_TYPE_RFSL:
1256 if (strcmp (op_end, ""))
1257 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1260 as_fatal (_("Error in statement syntax"));
1263 /* Check for spl registers. */
1264 if (check_spl_reg (®1))
1265 as_fatal (_("Cannot use special register with this instruction"));
1266 inst |= (immed << IMM_LOW) & RFSL_MASK;
1267 output = frag_more (isize);
1272 if (strcmp (op_end, ""))
1273 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1276 as_fatal (_("Error in statement syntax"));
1280 /* Check for spl registers. */
1281 if (check_spl_reg (®1))
1282 as_fatal (_("Cannot use special register with this instruction"));
1284 inst |= (reg1 << RA_LOW) & RA_MASK;
1285 output = frag_more (isize);
1288 /* For tuqula insn...:) */
1289 #ifndef ARCH_mbtumbl
1291 if (strcmp (op_end, ""))
1292 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1295 as_fatal (_("Error in statement syntax"));
1299 /* Check for spl registers. */
1300 if (check_spl_reg (®1))
1301 as_fatal (_("Cannot use special register with this instruction"));
1303 inst |= (reg1 << RD_LOW) & RD_MASK;
1304 output = frag_more (isize);
1308 case INST_TYPE_COND:
1309 if (strcmp (op_end, ""))
1310 op_end = parse_cond (op_end + 1, ®1); /* Get cond. */
1313 as_fatal (_("Error in statement syntax"));
1317 if (last_pseudo != 0 || last_output == NULL)
1319 as_fatal (_("IT, ITT, ITE pseudo instructions must follow CMP or CMPU isntructions"));
1323 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "cmp");
1324 if ((opcode1 == NULL) || ((last_inst & opcode1->opcode_mask) != opcode1->bit_sequence))
1326 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "cmpu");
1327 if ((opcode1 == NULL) || ((last_inst & opcode1->opcode_mask) != opcode1->bit_sequence))
1329 as_fatal (_("IT, ITT, ITE pseudo instructions must follow CMP or CMPU isntructions"));
1334 /* Modify last instruction */
1335 last_inst |= (reg1 << COND_LOW) & COND_MASK;
1336 last_inst |= opcode->bit_sequence;
1337 last_output[0] = INST_BYTE0 (last_inst);
1338 last_output[1] = INST_BYTE1 (last_inst);
1339 last_output[2] = INST_BYTE2 (last_inst);
1340 last_output[3] = INST_BYTE3 (last_inst);
1342 /* Only one pseudo instruction follows */
1347 case INST_TYPE_RD_SPECIAL:
1348 if (strcmp (op_end, ""))
1349 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1352 as_fatal (_("Error in statement syntax"));
1355 if (strcmp (op_end, ""))
1356 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1359 as_fatal (_("Error in statement syntax"));
1363 if (reg2 == REG_MSR)
1364 immed = opcode->immval_mask | REG_MSR_MASK;
1365 else if (reg2 == REG_PC)
1366 immed = opcode->immval_mask | REG_PC_MASK;
1367 #ifndef ARCH_mbtumbl
1368 else if (reg2 == REG_EAR)
1369 immed = opcode->immval_mask | REG_EAR_MASK;
1370 else if (reg2 == REG_ESR)
1371 immed = opcode->immval_mask | REG_ESR_MASK;
1372 else if (reg2 == REG_FSR)
1373 immed = opcode->immval_mask | REG_FSR_MASK;
1374 else if (reg2 == REG_BTR)
1375 immed = opcode->immval_mask | REG_BTR_MASK;
1376 else if (reg2 == REG_EDR)
1377 immed = opcode->immval_mask | REG_EDR_MASK;
1378 else if (reg2 == REG_PID)
1379 immed = opcode->immval_mask | REG_PID_MASK;
1380 else if (reg2 == REG_ZPR)
1381 immed = opcode->immval_mask | REG_ZPR_MASK;
1382 else if (reg2 == REG_TLBX)
1383 immed = opcode->immval_mask | REG_TLBX_MASK;
1384 else if (reg2 == REG_TLBLO)
1385 immed = opcode->immval_mask | REG_TLBLO_MASK;
1386 else if (reg2 == REG_TLBHI)
1387 immed = opcode->immval_mask | REG_TLBHI_MASK;
1388 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1389 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1392 as_fatal (_("invalid value for special purpose register"));
1393 inst |= (reg1 << RD_LOW) & RD_MASK;
1394 inst |= (immed << IMM_LOW) & IMM_MASK;
1395 output = frag_more (isize);
1398 case INST_TYPE_SPECIAL_R1:
1399 if (strcmp (op_end, ""))
1400 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1403 as_fatal (_("Error in statement syntax"));
1406 if (strcmp (op_end, ""))
1407 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1410 as_fatal (_("Error in statement syntax"));
1414 if (reg1 == REG_MSR)
1415 immed = opcode->immval_mask | REG_MSR_MASK;
1416 else if (reg1 == REG_PC)
1417 immed = opcode->immval_mask | REG_PC_MASK;
1418 #ifndef ARCH_mbtumbl
1419 else if (reg1 == REG_EAR)
1420 immed = opcode->immval_mask | REG_EAR_MASK;
1421 else if (reg1 == REG_ESR)
1422 immed = opcode->immval_mask | REG_ESR_MASK;
1423 else if (reg1 == REG_FSR)
1424 immed = opcode->immval_mask | REG_FSR_MASK;
1425 else if (reg1 == REG_BTR)
1426 immed = opcode->immval_mask | REG_BTR_MASK;
1427 else if (reg1 == REG_EDR)
1428 immed = opcode->immval_mask | REG_EDR_MASK;
1429 else if (reg1 == REG_PID)
1430 immed = opcode->immval_mask | REG_PID_MASK;
1431 else if (reg1 == REG_ZPR)
1432 immed = opcode->immval_mask | REG_ZPR_MASK;
1433 else if (reg1 == REG_TLBX)
1434 immed = opcode->immval_mask | REG_TLBX_MASK;
1435 else if (reg1 == REG_TLBLO)
1436 immed = opcode->immval_mask | REG_TLBLO_MASK;
1437 else if (reg1 == REG_TLBHI)
1438 immed = opcode->immval_mask | REG_TLBHI_MASK;
1439 else if (reg1 == REG_TLBSX)
1440 immed = opcode->immval_mask | REG_TLBSX_MASK;
1443 as_fatal (_("invalid value for special purpose register"));
1444 inst |= (reg2 << RA_LOW) & RA_MASK;
1445 inst |= (immed << IMM_LOW) & IMM_MASK;
1446 output = frag_more (isize);
1449 case INST_TYPE_RD_R1_SPECIAL:
1450 if (strcmp (op_end, ""))
1451 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1454 as_fatal (_("Error in statement syntax"));
1457 if (strcmp (op_end, ""))
1458 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */
1461 as_fatal (_("Error in statement syntax"));
1465 /* Check for spl registers. */
1466 if (check_spl_reg (®1))
1467 as_fatal (_("Cannot use special register with this instruction"));
1468 if (check_spl_reg (®2))
1469 as_fatal (_("Cannot use special register with this instruction"));
1471 /* insn wic ra, rb => wic ra, ra, rb. */
1472 inst |= (reg1 << RD_LOW) & RD_MASK;
1473 inst |= (reg1 << RA_LOW) & RA_MASK;
1474 inst |= (reg2 << RB_LOW) & RB_MASK;
1476 output = frag_more (isize);
1479 case INST_TYPE_RD_R2:
1480 if (strcmp (op_end, ""))
1481 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1484 as_fatal (_("Error in statement syntax"));
1487 if (strcmp (op_end, ""))
1488 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1491 as_fatal (_("Error in statement syntax"));
1495 /* Check for spl registers. */
1496 if (check_spl_reg (®1))
1497 as_fatal (_("Cannot use special register with this instruction"));
1498 if (check_spl_reg (®2))
1499 as_fatal (_("Cannot use special register with this instruction"));
1501 inst |= (reg1 << RD_LOW) & RD_MASK;
1502 inst |= (reg2 << RB_LOW) & RB_MASK;
1503 output = frag_more (isize);
1506 case INST_TYPE_R1_IMM:
1507 if (strcmp (op_end, ""))
1508 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */
1511 as_fatal (_("Error in statement syntax"));
1514 if (strcmp (op_end, ""))
1515 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1517 as_fatal (_("Error in statement syntax"));
1519 /* Check for spl registers. */
1520 if (check_spl_reg (®1))
1521 as_fatal (_("Cannot use special register with this instruction"));
1523 if (exp.X_op != O_constant)
1526 relax_substateT subtype;
1528 if (exp.X_md == IMM_GOT)
1529 subtype = GOT_OFFSET;
1530 else if (exp.X_md == IMM_PLT)
1531 subtype = PLT_OFFSET;
1533 subtype = opcode->inst_offset_type;
1534 output = frag_var (rs_machine_dependent,
1535 isize * 2, /* maxm of 2 words. */
1536 isize, /* minm of 1 word. */
1537 subtype, /* PC-relative or not. */
1545 output = frag_more (isize);
1546 immed = exp.X_add_number;
1549 temp = immed & 0xFFFF8000;
1550 if ((temp != 0) && (temp != 0xFFFF8000))
1552 /* Needs an immediate inst. */
1553 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1554 if (opcode1 == NULL)
1556 as_bad (_("unknown opcode \"%s\""), "imm");
1560 inst1 = opcode1->bit_sequence;
1561 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1562 output[0] = INST_BYTE0 (inst1);
1563 output[1] = INST_BYTE1 (inst1);
1564 output[2] = INST_BYTE2 (inst1);
1565 output[3] = INST_BYTE3 (inst1);
1566 output = frag_more (isize);
1569 inst |= (reg1 << RA_LOW) & RA_MASK;
1570 inst |= (immed << IMM_LOW) & IMM_MASK;
1573 case INST_TYPE_RD_IMM:
1574 if (strcmp (op_end, ""))
1575 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */
1578 as_fatal (_("Error in statement syntax"));
1581 if (strcmp (op_end, ""))
1582 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1584 as_fatal (_("Error in statement syntax"));
1586 /* Check for spl registers. */
1587 if (check_spl_reg (®1))
1588 as_fatal (_("Cannot use special register with this instruction"));
1590 if (exp.X_op != O_constant)
1593 relax_substateT subtype;
1595 if (exp.X_md == IMM_GOT)
1596 subtype = GOT_OFFSET;
1597 else if (exp.X_md == IMM_PLT)
1598 subtype = PLT_OFFSET;
1600 subtype = opcode->inst_offset_type;
1601 output = frag_var (rs_machine_dependent,
1602 isize * 2, /* maxm of 2 words. */
1603 isize, /* minm of 1 word. */
1604 subtype, /* PC-relative or not. */
1612 output = frag_more (isize);
1613 immed = exp.X_add_number;
1616 temp = immed & 0xFFFF8000;
1617 if ((temp != 0) && (temp != 0xFFFF8000))
1619 /* Needs an immediate inst. */
1620 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1621 if (opcode1 == NULL)
1623 as_bad (_("unknown opcode \"%s\""), "imm");
1627 inst1 = opcode1->bit_sequence;
1628 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1629 output[0] = INST_BYTE0 (inst1);
1630 output[1] = INST_BYTE1 (inst1);
1631 output[2] = INST_BYTE2 (inst1);
1632 output[3] = INST_BYTE3 (inst1);
1633 output = frag_more (isize);
1636 inst |= (reg1 << RD_LOW) & RD_MASK;
1637 inst |= (immed << IMM_LOW) & IMM_MASK;
1641 if (strcmp (op_end, ""))
1642 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */
1645 as_fatal (_("Error in statement syntax"));
1649 /* Check for spl registers. */
1650 if (check_spl_reg (®2))
1651 as_fatal (_("Cannot use special register with this instruction"));
1653 inst |= (reg2 << RB_LOW) & RB_MASK;
1654 output = frag_more (isize);
1658 case INST_TYPE_IMM5:
1659 if (streq (name, "imm"))
1660 as_fatal (_("An IMM instruction should not be present in the .s file"));
1662 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1664 if (exp.X_op != O_constant)
1667 relax_substateT subtype;
1669 if (exp.X_md == IMM_GOT)
1670 subtype = GOT_OFFSET;
1671 else if (exp.X_md == IMM_PLT)
1672 subtype = PLT_OFFSET;
1674 subtype = opcode->inst_offset_type;
1675 output = frag_var (rs_machine_dependent,
1676 isize * 2, /* maxm of 2 words. */
1677 isize, /* minm of 1 word. */
1678 subtype, /* PC-relative or not. */
1686 output = frag_more (isize);
1687 immed = exp.X_add_number;
1690 if (opcode->inst_type == INST_TYPE_IMM5)
1693 as_fatal (_("%s instruction only accepts value within range 0 - 31"), name);
1695 inst |= (immed << IMM_LOW) & IMM5_MASK;
1699 temp = immed & 0xFFFF8000;
1700 if ((temp != 0) && (temp != 0xFFFF8000))
1702 /* Needs an immediate inst. */
1703 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1704 if (opcode1 == NULL)
1706 as_bad (_("unknown opcode \"%s\""), "imm");
1710 inst1 = opcode1->bit_sequence;
1711 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1712 output[0] = INST_BYTE0 (inst1);
1713 output[1] = INST_BYTE1 (inst1);
1714 output[2] = INST_BYTE2 (inst1);
1715 output[3] = INST_BYTE3 (inst1);
1716 output = frag_more (isize);
1718 inst |= (immed << IMM_LOW) & IMM_MASK;
1722 case INST_TYPE_NONE:
1723 output = frag_more (isize);
1727 as_fatal (_("unimplemented opcode \"%s\""), name);
1730 /* Drop whitespace after all the operands have been parsed. */
1731 while (ISSPACE (* op_end))
1734 /* Give warning message if the insn has more operands than required. */
1735 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1736 as_warn (_("ignoring operands: %s "), op_end);
1740 output[0] = INST_BYTE0 (inst);
1741 output[1] = INST_BYTE1 (inst);
1742 output[2] = INST_BYTE2 (inst);
1743 output[3] = INST_BYTE3 (inst);
1745 last_output = output;
1748 last_pseudo = pseudo;
1751 dwarf2_emit_insn (4);
1756 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1761 /* Various routines to kill one day. */
1762 /* Equal to MAX_PRECISION in atof-ieee.c */
1763 #define MAX_LITTLENUMS 6
1765 /* Turn a string in input_line_pointer into a floating point constant of type
1766 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1767 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1769 md_atof (int type, char * litP, int * sizeP)
1772 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1804 return _("Bad call to MD_NTOF()");
1807 t = atof_ieee (input_line_pointer, type, words);
1810 input_line_pointer = t;
1812 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1814 if (! target_big_endian)
1816 for (i = prec - 1; i >= 0; i--)
1818 md_number_to_chars (litP, (valueT) words[i],
1819 sizeof (LITTLENUM_TYPE));
1820 litP += sizeof (LITTLENUM_TYPE);
1824 for (i = 0; i < prec; i++)
1826 md_number_to_chars (litP, (valueT) words[i],
1827 sizeof (LITTLENUM_TYPE));
1828 litP += sizeof (LITTLENUM_TYPE);
1834 const char * md_shortopts = "";
1836 struct option md_longopts[] =
1838 { NULL, no_argument, NULL, 0}
1841 size_t md_longopts_size = sizeof (md_longopts);
1843 int md_short_jump_size;
1846 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1847 addressT from_Nddr ATTRIBUTE_UNUSED,
1848 addressT to_Nddr ATTRIBUTE_UNUSED,
1849 fragS * frag ATTRIBUTE_UNUSED,
1850 symbolS * to_symbol ATTRIBUTE_UNUSED)
1852 as_fatal (_("failed sanity check: short_jump"));
1856 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1857 addressT from_Nddr ATTRIBUTE_UNUSED,
1858 addressT to_Nddr ATTRIBUTE_UNUSED,
1859 fragS * frag ATTRIBUTE_UNUSED,
1860 symbolS * to_symbol ATTRIBUTE_UNUSED)
1862 as_fatal (_("failed sanity check: long_jump"));
1865 /* Called after relaxing, change the frags so they know how big they are. */
1868 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1869 segT sec ATTRIBUTE_UNUSED,
1874 switch (fragP->fr_subtype)
1876 case UNDEFINED_PC_OFFSET:
1877 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1878 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1879 fragP->fr_fix += INST_WORD_SIZE * 2;
1882 case DEFINED_ABS_SEGMENT:
1883 if (fragP->fr_symbol == GOT_symbol)
1884 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1885 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1887 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1888 fragP->fr_offset, FALSE, BFD_RELOC_64);
1889 fragP->fr_fix += INST_WORD_SIZE * 2;
1892 case DEFINED_RO_SEGMENT:
1893 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1894 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1895 fragP->fr_fix += INST_WORD_SIZE;
1898 case DEFINED_RW_SEGMENT:
1899 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1900 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1901 fragP->fr_fix += INST_WORD_SIZE;
1904 case DEFINED_PC_OFFSET:
1905 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1906 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1907 fragP->fr_fix += INST_WORD_SIZE;
1910 case LARGE_DEFINED_PC_OFFSET:
1911 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1912 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1913 fragP->fr_fix += INST_WORD_SIZE * 2;
1917 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1918 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1919 fragP->fr_fix += INST_WORD_SIZE * 2;
1923 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1924 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1925 /* fixP->fx_plt = 1; */
1927 fragP->fr_fix += INST_WORD_SIZE * 2;
1931 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1932 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1933 fragP->fr_fix += INST_WORD_SIZE * 2;
1942 /* Applies the desired value to the specified location.
1943 Also sets up addends for 'rela' type relocations. */
1945 md_apply_fix (fixS * fixP,
1949 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1950 char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1951 const char * symname;
1952 /* Note: use offsetT because it is signed, valueT is unsigned. */
1953 offsetT val = (offsetT) * valp;
1955 struct op_code_struct * opcode1;
1956 unsigned long inst1;
1958 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
1960 /* fixP->fx_offset is supposed to be set up correctly for all
1961 symbol relocations. */
1962 if (fixP->fx_addsy == NULL)
1964 if (!fixP->fx_pcrel)
1965 fixP->fx_offset = val; /* Absolute relocation. */
1967 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1968 (unsigned int) fixP->fx_offset, (unsigned int) val);
1971 /* If we aren't adjusting this fixup to be against the section
1972 symbol, we need to adjust the value. */
1973 if (fixP->fx_addsy != NULL)
1975 if (S_IS_WEAK (fixP->fx_addsy)
1976 || (symbol_used_in_reloc_p (fixP->fx_addsy)
1977 && (((bfd_get_section_flags (stdoutput,
1978 S_GET_SEGMENT (fixP->fx_addsy))
1979 & SEC_LINK_ONCE) != 0)
1980 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
1982 sizeof (".gnu.linkonce") - 1))))
1984 val -= S_GET_VALUE (fixP->fx_addsy);
1985 if (val != 0 && ! fixP->fx_pcrel)
1987 /* In this case, the bfd_install_relocation routine will
1988 incorrectly add the symbol value back in. We just want
1989 the addend to appear in the object file.
1990 FIXME: If this makes VALUE zero, we're toast. */
1991 val -= S_GET_VALUE (fixP->fx_addsy);
1996 /* If the fix is relative to a symbol which is not defined, or not
1997 in the same segment as the fix, we cannot resolve it here. */
1998 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1999 if (fixP->fx_addsy != NULL
2000 && (!S_IS_DEFINED (fixP->fx_addsy)
2001 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
2005 /* For ELF we can just return and let the reloc that will be generated
2006 take care of everything. For COFF we still have to insert 'val'
2007 into the insn since the addend field will be ignored. */
2011 /* All fixups in the text section must be handled in the linker. */
2012 else if (segment->flags & SEC_CODE)
2014 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
2019 switch (fixP->fx_r_type)
2021 case BFD_RELOC_MICROBLAZE_32_LO:
2022 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2023 if (target_big_endian)
2025 buf[2] |= ((val >> 8) & 0xff);
2026 buf[3] |= (val & 0xff);
2030 buf[1] |= ((val >> 8) & 0xff);
2031 buf[0] |= (val & 0xff);
2034 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2035 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2036 /* Don't do anything if the symbol is not defined. */
2037 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2039 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
2040 as_bad_where (file, fixP->fx_line,
2041 _("pcrel for branch to %s too far (0x%x)"),
2042 symname, (int) val);
2043 if (target_big_endian)
2045 buf[2] |= ((val >> 8) & 0xff);
2046 buf[3] |= (val & 0xff);
2050 buf[1] |= ((val >> 8) & 0xff);
2051 buf[0] |= (val & 0xff);
2057 case BFD_RELOC_32_PCREL:
2058 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2059 /* Don't do anything if the symbol is not defined. */
2060 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2062 if (target_big_endian)
2064 buf[0] |= ((val >> 24) & 0xff);
2065 buf[1] |= ((val >> 16) & 0xff);
2066 buf[2] |= ((val >> 8) & 0xff);
2067 buf[3] |= (val & 0xff);
2071 buf[3] |= ((val >> 24) & 0xff);
2072 buf[2] |= ((val >> 16) & 0xff);
2073 buf[1] |= ((val >> 8) & 0xff);
2074 buf[0] |= (val & 0xff);
2078 case BFD_RELOC_64_PCREL:
2080 /* Add an imm instruction. First save the current instruction. */
2081 for (i = 0; i < INST_WORD_SIZE; i++)
2082 buf[i + INST_WORD_SIZE] = buf[i];
2084 /* Generate the imm instruction. */
2085 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2086 if (opcode1 == NULL)
2088 as_bad (_("unknown opcode \"%s\""), "imm");
2092 inst1 = opcode1->bit_sequence;
2093 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2094 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
2096 buf[0] = INST_BYTE0 (inst1);
2097 buf[1] = INST_BYTE1 (inst1);
2098 buf[2] = INST_BYTE2 (inst1);
2099 buf[3] = INST_BYTE3 (inst1);
2101 /* Add the value only if the symbol is defined. */
2102 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2104 if (target_big_endian)
2106 buf[6] |= ((val >> 8) & 0xff);
2107 buf[7] |= (val & 0xff);
2111 buf[5] |= ((val >> 8) & 0xff);
2112 buf[4] |= (val & 0xff);
2117 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2118 case BFD_RELOC_MICROBLAZE_64_GOT:
2119 case BFD_RELOC_MICROBLAZE_64_PLT:
2120 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2121 /* Add an imm instruction. First save the current instruction. */
2122 for (i = 0; i < INST_WORD_SIZE; i++)
2123 buf[i + INST_WORD_SIZE] = buf[i];
2125 /* Generate the imm instruction. */
2126 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2127 if (opcode1 == NULL)
2129 as_bad (_("unknown opcode \"%s\""), "imm");
2133 inst1 = opcode1->bit_sequence;
2135 /* We can fixup call to a defined non-global address
2136 within the same section only. */
2137 buf[0] = INST_BYTE0 (inst1);
2138 buf[1] = INST_BYTE1 (inst1);
2139 buf[2] = INST_BYTE2 (inst1);
2140 buf[3] = INST_BYTE3 (inst1);
2147 if (fixP->fx_addsy == NULL)
2149 /* This fixup has been resolved. Create a reloc in case the linker
2150 moves code around due to relaxing. */
2151 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2152 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2154 fixP->fx_r_type = BFD_RELOC_NONE;
2155 fixP->fx_addsy = section_symbol (absolute_section);
2161 md_operand (expressionS * expressionP)
2163 /* Ignore leading hash symbol, if present. */
2164 if (*input_line_pointer == '#')
2166 input_line_pointer ++;
2167 expression (expressionP);
2171 /* Called just before address relaxation, return the length
2172 by which a fragment must grow to reach it's destination. */
2175 md_estimate_size_before_relax (fragS * fragP,
2178 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2179 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2180 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2181 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2183 switch (fragP->fr_subtype)
2185 case INST_PC_OFFSET:
2186 /* Used to be a PC-relative branch. */
2187 if (!fragP->fr_symbol)
2189 /* We know the abs value: Should never happen. */
2190 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2193 else if ((S_GET_SEGMENT (fragP->fr_symbol) == segment_type))
2195 fragP->fr_subtype = DEFINED_PC_OFFSET;
2196 /* Don't know now whether we need an imm instruction. */
2197 fragP->fr_var = INST_WORD_SIZE;
2199 else if (S_IS_DEFINED (fragP->fr_symbol)
2200 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2202 /* Cannot have a PC-relative branch to a diff segment. */
2203 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2204 S_GET_NAME (fragP->fr_symbol));
2205 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2206 fragP->fr_var = INST_WORD_SIZE*2;
2210 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2211 fragP->fr_var = INST_WORD_SIZE*2;
2215 case INST_NO_OFFSET:
2216 /* Used to be a reference to somewhere which was unknown. */
2217 if (fragP->fr_symbol)
2219 if (fragP->fr_opcode == NULL)
2221 /* Used as an absolute value. */
2222 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2223 /* Variable part does not change. */
2224 fragP->fr_var = INST_WORD_SIZE*2;
2226 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2228 /* It is accessed using the small data read only anchor. */
2229 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2230 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2231 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2232 || (! S_IS_DEFINED (fragP->fr_symbol)))
2234 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2235 fragP->fr_var = INST_WORD_SIZE;
2239 /* Variable not in small data read only segment accessed
2240 using small data read only anchor. */
2241 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2243 as_bad_where (file, fragP->fr_line,
2244 _("Variable is accessed using small data read "
2245 "only anchor, but it is not in the small data "
2246 "read only section"));
2247 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2248 fragP->fr_var = INST_WORD_SIZE;
2251 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2253 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2254 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2255 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2256 || (!S_IS_DEFINED (fragP->fr_symbol)))
2258 /* It is accessed using the small data read write anchor. */
2259 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2260 fragP->fr_var = INST_WORD_SIZE;
2264 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2266 as_bad_where (file, fragP->fr_line,
2267 _("Variable is accessed using small data read "
2268 "write anchor, but it is not in the small data "
2269 "read write section"));
2270 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2271 fragP->fr_var = INST_WORD_SIZE;
2276 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2282 /* We know the abs value: Should never happen. */
2283 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2288 case UNDEFINED_PC_OFFSET:
2289 case LARGE_DEFINED_PC_OFFSET:
2290 case DEFINED_ABS_SEGMENT:
2294 fragP->fr_var = INST_WORD_SIZE*2;
2296 case DEFINED_RO_SEGMENT:
2297 case DEFINED_RW_SEGMENT:
2298 case DEFINED_PC_OFFSET:
2299 fragP->fr_var = INST_WORD_SIZE;
2305 return fragP->fr_var;
2308 /* Put number into target byte order. */
2311 md_number_to_chars (char * ptr, valueT use, int nbytes)
2313 if (target_big_endian)
2314 number_to_chars_bigendian (ptr, use, nbytes);
2316 number_to_chars_littleendian (ptr, use, nbytes);
2319 /* Round up a section size to the appropriate boundary. */
2322 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2324 return size; /* Byte alignment is fine. */
2328 /* The location from which a PC relative jump should be calculated,
2329 given a PC relative reloc. */
2332 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2335 /* If the symbol is undefined or defined in another section
2336 we leave the add number alone for the linker to fix it later.
2337 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2339 if (fixp->fx_addsy != (symbolS *) NULL
2340 && (!S_IS_DEFINED (fixp->fx_addsy)
2341 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2345 /* The case where we are going to resolve things... */
2346 if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2347 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2349 return fixp->fx_where + fixp->fx_frag->fr_address;
2355 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2356 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2359 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2362 bfd_reloc_code_real_type code;
2364 switch (fixp->fx_r_type)
2366 case BFD_RELOC_NONE:
2367 case BFD_RELOC_MICROBLAZE_64_NONE:
2369 case BFD_RELOC_MICROBLAZE_32_LO:
2370 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2373 case BFD_RELOC_64_PCREL:
2374 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2375 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2376 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2377 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2378 case BFD_RELOC_MICROBLAZE_64_GOT:
2379 case BFD_RELOC_MICROBLAZE_64_PLT:
2380 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2381 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2382 code = fixp->fx_r_type;
2386 switch (F (fixp->fx_size, fixp->fx_pcrel))
2388 MAP (1, 0, BFD_RELOC_8);
2389 MAP (2, 0, BFD_RELOC_16);
2390 MAP (4, 0, BFD_RELOC_32);
2391 MAP (1, 1, BFD_RELOC_8_PCREL);
2392 MAP (2, 1, BFD_RELOC_16_PCREL);
2393 MAP (4, 1, BFD_RELOC_32_PCREL);
2395 code = fixp->fx_r_type;
2396 as_bad (_("Can not do %d byte %srelocation"),
2398 fixp->fx_pcrel ? _("pc-relative") : "");
2403 rel = (arelent *) xmalloc (sizeof (arelent));
2404 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2406 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2407 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2409 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2411 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2412 /* Always pass the addend along! */
2413 rel->addend = fixp->fx_offset;
2414 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2416 if (rel->howto == NULL)
2418 as_bad_where (fixp->fx_file, fixp->fx_line,
2419 _("Cannot represent relocation type %s"),
2420 bfd_get_reloc_code_name (code));
2422 /* Set howto to a garbage value so that we can keep going. */
2423 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2424 gas_assert (rel->howto != NULL);
2430 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
2441 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2443 /* fprintf(stream, _("\
2444 MicroBlaze options:\n\
2445 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2449 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2450 found a machine specific op in an expression,
2451 then we create relocs accordingly. */
2454 cons_fix_new_microblaze (fragS * frag,
2460 bfd_reloc_code_real_type r;
2462 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2463 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2464 && (!S_IS_LOCAL (exp->X_op_symbol)))
2465 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2466 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2468 exp->X_op = O_symbol;
2469 r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2488 as_bad (_("unsupported BFD relocation size %u"), size);
2493 fix_new_exp (frag, where, size, exp, 0, r);