1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright (C) 2009-2016 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
27 #include "../opcodes/microblaze-opc.h"
28 #include "../opcodes/microblaze-opcm.h"
29 #include "safe-ctype.h"
31 #include <dwarf2dbg.h>
32 #include "aout/stab_gnu.h"
35 #define streq(a,b) (strcmp (a, b) == 0)
38 #define OPTION_EB (OPTION_MD_BASE + 0)
39 #define OPTION_EL (OPTION_MD_BASE + 1)
41 void microblaze_generate_symbol (char *sym
);
42 static bfd_boolean
check_spl_reg (unsigned *);
44 /* Several places in this file insert raw instructions into the
45 object. They should generate the instruction
46 and then use these four macros to crack the instruction value into
47 the appropriate byte values. */
48 #define INST_BYTE0(x) (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF))
49 #define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
50 #define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
51 #define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
53 /* This array holds the chars that always start a comment. If the
54 pre-processor is disabled, these aren't very useful. */
55 const char comment_chars
[] = "#";
57 const char line_separator_chars
[] = ";";
59 /* This array holds the chars that only start a comment at the beginning of
61 const char line_comment_chars
[] = "#";
63 const int md_reloc_size
= 8; /* Size of relocation record. */
65 /* Chars that can be used to separate mant
66 from exp in floating point numbers. */
67 const char EXP_CHARS
[] = "eE";
69 /* Chars that mean this number is a floating point constant
72 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
74 /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1. */
75 #define UNDEFINED_PC_OFFSET 2
76 #define DEFINED_ABS_SEGMENT 3
77 #define DEFINED_PC_OFFSET 4
78 #define DEFINED_RO_SEGMENT 5
79 #define DEFINED_RW_SEGMENT 6
80 #define LARGE_DEFINED_PC_OFFSET 7
83 #define GOTOFF_OFFSET 10
84 #define TLSGD_OFFSET 11
85 #define TLSLD_OFFSET 12
86 #define TLSDTPMOD_OFFSET 13
87 #define TLSDTPREL_OFFSET 14
88 #define TLSGOTTPREL_OFFSET 15
89 #define TLSTPREL_OFFSET 16
91 /* Initialize the relax table. */
92 const relax_typeS md_relax_table
[] =
94 { 1, 1, 0, 0 }, /* 0: Unused. */
95 { 1, 1, 0, 0 }, /* 1: Unused. */
96 { 1, 1, 0, 0 }, /* 2: Unused. */
97 { 1, 1, 0, 0 }, /* 3: Unused. */
98 { 32767, -32768, INST_WORD_SIZE
, LARGE_DEFINED_PC_OFFSET
}, /* 4: DEFINED_PC_OFFSET. */
99 { 1, 1, 0, 0 }, /* 5: Unused. */
100 { 1, 1, 0, 0 }, /* 6: Unused. */
101 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
102 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 8: GOT_OFFSET. */
103 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 9: PLT_OFFSET. */
104 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 10: GOTOFF_OFFSET. */
105 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 11: TLSGD_OFFSET. */
106 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 12: TLSLD_OFFSET. */
107 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */
108 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 14: TLSDTPREL_OFFSET. */
109 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
110 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 } /* 16: TLSTPREL_OFFSET. */
113 static struct hash_control
* opcode_hash_control
; /* Opcode mnemonics. */
115 static segT sbss_segment
= 0; /* Small bss section. */
116 static segT sbss2_segment
= 0; /* Section not used. */
117 static segT sdata_segment
= 0; /* Small data section. */
118 static segT sdata2_segment
= 0; /* Small read-only section. */
119 static segT rodata_segment
= 0; /* read-only section. */
121 /* Generate a symbol for stabs information. */
124 microblaze_generate_symbol (char *sym
)
126 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
127 static int microblaze_label_count
;
128 sprintf (sym
, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME
, microblaze_label_count
);
129 ++microblaze_label_count
;
132 /* Handle the section changing pseudo-ops. */
135 microblaze_s_text (int ignore ATTRIBUTE_UNUSED
)
138 obj_elf_text (ignore
);
145 microblaze_s_data (int ignore ATTRIBUTE_UNUSED
)
148 obj_elf_change_section (".data", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
154 /* Things in the .sdata segment are always considered to be in the small data section. */
157 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED
)
160 obj_elf_change_section (".sdata", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
166 /* Pseudo op to make file scope bss items. */
169 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED
)
179 segT current_seg
= now_seg
;
180 subsegT current_subseg
= now_subseg
;
182 c
= get_symbol_name (&name
);
184 /* Just after name is now '\0'. */
185 p
= input_line_pointer
;
186 (void) restore_line_pointer (c
);
188 if (*input_line_pointer
!= ',')
190 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
191 ignore_rest_of_line ();
195 input_line_pointer
++; /* skip ',' */
196 if ((size
= get_absolute_expression ()) < 0)
198 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size
);
199 ignore_rest_of_line ();
203 /* The third argument to .lcomm is the alignment. */
204 if (*input_line_pointer
!= ',')
208 ++input_line_pointer
;
209 align
= get_absolute_expression ();
212 as_warn (_("ignoring bad alignment"));
218 symbolP
= symbol_find_or_make (name
);
221 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
223 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
224 S_GET_NAME (symbolP
));
225 ignore_rest_of_line ();
229 if (S_GET_VALUE (symbolP
) && S_GET_VALUE (symbolP
) != (valueT
) size
)
231 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
232 S_GET_NAME (symbolP
),
233 (long) S_GET_VALUE (symbolP
),
236 ignore_rest_of_line ();
243 /* Convert to a power of 2 alignment. */
244 for (align2
= 0; (align
& 1) == 0; align
>>= 1, ++align2
);
247 as_bad (_("Common alignment not a power of 2"));
248 ignore_rest_of_line ();
255 record_alignment (current_seg
, align2
);
256 subseg_set (current_seg
, current_subseg
);
258 frag_align (align2
, 0, 0);
259 if (S_GET_SEGMENT (symbolP
) == current_seg
)
260 symbol_get_frag (symbolP
)->fr_symbol
= 0;
261 symbol_set_frag (symbolP
, frag_now
);
262 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
265 S_SET_SIZE (symbolP
, size
);
266 S_SET_SEGMENT (symbolP
, current_seg
);
267 subseg_set (current_seg
, current_subseg
);
268 demand_empty_rest_of_line ();
272 microblaze_s_rdata (int localvar
)
278 obj_elf_change_section (".rodata", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
279 if (rodata_segment
== 0)
280 rodata_segment
= subseg_new (".rodata", 0);
285 obj_elf_change_section (".sdata2", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
293 microblaze_s_bss (int localvar
)
296 if (localvar
== 0) /* bss. */
297 obj_elf_change_section (".bss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
298 else if (localvar
== 1)
301 obj_elf_change_section (".sbss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
302 if (sbss_segment
== 0)
303 sbss_segment
= subseg_new (".sbss", 0);
310 /* endp_p is always 1 as this func is called only for .end <funcname>
311 This func consumes the <funcname> and calls regular processing
312 s_func(1) with arg 1 (1 for end). */
315 microblaze_s_func (int end_p ATTRIBUTE_UNUSED
)
318 restore_line_pointer (get_symbol_name (&name
));
322 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
325 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED
)
332 c
= get_symbol_name (&name
);
333 symbolP
= symbol_find_or_make (name
);
334 S_SET_WEAK (symbolP
);
335 (void) restore_line_pointer (c
);
339 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
341 if (S_IS_DEFINED (symbolP
))
343 as_bad ("Ignoring attempt to redefine symbol `%s'.",
344 S_GET_NAME (symbolP
));
345 ignore_rest_of_line ();
349 if (*input_line_pointer
== ',')
351 ++input_line_pointer
;
356 if (exp
.X_op
!= O_symbol
)
358 as_bad ("bad .weakext directive");
359 ignore_rest_of_line ();
362 symbol_set_value_expression (symbolP
, &exp
);
365 demand_empty_rest_of_line ();
368 /* This table describes all the machine specific pseudo-ops the assembler
369 has to support. The fields are:
370 Pseudo-op name without dot
371 Function to call to execute this pseudo-op
372 Integer arg to pass to the function. */
373 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
374 and then in the read.c table. */
375 const pseudo_typeS md_pseudo_table
[] =
377 {"lcomm", microblaze_s_lcomm
, 1},
378 {"data", microblaze_s_data
, 0},
379 {"data8", cons
, 1}, /* Same as byte. */
380 {"data16", cons
, 2}, /* Same as hword. */
381 {"data32", cons
, 4}, /* Same as word. */
382 {"ent", s_func
, 0}, /* Treat ent as function entry point. */
383 {"end", microblaze_s_func
, 1}, /* Treat end as function end point. */
384 {"gpword", s_rva
, 4}, /* gpword label => store resolved label address in data section. */
385 {"weakext", microblaze_s_weakext
, 0},
386 {"rodata", microblaze_s_rdata
, 0},
387 {"sdata2", microblaze_s_rdata
, 1},
388 {"sdata", microblaze_s_sdata
, 0},
389 {"bss", microblaze_s_bss
, 0},
390 {"sbss", microblaze_s_bss
, 1},
391 {"text", microblaze_s_text
, 0},
393 {"frame", s_ignore
, 0},
394 {"mask", s_ignore
, 0}, /* Emitted by gcc. */
398 /* This function is called once, at assembler startup time. This should
399 set up all the tables, etc that the MD part of the assembler needs. */
404 struct op_code_struct
* opcode
;
406 opcode_hash_control
= hash_new ();
408 /* Insert unique names into hash table. */
409 for (opcode
= opcodes
; opcode
->name
; opcode
++)
410 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
413 /* Try to parse a reg name. */
416 parse_reg (char * s
, unsigned * reg
)
420 /* Strip leading whitespace. */
421 while (ISSPACE (* s
))
424 if (strncasecmp (s
, "rpc", 3) == 0)
429 else if (strncasecmp (s
, "rmsr", 4) == 0)
434 else if (strncasecmp (s
, "rear", 4) == 0)
439 else if (strncasecmp (s
, "resr", 4) == 0)
444 else if (strncasecmp (s
, "rfsr", 4) == 0)
449 else if (strncasecmp (s
, "rbtr", 4) == 0)
454 else if (strncasecmp (s
, "redr", 4) == 0)
459 /* MMU registers start. */
460 else if (strncasecmp (s
, "rpid", 4) == 0)
465 else if (strncasecmp (s
, "rzpr", 4) == 0)
470 else if (strncasecmp (s
, "rtlbx", 5) == 0)
475 else if (strncasecmp (s
, "rtlblo", 6) == 0)
480 else if (strncasecmp (s
, "rtlbhi", 6) == 0)
485 else if (strncasecmp (s
, "rtlbsx", 6) == 0)
490 /* MMU registers end. */
491 else if (strncasecmp (s
, "rpvr", 4) == 0)
493 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
495 tmpreg
= (s
[4]-'0')*10 + s
[5] - '0';
499 else if (ISDIGIT (s
[4]))
505 as_bad (_("register expected, but saw '%.6s'"), s
);
506 if ((int) tmpreg
>= MIN_PVR_REGNUM
&& tmpreg
<= MAX_PVR_REGNUM
)
507 *reg
= REG_PVR
+ tmpreg
;
510 as_bad (_("Invalid register number at '%.6s'"), s
);
515 else if (strncasecmp (s
, "rsp", 3) == 0)
520 else if (strncasecmp (s
, "rfsl", 4) == 0)
522 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
524 tmpreg
= (s
[4] - '0') * 10 + s
[5] - '0';
527 else if (ISDIGIT (s
[4]))
533 as_bad (_("register expected, but saw '%.6s'"), s
);
535 if ((int) tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
539 as_bad (_("Invalid register number at '%.6s'"), s
);
544 /* Stack protection registers. */
545 else if (strncasecmp (s
, "rshr", 4) == 0)
550 else if (strncasecmp (s
, "rslr", 4) == 0)
557 if (TOLOWER (s
[0]) == 'r')
559 if (ISDIGIT (s
[1]) && ISDIGIT (s
[2]))
561 tmpreg
= (s
[1] - '0') * 10 + s
[2] - '0';
564 else if (ISDIGIT (s
[1]))
570 as_bad (_("register expected, but saw '%.6s'"), s
);
572 if ((int)tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
576 as_bad (_("Invalid register number at '%.6s'"), s
);
582 as_bad (_("register expected, but saw '%.6s'"), s
);
588 parse_exp (char *s
, expressionS
*e
)
593 /* Skip whitespace. */
594 while (ISSPACE (* s
))
597 save
= input_line_pointer
;
598 input_line_pointer
= s
;
602 if (e
->X_op
== O_absent
)
603 as_fatal (_("missing operand"));
605 new_pointer
= input_line_pointer
;
606 input_line_pointer
= save
;
611 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
618 #define IMM_TLSDTPMOD 6
619 #define IMM_TLSDTPREL 7
620 #define IMM_TLSTPREL 8
624 const char *isuffix
; /* Suffix String */
625 int itype
; /* Suffix Type */
626 int otype
; /* Offset Type */
629 /* These are NOT in assending order of type, GOTOFF is ahead to make
630 sure @GOTOFF does not get matched with @GOT */
631 static struct imm_type imm_types
[] = {
632 { "NONE", IMM_NONE
, 0 },
633 { "GOTOFF", IMM_GOTOFF
, GOTOFF_OFFSET
},
634 { "GOT", IMM_GOT
, GOT_OFFSET
},
635 { "PLT", IMM_PLT
, PLT_OFFSET
},
636 { "TLSGD", IMM_TLSGD
, TLSGD_OFFSET
},
637 { "TLSLDM", IMM_TLSLD
, TLSLD_OFFSET
},
638 { "TLSDTPMOD", IMM_TLSDTPMOD
, TLSDTPMOD_OFFSET
},
639 { "TLSDTPREL", IMM_TLSDTPREL
, TLSDTPREL_OFFSET
},
640 { "TLSTPREL", IMM_TLSTPREL
, TLSTPREL_OFFSET
}
644 match_imm (const char *s
, int *ilen
)
649 /* Check for matching suffix */
650 for (i
= 1; i
< IMM_MAX
; i
++)
652 slen
= strlen (imm_types
[i
].isuffix
);
654 if (strncmp (imm_types
[i
].isuffix
, s
, slen
) == 0)
657 return imm_types
[i
].itype
;
665 get_imm_otype (int itype
)
670 /* Check for matching itype */
671 for (i
= 1; i
< IMM_MAX
; i
++)
673 if (imm_types
[i
].itype
== itype
)
675 otype
= imm_types
[i
].otype
;
682 static symbolS
* GOT_symbol
;
684 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
687 parse_imm (char * s
, expressionS
* e
, offsetT min
, offsetT max
)
695 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
696 for (atp
= s
; *atp
!= '@'; atp
++)
697 if (is_end_of_line
[(unsigned char) *atp
])
702 itype
= match_imm (atp
+ 1, &ilen
);
722 if (atp
&& !GOT_symbol
)
724 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
727 new_pointer
= parse_exp (s
, e
);
729 if (!GOT_symbol
&& ! strncmp (s
, GOT_SYMBOL_NAME
, 20))
731 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
734 if (e
->X_op
== O_absent
)
735 ; /* An error message has already been emitted. */
736 else if ((e
->X_op
!= O_constant
&& e
->X_op
!= O_symbol
) )
737 as_fatal (_("operand must be a constant or a label"));
738 else if (e
->X_op
== O_constant
)
740 /* Special case: sign extend negative 32-bit values to offsetT size. */
741 if ((e
->X_add_number
>> 31) == 1)
742 e
->X_add_number
|= -((addressT
) (1U << 31));
744 if (e
->X_add_number
< min
|| e
->X_add_number
> max
)
746 as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"),
747 (long) min
, (long) max
, (long) e
->X_add_number
);
753 *atp
= '@'; /* restore back (needed?) */
754 if (new_pointer
>= atp
)
755 new_pointer
+= ilen
+ 1; /* sizeof (imm_suffix) + 1 for '@' */
761 check_got (int * got_type
, int * got_len
)
769 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
770 for (atp
= input_line_pointer
; *atp
!= '@'; atp
++)
771 if (is_end_of_line
[(unsigned char) *atp
])
774 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
777 *got_type
= IMM_GOTOFF
;
779 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
784 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
793 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
795 first
= atp
- input_line_pointer
;
797 past_got
= atp
+ *got_len
+ 1;
798 for (new_pointer
= past_got
; !is_end_of_line
[(unsigned char) *new_pointer
++];)
800 second
= new_pointer
- past_got
;
801 /* One extra byte for ' ' and one for NUL. */
802 tmpbuf
= XNEWVEC (char, first
+ second
+ 2);
803 memcpy (tmpbuf
, input_line_pointer
, first
);
804 tmpbuf
[first
] = ' '; /* @GOTOFF is replaced with a single space. */
805 memcpy (tmpbuf
+ first
+ 1, past_got
, second
);
806 tmpbuf
[first
+ second
+ 1] = '\0';
811 extern bfd_reloc_code_real_type
812 parse_cons_expression_microblaze (expressionS
*exp
, int size
)
816 /* Handle @GOTOFF et.al. */
817 char *save
, *gotfree_copy
;
818 int got_len
, got_type
;
820 save
= input_line_pointer
;
821 gotfree_copy
= check_got (& got_type
, & got_len
);
823 input_line_pointer
= gotfree_copy
;
829 exp
->X_md
= got_type
;
830 input_line_pointer
= save
+ (input_line_pointer
- gotfree_copy
)
837 return BFD_RELOC_NONE
;
840 /* This is the guts of the machine-dependent assembler. STR points to a
841 machine dependent instruction. This function is supposed to emit
842 the frags/bytes it assembles to. */
844 static const char * str_microblaze_ro_anchor
= "RO";
845 static const char * str_microblaze_rw_anchor
= "RW";
848 check_spl_reg (unsigned * reg
)
850 if ((*reg
== REG_MSR
) || (*reg
== REG_PC
)
851 || (*reg
== REG_EAR
) || (*reg
== REG_ESR
)
852 || (*reg
== REG_FSR
) || (*reg
== REG_BTR
) || (*reg
== REG_EDR
)
853 || (*reg
== REG_PID
) || (*reg
== REG_ZPR
)
854 || (*reg
== REG_TLBX
) || (*reg
== REG_TLBLO
)
855 || (*reg
== REG_TLBHI
) || (*reg
== REG_TLBSX
)
856 || (*reg
== REG_SHR
) || (*reg
== REG_SLR
)
857 || (*reg
>= REG_PVR
+MIN_PVR_REGNUM
&& *reg
<= REG_PVR
+MAX_PVR_REGNUM
))
863 /* Here we decide which fixups can be adjusted to make them relative to
864 the beginning of the section instead of the symbol. Basically we need
865 to make sure that the dynamic relocations are done correctly, so in
866 some cases we force the original symbol to be used. */
869 tc_microblaze_fix_adjustable (struct fix
*fixP
)
871 if (GOT_symbol
&& fixP
->fx_subsy
== GOT_symbol
)
874 if (fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOTOFF
875 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_GOTOFF
876 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOT
877 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_PLT
878 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGD
879 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSLD
880 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
881 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPREL
882 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSDTPREL
883 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
884 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSTPREL
)
891 md_assemble (char * str
)
895 struct op_code_struct
* opcode
, *opcode1
;
896 char * output
= NULL
;
899 unsigned long inst
, inst1
;
904 unsigned int immed
, temp
;
908 /* Drop leading whitespace. */
909 while (ISSPACE (* str
))
912 /* Find the op code end. */
913 for (op_start
= op_end
= str
;
914 *op_end
&& !is_end_of_line
[(unsigned char) *op_end
] && *op_end
!= ' ';
917 name
[nlen
] = op_start
[nlen
];
919 if (nlen
== sizeof (name
) - 1)
927 as_bad (_("can't find opcode "));
931 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, name
);
934 as_bad (_("unknown opcode \"%s\""), name
);
938 inst
= opcode
->bit_sequence
;
941 switch (opcode
->inst_type
)
943 case INST_TYPE_RD_R1_R2
:
944 if (strcmp (op_end
, ""))
945 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
948 as_fatal (_("Error in statement syntax"));
951 if (strcmp (op_end
, ""))
952 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
955 as_fatal (_("Error in statement syntax"));
958 if (strcmp (op_end
, ""))
959 op_end
= parse_reg (op_end
+ 1, ®3
); /* Get r2. */
962 as_fatal (_("Error in statement syntax"));
966 /* Check for spl registers. */
967 if (check_spl_reg (& reg1
))
968 as_fatal (_("Cannot use special register with this instruction"));
969 if (check_spl_reg (& reg2
))
970 as_fatal (_("Cannot use special register with this instruction"));
971 if (check_spl_reg (& reg3
))
972 as_fatal (_("Cannot use special register with this instruction"));
974 if (streq (name
, "sub"))
976 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
977 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
978 inst
|= (reg3
<< RA_LOW
) & RA_MASK
;
979 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
983 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
984 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
985 inst
|= (reg3
<< RB_LOW
) & RB_MASK
;
987 output
= frag_more (isize
);
990 case INST_TYPE_RD_R1_IMM
:
991 if (strcmp (op_end
, ""))
992 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
995 as_fatal (_("Error in statement syntax"));
998 if (strcmp (op_end
, ""))
999 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1002 as_fatal (_("Error in statement syntax"));
1005 if (strcmp (op_end
, ""))
1006 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1008 as_fatal (_("Error in statement syntax"));
1010 /* Check for spl registers. */
1011 if (check_spl_reg (& reg1
))
1012 as_fatal (_("Cannot use special register with this instruction"));
1013 if (check_spl_reg (& reg2
))
1014 as_fatal (_("Cannot use special register with this instruction"));
1016 if (exp
.X_op
!= O_constant
)
1019 relax_substateT subtype
;
1021 if (streq (name
, "lmi"))
1022 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
1023 else if (streq (name
, "smi"))
1024 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
1026 if (reg2
== REG_ROSDP
)
1027 opc
= str_microblaze_ro_anchor
;
1028 else if (reg2
== REG_RWSDP
)
1029 opc
= str_microblaze_rw_anchor
;
1033 subtype
= get_imm_otype(exp
.X_md
);
1035 subtype
= opcode
->inst_offset_type
;
1037 output
= frag_var (rs_machine_dependent
,
1038 isize
* 2, /* maxm of 2 words. */
1039 isize
, /* minm of 1 word. */
1040 subtype
, /* PC-relative or not. */
1048 output
= frag_more (isize
);
1049 immed
= exp
.X_add_number
;
1052 if (streq (name
, "lmi") || streq (name
, "smi"))
1054 /* Load/store 32-d consecutive registers. Used on exit/entry
1055 to subroutines to save and restore registers to stack.
1056 Generate 32-d insts. */
1060 if (streq (name
, "lmi"))
1061 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "lwi");
1063 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "swi");
1066 as_bad (_("unknown opcode \"%s\""), "lwi");
1069 inst
= opcode
->bit_sequence
;
1070 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1071 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1072 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1074 for (i
= 0; i
< count
- 1; i
++)
1076 output
[0] = INST_BYTE0 (inst
);
1077 output
[1] = INST_BYTE1 (inst
);
1078 output
[2] = INST_BYTE2 (inst
);
1079 output
[3] = INST_BYTE3 (inst
);
1080 output
= frag_more (isize
);
1083 inst
= opcode
->bit_sequence
;
1084 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1085 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1086 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1091 temp
= immed
& 0xFFFF8000;
1092 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1094 /* Needs an immediate inst. */
1095 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1096 if (opcode1
== NULL
)
1098 as_bad (_("unknown opcode \"%s\""), "imm");
1102 inst1
= opcode1
->bit_sequence
;
1103 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1104 output
[0] = INST_BYTE0 (inst1
);
1105 output
[1] = INST_BYTE1 (inst1
);
1106 output
[2] = INST_BYTE2 (inst1
);
1107 output
[3] = INST_BYTE3 (inst1
);
1108 output
= frag_more (isize
);
1110 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1111 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1112 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1116 case INST_TYPE_RD_R1_IMM5
:
1117 if (strcmp (op_end
, ""))
1118 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1121 as_fatal (_("Error in statement syntax"));
1124 if (strcmp (op_end
, ""))
1125 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1128 as_fatal (_("Error in statement syntax"));
1131 if (strcmp (op_end
, ""))
1132 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1134 as_fatal (_("Error in statement syntax"));
1136 /* Check for spl registers. */
1137 if (check_spl_reg (®1
))
1138 as_fatal (_("Cannot use special register with this instruction"));
1139 if (check_spl_reg (®2
))
1140 as_fatal (_("Cannot use special register with this instruction"));
1142 if (exp
.X_op
!= O_constant
)
1143 as_warn (_("Symbol used as immediate for shift instruction"));
1146 output
= frag_more (isize
);
1147 immed
= exp
.X_add_number
;
1150 if (immed
!= (immed
% 32))
1152 as_warn (_("Shift value > 32. using <value %% 32>"));
1155 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1156 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1157 inst
|= (immed
<< IMM_LOW
) & IMM5_MASK
;
1160 case INST_TYPE_R1_R2
:
1161 if (strcmp (op_end
, ""))
1162 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1165 as_fatal (_("Error in statement syntax"));
1168 if (strcmp (op_end
, ""))
1169 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1172 as_fatal (_("Error in statement syntax"));
1176 /* Check for spl registers. */
1177 if (check_spl_reg (& reg1
))
1178 as_fatal (_("Cannot use special register with this instruction"));
1179 if (check_spl_reg (& reg2
))
1180 as_fatal (_("Cannot use special register with this instruction"));
1182 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1183 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1184 output
= frag_more (isize
);
1187 case INST_TYPE_RD_R1
:
1188 if (strcmp (op_end
, ""))
1189 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1192 as_fatal (_("Error in statement syntax"));
1195 if (strcmp (op_end
, ""))
1196 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1199 as_fatal (_("Error in statement syntax"));
1203 /* Check for spl registers. */
1204 if (check_spl_reg (®1
))
1205 as_fatal (_("Cannot use special register with this instruction"));
1206 if (check_spl_reg (®2
))
1207 as_fatal (_("Cannot use special register with this instruction"));
1209 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1210 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1211 output
= frag_more (isize
);
1214 case INST_TYPE_RD_RFSL
:
1215 if (strcmp (op_end
, ""))
1216 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1219 as_fatal (_("Error in statement syntax"));
1222 if (strcmp (op_end
, ""))
1223 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1226 as_fatal (_("Error in statement syntax"));
1230 /* Check for spl registers. */
1231 if (check_spl_reg (®1
))
1232 as_fatal (_("Cannot use special register with this instruction"));
1234 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1235 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1236 output
= frag_more (isize
);
1239 case INST_TYPE_RD_IMM15
:
1240 if (strcmp (op_end
, ""))
1241 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1244 as_fatal (_("Error in statement syntax"));
1248 if (strcmp (op_end
, ""))
1249 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1251 as_fatal (_("Error in statement syntax"));
1253 /* Check for spl registers. */
1254 if (check_spl_reg (®1
))
1255 as_fatal (_("Cannot use special register with this instruction"));
1257 if (exp
.X_op
!= O_constant
)
1258 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1261 output
= frag_more (isize
);
1262 immed
= exp
.X_add_number
;
1264 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1265 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1268 case INST_TYPE_R1_RFSL
:
1269 if (strcmp (op_end
, ""))
1270 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1273 as_fatal (_("Error in statement syntax"));
1276 if (strcmp (op_end
, ""))
1277 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1280 as_fatal (_("Error in statement syntax"));
1284 /* Check for spl registers. */
1285 if (check_spl_reg (®1
))
1286 as_fatal (_("Cannot use special register with this instruction"));
1288 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1289 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1290 output
= frag_more (isize
);
1293 case INST_TYPE_RFSL
:
1294 if (strcmp (op_end
, ""))
1295 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1298 as_fatal (_("Error in statement syntax"));
1301 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1302 output
= frag_more (isize
);
1306 if (strcmp (op_end
, ""))
1307 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1310 as_fatal (_("Error in statement syntax"));
1314 /* Check for spl registers. */
1315 if (check_spl_reg (®1
))
1316 as_fatal (_("Cannot use special register with this instruction"));
1318 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1319 output
= frag_more (isize
);
1322 /* For tuqula insn...:) */
1324 if (strcmp (op_end
, ""))
1325 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1328 as_fatal (_("Error in statement syntax"));
1332 /* Check for spl registers. */
1333 if (check_spl_reg (®1
))
1334 as_fatal (_("Cannot use special register with this instruction"));
1336 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1337 output
= frag_more (isize
);
1340 case INST_TYPE_RD_SPECIAL
:
1341 if (strcmp (op_end
, ""))
1342 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1345 as_fatal (_("Error in statement syntax"));
1348 if (strcmp (op_end
, ""))
1349 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1352 as_fatal (_("Error in statement syntax"));
1356 if (reg2
== REG_MSR
)
1357 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1358 else if (reg2
== REG_PC
)
1359 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1360 else if (reg2
== REG_EAR
)
1361 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1362 else if (reg2
== REG_ESR
)
1363 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1364 else if (reg2
== REG_FSR
)
1365 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1366 else if (reg2
== REG_BTR
)
1367 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1368 else if (reg2
== REG_EDR
)
1369 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1370 else if (reg2
== REG_PID
)
1371 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1372 else if (reg2
== REG_ZPR
)
1373 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1374 else if (reg2
== REG_TLBX
)
1375 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1376 else if (reg2
== REG_TLBLO
)
1377 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1378 else if (reg2
== REG_TLBHI
)
1379 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1380 else if (reg2
== REG_SHR
)
1381 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1382 else if (reg2
== REG_SLR
)
1383 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1384 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1385 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1387 as_fatal (_("invalid value for special purpose register"));
1388 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1389 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1390 output
= frag_more (isize
);
1393 case INST_TYPE_SPECIAL_R1
:
1394 if (strcmp (op_end
, ""))
1395 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1398 as_fatal (_("Error in statement syntax"));
1401 if (strcmp (op_end
, ""))
1402 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1405 as_fatal (_("Error in statement syntax"));
1409 if (reg1
== REG_MSR
)
1410 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1411 else if (reg1
== REG_PC
)
1412 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1413 else if (reg1
== REG_EAR
)
1414 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1415 else if (reg1
== REG_ESR
)
1416 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1417 else if (reg1
== REG_FSR
)
1418 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1419 else if (reg1
== REG_BTR
)
1420 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1421 else if (reg1
== REG_EDR
)
1422 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1423 else if (reg1
== REG_PID
)
1424 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1425 else if (reg1
== REG_ZPR
)
1426 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1427 else if (reg1
== REG_TLBX
)
1428 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1429 else if (reg1
== REG_TLBLO
)
1430 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1431 else if (reg1
== REG_TLBHI
)
1432 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1433 else if (reg1
== REG_TLBSX
)
1434 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1435 else if (reg1
== REG_SHR
)
1436 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1437 else if (reg1
== REG_SLR
)
1438 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1440 as_fatal (_("invalid value for special purpose register"));
1441 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1442 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1443 output
= frag_more (isize
);
1446 case INST_TYPE_R1_R2_SPECIAL
:
1447 if (strcmp (op_end
, ""))
1448 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1451 as_fatal (_("Error in statement syntax"));
1454 if (strcmp (op_end
, ""))
1455 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1458 as_fatal (_("Error in statement syntax"));
1462 /* Check for spl registers. */
1463 if (check_spl_reg (®1
))
1464 as_fatal (_("Cannot use special register with this instruction"));
1465 if (check_spl_reg (®2
))
1466 as_fatal (_("Cannot use special register with this instruction"));
1468 /* insn wic ra, rb => wic ra, ra, rb. */
1469 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1470 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1472 output
= frag_more (isize
);
1475 case INST_TYPE_RD_R2
:
1476 if (strcmp (op_end
, ""))
1477 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1480 as_fatal (_("Error in statement syntax"));
1483 if (strcmp (op_end
, ""))
1484 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1487 as_fatal (_("Error in statement syntax"));
1491 /* Check for spl registers. */
1492 if (check_spl_reg (®1
))
1493 as_fatal (_("Cannot use special register with this instruction"));
1494 if (check_spl_reg (®2
))
1495 as_fatal (_("Cannot use special register with this instruction"));
1497 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1498 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1499 output
= frag_more (isize
);
1502 case INST_TYPE_R1_IMM
:
1503 if (strcmp (op_end
, ""))
1504 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1507 as_fatal (_("Error in statement syntax"));
1510 if (strcmp (op_end
, ""))
1511 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1513 as_fatal (_("Error in statement syntax"));
1515 /* Check for spl registers. */
1516 if (check_spl_reg (®1
))
1517 as_fatal (_("Cannot use special register with this instruction"));
1519 if (exp
.X_op
!= O_constant
)
1522 relax_substateT subtype
;
1525 subtype
= get_imm_otype(exp
.X_md
);
1527 subtype
= opcode
->inst_offset_type
;
1529 output
= frag_var (rs_machine_dependent
,
1530 isize
* 2, /* maxm of 2 words. */
1531 isize
, /* minm of 1 word. */
1532 subtype
, /* PC-relative or not. */
1540 output
= frag_more (isize
);
1541 immed
= exp
.X_add_number
;
1544 temp
= immed
& 0xFFFF8000;
1545 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1547 /* Needs an immediate inst. */
1548 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1549 if (opcode1
== NULL
)
1551 as_bad (_("unknown opcode \"%s\""), "imm");
1555 inst1
= opcode1
->bit_sequence
;
1556 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1557 output
[0] = INST_BYTE0 (inst1
);
1558 output
[1] = INST_BYTE1 (inst1
);
1559 output
[2] = INST_BYTE2 (inst1
);
1560 output
[3] = INST_BYTE3 (inst1
);
1561 output
= frag_more (isize
);
1564 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1565 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1568 case INST_TYPE_RD_IMM
:
1569 if (strcmp (op_end
, ""))
1570 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1573 as_fatal (_("Error in statement syntax"));
1576 if (strcmp (op_end
, ""))
1577 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1579 as_fatal (_("Error in statement syntax"));
1581 /* Check for spl registers. */
1582 if (check_spl_reg (®1
))
1583 as_fatal (_("Cannot use special register with this instruction"));
1585 if (exp
.X_op
!= O_constant
)
1588 relax_substateT subtype
;
1591 subtype
= get_imm_otype(exp
.X_md
);
1593 subtype
= opcode
->inst_offset_type
;
1595 output
= frag_var (rs_machine_dependent
,
1596 isize
* 2, /* maxm of 2 words. */
1597 isize
, /* minm of 1 word. */
1598 subtype
, /* PC-relative or not. */
1606 output
= frag_more (isize
);
1607 immed
= exp
.X_add_number
;
1610 temp
= immed
& 0xFFFF8000;
1611 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1613 /* Needs an immediate inst. */
1614 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1615 if (opcode1
== NULL
)
1617 as_bad (_("unknown opcode \"%s\""), "imm");
1621 inst1
= opcode1
->bit_sequence
;
1622 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1623 output
[0] = INST_BYTE0 (inst1
);
1624 output
[1] = INST_BYTE1 (inst1
);
1625 output
[2] = INST_BYTE2 (inst1
);
1626 output
[3] = INST_BYTE3 (inst1
);
1627 output
= frag_more (isize
);
1630 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1631 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1635 if (strcmp (op_end
, ""))
1636 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1639 as_fatal (_("Error in statement syntax"));
1643 /* Check for spl registers. */
1644 if (check_spl_reg (®2
))
1645 as_fatal (_("Cannot use special register with this instruction"));
1647 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1648 output
= frag_more (isize
);
1652 if (streq (name
, "imm"))
1653 as_fatal (_("An IMM instruction should not be present in the .s file"));
1655 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1657 if (exp
.X_op
!= O_constant
)
1660 relax_substateT subtype
;
1663 subtype
= get_imm_otype(exp
.X_md
);
1665 subtype
= opcode
->inst_offset_type
;
1667 output
= frag_var (rs_machine_dependent
,
1668 isize
* 2, /* maxm of 2 words. */
1669 isize
, /* minm of 1 word. */
1670 subtype
, /* PC-relative or not. */
1678 output
= frag_more (isize
);
1679 immed
= exp
.X_add_number
;
1683 temp
= immed
& 0xFFFF8000;
1684 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1686 /* Needs an immediate inst. */
1687 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1688 if (opcode1
== NULL
)
1690 as_bad (_("unknown opcode \"%s\""), "imm");
1694 inst1
= opcode1
->bit_sequence
;
1695 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1696 output
[0] = INST_BYTE0 (inst1
);
1697 output
[1] = INST_BYTE1 (inst1
);
1698 output
[2] = INST_BYTE2 (inst1
);
1699 output
[3] = INST_BYTE3 (inst1
);
1700 output
= frag_more (isize
);
1702 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1705 case INST_TYPE_NONE
:
1706 output
= frag_more (isize
);
1709 case INST_TYPE_IMM5
:
1710 if (strcmp(op_end
, ""))
1711 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM5
, MAX_IMM5
);
1713 as_fatal(_("Error in statement syntax"));
1714 if (exp
.X_op
!= O_constant
) {
1715 as_warn(_("Symbol used as immediate for mbar instruction"));
1717 output
= frag_more (isize
);
1718 immed
= exp
.X_add_number
;
1720 if (immed
!= (immed
% 32)) {
1721 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1724 inst
|= (immed
<< IMM_MBAR
);
1728 as_fatal (_("unimplemented opcode \"%s\""), name
);
1731 /* Drop whitespace after all the operands have been parsed. */
1732 while (ISSPACE (* op_end
))
1735 /* Give warning message if the insn has more operands than required. */
1736 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1737 as_warn (_("ignoring operands: %s "), op_end
);
1739 output
[0] = INST_BYTE0 (inst
);
1740 output
[1] = INST_BYTE1 (inst
);
1741 output
[2] = INST_BYTE2 (inst
);
1742 output
[3] = INST_BYTE3 (inst
);
1745 dwarf2_emit_insn (4);
1750 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1755 /* Various routines to kill one day. */
1756 /* Equal to MAX_PRECISION in atof-ieee.c */
1757 #define MAX_LITTLENUMS 6
1759 /* Turn a string in input_line_pointer into a floating point constant of type
1760 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1761 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1763 md_atof (int type
, char * litP
, int * sizeP
)
1766 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1798 return _("Bad call to MD_NTOF()");
1801 t
= atof_ieee (input_line_pointer
, type
, words
);
1804 input_line_pointer
= t
;
1806 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1808 if (! target_big_endian
)
1810 for (i
= prec
- 1; i
>= 0; i
--)
1812 md_number_to_chars (litP
, (valueT
) words
[i
],
1813 sizeof (LITTLENUM_TYPE
));
1814 litP
+= sizeof (LITTLENUM_TYPE
);
1818 for (i
= 0; i
< prec
; i
++)
1820 md_number_to_chars (litP
, (valueT
) words
[i
],
1821 sizeof (LITTLENUM_TYPE
));
1822 litP
+= sizeof (LITTLENUM_TYPE
);
1828 const char * md_shortopts
= "";
1830 struct option md_longopts
[] =
1832 {"EB", no_argument
, NULL
, OPTION_EB
},
1833 {"EL", no_argument
, NULL
, OPTION_EL
},
1834 { NULL
, no_argument
, NULL
, 0}
1837 size_t md_longopts_size
= sizeof (md_longopts
);
1839 int md_short_jump_size
;
1842 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED
,
1843 addressT from_Nddr ATTRIBUTE_UNUSED
,
1844 addressT to_Nddr ATTRIBUTE_UNUSED
,
1845 fragS
* frag ATTRIBUTE_UNUSED
,
1846 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1848 as_fatal (_("failed sanity check: short_jump"));
1852 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED
,
1853 addressT from_Nddr ATTRIBUTE_UNUSED
,
1854 addressT to_Nddr ATTRIBUTE_UNUSED
,
1855 fragS
* frag ATTRIBUTE_UNUSED
,
1856 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1858 as_fatal (_("failed sanity check: long_jump"));
1861 /* Called after relaxing, change the frags so they know how big they are. */
1864 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1865 segT sec ATTRIBUTE_UNUSED
,
1870 switch (fragP
->fr_subtype
)
1872 case UNDEFINED_PC_OFFSET
:
1873 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1874 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1875 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1878 case DEFINED_ABS_SEGMENT
:
1879 if (fragP
->fr_symbol
== GOT_symbol
)
1880 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1881 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_GOTPC
);
1883 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1884 fragP
->fr_offset
, FALSE
, BFD_RELOC_64
);
1885 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1888 case DEFINED_RO_SEGMENT
:
1889 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1890 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_ROSDA
);
1891 fragP
->fr_fix
+= INST_WORD_SIZE
;
1894 case DEFINED_RW_SEGMENT
:
1895 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1896 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_RWSDA
);
1897 fragP
->fr_fix
+= INST_WORD_SIZE
;
1900 case DEFINED_PC_OFFSET
:
1901 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1902 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_32_LO_PCREL
);
1903 fragP
->fr_fix
+= INST_WORD_SIZE
;
1906 case LARGE_DEFINED_PC_OFFSET
:
1907 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1908 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1909 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1913 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1914 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOT
);
1915 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1919 fixP
= fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1920 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_PLT
);
1921 /* fixP->fx_plt = 1; */
1923 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1927 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1928 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOTOFF
);
1929 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1933 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1934 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSGD
);
1935 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1939 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1940 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSLD
);
1941 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1944 case TLSDTPREL_OFFSET
:
1945 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1946 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSDTPREL
);
1947 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1956 /* Applies the desired value to the specified location.
1957 Also sets up addends for 'rela' type relocations. */
1959 md_apply_fix (fixS
* fixP
,
1963 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1964 const char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
1965 const char * symname
;
1966 /* Note: use offsetT because it is signed, valueT is unsigned. */
1967 offsetT val
= (offsetT
) * valp
;
1969 struct op_code_struct
* opcode1
;
1970 unsigned long inst1
;
1972 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
1974 /* fixP->fx_offset is supposed to be set up correctly for all
1975 symbol relocations. */
1976 if (fixP
->fx_addsy
== NULL
)
1978 if (!fixP
->fx_pcrel
)
1979 fixP
->fx_offset
= val
; /* Absolute relocation. */
1981 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1982 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
1985 /* If we aren't adjusting this fixup to be against the section
1986 symbol, we need to adjust the value. */
1987 if (fixP
->fx_addsy
!= NULL
)
1989 if (S_IS_WEAK (fixP
->fx_addsy
)
1990 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
1991 && (((bfd_get_section_flags (stdoutput
,
1992 S_GET_SEGMENT (fixP
->fx_addsy
))
1993 & SEC_LINK_ONCE
) != 0)
1994 || !strncmp (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
1996 sizeof (".gnu.linkonce") - 1))))
1998 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1999 if (val
!= 0 && ! fixP
->fx_pcrel
)
2001 /* In this case, the bfd_install_relocation routine will
2002 incorrectly add the symbol value back in. We just want
2003 the addend to appear in the object file.
2004 FIXME: If this makes VALUE zero, we're toast. */
2005 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2010 /* If the fix is relative to a symbol which is not defined, or not
2011 in the same segment as the fix, we cannot resolve it here. */
2012 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
2013 if (fixP
->fx_addsy
!= NULL
2014 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2015 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
2019 /* For ELF we can just return and let the reloc that will be generated
2020 take care of everything. For COFF we still have to insert 'val'
2021 into the insn since the addend field will be ignored. */
2025 /* All fixups in the text section must be handled in the linker. */
2026 else if (segment
->flags
& SEC_CODE
)
2028 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
2033 switch (fixP
->fx_r_type
)
2035 case BFD_RELOC_MICROBLAZE_32_LO
:
2036 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2037 if (target_big_endian
)
2039 buf
[2] |= ((val
>> 8) & 0xff);
2040 buf
[3] |= (val
& 0xff);
2044 buf
[1] |= ((val
>> 8) & 0xff);
2045 buf
[0] |= (val
& 0xff);
2048 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2049 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2050 /* Don't do anything if the symbol is not defined. */
2051 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2053 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
2054 as_bad_where (file
, fixP
->fx_line
,
2055 _("pcrel for branch to %s too far (0x%x)"),
2056 symname
, (int) val
);
2057 if (target_big_endian
)
2059 buf
[2] |= ((val
>> 8) & 0xff);
2060 buf
[3] |= (val
& 0xff);
2064 buf
[1] |= ((val
>> 8) & 0xff);
2065 buf
[0] |= (val
& 0xff);
2071 case BFD_RELOC_32_PCREL
:
2072 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2073 /* Don't do anything if the symbol is not defined. */
2074 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2076 if (target_big_endian
)
2078 buf
[0] |= ((val
>> 24) & 0xff);
2079 buf
[1] |= ((val
>> 16) & 0xff);
2080 buf
[2] |= ((val
>> 8) & 0xff);
2081 buf
[3] |= (val
& 0xff);
2085 buf
[3] |= ((val
>> 24) & 0xff);
2086 buf
[2] |= ((val
>> 16) & 0xff);
2087 buf
[1] |= ((val
>> 8) & 0xff);
2088 buf
[0] |= (val
& 0xff);
2092 case BFD_RELOC_64_PCREL
:
2094 /* Add an imm instruction. First save the current instruction. */
2095 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2096 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2098 /* Generate the imm instruction. */
2099 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2100 if (opcode1
== NULL
)
2102 as_bad (_("unknown opcode \"%s\""), "imm");
2106 inst1
= opcode1
->bit_sequence
;
2107 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2108 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
2110 buf
[0] = INST_BYTE0 (inst1
);
2111 buf
[1] = INST_BYTE1 (inst1
);
2112 buf
[2] = INST_BYTE2 (inst1
);
2113 buf
[3] = INST_BYTE3 (inst1
);
2115 /* Add the value only if the symbol is defined. */
2116 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2118 if (target_big_endian
)
2120 buf
[6] |= ((val
>> 8) & 0xff);
2121 buf
[7] |= (val
& 0xff);
2125 buf
[5] |= ((val
>> 8) & 0xff);
2126 buf
[4] |= (val
& 0xff);
2131 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2132 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2133 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2134 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2137 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2138 case BFD_RELOC_MICROBLAZE_64_GOT
:
2139 case BFD_RELOC_MICROBLAZE_64_PLT
:
2140 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2141 /* Add an imm instruction. First save the current instruction. */
2142 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2143 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2145 /* Generate the imm instruction. */
2146 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2147 if (opcode1
== NULL
)
2149 as_bad (_("unknown opcode \"%s\""), "imm");
2153 inst1
= opcode1
->bit_sequence
;
2155 /* We can fixup call to a defined non-global address
2156 within the same section only. */
2157 buf
[0] = INST_BYTE0 (inst1
);
2158 buf
[1] = INST_BYTE1 (inst1
);
2159 buf
[2] = INST_BYTE2 (inst1
);
2160 buf
[3] = INST_BYTE3 (inst1
);
2167 if (fixP
->fx_addsy
== NULL
)
2169 /* This fixup has been resolved. Create a reloc in case the linker
2170 moves code around due to relaxing. */
2171 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2172 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2174 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2175 fixP
->fx_addsy
= section_symbol (absolute_section
);
2181 md_operand (expressionS
* expressionP
)
2183 /* Ignore leading hash symbol, if present. */
2184 if (*input_line_pointer
== '#')
2186 input_line_pointer
++;
2187 expression (expressionP
);
2191 /* Called just before address relaxation, return the length
2192 by which a fragment must grow to reach it's destination. */
2195 md_estimate_size_before_relax (fragS
* fragP
,
2198 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2199 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2200 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2201 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2203 switch (fragP
->fr_subtype
)
2205 case INST_PC_OFFSET
:
2206 /* Used to be a PC-relative branch. */
2207 if (!fragP
->fr_symbol
)
2209 /* We know the abs value: Should never happen. */
2210 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2213 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
&&
2214 !S_IS_WEAK (fragP
->fr_symbol
))
2216 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2217 /* Don't know now whether we need an imm instruction. */
2218 fragP
->fr_var
= INST_WORD_SIZE
;
2220 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2221 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2223 /* Cannot have a PC-relative branch to a diff segment. */
2224 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2225 S_GET_NAME (fragP
->fr_symbol
));
2226 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2227 fragP
->fr_var
= INST_WORD_SIZE
*2;
2231 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2232 fragP
->fr_var
= INST_WORD_SIZE
*2;
2236 case INST_NO_OFFSET
:
2237 /* Used to be a reference to somewhere which was unknown. */
2238 if (fragP
->fr_symbol
)
2240 if (fragP
->fr_opcode
== NULL
)
2242 /* Used as an absolute value. */
2243 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2244 /* Variable part does not change. */
2245 fragP
->fr_var
= INST_WORD_SIZE
*2;
2247 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2249 /* It is accessed using the small data read only anchor. */
2250 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2251 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2252 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2253 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2255 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2256 fragP
->fr_var
= INST_WORD_SIZE
;
2260 /* Variable not in small data read only segment accessed
2261 using small data read only anchor. */
2262 const char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2264 as_bad_where (file
, fragP
->fr_line
,
2265 _("Variable is accessed using small data read "
2266 "only anchor, but it is not in the small data "
2267 "read only section"));
2268 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2269 fragP
->fr_var
= INST_WORD_SIZE
;
2272 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2274 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2275 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2276 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2277 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2279 /* It is accessed using the small data read write anchor. */
2280 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2281 fragP
->fr_var
= INST_WORD_SIZE
;
2285 const char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2287 as_bad_where (file
, fragP
->fr_line
,
2288 _("Variable is accessed using small data read "
2289 "write anchor, but it is not in the small data "
2290 "read write section"));
2291 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2292 fragP
->fr_var
= INST_WORD_SIZE
;
2297 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2303 /* We know the abs value: Should never happen. */
2304 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2309 case UNDEFINED_PC_OFFSET
:
2310 case LARGE_DEFINED_PC_OFFSET
:
2311 case DEFINED_ABS_SEGMENT
:
2317 case TLSTPREL_OFFSET
:
2318 case TLSDTPREL_OFFSET
:
2319 fragP
->fr_var
= INST_WORD_SIZE
*2;
2321 case DEFINED_RO_SEGMENT
:
2322 case DEFINED_RW_SEGMENT
:
2323 case DEFINED_PC_OFFSET
:
2324 case TLSDTPMOD_OFFSET
:
2325 fragP
->fr_var
= INST_WORD_SIZE
;
2331 return fragP
->fr_var
;
2334 /* Put number into target byte order. */
2337 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2339 if (target_big_endian
)
2340 number_to_chars_bigendian (ptr
, use
, nbytes
);
2342 number_to_chars_littleendian (ptr
, use
, nbytes
);
2345 /* Round up a section size to the appropriate boundary. */
2348 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2350 return size
; /* Byte alignment is fine. */
2354 /* The location from which a PC relative jump should be calculated,
2355 given a PC relative reloc. */
2358 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2361 /* If the symbol is undefined or defined in another section
2362 we leave the add number alone for the linker to fix it later.
2363 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2365 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2366 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2367 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2371 /* The case where we are going to resolve things... */
2372 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2373 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2375 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2381 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2382 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2385 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2388 bfd_reloc_code_real_type code
;
2390 switch (fixp
->fx_r_type
)
2392 case BFD_RELOC_NONE
:
2393 case BFD_RELOC_MICROBLAZE_64_NONE
:
2395 case BFD_RELOC_MICROBLAZE_32_LO
:
2396 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2399 case BFD_RELOC_64_PCREL
:
2400 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2401 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2402 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2403 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2404 case BFD_RELOC_MICROBLAZE_64_GOT
:
2405 case BFD_RELOC_MICROBLAZE_64_PLT
:
2406 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2407 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2408 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2409 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2410 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
2411 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
2412 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2413 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
2414 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
2415 code
= fixp
->fx_r_type
;
2419 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2421 MAP (1, 0, BFD_RELOC_8
);
2422 MAP (2, 0, BFD_RELOC_16
);
2423 MAP (4, 0, BFD_RELOC_32
);
2424 MAP (1, 1, BFD_RELOC_8_PCREL
);
2425 MAP (2, 1, BFD_RELOC_16_PCREL
);
2426 MAP (4, 1, BFD_RELOC_32_PCREL
);
2428 code
= fixp
->fx_r_type
;
2429 as_bad (_("Can not do %d byte %srelocation"),
2431 fixp
->fx_pcrel
? _("pc-relative") : "");
2436 rel
= XNEW (arelent
);
2437 rel
->sym_ptr_ptr
= XNEW (asymbol
*);
2439 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2440 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2442 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2444 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2445 /* Always pass the addend along! */
2446 rel
->addend
= fixp
->fx_offset
;
2447 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2449 if (rel
->howto
== NULL
)
2451 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2452 _("Cannot represent relocation type %s"),
2453 bfd_get_reloc_code_name (code
));
2455 /* Set howto to a garbage value so that we can keep going. */
2456 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2457 gas_assert (rel
->howto
!= NULL
);
2463 md_parse_option (int c
, const char * arg ATTRIBUTE_UNUSED
)
2468 target_big_endian
= 1;
2471 target_big_endian
= 0;
2480 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2482 /* fprintf(stream, _("\
2483 MicroBlaze options:\n\
2484 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2488 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2489 found a machine specific op in an expression,
2490 then we create relocs accordingly. */
2493 cons_fix_new_microblaze (fragS
* frag
,
2497 bfd_reloc_code_real_type r
)
2499 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2500 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2501 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2502 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2503 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2505 exp
->X_op
= O_symbol
;
2506 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2525 as_bad (_("unsupported BFD relocation size %u"), size
);
2530 fix_new_exp (frag
, where
, size
, exp
, 0, r
);