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
84 #define TLSGD_OFFSET 11
85 #define TLSLD_OFFSET 12
86 #define TLSDTPMOD_OFFSET 13
87 #define TLSDTPREL_OFFSET 14
88 #define TLSGOTTPREL_OFFSET 15
89 #define TLSTPREL_OFFSET 16
91 /* Initialize the relax table. */
92 const relax_typeS md_relax_table
[] =
94 { 1, 1, 0, 0 }, /* 0: Unused. */
95 { 1, 1, 0, 0 }, /* 1: Unused. */
96 { 1, 1, 0, 0 }, /* 2: Unused. */
97 { 1, 1, 0, 0 }, /* 3: Unused. */
98 { 32767, -32768, INST_WORD_SIZE
, LARGE_DEFINED_PC_OFFSET
}, /* 4: DEFINED_PC_OFFSET. */
99 { 1, 1, 0, 0 }, /* 5: Unused. */
100 { 1, 1, 0, 0 }, /* 6: Unused. */
101 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
102 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 8: GOT_OFFSET. */
103 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 9: PLT_OFFSET. */
104 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 10: GOTOFF_OFFSET. */
105 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 11: TLSGD_OFFSET. */
106 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 12: TLSLD_OFFSET. */
107 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */
108 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 14: TLSDTPREL_OFFSET. */
109 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
110 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 } /* 16: TLSTPREL_OFFSET. */
113 static struct hash_control
* opcode_hash_control
; /* Opcode mnemonics. */
115 static segT sbss_segment
= 0; /* Small bss section. */
116 static segT sbss2_segment
= 0; /* Section not used. */
117 static segT sdata_segment
= 0; /* Small data section. */
118 static segT sdata2_segment
= 0; /* Small read-only section. */
119 static segT rodata_segment
= 0; /* read-only section. */
121 /* Generate a symbol for stabs information. */
124 microblaze_generate_symbol (char *sym
)
126 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
127 static int microblaze_label_count
;
128 sprintf (sym
, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME
, microblaze_label_count
);
129 ++microblaze_label_count
;
132 /* Handle the section changing pseudo-ops. */
135 microblaze_s_text (int ignore ATTRIBUTE_UNUSED
)
138 obj_elf_text (ignore
);
145 microblaze_s_data (int ignore ATTRIBUTE_UNUSED
)
148 obj_elf_change_section (".data", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
154 /* Things in the .sdata segment are always considered to be in the small data section. */
157 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED
)
160 obj_elf_change_section (".sdata", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
166 /* Pseudo op to make file scope bss items. */
169 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED
)
179 segT current_seg
= now_seg
;
180 subsegT current_subseg
= now_subseg
;
182 name
= input_line_pointer
;
183 c
= get_symbol_end ();
185 /* Just after name is now '\0'. */
186 p
= input_line_pointer
;
189 if (*input_line_pointer
!= ',')
191 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
192 ignore_rest_of_line ();
196 input_line_pointer
++; /* skip ',' */
197 if ((size
= get_absolute_expression ()) < 0)
199 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size
);
200 ignore_rest_of_line ();
204 /* The third argument to .lcomm is the alignment. */
205 if (*input_line_pointer
!= ',')
209 ++input_line_pointer
;
210 align
= get_absolute_expression ();
213 as_warn (_("ignoring bad alignment"));
219 symbolP
= symbol_find_or_make (name
);
222 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
224 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
225 S_GET_NAME (symbolP
));
226 ignore_rest_of_line ();
230 if (S_GET_VALUE (symbolP
) && S_GET_VALUE (symbolP
) != (valueT
) size
)
232 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
233 S_GET_NAME (symbolP
),
234 (long) S_GET_VALUE (symbolP
),
237 ignore_rest_of_line ();
244 /* Convert to a power of 2 alignment. */
245 for (align2
= 0; (align
& 1) == 0; align
>>= 1, ++align2
);
248 as_bad (_("Common alignment not a power of 2"));
249 ignore_rest_of_line ();
256 record_alignment (current_seg
, align2
);
257 subseg_set (current_seg
, current_subseg
);
259 frag_align (align2
, 0, 0);
260 if (S_GET_SEGMENT (symbolP
) == current_seg
)
261 symbol_get_frag (symbolP
)->fr_symbol
= 0;
262 symbol_set_frag (symbolP
, frag_now
);
263 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
266 S_SET_SIZE (symbolP
, size
);
267 S_SET_SEGMENT (symbolP
, current_seg
);
268 subseg_set (current_seg
, current_subseg
);
269 demand_empty_rest_of_line ();
273 microblaze_s_rdata (int localvar
)
279 obj_elf_change_section (".rodata", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
280 if (rodata_segment
== 0)
281 rodata_segment
= subseg_new (".rodata", 0);
286 obj_elf_change_section (".sdata2", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
294 microblaze_s_bss (int localvar
)
297 if (localvar
== 0) /* bss. */
298 obj_elf_change_section (".bss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
299 else if (localvar
== 1)
302 obj_elf_change_section (".sbss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
303 if (sbss_segment
== 0)
304 sbss_segment
= subseg_new (".sbss", 0);
311 /* endp_p is always 1 as this func is called only for .end <funcname>
312 This func consumes the <funcname> and calls regular processing
313 s_func(1) with arg 1 (1 for end). */
316 microblaze_s_func (int end_p ATTRIBUTE_UNUSED
)
318 *input_line_pointer
= get_symbol_end ();
322 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
325 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED
)
332 name
= input_line_pointer
;
333 c
= get_symbol_end ();
334 symbolP
= symbol_find_or_make (name
);
335 S_SET_WEAK (symbolP
);
336 *input_line_pointer
= c
;
340 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
342 if (S_IS_DEFINED (symbolP
))
344 as_bad ("Ignoring attempt to redefine symbol `%s'.",
345 S_GET_NAME (symbolP
));
346 ignore_rest_of_line ();
350 if (*input_line_pointer
== ',')
352 ++input_line_pointer
;
357 if (exp
.X_op
!= O_symbol
)
359 as_bad ("bad .weakext directive");
360 ignore_rest_of_line ();
363 symbol_set_value_expression (symbolP
, &exp
);
366 demand_empty_rest_of_line ();
369 /* This table describes all the machine specific pseudo-ops the assembler
370 has to support. The fields are:
371 Pseudo-op name without dot
372 Function to call to execute this pseudo-op
373 Integer arg to pass to the function. */
374 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
375 and then in the read.c table. */
376 const pseudo_typeS md_pseudo_table
[] =
378 {"lcomm", microblaze_s_lcomm
, 1},
379 {"data", microblaze_s_data
, 0},
380 {"data8", cons
, 1}, /* Same as byte. */
381 {"data16", cons
, 2}, /* Same as hword. */
382 {"data32", cons
, 4}, /* Same as word. */
383 {"ent", s_func
, 0}, /* Treat ent as function entry point. */
384 {"end", microblaze_s_func
, 1}, /* Treat end as function end point. */
385 {"gpword", s_rva
, 4}, /* gpword label => store resolved label address in data section. */
386 {"weakext", microblaze_s_weakext
, 0},
387 {"rodata", microblaze_s_rdata
, 0},
388 {"sdata2", microblaze_s_rdata
, 1},
389 {"sdata", microblaze_s_sdata
, 0},
390 {"bss", microblaze_s_bss
, 0},
391 {"sbss", microblaze_s_bss
, 1},
392 {"text", microblaze_s_text
, 0},
394 {"frame", s_ignore
, 0},
395 {"mask", s_ignore
, 0}, /* Emitted by gcc. */
399 /* This function is called once, at assembler startup time. This should
400 set up all the tables, etc that the MD part of the assembler needs. */
405 struct op_code_struct
* opcode
;
407 opcode_hash_control
= hash_new ();
409 /* Insert unique names into hash table. */
410 for (opcode
= opcodes
; opcode
->name
; opcode
++)
411 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
414 /* Try to parse a reg name. */
417 parse_reg (char * s
, unsigned * reg
)
421 /* Strip leading whitespace. */
422 while (ISSPACE (* s
))
425 if (strncasecmp (s
, "rpc", 3) == 0)
430 else if (strncasecmp (s
, "rmsr", 4) == 0)
435 else if (strncasecmp (s
, "rear", 4) == 0)
440 else if (strncasecmp (s
, "resr", 4) == 0)
445 else if (strncasecmp (s
, "rfsr", 4) == 0)
450 else if (strncasecmp (s
, "rbtr", 4) == 0)
455 else if (strncasecmp (s
, "redr", 4) == 0)
460 /* MMU registers start. */
461 else if (strncasecmp (s
, "rpid", 4) == 0)
466 else if (strncasecmp (s
, "rzpr", 4) == 0)
471 else if (strncasecmp (s
, "rtlbx", 5) == 0)
476 else if (strncasecmp (s
, "rtlblo", 6) == 0)
481 else if (strncasecmp (s
, "rtlbhi", 6) == 0)
486 else if (strncasecmp (s
, "rtlbsx", 6) == 0)
491 /* MMU registers end. */
492 else if (strncasecmp (s
, "rpvr", 4) == 0)
494 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
496 tmpreg
= (s
[4]-'0')*10 + s
[5] - '0';
500 else if (ISDIGIT (s
[4]))
506 as_bad (_("register expected, but saw '%.6s'"), s
);
507 if ((int) tmpreg
>= MIN_PVR_REGNUM
&& tmpreg
<= MAX_PVR_REGNUM
)
508 *reg
= REG_PVR
+ tmpreg
;
511 as_bad (_("Invalid register number at '%.6s'"), s
);
516 else if (strncasecmp (s
, "rsp", 3) == 0)
521 else if (strncasecmp (s
, "rfsl", 4) == 0)
523 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
525 tmpreg
= (s
[4] - '0') * 10 + s
[5] - '0';
528 else if (ISDIGIT (s
[4]))
534 as_bad (_("register expected, but saw '%.6s'"), s
);
536 if ((int) tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
540 as_bad (_("Invalid register number at '%.6s'"), s
);
545 /* Stack protection registers. */
546 else if (strncasecmp (s
, "rshr", 4) == 0)
551 else if (strncasecmp (s
, "rslr", 4) == 0)
558 if (TOLOWER (s
[0]) == 'r')
560 if (ISDIGIT (s
[1]) && ISDIGIT (s
[2]))
562 tmpreg
= (s
[1] - '0') * 10 + s
[2] - '0';
565 else if (ISDIGIT (s
[1]))
571 as_bad (_("register expected, but saw '%.6s'"), s
);
573 if ((int)tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
577 as_bad (_("Invalid register number at '%.6s'"), s
);
583 as_bad (_("register expected, but saw '%.6s'"), s
);
589 parse_exp (char *s
, expressionS
*e
)
594 /* Skip whitespace. */
595 while (ISSPACE (* s
))
598 save
= input_line_pointer
;
599 input_line_pointer
= s
;
603 if (e
->X_op
== O_absent
)
604 as_fatal (_("missing operand"));
606 new_pointer
= input_line_pointer
;
607 input_line_pointer
= save
;
612 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
619 #define IMM_TLSDTPMOD 6
620 #define IMM_TLSDTPREL 7
621 #define IMM_TLSTPREL 8
625 char *isuffix
; /* Suffix String */
626 int itype
; /* Suffix Type */
627 int otype
; /* Offset Type */
630 /* These are NOT in assending order of type, GOTOFF is ahead to make
631 sure @GOTOFF does not get matched with @GOT */
632 static struct imm_type imm_types
[] = {
633 { "NONE", IMM_NONE
, 0 },
634 { "GOTOFF", IMM_GOTOFF
, GOTOFF_OFFSET
},
635 { "GOT", IMM_GOT
, GOT_OFFSET
},
636 { "PLT", IMM_PLT
, PLT_OFFSET
},
637 { "TLSGD", IMM_TLSGD
, TLSGD_OFFSET
},
638 { "TLSLDM", IMM_TLSLD
, TLSLD_OFFSET
},
639 { "TLSDTPMOD", IMM_TLSDTPMOD
, TLSDTPMOD_OFFSET
},
640 { "TLSDTPREL", IMM_TLSDTPREL
, TLSDTPREL_OFFSET
},
641 { "TLSTPREL", IMM_TLSTPREL
, TLSTPREL_OFFSET
}
645 match_imm (const char *s
, int *ilen
)
650 /* Check for matching suffix */
651 for (i
= 1; i
< IMM_MAX
; i
++)
653 slen
= strlen (imm_types
[i
].isuffix
);
655 if (strncmp (imm_types
[i
].isuffix
, s
, slen
) == 0)
658 return imm_types
[i
].itype
;
666 get_imm_otype (int itype
)
671 /* Check for matching itype */
672 for (i
= 1; i
< IMM_MAX
; i
++)
674 if (imm_types
[i
].itype
== itype
)
676 otype
= imm_types
[i
].otype
;
683 static symbolS
* GOT_symbol
;
685 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
688 parse_imm (char * s
, expressionS
* e
, int min
, int max
)
696 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
697 for (atp
= s
; *atp
!= '@'; atp
++)
698 if (is_end_of_line
[(unsigned char) *atp
])
703 itype
= match_imm (atp
+ 1, &ilen
);
723 if (atp
&& !GOT_symbol
)
725 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
728 new_pointer
= parse_exp (s
, e
);
730 if (!GOT_symbol
&& ! strncmp (s
, GOT_SYMBOL_NAME
, 20))
732 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
735 if (e
->X_op
== O_absent
)
736 ; /* An error message has already been emitted. */
737 else if ((e
->X_op
!= O_constant
&& e
->X_op
!= O_symbol
) )
738 as_fatal (_("operand must be a constant or a label"));
739 else if ((e
->X_op
== O_constant
) && ((int) e
->X_add_number
< min
740 || (int) e
->X_add_number
> max
))
742 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
743 min
, max
, (int) e
->X_add_number
);
748 *atp
= '@'; /* restore back (needed?) */
749 if (new_pointer
>= atp
)
750 new_pointer
+= ilen
+ 1; /* sizeof (imm_suffix) + 1 for '@' */
756 check_got (int * got_type
, int * got_len
)
764 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
765 for (atp
= input_line_pointer
; *atp
!= '@'; atp
++)
766 if (is_end_of_line
[(unsigned char) *atp
])
769 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
772 *got_type
= IMM_GOTOFF
;
774 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
779 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
788 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
790 first
= atp
- input_line_pointer
;
792 past_got
= atp
+ *got_len
+ 1;
793 for (new_pointer
= past_got
; !is_end_of_line
[(unsigned char) *new_pointer
++];)
795 second
= new_pointer
- past_got
;
796 tmpbuf
= xmalloc (first
+ second
+ 2); /* One extra byte for ' ' and one for NUL. */
797 memcpy (tmpbuf
, input_line_pointer
, first
);
798 tmpbuf
[first
] = ' '; /* @GOTOFF is replaced with a single space. */
799 memcpy (tmpbuf
+ first
+ 1, past_got
, second
);
800 tmpbuf
[first
+ second
+ 1] = '\0';
806 parse_cons_expression_microblaze (expressionS
*exp
, int size
)
810 /* Handle @GOTOFF et.al. */
811 char *save
, *gotfree_copy
;
812 int got_len
, got_type
;
814 save
= input_line_pointer
;
815 gotfree_copy
= check_got (& got_type
, & got_len
);
817 input_line_pointer
= gotfree_copy
;
823 exp
->X_md
= got_type
;
824 input_line_pointer
= save
+ (input_line_pointer
- gotfree_copy
)
833 /* This is the guts of the machine-dependent assembler. STR points to a
834 machine dependent instruction. This function is supposed to emit
835 the frags/bytes it assembles to. */
837 static char * str_microblaze_ro_anchor
= "RO";
838 static char * str_microblaze_rw_anchor
= "RW";
841 check_spl_reg (unsigned * reg
)
843 if ((*reg
== REG_MSR
) || (*reg
== REG_PC
)
844 || (*reg
== REG_EAR
) || (*reg
== REG_ESR
)
845 || (*reg
== REG_FSR
) || (*reg
== REG_BTR
) || (*reg
== REG_EDR
)
846 || (*reg
== REG_PID
) || (*reg
== REG_ZPR
)
847 || (*reg
== REG_TLBX
) || (*reg
== REG_TLBLO
)
848 || (*reg
== REG_TLBHI
) || (*reg
== REG_TLBSX
)
849 || (*reg
== REG_SHR
) || (*reg
== REG_SLR
)
850 || (*reg
>= REG_PVR
+MIN_PVR_REGNUM
&& *reg
<= REG_PVR
+MAX_PVR_REGNUM
))
856 /* Here we decide which fixups can be adjusted to make them relative to
857 the beginning of the section instead of the symbol. Basically we need
858 to make sure that the dynamic relocations are done correctly, so in
859 some cases we force the original symbol to be used. */
862 tc_microblaze_fix_adjustable (struct fix
*fixP
)
864 if (GOT_symbol
&& fixP
->fx_subsy
== GOT_symbol
)
867 if (fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOTOFF
868 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_GOTOFF
869 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOT
870 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_PLT
871 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGD
872 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSLD
873 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
874 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPREL
875 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSDTPREL
876 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
877 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSTPREL
)
884 md_assemble (char * str
)
888 struct op_code_struct
* opcode
, *opcode1
;
889 char * output
= NULL
;
892 unsigned long inst
, inst1
;
897 unsigned int immed
, temp
;
901 /* Drop leading whitespace. */
902 while (ISSPACE (* str
))
905 /* Find the op code end. */
906 for (op_start
= op_end
= str
;
907 *op_end
&& !is_end_of_line
[(unsigned char) *op_end
] && *op_end
!= ' ';
910 name
[nlen
] = op_start
[nlen
];
912 if (nlen
== sizeof (name
) - 1)
920 as_bad (_("can't find opcode "));
924 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, name
);
927 as_bad (_("unknown opcode \"%s\""), name
);
931 inst
= opcode
->bit_sequence
;
934 switch (opcode
->inst_type
)
936 case INST_TYPE_RD_R1_R2
:
937 if (strcmp (op_end
, ""))
938 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
941 as_fatal (_("Error in statement syntax"));
944 if (strcmp (op_end
, ""))
945 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
948 as_fatal (_("Error in statement syntax"));
951 if (strcmp (op_end
, ""))
952 op_end
= parse_reg (op_end
+ 1, ®3
); /* Get r2. */
955 as_fatal (_("Error in statement syntax"));
959 /* Check for spl registers. */
960 if (check_spl_reg (& reg1
))
961 as_fatal (_("Cannot use special register with this instruction"));
962 if (check_spl_reg (& reg2
))
963 as_fatal (_("Cannot use special register with this instruction"));
964 if (check_spl_reg (& reg3
))
965 as_fatal (_("Cannot use special register with this instruction"));
967 if (streq (name
, "sub"))
969 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
970 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
971 inst
|= (reg3
<< RA_LOW
) & RA_MASK
;
972 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
976 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
977 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
978 inst
|= (reg3
<< RB_LOW
) & RB_MASK
;
980 output
= frag_more (isize
);
983 case INST_TYPE_RD_R1_IMM
:
984 if (strcmp (op_end
, ""))
985 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
988 as_fatal (_("Error in statement syntax"));
991 if (strcmp (op_end
, ""))
992 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
995 as_fatal (_("Error in statement syntax"));
998 if (strcmp (op_end
, ""))
999 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1001 as_fatal (_("Error in statement syntax"));
1003 /* Check for spl registers. */
1004 if (check_spl_reg (& reg1
))
1005 as_fatal (_("Cannot use special register with this instruction"));
1006 if (check_spl_reg (& reg2
))
1007 as_fatal (_("Cannot use special register with this instruction"));
1009 if (exp
.X_op
!= O_constant
)
1012 relax_substateT subtype
;
1014 if (streq (name
, "lmi"))
1015 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
1016 else if (streq (name
, "smi"))
1017 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
1019 if (reg2
== REG_ROSDP
)
1020 opc
= str_microblaze_ro_anchor
;
1021 else if (reg2
== REG_RWSDP
)
1022 opc
= str_microblaze_rw_anchor
;
1026 subtype
= get_imm_otype(exp
.X_md
);
1028 subtype
= opcode
->inst_offset_type
;
1030 output
= frag_var (rs_machine_dependent
,
1031 isize
* 2, /* maxm of 2 words. */
1032 isize
, /* minm of 1 word. */
1033 subtype
, /* PC-relative or not. */
1041 output
= frag_more (isize
);
1042 immed
= exp
.X_add_number
;
1045 if (streq (name
, "lmi") || streq (name
, "smi"))
1047 /* Load/store 32-d consecutive registers. Used on exit/entry
1048 to subroutines to save and restore registers to stack.
1049 Generate 32-d insts. */
1053 if (streq (name
, "lmi"))
1054 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "lwi");
1056 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "swi");
1059 as_bad (_("unknown opcode \"%s\""), "lwi");
1062 inst
= opcode
->bit_sequence
;
1063 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1064 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1065 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1067 for (i
= 0; i
< count
- 1; i
++)
1069 output
[0] = INST_BYTE0 (inst
);
1070 output
[1] = INST_BYTE1 (inst
);
1071 output
[2] = INST_BYTE2 (inst
);
1072 output
[3] = INST_BYTE3 (inst
);
1073 output
= frag_more (isize
);
1076 inst
= opcode
->bit_sequence
;
1077 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1078 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1079 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1084 temp
= immed
& 0xFFFF8000;
1085 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1087 /* Needs an immediate inst. */
1088 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1089 if (opcode1
== NULL
)
1091 as_bad (_("unknown opcode \"%s\""), "imm");
1095 inst1
= opcode1
->bit_sequence
;
1096 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1097 output
[0] = INST_BYTE0 (inst1
);
1098 output
[1] = INST_BYTE1 (inst1
);
1099 output
[2] = INST_BYTE2 (inst1
);
1100 output
[3] = INST_BYTE3 (inst1
);
1101 output
= frag_more (isize
);
1103 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1104 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1105 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1109 case INST_TYPE_RD_R1_IMM5
:
1110 if (strcmp (op_end
, ""))
1111 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1114 as_fatal (_("Error in statement syntax"));
1117 if (strcmp (op_end
, ""))
1118 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1121 as_fatal (_("Error in statement syntax"));
1124 if (strcmp (op_end
, ""))
1125 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1127 as_fatal (_("Error in statement syntax"));
1129 /* Check for spl registers. */
1130 if (check_spl_reg (®1
))
1131 as_fatal (_("Cannot use special register with this instruction"));
1132 if (check_spl_reg (®2
))
1133 as_fatal (_("Cannot use special register with this instruction"));
1135 if (exp
.X_op
!= O_constant
)
1136 as_warn (_("Symbol used as immediate for shift instruction"));
1139 output
= frag_more (isize
);
1140 immed
= exp
.X_add_number
;
1143 if (immed
!= (immed
% 32))
1145 as_warn (_("Shift value > 32. using <value %% 32>"));
1148 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1149 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1150 inst
|= (immed
<< IMM_LOW
) & IMM5_MASK
;
1153 case INST_TYPE_R1_R2
:
1154 if (strcmp (op_end
, ""))
1155 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1158 as_fatal (_("Error in statement syntax"));
1161 if (strcmp (op_end
, ""))
1162 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1165 as_fatal (_("Error in statement syntax"));
1169 /* Check for spl registers. */
1170 if (check_spl_reg (& reg1
))
1171 as_fatal (_("Cannot use special register with this instruction"));
1172 if (check_spl_reg (& reg2
))
1173 as_fatal (_("Cannot use special register with this instruction"));
1175 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1176 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1177 output
= frag_more (isize
);
1180 case INST_TYPE_RD_R1
:
1181 if (strcmp (op_end
, ""))
1182 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1185 as_fatal (_("Error in statement syntax"));
1188 if (strcmp (op_end
, ""))
1189 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1192 as_fatal (_("Error in statement syntax"));
1196 /* Check for spl registers. */
1197 if (check_spl_reg (®1
))
1198 as_fatal (_("Cannot use special register with this instruction"));
1199 if (check_spl_reg (®2
))
1200 as_fatal (_("Cannot use special register with this instruction"));
1202 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1203 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1204 output
= frag_more (isize
);
1207 case INST_TYPE_RD_RFSL
:
1208 if (strcmp (op_end
, ""))
1209 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1212 as_fatal (_("Error in statement syntax"));
1215 if (strcmp (op_end
, ""))
1216 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1219 as_fatal (_("Error in statement syntax"));
1223 /* Check for spl registers. */
1224 if (check_spl_reg (®1
))
1225 as_fatal (_("Cannot use special register with this instruction"));
1227 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1228 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1229 output
= frag_more (isize
);
1232 case INST_TYPE_RD_IMM15
:
1233 if (strcmp (op_end
, ""))
1234 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1237 as_fatal (_("Error in statement syntax"));
1241 if (strcmp (op_end
, ""))
1242 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1244 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 if (exp
.X_op
!= O_constant
)
1251 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1254 output
= frag_more (isize
);
1255 immed
= exp
.X_add_number
;
1257 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1258 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1261 case INST_TYPE_R1_RFSL
:
1262 if (strcmp (op_end
, ""))
1263 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1266 as_fatal (_("Error in statement syntax"));
1269 if (strcmp (op_end
, ""))
1270 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1273 as_fatal (_("Error in statement syntax"));
1277 /* Check for spl registers. */
1278 if (check_spl_reg (®1
))
1279 as_fatal (_("Cannot use special register with this instruction"));
1281 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1282 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1283 output
= frag_more (isize
);
1286 case INST_TYPE_RFSL
:
1287 if (strcmp (op_end
, ""))
1288 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1291 as_fatal (_("Error in statement syntax"));
1294 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1295 output
= frag_more (isize
);
1299 if (strcmp (op_end
, ""))
1300 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1303 as_fatal (_("Error in statement syntax"));
1307 /* Check for spl registers. */
1308 if (check_spl_reg (®1
))
1309 as_fatal (_("Cannot use special register with this instruction"));
1311 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1312 output
= frag_more (isize
);
1315 /* For tuqula insn...:) */
1317 if (strcmp (op_end
, ""))
1318 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1321 as_fatal (_("Error in statement syntax"));
1325 /* Check for spl registers. */
1326 if (check_spl_reg (®1
))
1327 as_fatal (_("Cannot use special register with this instruction"));
1329 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1330 output
= frag_more (isize
);
1333 case INST_TYPE_RD_SPECIAL
:
1334 if (strcmp (op_end
, ""))
1335 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1338 as_fatal (_("Error in statement syntax"));
1341 if (strcmp (op_end
, ""))
1342 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1345 as_fatal (_("Error in statement syntax"));
1349 if (reg2
== REG_MSR
)
1350 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1351 else if (reg2
== REG_PC
)
1352 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1353 else if (reg2
== REG_EAR
)
1354 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1355 else if (reg2
== REG_ESR
)
1356 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1357 else if (reg2
== REG_FSR
)
1358 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1359 else if (reg2
== REG_BTR
)
1360 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1361 else if (reg2
== REG_EDR
)
1362 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1363 else if (reg2
== REG_PID
)
1364 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1365 else if (reg2
== REG_ZPR
)
1366 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1367 else if (reg2
== REG_TLBX
)
1368 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1369 else if (reg2
== REG_TLBLO
)
1370 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1371 else if (reg2
== REG_TLBHI
)
1372 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1373 else if (reg2
== REG_SHR
)
1374 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1375 else if (reg2
== REG_SLR
)
1376 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1377 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1378 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1380 as_fatal (_("invalid value for special purpose register"));
1381 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1382 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1383 output
= frag_more (isize
);
1386 case INST_TYPE_SPECIAL_R1
:
1387 if (strcmp (op_end
, ""))
1388 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1391 as_fatal (_("Error in statement syntax"));
1394 if (strcmp (op_end
, ""))
1395 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1398 as_fatal (_("Error in statement syntax"));
1402 if (reg1
== REG_MSR
)
1403 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1404 else if (reg1
== REG_PC
)
1405 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1406 else if (reg1
== REG_EAR
)
1407 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1408 else if (reg1
== REG_ESR
)
1409 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1410 else if (reg1
== REG_FSR
)
1411 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1412 else if (reg1
== REG_BTR
)
1413 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1414 else if (reg1
== REG_EDR
)
1415 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1416 else if (reg1
== REG_PID
)
1417 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1418 else if (reg1
== REG_ZPR
)
1419 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1420 else if (reg1
== REG_TLBX
)
1421 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1422 else if (reg1
== REG_TLBLO
)
1423 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1424 else if (reg1
== REG_TLBHI
)
1425 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1426 else if (reg1
== REG_TLBSX
)
1427 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1428 else if (reg1
== REG_SHR
)
1429 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1430 else if (reg1
== REG_SLR
)
1431 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1433 as_fatal (_("invalid value for special purpose register"));
1434 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1435 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1436 output
= frag_more (isize
);
1439 case INST_TYPE_R1_R2_SPECIAL
:
1440 if (strcmp (op_end
, ""))
1441 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1444 as_fatal (_("Error in statement syntax"));
1447 if (strcmp (op_end
, ""))
1448 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1451 as_fatal (_("Error in statement syntax"));
1455 /* Check for spl registers. */
1456 if (check_spl_reg (®1
))
1457 as_fatal (_("Cannot use special register with this instruction"));
1458 if (check_spl_reg (®2
))
1459 as_fatal (_("Cannot use special register with this instruction"));
1461 /* insn wic ra, rb => wic ra, ra, rb. */
1462 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1463 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1465 output
= frag_more (isize
);
1468 case INST_TYPE_RD_R2
:
1469 if (strcmp (op_end
, ""))
1470 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1473 as_fatal (_("Error in statement syntax"));
1476 if (strcmp (op_end
, ""))
1477 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1480 as_fatal (_("Error in statement syntax"));
1484 /* Check for spl registers. */
1485 if (check_spl_reg (®1
))
1486 as_fatal (_("Cannot use special register with this instruction"));
1487 if (check_spl_reg (®2
))
1488 as_fatal (_("Cannot use special register with this instruction"));
1490 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1491 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1492 output
= frag_more (isize
);
1495 case INST_TYPE_R1_IMM
:
1496 if (strcmp (op_end
, ""))
1497 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1500 as_fatal (_("Error in statement syntax"));
1503 if (strcmp (op_end
, ""))
1504 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1506 as_fatal (_("Error in statement syntax"));
1508 /* Check for spl registers. */
1509 if (check_spl_reg (®1
))
1510 as_fatal (_("Cannot use special register with this instruction"));
1512 if (exp
.X_op
!= O_constant
)
1515 relax_substateT subtype
;
1518 subtype
= get_imm_otype(exp
.X_md
);
1520 subtype
= opcode
->inst_offset_type
;
1522 output
= frag_var (rs_machine_dependent
,
1523 isize
* 2, /* maxm of 2 words. */
1524 isize
, /* minm of 1 word. */
1525 subtype
, /* PC-relative or not. */
1533 output
= frag_more (isize
);
1534 immed
= exp
.X_add_number
;
1537 temp
= immed
& 0xFFFF8000;
1538 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1540 /* Needs an immediate inst. */
1541 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1542 if (opcode1
== NULL
)
1544 as_bad (_("unknown opcode \"%s\""), "imm");
1548 inst1
= opcode1
->bit_sequence
;
1549 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1550 output
[0] = INST_BYTE0 (inst1
);
1551 output
[1] = INST_BYTE1 (inst1
);
1552 output
[2] = INST_BYTE2 (inst1
);
1553 output
[3] = INST_BYTE3 (inst1
);
1554 output
= frag_more (isize
);
1557 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1558 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1561 case INST_TYPE_RD_IMM
:
1562 if (strcmp (op_end
, ""))
1563 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1566 as_fatal (_("Error in statement syntax"));
1569 if (strcmp (op_end
, ""))
1570 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1572 as_fatal (_("Error in statement syntax"));
1574 /* Check for spl registers. */
1575 if (check_spl_reg (®1
))
1576 as_fatal (_("Cannot use special register with this instruction"));
1578 if (exp
.X_op
!= O_constant
)
1581 relax_substateT subtype
;
1584 subtype
= get_imm_otype(exp
.X_md
);
1586 subtype
= opcode
->inst_offset_type
;
1588 output
= frag_var (rs_machine_dependent
,
1589 isize
* 2, /* maxm of 2 words. */
1590 isize
, /* minm of 1 word. */
1591 subtype
, /* PC-relative or not. */
1599 output
= frag_more (isize
);
1600 immed
= exp
.X_add_number
;
1603 temp
= immed
& 0xFFFF8000;
1604 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1606 /* Needs an immediate inst. */
1607 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1608 if (opcode1
== NULL
)
1610 as_bad (_("unknown opcode \"%s\""), "imm");
1614 inst1
= opcode1
->bit_sequence
;
1615 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1616 output
[0] = INST_BYTE0 (inst1
);
1617 output
[1] = INST_BYTE1 (inst1
);
1618 output
[2] = INST_BYTE2 (inst1
);
1619 output
[3] = INST_BYTE3 (inst1
);
1620 output
= frag_more (isize
);
1623 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1624 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1628 if (strcmp (op_end
, ""))
1629 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1632 as_fatal (_("Error in statement syntax"));
1636 /* Check for spl registers. */
1637 if (check_spl_reg (®2
))
1638 as_fatal (_("Cannot use special register with this instruction"));
1640 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1641 output
= frag_more (isize
);
1645 if (streq (name
, "imm"))
1646 as_fatal (_("An IMM instruction should not be present in the .s file"));
1648 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1650 if (exp
.X_op
!= O_constant
)
1653 relax_substateT subtype
;
1656 subtype
= get_imm_otype(exp
.X_md
);
1658 subtype
= opcode
->inst_offset_type
;
1660 output
= frag_var (rs_machine_dependent
,
1661 isize
* 2, /* maxm of 2 words. */
1662 isize
, /* minm of 1 word. */
1663 subtype
, /* PC-relative or not. */
1671 output
= frag_more (isize
);
1672 immed
= exp
.X_add_number
;
1676 temp
= immed
& 0xFFFF8000;
1677 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1679 /* Needs an immediate inst. */
1680 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1681 if (opcode1
== NULL
)
1683 as_bad (_("unknown opcode \"%s\""), "imm");
1687 inst1
= opcode1
->bit_sequence
;
1688 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1689 output
[0] = INST_BYTE0 (inst1
);
1690 output
[1] = INST_BYTE1 (inst1
);
1691 output
[2] = INST_BYTE2 (inst1
);
1692 output
[3] = INST_BYTE3 (inst1
);
1693 output
= frag_more (isize
);
1695 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1698 case INST_TYPE_NONE
:
1699 output
= frag_more (isize
);
1702 case INST_TYPE_IMM5
:
1703 if (strcmp(op_end
, ""))
1704 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM5
, MAX_IMM5
);
1706 as_fatal(_("Error in statement syntax"));
1707 if (exp
.X_op
!= O_constant
) {
1708 as_warn(_("Symbol used as immediate for mbar instruction"));
1710 output
= frag_more (isize
);
1711 immed
= exp
.X_add_number
;
1713 if (immed
!= (immed
% 32)) {
1714 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1717 inst
|= (immed
<< IMM_MBAR
);
1721 as_fatal (_("unimplemented opcode \"%s\""), name
);
1724 /* Drop whitespace after all the operands have been parsed. */
1725 while (ISSPACE (* op_end
))
1728 /* Give warning message if the insn has more operands than required. */
1729 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1730 as_warn (_("ignoring operands: %s "), op_end
);
1732 output
[0] = INST_BYTE0 (inst
);
1733 output
[1] = INST_BYTE1 (inst
);
1734 output
[2] = INST_BYTE2 (inst
);
1735 output
[3] = INST_BYTE3 (inst
);
1738 dwarf2_emit_insn (4);
1743 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1748 /* Various routines to kill one day. */
1749 /* Equal to MAX_PRECISION in atof-ieee.c */
1750 #define MAX_LITTLENUMS 6
1752 /* Turn a string in input_line_pointer into a floating point constant of type
1753 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1754 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1756 md_atof (int type
, char * litP
, int * sizeP
)
1759 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1791 return _("Bad call to MD_NTOF()");
1794 t
= atof_ieee (input_line_pointer
, type
, words
);
1797 input_line_pointer
= t
;
1799 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1801 if (! target_big_endian
)
1803 for (i
= prec
- 1; i
>= 0; i
--)
1805 md_number_to_chars (litP
, (valueT
) words
[i
],
1806 sizeof (LITTLENUM_TYPE
));
1807 litP
+= sizeof (LITTLENUM_TYPE
);
1811 for (i
= 0; i
< prec
; i
++)
1813 md_number_to_chars (litP
, (valueT
) words
[i
],
1814 sizeof (LITTLENUM_TYPE
));
1815 litP
+= sizeof (LITTLENUM_TYPE
);
1821 const char * md_shortopts
= "";
1823 struct option md_longopts
[] =
1825 {"EB", no_argument
, NULL
, OPTION_EB
},
1826 {"EL", no_argument
, NULL
, OPTION_EL
},
1827 { NULL
, no_argument
, NULL
, 0}
1830 size_t md_longopts_size
= sizeof (md_longopts
);
1832 int md_short_jump_size
;
1835 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED
,
1836 addressT from_Nddr ATTRIBUTE_UNUSED
,
1837 addressT to_Nddr ATTRIBUTE_UNUSED
,
1838 fragS
* frag ATTRIBUTE_UNUSED
,
1839 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1841 as_fatal (_("failed sanity check: short_jump"));
1845 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED
,
1846 addressT from_Nddr ATTRIBUTE_UNUSED
,
1847 addressT to_Nddr ATTRIBUTE_UNUSED
,
1848 fragS
* frag ATTRIBUTE_UNUSED
,
1849 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1851 as_fatal (_("failed sanity check: long_jump"));
1854 /* Called after relaxing, change the frags so they know how big they are. */
1857 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1858 segT sec ATTRIBUTE_UNUSED
,
1863 switch (fragP
->fr_subtype
)
1865 case UNDEFINED_PC_OFFSET
:
1866 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1867 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1868 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1871 case DEFINED_ABS_SEGMENT
:
1872 if (fragP
->fr_symbol
== GOT_symbol
)
1873 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1874 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_GOTPC
);
1876 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1877 fragP
->fr_offset
, FALSE
, BFD_RELOC_64
);
1878 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1881 case DEFINED_RO_SEGMENT
:
1882 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1883 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_ROSDA
);
1884 fragP
->fr_fix
+= INST_WORD_SIZE
;
1887 case DEFINED_RW_SEGMENT
:
1888 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1889 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_RWSDA
);
1890 fragP
->fr_fix
+= INST_WORD_SIZE
;
1893 case DEFINED_PC_OFFSET
:
1894 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1895 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_32_LO_PCREL
);
1896 fragP
->fr_fix
+= INST_WORD_SIZE
;
1899 case LARGE_DEFINED_PC_OFFSET
:
1900 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1901 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1902 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1906 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1907 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOT
);
1908 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1912 fixP
= fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1913 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_PLT
);
1914 /* fixP->fx_plt = 1; */
1916 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1920 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1921 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOTOFF
);
1922 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1926 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1927 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSGD
);
1928 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1932 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1933 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSLD
);
1934 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1937 case TLSDTPREL_OFFSET
:
1938 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1939 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSDTPREL
);
1940 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1949 /* Applies the desired value to the specified location.
1950 Also sets up addends for 'rela' type relocations. */
1952 md_apply_fix (fixS
* fixP
,
1956 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1957 char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
1958 const char * symname
;
1959 /* Note: use offsetT because it is signed, valueT is unsigned. */
1960 offsetT val
= (offsetT
) * valp
;
1962 struct op_code_struct
* opcode1
;
1963 unsigned long inst1
;
1965 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
1967 /* fixP->fx_offset is supposed to be set up correctly for all
1968 symbol relocations. */
1969 if (fixP
->fx_addsy
== NULL
)
1971 if (!fixP
->fx_pcrel
)
1972 fixP
->fx_offset
= val
; /* Absolute relocation. */
1974 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1975 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
1978 /* If we aren't adjusting this fixup to be against the section
1979 symbol, we need to adjust the value. */
1980 if (fixP
->fx_addsy
!= NULL
)
1982 if (S_IS_WEAK (fixP
->fx_addsy
)
1983 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
1984 && (((bfd_get_section_flags (stdoutput
,
1985 S_GET_SEGMENT (fixP
->fx_addsy
))
1986 & SEC_LINK_ONCE
) != 0)
1987 || !strncmp (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
1989 sizeof (".gnu.linkonce") - 1))))
1991 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1992 if (val
!= 0 && ! fixP
->fx_pcrel
)
1994 /* In this case, the bfd_install_relocation routine will
1995 incorrectly add the symbol value back in. We just want
1996 the addend to appear in the object file.
1997 FIXME: If this makes VALUE zero, we're toast. */
1998 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2003 /* If the fix is relative to a symbol which is not defined, or not
2004 in the same segment as the fix, we cannot resolve it here. */
2005 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
2006 if (fixP
->fx_addsy
!= NULL
2007 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2008 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
2012 /* For ELF we can just return and let the reloc that will be generated
2013 take care of everything. For COFF we still have to insert 'val'
2014 into the insn since the addend field will be ignored. */
2018 /* All fixups in the text section must be handled in the linker. */
2019 else if (segment
->flags
& SEC_CODE
)
2021 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
2026 switch (fixP
->fx_r_type
)
2028 case BFD_RELOC_MICROBLAZE_32_LO
:
2029 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2030 if (target_big_endian
)
2032 buf
[2] |= ((val
>> 8) & 0xff);
2033 buf
[3] |= (val
& 0xff);
2037 buf
[1] |= ((val
>> 8) & 0xff);
2038 buf
[0] |= (val
& 0xff);
2041 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2042 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2043 /* Don't do anything if the symbol is not defined. */
2044 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2046 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
2047 as_bad_where (file
, fixP
->fx_line
,
2048 _("pcrel for branch to %s too far (0x%x)"),
2049 symname
, (int) val
);
2050 if (target_big_endian
)
2052 buf
[2] |= ((val
>> 8) & 0xff);
2053 buf
[3] |= (val
& 0xff);
2057 buf
[1] |= ((val
>> 8) & 0xff);
2058 buf
[0] |= (val
& 0xff);
2064 case BFD_RELOC_32_PCREL
:
2065 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2066 /* Don't do anything if the symbol is not defined. */
2067 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2069 if (target_big_endian
)
2071 buf
[0] |= ((val
>> 24) & 0xff);
2072 buf
[1] |= ((val
>> 16) & 0xff);
2073 buf
[2] |= ((val
>> 8) & 0xff);
2074 buf
[3] |= (val
& 0xff);
2078 buf
[3] |= ((val
>> 24) & 0xff);
2079 buf
[2] |= ((val
>> 16) & 0xff);
2080 buf
[1] |= ((val
>> 8) & 0xff);
2081 buf
[0] |= (val
& 0xff);
2085 case BFD_RELOC_64_PCREL
:
2087 /* Add an imm instruction. First save the current instruction. */
2088 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2089 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2091 /* Generate the imm instruction. */
2092 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2093 if (opcode1
== NULL
)
2095 as_bad (_("unknown opcode \"%s\""), "imm");
2099 inst1
= opcode1
->bit_sequence
;
2100 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2101 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
2103 buf
[0] = INST_BYTE0 (inst1
);
2104 buf
[1] = INST_BYTE1 (inst1
);
2105 buf
[2] = INST_BYTE2 (inst1
);
2106 buf
[3] = INST_BYTE3 (inst1
);
2108 /* Add the value only if the symbol is defined. */
2109 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2111 if (target_big_endian
)
2113 buf
[6] |= ((val
>> 8) & 0xff);
2114 buf
[7] |= (val
& 0xff);
2118 buf
[5] |= ((val
>> 8) & 0xff);
2119 buf
[4] |= (val
& 0xff);
2124 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2125 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2126 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2127 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2129 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2130 case BFD_RELOC_MICROBLAZE_64_GOT
:
2131 case BFD_RELOC_MICROBLAZE_64_PLT
:
2132 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2133 /* Add an imm instruction. First save the current instruction. */
2134 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2135 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2137 /* Generate the imm instruction. */
2138 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2139 if (opcode1
== NULL
)
2141 as_bad (_("unknown opcode \"%s\""), "imm");
2145 inst1
= opcode1
->bit_sequence
;
2147 /* We can fixup call to a defined non-global address
2148 within the same section only. */
2149 buf
[0] = INST_BYTE0 (inst1
);
2150 buf
[1] = INST_BYTE1 (inst1
);
2151 buf
[2] = INST_BYTE2 (inst1
);
2152 buf
[3] = INST_BYTE3 (inst1
);
2159 if (fixP
->fx_addsy
== NULL
)
2161 /* This fixup has been resolved. Create a reloc in case the linker
2162 moves code around due to relaxing. */
2163 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2164 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2166 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2167 fixP
->fx_addsy
= section_symbol (absolute_section
);
2173 md_operand (expressionS
* expressionP
)
2175 /* Ignore leading hash symbol, if present. */
2176 if (*input_line_pointer
== '#')
2178 input_line_pointer
++;
2179 expression (expressionP
);
2183 /* Called just before address relaxation, return the length
2184 by which a fragment must grow to reach it's destination. */
2187 md_estimate_size_before_relax (fragS
* fragP
,
2190 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2191 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2192 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2193 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2195 switch (fragP
->fr_subtype
)
2197 case INST_PC_OFFSET
:
2198 /* Used to be a PC-relative branch. */
2199 if (!fragP
->fr_symbol
)
2201 /* We know the abs value: Should never happen. */
2202 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2205 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
&&
2206 !S_IS_WEAK (fragP
->fr_symbol
))
2208 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2209 /* Don't know now whether we need an imm instruction. */
2210 fragP
->fr_var
= INST_WORD_SIZE
;
2212 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2213 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2215 /* Cannot have a PC-relative branch to a diff segment. */
2216 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2217 S_GET_NAME (fragP
->fr_symbol
));
2218 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2219 fragP
->fr_var
= INST_WORD_SIZE
*2;
2223 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2224 fragP
->fr_var
= INST_WORD_SIZE
*2;
2228 case INST_NO_OFFSET
:
2229 /* Used to be a reference to somewhere which was unknown. */
2230 if (fragP
->fr_symbol
)
2232 if (fragP
->fr_opcode
== NULL
)
2234 /* Used as an absolute value. */
2235 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2236 /* Variable part does not change. */
2237 fragP
->fr_var
= INST_WORD_SIZE
*2;
2239 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2241 /* It is accessed using the small data read only anchor. */
2242 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2243 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2244 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2245 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2247 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2248 fragP
->fr_var
= INST_WORD_SIZE
;
2252 /* Variable not in small data read only segment accessed
2253 using small data read only anchor. */
2254 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2256 as_bad_where (file
, fragP
->fr_line
,
2257 _("Variable is accessed using small data read "
2258 "only anchor, but it is not in the small data "
2259 "read only section"));
2260 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2261 fragP
->fr_var
= INST_WORD_SIZE
;
2264 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2266 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2267 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2268 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2269 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2271 /* It is accessed using the small data read write anchor. */
2272 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2273 fragP
->fr_var
= INST_WORD_SIZE
;
2277 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2279 as_bad_where (file
, fragP
->fr_line
,
2280 _("Variable is accessed using small data read "
2281 "write anchor, but it is not in the small data "
2282 "read write section"));
2283 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2284 fragP
->fr_var
= INST_WORD_SIZE
;
2289 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2295 /* We know the abs value: Should never happen. */
2296 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2301 case UNDEFINED_PC_OFFSET
:
2302 case LARGE_DEFINED_PC_OFFSET
:
2303 case DEFINED_ABS_SEGMENT
:
2309 case TLSTPREL_OFFSET
:
2310 case TLSDTPREL_OFFSET
:
2311 fragP
->fr_var
= INST_WORD_SIZE
*2;
2313 case DEFINED_RO_SEGMENT
:
2314 case DEFINED_RW_SEGMENT
:
2315 case DEFINED_PC_OFFSET
:
2316 case TLSDTPMOD_OFFSET
:
2317 fragP
->fr_var
= INST_WORD_SIZE
;
2323 return fragP
->fr_var
;
2326 /* Put number into target byte order. */
2329 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2331 if (target_big_endian
)
2332 number_to_chars_bigendian (ptr
, use
, nbytes
);
2334 number_to_chars_littleendian (ptr
, use
, nbytes
);
2337 /* Round up a section size to the appropriate boundary. */
2340 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2342 return size
; /* Byte alignment is fine. */
2346 /* The location from which a PC relative jump should be calculated,
2347 given a PC relative reloc. */
2350 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2353 /* If the symbol is undefined or defined in another section
2354 we leave the add number alone for the linker to fix it later.
2355 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2357 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2358 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2359 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2363 /* The case where we are going to resolve things... */
2364 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2365 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2367 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2373 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2374 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2377 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2380 bfd_reloc_code_real_type code
;
2382 switch (fixp
->fx_r_type
)
2384 case BFD_RELOC_NONE
:
2385 case BFD_RELOC_MICROBLAZE_64_NONE
:
2387 case BFD_RELOC_MICROBLAZE_32_LO
:
2388 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2391 case BFD_RELOC_64_PCREL
:
2392 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2393 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2394 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2395 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2396 case BFD_RELOC_MICROBLAZE_64_GOT
:
2397 case BFD_RELOC_MICROBLAZE_64_PLT
:
2398 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2399 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2400 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2401 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2402 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
2403 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
2404 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2405 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
2406 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
2407 code
= fixp
->fx_r_type
;
2411 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2413 MAP (1, 0, BFD_RELOC_8
);
2414 MAP (2, 0, BFD_RELOC_16
);
2415 MAP (4, 0, BFD_RELOC_32
);
2416 MAP (1, 1, BFD_RELOC_8_PCREL
);
2417 MAP (2, 1, BFD_RELOC_16_PCREL
);
2418 MAP (4, 1, BFD_RELOC_32_PCREL
);
2420 code
= fixp
->fx_r_type
;
2421 as_bad (_("Can not do %d byte %srelocation"),
2423 fixp
->fx_pcrel
? _("pc-relative") : "");
2428 rel
= (arelent
*) xmalloc (sizeof (arelent
));
2429 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2431 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2432 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2434 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2436 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2437 /* Always pass the addend along! */
2438 rel
->addend
= fixp
->fx_offset
;
2439 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2441 if (rel
->howto
== NULL
)
2443 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2444 _("Cannot represent relocation type %s"),
2445 bfd_get_reloc_code_name (code
));
2447 /* Set howto to a garbage value so that we can keep going. */
2448 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2449 gas_assert (rel
->howto
!= NULL
);
2455 md_parse_option (int c
, char * arg ATTRIBUTE_UNUSED
)
2460 target_big_endian
= 1;
2463 target_big_endian
= 0;
2472 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2474 /* fprintf(stream, _("\
2475 MicroBlaze options:\n\
2476 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2480 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2481 found a machine specific op in an expression,
2482 then we create relocs accordingly. */
2485 cons_fix_new_microblaze (fragS
* frag
,
2491 bfd_reloc_code_real_type r
;
2493 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2494 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2495 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2496 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2497 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2499 exp
->X_op
= O_symbol
;
2500 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2519 as_bad (_("unsupported BFD relocation size %u"), size
);
2524 fix_new_exp (frag
, where
, size
, exp
, 0, r
);