1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright (C) 2009-2024 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 bool 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
90 #define TEXT_OFFSET 17
91 #define TEXT_PC_OFFSET 18
93 /* Initialize the relax table. */
94 const relax_typeS md_relax_table
[] =
96 { 1, 1, 0, 0 }, /* 0: Unused. */
97 { 1, 1, 0, 0 }, /* 1: Unused. */
98 { 1, 1, 0, 0 }, /* 2: Unused. */
99 { 1, 1, 0, 0 }, /* 3: Unused. */
100 { 32767, -32768, INST_WORD_SIZE
, LARGE_DEFINED_PC_OFFSET
}, /* 4: DEFINED_PC_OFFSET. */
101 { 1, 1, 0, 0 }, /* 5: Unused. */
102 { 1, 1, 0, 0 }, /* 6: Unused. */
103 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
104 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 8: GOT_OFFSET. */
105 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 9: PLT_OFFSET. */
106 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 10: GOTOFF_OFFSET. */
107 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 11: TLSGD_OFFSET. */
108 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 12: TLSLD_OFFSET. */
109 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */
110 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 14: TLSDTPREL_OFFSET. */
111 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
112 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 16: TLSTPREL_OFFSET. */
113 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 17: TEXT_OFFSET. */
114 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 } /* 18: TEXT_PC_OFFSET. */
117 static htab_t opcode_hash_control
; /* Opcode mnemonics. */
119 static segT sbss_segment
= 0; /* Small bss section. */
120 static segT sbss2_segment
= 0; /* Section not used. */
121 static segT sdata_segment
= 0; /* Small data section. */
122 static segT sdata2_segment
= 0; /* Small read-only section. */
123 static segT rodata_segment
= 0; /* read-only section. */
125 /* Generate a symbol for stabs information. */
128 microblaze_generate_symbol (char *sym
)
130 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
131 static int microblaze_label_count
;
132 sprintf (sym
, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME
, microblaze_label_count
);
133 ++microblaze_label_count
;
136 /* Handle the section changing pseudo-ops. */
139 microblaze_s_text (int ignore ATTRIBUTE_UNUSED
)
142 obj_elf_text (ignore
);
149 microblaze_s_data (int ignore ATTRIBUTE_UNUSED
)
152 obj_elf_change_section (".data", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
,
159 /* Things in the .sdata segment are always considered to be in the small data section. */
162 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED
)
165 obj_elf_change_section (".sdata", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
,
172 /* Pseudo op to make file scope bss items. */
175 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED
)
185 segT current_seg
= now_seg
;
186 subsegT current_subseg
= now_subseg
;
188 c
= get_symbol_name (&name
);
190 /* Just after name is now '\0'. */
191 p
= input_line_pointer
;
192 (void) restore_line_pointer (c
);
194 if (*input_line_pointer
!= ',')
196 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
197 ignore_rest_of_line ();
201 input_line_pointer
++; /* skip ',' */
202 if ((size
= get_absolute_expression ()) < 0)
204 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size
);
205 ignore_rest_of_line ();
209 /* The third argument to .lcomm is the alignment. */
210 if (*input_line_pointer
!= ',')
214 ++input_line_pointer
;
215 align
= get_absolute_expression ();
218 as_warn (_("ignoring bad alignment"));
224 symbolP
= symbol_find_or_make (name
);
227 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
229 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
230 S_GET_NAME (symbolP
));
231 ignore_rest_of_line ();
235 if (S_GET_VALUE (symbolP
) && S_GET_VALUE (symbolP
) != (valueT
) size
)
237 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
238 S_GET_NAME (symbolP
),
239 (long) S_GET_VALUE (symbolP
),
242 ignore_rest_of_line ();
249 /* Convert to a power of 2 alignment. */
250 for (align2
= 0; (align
& 1) == 0; align
>>= 1, ++align2
);
253 as_bad (_("Common alignment not a power of 2"));
254 ignore_rest_of_line ();
261 record_alignment (current_seg
, align2
);
262 subseg_set (current_seg
, current_subseg
);
264 frag_align (align2
, 0, 0);
265 if (S_GET_SEGMENT (symbolP
) == current_seg
)
266 symbol_get_frag (symbolP
)->fr_symbol
= 0;
267 symbol_set_frag (symbolP
, frag_now
);
268 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
271 S_SET_SIZE (symbolP
, size
);
272 S_SET_SEGMENT (symbolP
, current_seg
);
273 subseg_set (current_seg
, current_subseg
);
274 demand_empty_rest_of_line ();
278 microblaze_s_rdata (int localvar
)
284 obj_elf_change_section (".rodata", SHT_PROGBITS
, SHF_ALLOC
,
286 if (rodata_segment
== 0)
287 rodata_segment
= subseg_new (".rodata", 0);
292 obj_elf_change_section (".sdata2", SHT_PROGBITS
, SHF_ALLOC
,
301 microblaze_s_bss (int localvar
)
304 if (localvar
== 0) /* bss. */
305 obj_elf_change_section (".bss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
,
307 else if (localvar
== 1)
310 obj_elf_change_section (".sbss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
,
312 if (sbss_segment
== 0)
313 sbss_segment
= subseg_new (".sbss", 0);
320 /* endp_p is always 1 as this func is called only for .end <funcname>
321 This func consumes the <funcname> and calls regular processing
322 s_func(1) with arg 1 (1 for end). */
325 microblaze_s_func (int end_p ATTRIBUTE_UNUSED
)
328 restore_line_pointer (get_symbol_name (&name
));
332 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
335 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED
)
342 c
= get_symbol_name (&name
);
343 symbolP
= symbol_find_or_make (name
);
344 S_SET_WEAK (symbolP
);
345 (void) restore_line_pointer (c
);
349 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
351 if (S_IS_DEFINED (symbolP
))
353 as_bad ("Ignoring attempt to redefine symbol `%s'.",
354 S_GET_NAME (symbolP
));
355 ignore_rest_of_line ();
359 if (*input_line_pointer
== ',')
361 ++input_line_pointer
;
366 if (exp
.X_op
!= O_symbol
)
368 as_bad ("bad .weakext directive");
369 ignore_rest_of_line ();
372 symbol_set_value_expression (symbolP
, &exp
);
375 demand_empty_rest_of_line ();
378 /* This table describes all the machine specific pseudo-ops the assembler
379 has to support. The fields are:
380 Pseudo-op name without dot
381 Function to call to execute this pseudo-op
382 Integer arg to pass to the function. */
383 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
384 and then in the read.c table. */
385 const pseudo_typeS md_pseudo_table
[] =
387 {"lcomm", microblaze_s_lcomm
, 1},
388 {"data", microblaze_s_data
, 0},
389 {"data8", cons
, 1}, /* Same as byte. */
390 {"data16", cons
, 2}, /* Same as hword. */
391 {"data32", cons
, 4}, /* Same as word. */
392 {"ent", s_func
, 0}, /* Treat ent as function entry point. */
393 {"end", microblaze_s_func
, 1}, /* Treat end as function end point. */
394 {"gpword", s_rva
, 4}, /* gpword label => store resolved label address in data section. */
395 {"weakext", microblaze_s_weakext
, 0},
396 {"rodata", microblaze_s_rdata
, 0},
397 {"sdata2", microblaze_s_rdata
, 1},
398 {"sdata", microblaze_s_sdata
, 0},
399 {"bss", microblaze_s_bss
, 0},
400 {"sbss", microblaze_s_bss
, 1},
401 {"text", microblaze_s_text
, 0},
403 {"frame", s_ignore
, 0},
404 {"mask", s_ignore
, 0}, /* Emitted by gcc. */
408 /* This function is called once, at assembler startup time. This should
409 set up all the tables, etc that the MD part of the assembler needs. */
414 const struct op_code_struct
* opcode
;
416 opcode_hash_control
= str_htab_create ();
418 /* Insert unique names into hash table. */
419 for (opcode
= microblaze_opcodes
; opcode
->name
; opcode
++)
420 str_hash_insert (opcode_hash_control
, opcode
->name
, opcode
, 0);
423 /* Try to parse a reg name. */
426 parse_reg (char * s
, unsigned * reg
)
430 /* Strip leading whitespace. */
431 while (ISSPACE (* s
))
434 if (strncasecmp (s
, "rpc", 3) == 0)
439 else if (strncasecmp (s
, "rmsr", 4) == 0)
444 else if (strncasecmp (s
, "rear", 4) == 0)
449 else if (strncasecmp (s
, "resr", 4) == 0)
454 else if (strncasecmp (s
, "rfsr", 4) == 0)
459 else if (strncasecmp (s
, "rbtr", 4) == 0)
464 else if (strncasecmp (s
, "redr", 4) == 0)
469 /* MMU registers start. */
470 else if (strncasecmp (s
, "rpid", 4) == 0)
475 else if (strncasecmp (s
, "rzpr", 4) == 0)
480 else if (strncasecmp (s
, "rtlbx", 5) == 0)
485 else if (strncasecmp (s
, "rtlblo", 6) == 0)
490 else if (strncasecmp (s
, "rtlbhi", 6) == 0)
495 else if (strncasecmp (s
, "rtlbsx", 6) == 0)
500 /* MMU registers end. */
501 else if (strncasecmp (s
, "rpvr", 4) == 0)
503 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
505 tmpreg
= (s
[4]-'0')*10 + s
[5] - '0';
509 else if (ISDIGIT (s
[4]))
515 as_bad (_("register expected, but saw '%.6s'"), s
);
516 if ((int) tmpreg
>= MIN_PVR_REGNUM
&& tmpreg
<= MAX_PVR_REGNUM
)
517 *reg
= REG_PVR
+ tmpreg
;
520 as_bad (_("Invalid register number at '%.6s'"), s
);
525 else if (strncasecmp (s
, "rsp", 3) == 0)
530 else if (strncasecmp (s
, "rfsl", 4) == 0)
532 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
534 tmpreg
= (s
[4] - '0') * 10 + s
[5] - '0';
537 else if (ISDIGIT (s
[4]))
543 as_bad (_("register expected, but saw '%.6s'"), s
);
545 if ((int) tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
549 as_bad (_("Invalid register number at '%.6s'"), s
);
554 /* Stack protection registers. */
555 else if (strncasecmp (s
, "rshr", 4) == 0)
560 else if (strncasecmp (s
, "rslr", 4) == 0)
567 if (TOLOWER (s
[0]) == 'r')
569 if (ISDIGIT (s
[1]) && ISDIGIT (s
[2]))
571 tmpreg
= (s
[1] - '0') * 10 + s
[2] - '0';
574 else if (ISDIGIT (s
[1]))
580 as_bad (_("register expected, but saw '%.6s'"), s
);
582 if ((int)tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
586 as_bad (_("Invalid register number at '%.6s'"), s
);
592 as_bad (_("register expected, but saw '%.6s'"), s
);
598 parse_exp (char *s
, expressionS
*e
)
603 /* Skip whitespace. */
604 while (ISSPACE (* s
))
607 save
= input_line_pointer
;
608 input_line_pointer
= s
;
612 if (e
->X_op
== O_absent
)
613 as_fatal (_("missing operand"));
615 new_pointer
= input_line_pointer
;
616 input_line_pointer
= save
;
621 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
628 #define IMM_TLSDTPMOD 6
629 #define IMM_TLSDTPREL 7
630 #define IMM_TLSTPREL 8
632 #define IMM_TXTPCREL 10
636 const char *isuffix
; /* Suffix String */
637 int itype
; /* Suffix Type */
638 int otype
; /* Offset Type */
641 /* These are NOT in ascending order of type, GOTOFF is ahead to make
642 sure @GOTOFF does not get matched with @GOT */
643 static struct imm_type imm_types
[] = {
644 { "NONE", IMM_NONE
, 0 },
645 { "GOTOFF", IMM_GOTOFF
, GOTOFF_OFFSET
},
646 { "GOT", IMM_GOT
, GOT_OFFSET
},
647 { "PLT", IMM_PLT
, PLT_OFFSET
},
648 { "TLSGD", IMM_TLSGD
, TLSGD_OFFSET
},
649 { "TLSLDM", IMM_TLSLD
, TLSLD_OFFSET
},
650 { "TLSDTPMOD", IMM_TLSDTPMOD
, TLSDTPMOD_OFFSET
},
651 { "TLSDTPREL", IMM_TLSDTPREL
, TLSDTPREL_OFFSET
},
652 { "TLSTPREL", IMM_TLSTPREL
, TLSTPREL_OFFSET
},
653 { "TXTREL", IMM_TXTREL
, TEXT_OFFSET
},
654 { "TXTPCREL", IMM_TXTPCREL
, TEXT_PC_OFFSET
}
658 match_imm (const char *s
, int *ilen
)
663 /* Check for matching suffix */
664 for (i
= 1; i
< IMM_MAX
; i
++)
666 slen
= strlen (imm_types
[i
].isuffix
);
668 if (strncmp (imm_types
[i
].isuffix
, s
, slen
) == 0)
671 return imm_types
[i
].itype
;
679 get_imm_otype (int itype
)
684 /* Check for matching itype */
685 for (i
= 1; i
< IMM_MAX
; i
++)
687 if (imm_types
[i
].itype
== itype
)
689 otype
= imm_types
[i
].otype
;
696 static symbolS
* GOT_symbol
;
698 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
701 parse_imm (char * s
, expressionS
* e
, offsetT min
, offsetT max
)
709 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
710 for (atp
= s
; *atp
!= '@'; atp
++)
711 if (is_end_of_line
[(unsigned char) *atp
])
716 itype
= match_imm (atp
+ 1, &ilen
);
736 if (atp
&& !GOT_symbol
)
738 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
741 new_pointer
= parse_exp (s
, e
);
743 if (!GOT_symbol
&& startswith (s
, GOT_SYMBOL_NAME
))
745 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
748 if (e
->X_op
== O_absent
)
749 ; /* An error message has already been emitted. */
750 else if ((e
->X_op
!= O_constant
&& e
->X_op
!= O_symbol
) )
751 as_fatal (_("operand must be a constant or a label"));
752 else if (e
->X_op
== O_constant
)
754 /* Special case: sign extend negative 32-bit values to offsetT size. */
755 if ((e
->X_add_number
>> 31) == 1)
756 e
->X_add_number
|= -((addressT
) (1U << 31));
758 if ((int)e
->X_add_number
< min
|| (int)e
->X_add_number
> max
)
760 as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"),
761 (long) min
, (long) max
, (long) e
->X_add_number
);
767 *atp
= '@'; /* restore back (needed?) */
768 if (new_pointer
>= atp
)
769 new_pointer
+= ilen
+ 1; /* sizeof (imm_suffix) + 1 for '@' */
775 check_got (int * got_type
, int * got_len
)
783 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
784 for (atp
= input_line_pointer
; *atp
!= '@'; atp
++)
785 if (is_end_of_line
[(unsigned char) *atp
])
788 if (startswith (atp
+ 1, "GOTOFF"))
791 *got_type
= IMM_GOTOFF
;
793 else if (startswith (atp
+ 1, "GOT"))
798 else if (startswith (atp
+ 1, "PLT"))
807 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
809 first
= atp
- input_line_pointer
;
811 past_got
= atp
+ *got_len
+ 1;
812 for (new_pointer
= past_got
; !is_end_of_line
[(unsigned char) *new_pointer
++];)
814 second
= new_pointer
- past_got
;
815 /* One extra byte for ' ' and one for NUL. */
816 tmpbuf
= XNEWVEC (char, first
+ second
+ 2);
817 memcpy (tmpbuf
, input_line_pointer
, first
);
818 tmpbuf
[first
] = ' '; /* @GOTOFF is replaced with a single space. */
819 memcpy (tmpbuf
+ first
+ 1, past_got
, second
);
820 tmpbuf
[first
+ second
+ 1] = '\0';
825 extern bfd_reloc_code_real_type
826 parse_cons_expression_microblaze (expressionS
*exp
, int size
)
830 /* Handle @GOTOFF et.al. */
831 char *save
, *gotfree_copy
;
832 int got_len
, got_type
;
834 save
= input_line_pointer
;
835 gotfree_copy
= check_got (& got_type
, & got_len
);
837 input_line_pointer
= gotfree_copy
;
843 exp
->X_md
= got_type
;
844 input_line_pointer
= save
+ (input_line_pointer
- gotfree_copy
)
851 return BFD_RELOC_NONE
;
854 /* This is the guts of the machine-dependent assembler. STR points to a
855 machine dependent instruction. This function is supposed to emit
856 the frags/bytes it assembles to. */
858 static const char * str_microblaze_ro_anchor
= "RO";
859 static const char * str_microblaze_rw_anchor
= "RW";
862 check_spl_reg (unsigned * reg
)
864 if ((*reg
== REG_MSR
) || (*reg
== REG_PC
)
865 || (*reg
== REG_EAR
) || (*reg
== REG_ESR
)
866 || (*reg
== REG_FSR
) || (*reg
== REG_BTR
) || (*reg
== REG_EDR
)
867 || (*reg
== REG_PID
) || (*reg
== REG_ZPR
)
868 || (*reg
== REG_TLBX
) || (*reg
== REG_TLBLO
)
869 || (*reg
== REG_TLBHI
) || (*reg
== REG_TLBSX
)
870 || (*reg
== REG_SHR
) || (*reg
== REG_SLR
)
871 || (*reg
>= REG_PVR
+MIN_PVR_REGNUM
&& *reg
<= REG_PVR
+MAX_PVR_REGNUM
))
877 /* Here we decide which fixups can be adjusted to make them relative to
878 the beginning of the section instead of the symbol. Basically we need
879 to make sure that the dynamic relocations are done correctly, so in
880 some cases we force the original symbol to be used. */
883 tc_microblaze_fix_adjustable (struct fix
*fixP
)
885 if (GOT_symbol
&& fixP
->fx_subsy
== GOT_symbol
)
888 if (fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOTOFF
889 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_GOTOFF
890 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOT
891 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_PLT
892 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGD
893 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSLD
894 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
895 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPREL
896 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSDTPREL
897 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
898 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSTPREL
)
905 md_assemble (char * str
)
909 struct op_code_struct
* opcode
, *opcode1
;
910 char * output
= NULL
;
913 unsigned long inst
, inst1
;
918 unsigned int immed
= 0, immed2
= 0, temp
;
922 /* Drop leading whitespace. */
923 while (ISSPACE (* str
))
926 /* Find the op code end. */
927 for (op_start
= op_end
= str
;
928 *op_end
&& !is_end_of_line
[(unsigned char) *op_end
] && *op_end
!= ' ';
931 name
[nlen
] = op_start
[nlen
];
933 if (nlen
== sizeof (name
) - 1)
941 as_bad (_("can't find opcode "));
945 opcode
= (struct op_code_struct
*) str_hash_find (opcode_hash_control
, name
);
948 as_bad (_("unknown opcode \"%s\""), name
);
952 inst
= opcode
->bit_sequence
;
955 switch (opcode
->inst_type
)
957 case INST_TYPE_RD_R1_R2
:
958 if (strcmp (op_end
, ""))
959 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
962 as_fatal (_("Error in statement syntax"));
965 if (strcmp (op_end
, ""))
966 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
969 as_fatal (_("Error in statement syntax"));
972 if (strcmp (op_end
, ""))
973 op_end
= parse_reg (op_end
+ 1, ®3
); /* Get r2. */
976 as_fatal (_("Error in statement syntax"));
980 /* Check for spl registers. */
981 if (check_spl_reg (& reg1
))
982 as_fatal (_("Cannot use special register with this instruction"));
983 if (check_spl_reg (& reg2
))
984 as_fatal (_("Cannot use special register with this instruction"));
985 if (check_spl_reg (& reg3
))
986 as_fatal (_("Cannot use special register with this instruction"));
988 if (streq (name
, "sub"))
990 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
991 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
992 inst
|= (reg3
<< RA_LOW
) & RA_MASK
;
993 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
997 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
998 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
999 inst
|= (reg3
<< RB_LOW
) & RB_MASK
;
1001 output
= frag_more (isize
);
1004 case INST_TYPE_RD_R1_IMM
:
1005 if (strcmp (op_end
, ""))
1006 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1009 as_fatal (_("Error in statement syntax"));
1012 if (strcmp (op_end
, ""))
1013 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1016 as_fatal (_("Error in statement syntax"));
1019 if (strcmp (op_end
, ""))
1020 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1022 as_fatal (_("Error in statement syntax"));
1024 /* Check for spl registers. */
1025 if (check_spl_reg (& reg1
))
1026 as_fatal (_("Cannot use special register with this instruction"));
1027 if (check_spl_reg (& reg2
))
1028 as_fatal (_("Cannot use special register with this instruction"));
1030 if (exp
.X_op
!= O_constant
|| exp
.X_md
== IMM_TXTPCREL
)
1033 relax_substateT subtype
;
1035 if (streq (name
, "lmi"))
1036 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
1037 else if (streq (name
, "smi"))
1038 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
1040 if (reg2
== REG_ROSDP
)
1041 opc
= str_microblaze_ro_anchor
;
1042 else if (reg2
== REG_RWSDP
)
1043 opc
= str_microblaze_rw_anchor
;
1047 subtype
= get_imm_otype(exp
.X_md
);
1049 subtype
= opcode
->inst_offset_type
;
1051 output
= frag_var (rs_machine_dependent
,
1052 isize
* 2, /* maxm of 2 words. */
1053 isize
, /* minm of 1 word. */
1054 subtype
, /* PC-relative or not. */
1062 output
= frag_more (isize
);
1063 immed
= exp
.X_add_number
;
1066 if (streq (name
, "lmi") || streq (name
, "smi"))
1068 /* Load/store 32-d consecutive registers. Used on exit/entry
1069 to subroutines to save and restore registers to stack.
1070 Generate 32-d insts. */
1074 if (streq (name
, "lmi"))
1076 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1080 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1084 as_bad (_("unknown opcode \"%s\""), "lwi");
1087 inst
= opcode
->bit_sequence
;
1088 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1089 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1090 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1092 for (i
= 0; i
< count
- 1; i
++)
1094 output
[0] = INST_BYTE0 (inst
);
1095 output
[1] = INST_BYTE1 (inst
);
1096 output
[2] = INST_BYTE2 (inst
);
1097 output
[3] = INST_BYTE3 (inst
);
1098 output
= frag_more (isize
);
1101 inst
= opcode
->bit_sequence
;
1102 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1103 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1104 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1109 temp
= immed
& 0xFFFF8000;
1110 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1112 /* Needs an immediate inst. */
1114 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1116 if (opcode1
== NULL
)
1118 as_bad (_("unknown opcode \"%s\""), "imm");
1122 inst1
= opcode1
->bit_sequence
;
1123 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1124 output
[0] = INST_BYTE0 (inst1
);
1125 output
[1] = INST_BYTE1 (inst1
);
1126 output
[2] = INST_BYTE2 (inst1
);
1127 output
[3] = INST_BYTE3 (inst1
);
1128 output
= frag_more (isize
);
1130 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1131 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1132 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1136 case INST_TYPE_RD_R1_IMM5
:
1137 if (strcmp (op_end
, ""))
1138 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1141 as_fatal (_("Error in statement syntax"));
1144 if (strcmp (op_end
, ""))
1145 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1148 as_fatal (_("Error in statement syntax"));
1151 if (strcmp (op_end
, ""))
1152 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1154 as_fatal (_("Error in statement syntax"));
1156 /* Check for spl registers. */
1157 if (check_spl_reg (®1
))
1158 as_fatal (_("Cannot use special register with this instruction"));
1159 if (check_spl_reg (®2
))
1160 as_fatal (_("Cannot use special register with this instruction"));
1162 if (exp
.X_op
!= O_constant
)
1163 as_warn (_("Symbol used as immediate for shift instruction"));
1166 output
= frag_more (isize
);
1167 immed
= exp
.X_add_number
;
1170 if (immed
!= (immed
% 32))
1172 as_warn (_("Shift value > 32. using <value %% 32>"));
1175 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1176 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1177 inst
|= (immed
<< IMM_LOW
) & IMM5_MASK
;
1180 case INST_TYPE_RD_R1_IMMW_IMMS
:
1181 if (strcmp (op_end
, ""))
1182 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1185 as_fatal (_("Error in statement syntax"));
1189 if (strcmp (op_end
, ""))
1190 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1193 as_fatal (_("Error in statement syntax"));
1197 /* Check for spl registers. */
1198 if (check_spl_reg (®1
))
1199 as_fatal (_("Cannot use special register with this instruction"));
1200 if (check_spl_reg (®2
))
1201 as_fatal (_("Cannot use special register with this instruction"));
1203 /* Width immediate value. */
1204 if (strcmp (op_end
, ""))
1205 op_end
= parse_imm (op_end
+ 1, &exp
, MIN_IMM_WIDTH
, MAX_IMM_WIDTH
);
1207 as_fatal (_("Error in statement syntax"));
1209 if (exp
.X_op
!= O_constant
)
1212 "Symbol used as immediate width value for bit field instruction"));
1216 immed
= exp
.X_add_number
;
1218 if (opcode
->instr
== bsefi
&& immed
> 31)
1219 as_fatal (_("Width value must be less than 32"));
1221 /* Shift immediate value. */
1222 if (strcmp (op_end
, ""))
1223 op_end
= parse_imm (op_end
+ 1, &exp
, MIN_IMM
, MAX_IMM
);
1225 as_fatal (_("Error in statement syntax"));
1227 if (exp
.X_op
!= O_constant
)
1230 "Symbol used as immediate shift value for bit field instruction"));
1235 output
= frag_more (isize
);
1236 immed2
= exp
.X_add_number
;
1239 if (immed2
!= (immed2
% 32))
1241 as_warn (_("Shift value greater than 32. using <value %% 32>"));
1242 immed2
= immed2
% 32;
1245 /* Check combined value. */
1246 if (immed
+ immed2
> 32)
1247 as_fatal (_("Width value + shift value must not be greater than 32"));
1249 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1250 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1252 if (opcode
->instr
== bsefi
)
1253 inst
|= (immed
& IMM5_MASK
) << IMM_WIDTH_LOW
; /* bsefi */
1255 inst
|= ((immed
+ immed2
- 1) & IMM5_MASK
)
1256 << IMM_WIDTH_LOW
; /* bsifi */
1258 inst
|= (immed2
<< IMM_LOW
) & IMM5_MASK
;
1261 case INST_TYPE_R1_R2
:
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, ®2
); /* Get r2. */
1273 as_fatal (_("Error in statement syntax"));
1277 /* Check for spl registers. */
1278 if (check_spl_reg (& reg1
))
1279 as_fatal (_("Cannot use special register with this instruction"));
1280 if (check_spl_reg (& reg2
))
1281 as_fatal (_("Cannot use special register with this instruction"));
1283 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1284 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1285 output
= frag_more (isize
);
1288 case INST_TYPE_RD_R1
:
1289 if (strcmp (op_end
, ""))
1290 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1293 as_fatal (_("Error in statement syntax"));
1296 if (strcmp (op_end
, ""))
1297 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1300 as_fatal (_("Error in statement syntax"));
1304 /* Check for spl registers. */
1305 if (check_spl_reg (®1
))
1306 as_fatal (_("Cannot use special register with this instruction"));
1307 if (check_spl_reg (®2
))
1308 as_fatal (_("Cannot use special register with this instruction"));
1310 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1311 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1312 output
= frag_more (isize
);
1315 case INST_TYPE_RD_RFSL
:
1316 if (strcmp (op_end
, ""))
1317 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1320 as_fatal (_("Error in statement syntax"));
1323 if (strcmp (op_end
, ""))
1324 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1327 as_fatal (_("Error in statement syntax"));
1331 /* Check for spl registers. */
1332 if (check_spl_reg (®1
))
1333 as_fatal (_("Cannot use special register with this instruction"));
1335 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1336 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1337 output
= frag_more (isize
);
1340 case INST_TYPE_RD_IMM15
:
1341 if (strcmp (op_end
, ""))
1342 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1345 as_fatal (_("Error in statement syntax"));
1349 if (strcmp (op_end
, ""))
1350 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1352 as_fatal (_("Error in statement syntax"));
1354 /* Check for spl registers. */
1355 if (check_spl_reg (®1
))
1356 as_fatal (_("Cannot use special register with this instruction"));
1358 if (exp
.X_op
!= O_constant
)
1359 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1362 output
= frag_more (isize
);
1363 immed
= exp
.X_add_number
;
1365 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1366 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1369 case INST_TYPE_R1_RFSL
:
1370 if (strcmp (op_end
, ""))
1371 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1374 as_fatal (_("Error in statement syntax"));
1377 if (strcmp (op_end
, ""))
1378 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1381 as_fatal (_("Error in statement syntax"));
1385 /* Check for spl registers. */
1386 if (check_spl_reg (®1
))
1387 as_fatal (_("Cannot use special register with this instruction"));
1389 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1390 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1391 output
= frag_more (isize
);
1394 case INST_TYPE_RFSL
:
1395 if (strcmp (op_end
, ""))
1396 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1399 as_fatal (_("Error in statement syntax"));
1402 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1403 output
= frag_more (isize
);
1407 if (strcmp (op_end
, ""))
1408 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1411 as_fatal (_("Error in statement syntax"));
1415 /* Check for spl registers. */
1416 if (check_spl_reg (®1
))
1417 as_fatal (_("Cannot use special register with this instruction"));
1419 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1420 output
= frag_more (isize
);
1423 /* For tuqula insn...:) */
1425 if (strcmp (op_end
, ""))
1426 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1429 as_fatal (_("Error in statement syntax"));
1433 /* Check for spl registers. */
1434 if (check_spl_reg (®1
))
1435 as_fatal (_("Cannot use special register with this instruction"));
1437 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1438 output
= frag_more (isize
);
1441 case INST_TYPE_RD_SPECIAL
:
1442 if (strcmp (op_end
, ""))
1443 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1446 as_fatal (_("Error in statement syntax"));
1449 if (strcmp (op_end
, ""))
1450 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1453 as_fatal (_("Error in statement syntax"));
1457 if (reg2
== REG_MSR
)
1458 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1459 else if (reg2
== REG_PC
)
1460 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1461 else if (reg2
== REG_EAR
)
1462 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1463 else if (reg2
== REG_ESR
)
1464 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1465 else if (reg2
== REG_FSR
)
1466 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1467 else if (reg2
== REG_BTR
)
1468 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1469 else if (reg2
== REG_EDR
)
1470 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1471 else if (reg2
== REG_PID
)
1472 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1473 else if (reg2
== REG_ZPR
)
1474 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1475 else if (reg2
== REG_TLBX
)
1476 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1477 else if (reg2
== REG_TLBLO
)
1478 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1479 else if (reg2
== REG_TLBHI
)
1480 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1481 else if (reg2
== REG_SHR
)
1482 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1483 else if (reg2
== REG_SLR
)
1484 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1485 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1486 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1488 as_fatal (_("invalid value for special purpose register"));
1489 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1490 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1491 output
= frag_more (isize
);
1494 case INST_TYPE_SPECIAL_R1
:
1495 if (strcmp (op_end
, ""))
1496 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1499 as_fatal (_("Error in statement syntax"));
1502 if (strcmp (op_end
, ""))
1503 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1506 as_fatal (_("Error in statement syntax"));
1510 if (reg1
== REG_MSR
)
1511 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1512 else if (reg1
== REG_PC
)
1513 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1514 else if (reg1
== REG_EAR
)
1515 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1516 else if (reg1
== REG_ESR
)
1517 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1518 else if (reg1
== REG_FSR
)
1519 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1520 else if (reg1
== REG_BTR
)
1521 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1522 else if (reg1
== REG_EDR
)
1523 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1524 else if (reg1
== REG_PID
)
1525 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1526 else if (reg1
== REG_ZPR
)
1527 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1528 else if (reg1
== REG_TLBX
)
1529 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1530 else if (reg1
== REG_TLBLO
)
1531 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1532 else if (reg1
== REG_TLBHI
)
1533 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1534 else if (reg1
== REG_TLBSX
)
1535 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1536 else if (reg1
== REG_SHR
)
1537 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1538 else if (reg1
== REG_SLR
)
1539 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1541 as_fatal (_("invalid value for special purpose register"));
1542 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1543 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1544 output
= frag_more (isize
);
1547 case INST_TYPE_R1_R2_SPECIAL
:
1548 if (strcmp (op_end
, ""))
1549 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1552 as_fatal (_("Error in statement syntax"));
1555 if (strcmp (op_end
, ""))
1556 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1559 as_fatal (_("Error in statement syntax"));
1563 /* Check for spl registers. */
1564 if (check_spl_reg (®1
))
1565 as_fatal (_("Cannot use special register with this instruction"));
1566 if (check_spl_reg (®2
))
1567 as_fatal (_("Cannot use special register with this instruction"));
1569 /* insn wic ra, rb => wic ra, ra, rb. */
1570 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1571 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1573 output
= frag_more (isize
);
1576 case INST_TYPE_RD_R2
:
1577 if (strcmp (op_end
, ""))
1578 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1581 as_fatal (_("Error in statement syntax"));
1584 if (strcmp (op_end
, ""))
1585 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1588 as_fatal (_("Error in statement syntax"));
1592 /* Check for spl registers. */
1593 if (check_spl_reg (®1
))
1594 as_fatal (_("Cannot use special register with this instruction"));
1595 if (check_spl_reg (®2
))
1596 as_fatal (_("Cannot use special register with this instruction"));
1598 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1599 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1600 output
= frag_more (isize
);
1603 case INST_TYPE_R1_IMM
:
1604 if (strcmp (op_end
, ""))
1605 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1608 as_fatal (_("Error in statement syntax"));
1611 if (strcmp (op_end
, ""))
1612 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1614 as_fatal (_("Error in statement syntax"));
1616 /* Check for spl registers. */
1617 if (check_spl_reg (®1
))
1618 as_fatal (_("Cannot use special register with this instruction"));
1620 if (exp
.X_op
!= O_constant
)
1623 relax_substateT subtype
;
1626 subtype
= get_imm_otype(exp
.X_md
);
1628 subtype
= opcode
->inst_offset_type
;
1630 output
= frag_var (rs_machine_dependent
,
1631 isize
* 2, /* maxm of 2 words. */
1632 isize
, /* minm of 1 word. */
1633 subtype
, /* PC-relative or not. */
1641 output
= frag_more (isize
);
1642 immed
= exp
.X_add_number
;
1645 temp
= immed
& 0xFFFF8000;
1646 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1648 /* Needs an immediate inst. */
1650 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1652 if (opcode1
== NULL
)
1654 as_bad (_("unknown opcode \"%s\""), "imm");
1658 inst1
= opcode1
->bit_sequence
;
1659 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1660 output
[0] = INST_BYTE0 (inst1
);
1661 output
[1] = INST_BYTE1 (inst1
);
1662 output
[2] = INST_BYTE2 (inst1
);
1663 output
[3] = INST_BYTE3 (inst1
);
1664 output
= frag_more (isize
);
1667 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1668 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1671 case INST_TYPE_RD_IMM
:
1672 if (strcmp (op_end
, ""))
1673 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1676 as_fatal (_("Error in statement syntax"));
1679 if (strcmp (op_end
, ""))
1680 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1682 as_fatal (_("Error in statement syntax"));
1684 /* Check for spl registers. */
1685 if (check_spl_reg (®1
))
1686 as_fatal (_("Cannot use special register with this instruction"));
1688 if (exp
.X_op
!= O_constant
)
1691 relax_substateT subtype
;
1694 subtype
= get_imm_otype(exp
.X_md
);
1696 subtype
= opcode
->inst_offset_type
;
1698 output
= frag_var (rs_machine_dependent
,
1699 isize
* 2, /* maxm of 2 words. */
1700 isize
, /* minm of 1 word. */
1701 subtype
, /* PC-relative or not. */
1709 output
= frag_more (isize
);
1710 immed
= exp
.X_add_number
;
1713 temp
= immed
& 0xFFFF8000;
1714 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1716 /* Needs an immediate inst. */
1718 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1720 if (opcode1
== NULL
)
1722 as_bad (_("unknown opcode \"%s\""), "imm");
1726 inst1
= opcode1
->bit_sequence
;
1727 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1728 output
[0] = INST_BYTE0 (inst1
);
1729 output
[1] = INST_BYTE1 (inst1
);
1730 output
[2] = INST_BYTE2 (inst1
);
1731 output
[3] = INST_BYTE3 (inst1
);
1732 output
= frag_more (isize
);
1735 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1736 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1740 if (strcmp (op_end
, ""))
1741 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1744 as_fatal (_("Error in statement syntax"));
1748 /* Check for spl registers. */
1749 if (check_spl_reg (®2
))
1750 as_fatal (_("Cannot use special register with this instruction"));
1752 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1753 output
= frag_more (isize
);
1757 if (streq (name
, "imm"))
1758 as_fatal (_("An IMM instruction should not be present in the .s file"));
1760 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1762 if (exp
.X_op
!= O_constant
)
1765 relax_substateT subtype
;
1768 subtype
= get_imm_otype(exp
.X_md
);
1770 subtype
= opcode
->inst_offset_type
;
1772 output
= frag_var (rs_machine_dependent
,
1773 isize
* 2, /* maxm of 2 words. */
1774 isize
, /* minm of 1 word. */
1775 subtype
, /* PC-relative or not. */
1783 output
= frag_more (isize
);
1784 immed
= exp
.X_add_number
;
1788 temp
= immed
& 0xFFFF8000;
1789 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1791 /* Needs an immediate inst. */
1793 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1795 if (opcode1
== NULL
)
1797 as_bad (_("unknown opcode \"%s\""), "imm");
1801 inst1
= opcode1
->bit_sequence
;
1802 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1803 output
[0] = INST_BYTE0 (inst1
);
1804 output
[1] = INST_BYTE1 (inst1
);
1805 output
[2] = INST_BYTE2 (inst1
);
1806 output
[3] = INST_BYTE3 (inst1
);
1807 output
= frag_more (isize
);
1809 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1812 case INST_TYPE_NONE
:
1813 output
= frag_more (isize
);
1816 case INST_TYPE_IMM5
:
1817 if (strcmp(op_end
, ""))
1818 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM5
, MAX_IMM5
);
1820 as_fatal(_("Error in statement syntax"));
1821 if (exp
.X_op
!= O_constant
) {
1822 as_warn(_("Symbol used as immediate for mbar instruction"));
1824 output
= frag_more (isize
);
1825 immed
= exp
.X_add_number
;
1827 if (immed
!= (immed
% 32)) {
1828 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1831 inst
|= (immed
<< IMM_MBAR
);
1835 as_fatal (_("unimplemented opcode \"%s\""), name
);
1838 /* Drop whitespace after all the operands have been parsed. */
1839 while (ISSPACE (* op_end
))
1842 /* Give warning message if the insn has more operands than required. */
1843 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1844 as_warn (_("ignoring operands: %s "), op_end
);
1846 output
[0] = INST_BYTE0 (inst
);
1847 output
[1] = INST_BYTE1 (inst
);
1848 output
[2] = INST_BYTE2 (inst
);
1849 output
[3] = INST_BYTE3 (inst
);
1852 dwarf2_emit_insn (4);
1857 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1862 /* Turn a string in input_line_pointer into a floating point constant of type
1863 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1864 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1867 md_atof (int type
, char * litP
, int * sizeP
)
1870 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1902 return _("Bad call to MD_NTOF()");
1905 t
= atof_ieee (input_line_pointer
, type
, words
);
1908 input_line_pointer
= t
;
1910 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1912 if (! target_big_endian
)
1914 for (i
= prec
- 1; i
>= 0; i
--)
1916 md_number_to_chars (litP
, (valueT
) words
[i
],
1917 sizeof (LITTLENUM_TYPE
));
1918 litP
+= sizeof (LITTLENUM_TYPE
);
1922 for (i
= 0; i
< prec
; i
++)
1924 md_number_to_chars (litP
, (valueT
) words
[i
],
1925 sizeof (LITTLENUM_TYPE
));
1926 litP
+= sizeof (LITTLENUM_TYPE
);
1932 const char * md_shortopts
= "";
1934 struct option md_longopts
[] =
1936 {"EB", no_argument
, NULL
, OPTION_EB
},
1937 {"EL", no_argument
, NULL
, OPTION_EL
},
1938 {"mlittle-endian", no_argument
, NULL
, OPTION_EL
},
1939 {"mbig-endian", no_argument
, NULL
, OPTION_EB
},
1940 { NULL
, no_argument
, NULL
, 0}
1943 size_t md_longopts_size
= sizeof (md_longopts
);
1945 int md_short_jump_size
;
1948 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED
,
1949 addressT from_Nddr ATTRIBUTE_UNUSED
,
1950 addressT to_Nddr ATTRIBUTE_UNUSED
,
1951 fragS
* frag ATTRIBUTE_UNUSED
,
1952 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1954 as_fatal (_("failed sanity check: short_jump"));
1958 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED
,
1959 addressT from_Nddr ATTRIBUTE_UNUSED
,
1960 addressT to_Nddr ATTRIBUTE_UNUSED
,
1961 fragS
* frag ATTRIBUTE_UNUSED
,
1962 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1964 as_fatal (_("failed sanity check: long_jump"));
1967 /* Called after relaxing, change the frags so they know how big they are. */
1970 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1971 segT sec ATTRIBUTE_UNUSED
,
1976 switch (fragP
->fr_subtype
)
1978 case UNDEFINED_PC_OFFSET
:
1979 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1980 fragP
->fr_offset
, true, BFD_RELOC_64_PCREL
);
1981 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1984 case DEFINED_ABS_SEGMENT
:
1985 if (fragP
->fr_symbol
== GOT_symbol
)
1986 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1987 fragP
->fr_offset
, true, BFD_RELOC_MICROBLAZE_64_GOTPC
);
1989 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1990 fragP
->fr_offset
, false, BFD_RELOC_64
);
1991 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1994 case DEFINED_RO_SEGMENT
:
1995 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1996 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_32_ROSDA
);
1997 fragP
->fr_fix
+= INST_WORD_SIZE
;
2000 case DEFINED_RW_SEGMENT
:
2001 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
2002 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_32_RWSDA
);
2003 fragP
->fr_fix
+= INST_WORD_SIZE
;
2006 case DEFINED_PC_OFFSET
:
2007 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
2008 fragP
->fr_offset
, true, BFD_RELOC_MICROBLAZE_32_LO_PCREL
);
2009 fragP
->fr_fix
+= INST_WORD_SIZE
;
2012 case LARGE_DEFINED_PC_OFFSET
:
2013 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2014 fragP
->fr_offset
, true, BFD_RELOC_64_PCREL
);
2015 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2019 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2020 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_GOT
);
2021 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2025 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2026 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TEXTREL
);
2027 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2030 case TEXT_PC_OFFSET
:
2031 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2032 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TEXTPCREL
);
2033 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2037 fixP
= fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2038 fragP
->fr_offset
, true, BFD_RELOC_MICROBLAZE_64_PLT
);
2039 /* fixP->fx_plt = 1; */
2041 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2045 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2046 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_GOTOFF
);
2047 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2051 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2052 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TLSGD
);
2053 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2057 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2058 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TLSLD
);
2059 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2062 case TLSDTPREL_OFFSET
:
2063 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
2064 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TLSDTPREL
);
2065 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
2074 /* Applies the desired value to the specified location.
2075 Also sets up addends for 'rela' type relocations. */
2077 md_apply_fix (fixS
* fixP
,
2081 char * buf
= fixP
->fx_where
+ &fixP
->fx_frag
->fr_literal
[0];
2082 const char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
2083 const char * symname
;
2084 /* Note: use offsetT because it is signed, valueT is unsigned. */
2085 offsetT val
= (offsetT
) * valp
;
2087 struct op_code_struct
* opcode1
;
2088 unsigned long inst1
;
2090 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
2092 /* fixP->fx_offset is supposed to be set up correctly for all
2093 symbol relocations. */
2094 if (fixP
->fx_addsy
== NULL
)
2096 if (!fixP
->fx_pcrel
)
2097 fixP
->fx_offset
= val
; /* Absolute relocation. */
2099 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
2100 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
2103 /* If we aren't adjusting this fixup to be against the section
2104 symbol, we need to adjust the value. */
2105 if (fixP
->fx_addsy
!= NULL
)
2107 if (S_IS_WEAK (fixP
->fx_addsy
)
2108 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
2109 && (((bfd_section_flags (S_GET_SEGMENT (fixP
->fx_addsy
))
2110 & SEC_LINK_ONCE
) != 0)
2111 || startswith (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
2114 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2115 if (val
!= 0 && ! fixP
->fx_pcrel
)
2117 /* In this case, the bfd_install_relocation routine will
2118 incorrectly add the symbol value back in. We just want
2119 the addend to appear in the object file.
2120 FIXME: If this makes VALUE zero, we're toast. */
2121 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2126 /* If the fix is relative to a symbol which is not defined, or not
2127 in the same segment as the fix, we cannot resolve it here. */
2128 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
2129 if (fixP
->fx_addsy
!= NULL
2130 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2131 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
2135 /* For ELF we can just return and let the reloc that will be generated
2136 take care of everything. For COFF we still have to insert 'val'
2137 into the insn since the addend field will be ignored. */
2141 /* All fixups in the text section must be handled in the linker. */
2142 else if (segment
->flags
& SEC_CODE
)
2144 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
2149 switch (fixP
->fx_r_type
)
2151 case BFD_RELOC_MICROBLAZE_32_LO
:
2152 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2153 if (target_big_endian
)
2155 buf
[2] |= ((val
>> 8) & 0xff);
2156 buf
[3] |= (val
& 0xff);
2160 buf
[1] |= ((val
>> 8) & 0xff);
2161 buf
[0] |= (val
& 0xff);
2164 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2165 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2166 /* Don't do anything if the symbol is not defined. */
2167 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2169 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
2170 as_bad_where (file
, fixP
->fx_line
,
2171 _("pcrel for branch to %s too far (0x%x)"),
2172 symname
, (int) val
);
2173 if (target_big_endian
)
2175 buf
[2] |= ((val
>> 8) & 0xff);
2176 buf
[3] |= (val
& 0xff);
2180 buf
[1] |= ((val
>> 8) & 0xff);
2181 buf
[0] |= (val
& 0xff);
2187 case BFD_RELOC_32_PCREL
:
2188 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2189 /* Don't do anything if the symbol is not defined. */
2190 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2192 if (target_big_endian
)
2194 buf
[0] |= ((val
>> 24) & 0xff);
2195 buf
[1] |= ((val
>> 16) & 0xff);
2196 buf
[2] |= ((val
>> 8) & 0xff);
2197 buf
[3] |= (val
& 0xff);
2201 buf
[3] |= ((val
>> 24) & 0xff);
2202 buf
[2] |= ((val
>> 16) & 0xff);
2203 buf
[1] |= ((val
>> 8) & 0xff);
2204 buf
[0] |= (val
& 0xff);
2208 case BFD_RELOC_64_PCREL
:
2210 case BFD_RELOC_MICROBLAZE_64_TEXTREL
:
2211 /* Add an imm instruction. First save the current instruction. */
2212 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2213 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2215 /* Generate the imm instruction. */
2217 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
, "imm");
2218 if (opcode1
== NULL
)
2220 as_bad (_("unknown opcode \"%s\""), "imm");
2224 inst1
= opcode1
->bit_sequence
;
2225 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2226 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
2228 buf
[0] = INST_BYTE0 (inst1
);
2229 buf
[1] = INST_BYTE1 (inst1
);
2230 buf
[2] = INST_BYTE2 (inst1
);
2231 buf
[3] = INST_BYTE3 (inst1
);
2233 /* Add the value only if the symbol is defined. */
2234 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2236 if (target_big_endian
)
2238 buf
[6] |= ((val
>> 8) & 0xff);
2239 buf
[7] |= (val
& 0xff);
2243 buf
[5] |= ((val
>> 8) & 0xff);
2244 buf
[4] |= (val
& 0xff);
2249 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2250 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2251 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2252 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2255 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2256 case BFD_RELOC_MICROBLAZE_64_GOT
:
2257 case BFD_RELOC_MICROBLAZE_64_PLT
:
2258 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2259 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL
:
2260 /* Add an imm instruction. First save the current instruction. */
2261 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2262 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2264 /* Generate the imm instruction. */
2266 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
, "imm");
2267 if (opcode1
== NULL
)
2269 as_bad (_("unknown opcode \"%s\""), "imm");
2273 inst1
= opcode1
->bit_sequence
;
2275 /* We can fixup call to a defined non-global address
2276 within the same section only. */
2277 buf
[0] = INST_BYTE0 (inst1
);
2278 buf
[1] = INST_BYTE1 (inst1
);
2279 buf
[2] = INST_BYTE2 (inst1
);
2280 buf
[3] = INST_BYTE3 (inst1
);
2287 if (fixP
->fx_addsy
== NULL
)
2289 /* This fixup has been resolved. Create a reloc in case the linker
2290 moves code around due to relaxing. */
2291 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2292 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2293 else if (fixP
->fx_r_type
== BFD_RELOC_32
)
2294 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_32_NONE
;
2296 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2297 fixP
->fx_addsy
= section_symbol (absolute_section
);
2303 md_operand (expressionS
* expressionP
)
2305 /* Ignore leading hash symbol, if present. */
2306 if (*input_line_pointer
== '#')
2308 input_line_pointer
++;
2309 expression (expressionP
);
2313 /* Called just before address relaxation, return the length
2314 by which a fragment must grow to reach it's destination. */
2317 md_estimate_size_before_relax (fragS
* fragP
,
2320 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2321 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2322 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2323 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2325 switch (fragP
->fr_subtype
)
2327 case INST_PC_OFFSET
:
2328 /* Used to be a PC-relative branch. */
2329 if (!fragP
->fr_symbol
)
2331 /* We know the abs value: Should never happen. */
2332 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2335 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
&&
2336 !S_IS_WEAK (fragP
->fr_symbol
))
2338 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2339 /* Don't know now whether we need an imm instruction. */
2340 fragP
->fr_var
= INST_WORD_SIZE
;
2342 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2343 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2345 /* Cannot have a PC-relative branch to a diff segment. */
2346 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2347 S_GET_NAME (fragP
->fr_symbol
));
2348 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2349 fragP
->fr_var
= INST_WORD_SIZE
*2;
2353 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2354 fragP
->fr_var
= INST_WORD_SIZE
*2;
2358 case INST_NO_OFFSET
:
2360 /* Used to be a reference to somewhere which was unknown. */
2361 if (fragP
->fr_symbol
)
2363 if (fragP
->fr_opcode
== NULL
)
2365 /* Used as an absolute value. */
2366 if (fragP
->fr_subtype
== INST_NO_OFFSET
)
2367 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2368 /* Variable part does not change. */
2369 fragP
->fr_var
= INST_WORD_SIZE
*2;
2371 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2373 /* It is accessed using the small data read only anchor. */
2374 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2375 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2376 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2377 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2379 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2380 fragP
->fr_var
= INST_WORD_SIZE
;
2384 /* Variable not in small data read only segment accessed
2385 using small data read only anchor. */
2386 const char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2388 as_bad_where (file
, fragP
->fr_line
,
2389 _("Variable is accessed using small data read "
2390 "only anchor, but it is not in the small data "
2391 "read only section"));
2392 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2393 fragP
->fr_var
= INST_WORD_SIZE
;
2396 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2398 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2399 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2400 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2401 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2403 /* It is accessed using the small data read write anchor. */
2404 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2405 fragP
->fr_var
= INST_WORD_SIZE
;
2409 const char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2411 as_bad_where (file
, fragP
->fr_line
,
2412 _("Variable is accessed using small data read "
2413 "write anchor, but it is not in the small data "
2414 "read write section"));
2415 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2416 fragP
->fr_var
= INST_WORD_SIZE
;
2421 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2427 /* We know the abs value: Should never happen. */
2428 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2433 case UNDEFINED_PC_OFFSET
:
2434 case LARGE_DEFINED_PC_OFFSET
:
2435 case DEFINED_ABS_SEGMENT
:
2439 case TEXT_PC_OFFSET
:
2442 case TLSTPREL_OFFSET
:
2443 case TLSDTPREL_OFFSET
:
2444 fragP
->fr_var
= INST_WORD_SIZE
*2;
2446 case DEFINED_RO_SEGMENT
:
2447 case DEFINED_RW_SEGMENT
:
2448 case DEFINED_PC_OFFSET
:
2449 case TLSDTPMOD_OFFSET
:
2450 fragP
->fr_var
= INST_WORD_SIZE
;
2456 return fragP
->fr_var
;
2459 /* Put number into target byte order. */
2462 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2464 if (target_big_endian
)
2465 number_to_chars_bigendian (ptr
, use
, nbytes
);
2467 number_to_chars_littleendian (ptr
, use
, nbytes
);
2470 /* Round up a section size to the appropriate boundary. */
2473 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2475 return size
; /* Byte alignment is fine. */
2479 /* The location from which a PC relative jump should be calculated,
2480 given a PC relative reloc. */
2483 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2486 /* If the symbol is undefined or defined in another section
2487 we leave the add number alone for the linker to fix it later.
2488 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2490 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2491 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2492 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2496 /* The case where we are going to resolve things... */
2497 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2498 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2500 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2506 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2507 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2510 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2513 bfd_reloc_code_real_type code
;
2515 switch (fixp
->fx_r_type
)
2517 case BFD_RELOC_NONE
:
2518 case BFD_RELOC_MICROBLAZE_32_NONE
:
2519 case BFD_RELOC_MICROBLAZE_64_NONE
:
2521 case BFD_RELOC_MICROBLAZE_32_LO
:
2522 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2525 case BFD_RELOC_64_PCREL
:
2526 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2527 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2528 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2529 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2530 case BFD_RELOC_MICROBLAZE_64_GOT
:
2531 case BFD_RELOC_MICROBLAZE_64_PLT
:
2532 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2533 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2534 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2535 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2536 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
2537 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
2538 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2539 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
2540 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
2541 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL
:
2542 case BFD_RELOC_MICROBLAZE_64_TEXTREL
:
2543 code
= fixp
->fx_r_type
;
2547 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2549 MAP (1, 0, BFD_RELOC_8
);
2550 MAP (2, 0, BFD_RELOC_16
);
2551 MAP (4, 0, BFD_RELOC_32
);
2552 MAP (1, 1, BFD_RELOC_8_PCREL
);
2553 MAP (2, 1, BFD_RELOC_16_PCREL
);
2554 MAP (4, 1, BFD_RELOC_32_PCREL
);
2556 code
= fixp
->fx_r_type
;
2557 as_bad (_("Can not do %d byte %srelocation"),
2559 fixp
->fx_pcrel
? _("pc-relative ") : "");
2564 rel
= XNEW (arelent
);
2565 rel
->sym_ptr_ptr
= XNEW (asymbol
*);
2567 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2568 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2570 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2572 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2573 /* Always pass the addend along! */
2574 rel
->addend
= fixp
->fx_offset
;
2575 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2577 if (rel
->howto
== NULL
)
2579 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2580 _("Cannot represent relocation type %s"),
2581 bfd_get_reloc_code_name (code
));
2583 /* Set howto to a garbage value so that we can keep going. */
2584 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2585 gas_assert (rel
->howto
!= NULL
);
2591 md_parse_option (int c
, const char * arg ATTRIBUTE_UNUSED
)
2596 target_big_endian
= 1;
2599 target_big_endian
= 0;
2608 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2610 /* fprintf(stream, _("\
2611 MicroBlaze options:\n\
2612 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2613 fprintf (stream
, _(" MicroBlaze specific assembler options:\n"));
2614 fprintf (stream
, " -%-23s%s\n", "mbig-endian", N_("assemble for a big endian cpu"));
2615 fprintf (stream
, " -%-23s%s\n", "mlittle-endian", N_("assemble for a little endian cpu"));
2619 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2620 found a machine specific op in an expression,
2621 then we create relocs accordingly. */
2624 cons_fix_new_microblaze (fragS
* frag
,
2628 bfd_reloc_code_real_type r
)
2630 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2631 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2632 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2633 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2634 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2636 exp
->X_op
= O_symbol
;
2637 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2656 as_bad (_("unsupported BFD relocation size %u"), size
);
2661 fix_new_exp (frag
, where
, size
, exp
, 0, r
);