1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright (C) 2009-2022 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 (e
->X_add_number
< min
|| 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, 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_R1_R2
:
1181 if (strcmp (op_end
, ""))
1182 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1185 as_fatal (_("Error in statement syntax"));
1188 if (strcmp (op_end
, ""))
1189 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1192 as_fatal (_("Error in statement syntax"));
1196 /* Check for spl registers. */
1197 if (check_spl_reg (& reg1
))
1198 as_fatal (_("Cannot use special register with this instruction"));
1199 if (check_spl_reg (& reg2
))
1200 as_fatal (_("Cannot use special register with this instruction"));
1202 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1203 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1204 output
= frag_more (isize
);
1207 case INST_TYPE_RD_R1
:
1208 if (strcmp (op_end
, ""))
1209 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1212 as_fatal (_("Error in statement syntax"));
1215 if (strcmp (op_end
, ""))
1216 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1219 as_fatal (_("Error in statement syntax"));
1223 /* Check for spl registers. */
1224 if (check_spl_reg (®1
))
1225 as_fatal (_("Cannot use special register with this instruction"));
1226 if (check_spl_reg (®2
))
1227 as_fatal (_("Cannot use special register with this instruction"));
1229 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1230 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1231 output
= frag_more (isize
);
1234 case INST_TYPE_RD_RFSL
:
1235 if (strcmp (op_end
, ""))
1236 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1239 as_fatal (_("Error in statement syntax"));
1242 if (strcmp (op_end
, ""))
1243 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1246 as_fatal (_("Error in statement syntax"));
1250 /* Check for spl registers. */
1251 if (check_spl_reg (®1
))
1252 as_fatal (_("Cannot use special register with this instruction"));
1254 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1255 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1256 output
= frag_more (isize
);
1259 case INST_TYPE_RD_IMM15
:
1260 if (strcmp (op_end
, ""))
1261 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1264 as_fatal (_("Error in statement syntax"));
1268 if (strcmp (op_end
, ""))
1269 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1271 as_fatal (_("Error in statement syntax"));
1273 /* Check for spl registers. */
1274 if (check_spl_reg (®1
))
1275 as_fatal (_("Cannot use special register with this instruction"));
1277 if (exp
.X_op
!= O_constant
)
1278 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1281 output
= frag_more (isize
);
1282 immed
= exp
.X_add_number
;
1284 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1285 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1288 case INST_TYPE_R1_RFSL
:
1289 if (strcmp (op_end
, ""))
1290 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1293 as_fatal (_("Error in statement syntax"));
1296 if (strcmp (op_end
, ""))
1297 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
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"));
1308 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1309 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1310 output
= frag_more (isize
);
1313 case INST_TYPE_RFSL
:
1314 if (strcmp (op_end
, ""))
1315 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1318 as_fatal (_("Error in statement syntax"));
1321 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1322 output
= frag_more (isize
);
1326 if (strcmp (op_end
, ""))
1327 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1330 as_fatal (_("Error in statement syntax"));
1334 /* Check for spl registers. */
1335 if (check_spl_reg (®1
))
1336 as_fatal (_("Cannot use special register with this instruction"));
1338 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1339 output
= frag_more (isize
);
1342 /* For tuqula insn...:) */
1344 if (strcmp (op_end
, ""))
1345 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1348 as_fatal (_("Error in statement syntax"));
1352 /* Check for spl registers. */
1353 if (check_spl_reg (®1
))
1354 as_fatal (_("Cannot use special register with this instruction"));
1356 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1357 output
= frag_more (isize
);
1360 case INST_TYPE_RD_SPECIAL
:
1361 if (strcmp (op_end
, ""))
1362 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1365 as_fatal (_("Error in statement syntax"));
1368 if (strcmp (op_end
, ""))
1369 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1372 as_fatal (_("Error in statement syntax"));
1376 if (reg2
== REG_MSR
)
1377 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1378 else if (reg2
== REG_PC
)
1379 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1380 else if (reg2
== REG_EAR
)
1381 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1382 else if (reg2
== REG_ESR
)
1383 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1384 else if (reg2
== REG_FSR
)
1385 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1386 else if (reg2
== REG_BTR
)
1387 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1388 else if (reg2
== REG_EDR
)
1389 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1390 else if (reg2
== REG_PID
)
1391 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1392 else if (reg2
== REG_ZPR
)
1393 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1394 else if (reg2
== REG_TLBX
)
1395 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1396 else if (reg2
== REG_TLBLO
)
1397 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1398 else if (reg2
== REG_TLBHI
)
1399 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1400 else if (reg2
== REG_SHR
)
1401 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1402 else if (reg2
== REG_SLR
)
1403 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1404 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1405 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1407 as_fatal (_("invalid value for special purpose register"));
1408 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1409 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1410 output
= frag_more (isize
);
1413 case INST_TYPE_SPECIAL_R1
:
1414 if (strcmp (op_end
, ""))
1415 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1418 as_fatal (_("Error in statement syntax"));
1421 if (strcmp (op_end
, ""))
1422 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1425 as_fatal (_("Error in statement syntax"));
1429 if (reg1
== REG_MSR
)
1430 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1431 else if (reg1
== REG_PC
)
1432 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1433 else if (reg1
== REG_EAR
)
1434 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1435 else if (reg1
== REG_ESR
)
1436 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1437 else if (reg1
== REG_FSR
)
1438 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1439 else if (reg1
== REG_BTR
)
1440 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1441 else if (reg1
== REG_EDR
)
1442 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1443 else if (reg1
== REG_PID
)
1444 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1445 else if (reg1
== REG_ZPR
)
1446 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1447 else if (reg1
== REG_TLBX
)
1448 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1449 else if (reg1
== REG_TLBLO
)
1450 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1451 else if (reg1
== REG_TLBHI
)
1452 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1453 else if (reg1
== REG_TLBSX
)
1454 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1455 else if (reg1
== REG_SHR
)
1456 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1457 else if (reg1
== REG_SLR
)
1458 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1460 as_fatal (_("invalid value for special purpose register"));
1461 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1462 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1463 output
= frag_more (isize
);
1466 case INST_TYPE_R1_R2_SPECIAL
:
1467 if (strcmp (op_end
, ""))
1468 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1471 as_fatal (_("Error in statement syntax"));
1474 if (strcmp (op_end
, ""))
1475 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1478 as_fatal (_("Error in statement syntax"));
1482 /* Check for spl registers. */
1483 if (check_spl_reg (®1
))
1484 as_fatal (_("Cannot use special register with this instruction"));
1485 if (check_spl_reg (®2
))
1486 as_fatal (_("Cannot use special register with this instruction"));
1488 /* insn wic ra, rb => wic ra, ra, rb. */
1489 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1490 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1492 output
= frag_more (isize
);
1495 case INST_TYPE_RD_R2
:
1496 if (strcmp (op_end
, ""))
1497 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1500 as_fatal (_("Error in statement syntax"));
1503 if (strcmp (op_end
, ""))
1504 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1507 as_fatal (_("Error in statement syntax"));
1511 /* Check for spl registers. */
1512 if (check_spl_reg (®1
))
1513 as_fatal (_("Cannot use special register with this instruction"));
1514 if (check_spl_reg (®2
))
1515 as_fatal (_("Cannot use special register with this instruction"));
1517 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1518 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1519 output
= frag_more (isize
);
1522 case INST_TYPE_R1_IMM
:
1523 if (strcmp (op_end
, ""))
1524 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1527 as_fatal (_("Error in statement syntax"));
1530 if (strcmp (op_end
, ""))
1531 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1533 as_fatal (_("Error in statement syntax"));
1535 /* Check for spl registers. */
1536 if (check_spl_reg (®1
))
1537 as_fatal (_("Cannot use special register with this instruction"));
1539 if (exp
.X_op
!= O_constant
)
1542 relax_substateT subtype
;
1545 subtype
= get_imm_otype(exp
.X_md
);
1547 subtype
= opcode
->inst_offset_type
;
1549 output
= frag_var (rs_machine_dependent
,
1550 isize
* 2, /* maxm of 2 words. */
1551 isize
, /* minm of 1 word. */
1552 subtype
, /* PC-relative or not. */
1560 output
= frag_more (isize
);
1561 immed
= exp
.X_add_number
;
1564 temp
= immed
& 0xFFFF8000;
1565 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1567 /* Needs an immediate inst. */
1569 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1571 if (opcode1
== NULL
)
1573 as_bad (_("unknown opcode \"%s\""), "imm");
1577 inst1
= opcode1
->bit_sequence
;
1578 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1579 output
[0] = INST_BYTE0 (inst1
);
1580 output
[1] = INST_BYTE1 (inst1
);
1581 output
[2] = INST_BYTE2 (inst1
);
1582 output
[3] = INST_BYTE3 (inst1
);
1583 output
= frag_more (isize
);
1586 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1587 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1590 case INST_TYPE_RD_IMM
:
1591 if (strcmp (op_end
, ""))
1592 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1595 as_fatal (_("Error in statement syntax"));
1598 if (strcmp (op_end
, ""))
1599 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1601 as_fatal (_("Error in statement syntax"));
1603 /* Check for spl registers. */
1604 if (check_spl_reg (®1
))
1605 as_fatal (_("Cannot use special register with this instruction"));
1607 if (exp
.X_op
!= O_constant
)
1610 relax_substateT subtype
;
1613 subtype
= get_imm_otype(exp
.X_md
);
1615 subtype
= opcode
->inst_offset_type
;
1617 output
= frag_var (rs_machine_dependent
,
1618 isize
* 2, /* maxm of 2 words. */
1619 isize
, /* minm of 1 word. */
1620 subtype
, /* PC-relative or not. */
1628 output
= frag_more (isize
);
1629 immed
= exp
.X_add_number
;
1632 temp
= immed
& 0xFFFF8000;
1633 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1635 /* Needs an immediate inst. */
1637 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1639 if (opcode1
== NULL
)
1641 as_bad (_("unknown opcode \"%s\""), "imm");
1645 inst1
= opcode1
->bit_sequence
;
1646 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1647 output
[0] = INST_BYTE0 (inst1
);
1648 output
[1] = INST_BYTE1 (inst1
);
1649 output
[2] = INST_BYTE2 (inst1
);
1650 output
[3] = INST_BYTE3 (inst1
);
1651 output
= frag_more (isize
);
1654 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1655 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1659 if (strcmp (op_end
, ""))
1660 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1663 as_fatal (_("Error in statement syntax"));
1667 /* Check for spl registers. */
1668 if (check_spl_reg (®2
))
1669 as_fatal (_("Cannot use special register with this instruction"));
1671 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1672 output
= frag_more (isize
);
1676 if (streq (name
, "imm"))
1677 as_fatal (_("An IMM instruction should not be present in the .s file"));
1679 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1681 if (exp
.X_op
!= O_constant
)
1684 relax_substateT subtype
;
1687 subtype
= get_imm_otype(exp
.X_md
);
1689 subtype
= opcode
->inst_offset_type
;
1691 output
= frag_var (rs_machine_dependent
,
1692 isize
* 2, /* maxm of 2 words. */
1693 isize
, /* minm of 1 word. */
1694 subtype
, /* PC-relative or not. */
1702 output
= frag_more (isize
);
1703 immed
= exp
.X_add_number
;
1707 temp
= immed
& 0xFFFF8000;
1708 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1710 /* Needs an immediate inst. */
1712 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
,
1714 if (opcode1
== NULL
)
1716 as_bad (_("unknown opcode \"%s\""), "imm");
1720 inst1
= opcode1
->bit_sequence
;
1721 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1722 output
[0] = INST_BYTE0 (inst1
);
1723 output
[1] = INST_BYTE1 (inst1
);
1724 output
[2] = INST_BYTE2 (inst1
);
1725 output
[3] = INST_BYTE3 (inst1
);
1726 output
= frag_more (isize
);
1728 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1731 case INST_TYPE_NONE
:
1732 output
= frag_more (isize
);
1735 case INST_TYPE_IMM5
:
1736 if (strcmp(op_end
, ""))
1737 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM5
, MAX_IMM5
);
1739 as_fatal(_("Error in statement syntax"));
1740 if (exp
.X_op
!= O_constant
) {
1741 as_warn(_("Symbol used as immediate for mbar instruction"));
1743 output
= frag_more (isize
);
1744 immed
= exp
.X_add_number
;
1746 if (immed
!= (immed
% 32)) {
1747 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1750 inst
|= (immed
<< IMM_MBAR
);
1754 as_fatal (_("unimplemented opcode \"%s\""), name
);
1757 /* Drop whitespace after all the operands have been parsed. */
1758 while (ISSPACE (* op_end
))
1761 /* Give warning message if the insn has more operands than required. */
1762 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1763 as_warn (_("ignoring operands: %s "), op_end
);
1765 output
[0] = INST_BYTE0 (inst
);
1766 output
[1] = INST_BYTE1 (inst
);
1767 output
[2] = INST_BYTE2 (inst
);
1768 output
[3] = INST_BYTE3 (inst
);
1771 dwarf2_emit_insn (4);
1776 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1781 /* Turn a string in input_line_pointer into a floating point constant of type
1782 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1783 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1786 md_atof (int type
, char * litP
, int * sizeP
)
1789 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1821 return _("Bad call to MD_NTOF()");
1824 t
= atof_ieee (input_line_pointer
, type
, words
);
1827 input_line_pointer
= t
;
1829 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1831 if (! target_big_endian
)
1833 for (i
= prec
- 1; i
>= 0; i
--)
1835 md_number_to_chars (litP
, (valueT
) words
[i
],
1836 sizeof (LITTLENUM_TYPE
));
1837 litP
+= sizeof (LITTLENUM_TYPE
);
1841 for (i
= 0; i
< prec
; i
++)
1843 md_number_to_chars (litP
, (valueT
) words
[i
],
1844 sizeof (LITTLENUM_TYPE
));
1845 litP
+= sizeof (LITTLENUM_TYPE
);
1851 const char * md_shortopts
= "";
1853 struct option md_longopts
[] =
1855 {"EB", no_argument
, NULL
, OPTION_EB
},
1856 {"EL", no_argument
, NULL
, OPTION_EL
},
1857 { NULL
, no_argument
, NULL
, 0}
1860 size_t md_longopts_size
= sizeof (md_longopts
);
1862 int md_short_jump_size
;
1865 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED
,
1866 addressT from_Nddr ATTRIBUTE_UNUSED
,
1867 addressT to_Nddr ATTRIBUTE_UNUSED
,
1868 fragS
* frag ATTRIBUTE_UNUSED
,
1869 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1871 as_fatal (_("failed sanity check: short_jump"));
1875 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED
,
1876 addressT from_Nddr ATTRIBUTE_UNUSED
,
1877 addressT to_Nddr ATTRIBUTE_UNUSED
,
1878 fragS
* frag ATTRIBUTE_UNUSED
,
1879 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1881 as_fatal (_("failed sanity check: long_jump"));
1884 /* Called after relaxing, change the frags so they know how big they are. */
1887 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1888 segT sec ATTRIBUTE_UNUSED
,
1893 switch (fragP
->fr_subtype
)
1895 case UNDEFINED_PC_OFFSET
:
1896 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1897 fragP
->fr_offset
, true, BFD_RELOC_64_PCREL
);
1898 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1901 case DEFINED_ABS_SEGMENT
:
1902 if (fragP
->fr_symbol
== GOT_symbol
)
1903 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1904 fragP
->fr_offset
, true, BFD_RELOC_MICROBLAZE_64_GOTPC
);
1906 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1907 fragP
->fr_offset
, false, BFD_RELOC_64
);
1908 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1911 case DEFINED_RO_SEGMENT
:
1912 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1913 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_32_ROSDA
);
1914 fragP
->fr_fix
+= INST_WORD_SIZE
;
1917 case DEFINED_RW_SEGMENT
:
1918 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1919 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_32_RWSDA
);
1920 fragP
->fr_fix
+= INST_WORD_SIZE
;
1923 case DEFINED_PC_OFFSET
:
1924 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1925 fragP
->fr_offset
, true, BFD_RELOC_MICROBLAZE_32_LO_PCREL
);
1926 fragP
->fr_fix
+= INST_WORD_SIZE
;
1929 case LARGE_DEFINED_PC_OFFSET
:
1930 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1931 fragP
->fr_offset
, true, BFD_RELOC_64_PCREL
);
1932 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1936 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1937 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_GOT
);
1938 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1942 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1943 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TEXTREL
);
1944 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1947 case TEXT_PC_OFFSET
:
1948 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1949 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TEXTPCREL
);
1950 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1954 fixP
= fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1955 fragP
->fr_offset
, true, BFD_RELOC_MICROBLAZE_64_PLT
);
1956 /* fixP->fx_plt = 1; */
1958 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1962 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1963 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_GOTOFF
);
1964 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1968 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1969 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TLSGD
);
1970 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1974 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1975 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TLSLD
);
1976 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1979 case TLSDTPREL_OFFSET
:
1980 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1981 fragP
->fr_offset
, false, BFD_RELOC_MICROBLAZE_64_TLSDTPREL
);
1982 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1991 /* Applies the desired value to the specified location.
1992 Also sets up addends for 'rela' type relocations. */
1994 md_apply_fix (fixS
* fixP
,
1998 char * buf
= fixP
->fx_where
+ &fixP
->fx_frag
->fr_literal
[0];
1999 const char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
2000 const char * symname
;
2001 /* Note: use offsetT because it is signed, valueT is unsigned. */
2002 offsetT val
= (offsetT
) * valp
;
2004 struct op_code_struct
* opcode1
;
2005 unsigned long inst1
;
2007 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
2009 /* fixP->fx_offset is supposed to be set up correctly for all
2010 symbol relocations. */
2011 if (fixP
->fx_addsy
== NULL
)
2013 if (!fixP
->fx_pcrel
)
2014 fixP
->fx_offset
= val
; /* Absolute relocation. */
2016 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
2017 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
2020 /* If we aren't adjusting this fixup to be against the section
2021 symbol, we need to adjust the value. */
2022 if (fixP
->fx_addsy
!= NULL
)
2024 if (S_IS_WEAK (fixP
->fx_addsy
)
2025 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
2026 && (((bfd_section_flags (S_GET_SEGMENT (fixP
->fx_addsy
))
2027 & SEC_LINK_ONCE
) != 0)
2028 || startswith (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
2031 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2032 if (val
!= 0 && ! fixP
->fx_pcrel
)
2034 /* In this case, the bfd_install_relocation routine will
2035 incorrectly add the symbol value back in. We just want
2036 the addend to appear in the object file.
2037 FIXME: If this makes VALUE zero, we're toast. */
2038 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2043 /* If the fix is relative to a symbol which is not defined, or not
2044 in the same segment as the fix, we cannot resolve it here. */
2045 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
2046 if (fixP
->fx_addsy
!= NULL
2047 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2048 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
2052 /* For ELF we can just return and let the reloc that will be generated
2053 take care of everything. For COFF we still have to insert 'val'
2054 into the insn since the addend field will be ignored. */
2058 /* All fixups in the text section must be handled in the linker. */
2059 else if (segment
->flags
& SEC_CODE
)
2061 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
2066 switch (fixP
->fx_r_type
)
2068 case BFD_RELOC_MICROBLAZE_32_LO
:
2069 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2070 if (target_big_endian
)
2072 buf
[2] |= ((val
>> 8) & 0xff);
2073 buf
[3] |= (val
& 0xff);
2077 buf
[1] |= ((val
>> 8) & 0xff);
2078 buf
[0] |= (val
& 0xff);
2081 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2082 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2083 /* Don't do anything if the symbol is not defined. */
2084 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2086 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
2087 as_bad_where (file
, fixP
->fx_line
,
2088 _("pcrel for branch to %s too far (0x%x)"),
2089 symname
, (int) val
);
2090 if (target_big_endian
)
2092 buf
[2] |= ((val
>> 8) & 0xff);
2093 buf
[3] |= (val
& 0xff);
2097 buf
[1] |= ((val
>> 8) & 0xff);
2098 buf
[0] |= (val
& 0xff);
2104 case BFD_RELOC_32_PCREL
:
2105 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2106 /* Don't do anything if the symbol is not defined. */
2107 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2109 if (target_big_endian
)
2111 buf
[0] |= ((val
>> 24) & 0xff);
2112 buf
[1] |= ((val
>> 16) & 0xff);
2113 buf
[2] |= ((val
>> 8) & 0xff);
2114 buf
[3] |= (val
& 0xff);
2118 buf
[3] |= ((val
>> 24) & 0xff);
2119 buf
[2] |= ((val
>> 16) & 0xff);
2120 buf
[1] |= ((val
>> 8) & 0xff);
2121 buf
[0] |= (val
& 0xff);
2125 case BFD_RELOC_64_PCREL
:
2127 case BFD_RELOC_MICROBLAZE_64_TEXTREL
:
2128 /* Add an imm instruction. First save the current instruction. */
2129 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2130 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2132 /* Generate the imm instruction. */
2134 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
, "imm");
2135 if (opcode1
== NULL
)
2137 as_bad (_("unknown opcode \"%s\""), "imm");
2141 inst1
= opcode1
->bit_sequence
;
2142 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2143 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
2145 buf
[0] = INST_BYTE0 (inst1
);
2146 buf
[1] = INST_BYTE1 (inst1
);
2147 buf
[2] = INST_BYTE2 (inst1
);
2148 buf
[3] = INST_BYTE3 (inst1
);
2150 /* Add the value only if the symbol is defined. */
2151 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2153 if (target_big_endian
)
2155 buf
[6] |= ((val
>> 8) & 0xff);
2156 buf
[7] |= (val
& 0xff);
2160 buf
[5] |= ((val
>> 8) & 0xff);
2161 buf
[4] |= (val
& 0xff);
2166 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2167 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2168 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2169 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2172 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2173 case BFD_RELOC_MICROBLAZE_64_GOT
:
2174 case BFD_RELOC_MICROBLAZE_64_PLT
:
2175 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2176 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL
:
2177 /* Add an imm instruction. First save the current instruction. */
2178 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2179 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2181 /* Generate the imm instruction. */
2183 = (struct op_code_struct
*) str_hash_find (opcode_hash_control
, "imm");
2184 if (opcode1
== NULL
)
2186 as_bad (_("unknown opcode \"%s\""), "imm");
2190 inst1
= opcode1
->bit_sequence
;
2192 /* We can fixup call to a defined non-global address
2193 within the same section only. */
2194 buf
[0] = INST_BYTE0 (inst1
);
2195 buf
[1] = INST_BYTE1 (inst1
);
2196 buf
[2] = INST_BYTE2 (inst1
);
2197 buf
[3] = INST_BYTE3 (inst1
);
2204 if (fixP
->fx_addsy
== NULL
)
2206 /* This fixup has been resolved. Create a reloc in case the linker
2207 moves code around due to relaxing. */
2208 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2209 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2211 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2212 fixP
->fx_addsy
= section_symbol (absolute_section
);
2218 md_operand (expressionS
* expressionP
)
2220 /* Ignore leading hash symbol, if present. */
2221 if (*input_line_pointer
== '#')
2223 input_line_pointer
++;
2224 expression (expressionP
);
2228 /* Called just before address relaxation, return the length
2229 by which a fragment must grow to reach it's destination. */
2232 md_estimate_size_before_relax (fragS
* fragP
,
2235 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2236 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2237 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2238 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2240 switch (fragP
->fr_subtype
)
2242 case INST_PC_OFFSET
:
2243 /* Used to be a PC-relative branch. */
2244 if (!fragP
->fr_symbol
)
2246 /* We know the abs value: Should never happen. */
2247 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2250 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
&&
2251 !S_IS_WEAK (fragP
->fr_symbol
))
2253 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2254 /* Don't know now whether we need an imm instruction. */
2255 fragP
->fr_var
= INST_WORD_SIZE
;
2257 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2258 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2260 /* Cannot have a PC-relative branch to a diff segment. */
2261 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2262 S_GET_NAME (fragP
->fr_symbol
));
2263 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2264 fragP
->fr_var
= INST_WORD_SIZE
*2;
2268 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2269 fragP
->fr_var
= INST_WORD_SIZE
*2;
2273 case INST_NO_OFFSET
:
2275 /* Used to be a reference to somewhere which was unknown. */
2276 if (fragP
->fr_symbol
)
2278 if (fragP
->fr_opcode
== NULL
)
2280 /* Used as an absolute value. */
2281 if (fragP
->fr_subtype
== INST_NO_OFFSET
)
2282 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2283 /* Variable part does not change. */
2284 fragP
->fr_var
= INST_WORD_SIZE
*2;
2286 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2288 /* It is accessed using the small data read only anchor. */
2289 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2290 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2291 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2292 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2294 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2295 fragP
->fr_var
= INST_WORD_SIZE
;
2299 /* Variable not in small data read only segment accessed
2300 using small data read only anchor. */
2301 const char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2303 as_bad_where (file
, fragP
->fr_line
,
2304 _("Variable is accessed using small data read "
2305 "only anchor, but it is not in the small data "
2306 "read only section"));
2307 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2308 fragP
->fr_var
= INST_WORD_SIZE
;
2311 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2313 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2314 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2315 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2316 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2318 /* It is accessed using the small data read write anchor. */
2319 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2320 fragP
->fr_var
= INST_WORD_SIZE
;
2324 const char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2326 as_bad_where (file
, fragP
->fr_line
,
2327 _("Variable is accessed using small data read "
2328 "write anchor, but it is not in the small data "
2329 "read write section"));
2330 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2331 fragP
->fr_var
= INST_WORD_SIZE
;
2336 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2342 /* We know the abs value: Should never happen. */
2343 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2348 case UNDEFINED_PC_OFFSET
:
2349 case LARGE_DEFINED_PC_OFFSET
:
2350 case DEFINED_ABS_SEGMENT
:
2354 case TEXT_PC_OFFSET
:
2357 case TLSTPREL_OFFSET
:
2358 case TLSDTPREL_OFFSET
:
2359 fragP
->fr_var
= INST_WORD_SIZE
*2;
2361 case DEFINED_RO_SEGMENT
:
2362 case DEFINED_RW_SEGMENT
:
2363 case DEFINED_PC_OFFSET
:
2364 case TLSDTPMOD_OFFSET
:
2365 fragP
->fr_var
= INST_WORD_SIZE
;
2371 return fragP
->fr_var
;
2374 /* Put number into target byte order. */
2377 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2379 if (target_big_endian
)
2380 number_to_chars_bigendian (ptr
, use
, nbytes
);
2382 number_to_chars_littleendian (ptr
, use
, nbytes
);
2385 /* Round up a section size to the appropriate boundary. */
2388 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2390 return size
; /* Byte alignment is fine. */
2394 /* The location from which a PC relative jump should be calculated,
2395 given a PC relative reloc. */
2398 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2401 /* If the symbol is undefined or defined in another section
2402 we leave the add number alone for the linker to fix it later.
2403 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2405 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2406 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2407 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2411 /* The case where we are going to resolve things... */
2412 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2413 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2415 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2421 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2422 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2425 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2428 bfd_reloc_code_real_type code
;
2430 switch (fixp
->fx_r_type
)
2432 case BFD_RELOC_NONE
:
2433 case BFD_RELOC_MICROBLAZE_64_NONE
:
2435 case BFD_RELOC_MICROBLAZE_32_LO
:
2436 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2439 case BFD_RELOC_64_PCREL
:
2440 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2441 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2442 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2443 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2444 case BFD_RELOC_MICROBLAZE_64_GOT
:
2445 case BFD_RELOC_MICROBLAZE_64_PLT
:
2446 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2447 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2448 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2449 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2450 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
2451 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
2452 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2453 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
2454 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
2455 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL
:
2456 case BFD_RELOC_MICROBLAZE_64_TEXTREL
:
2457 code
= fixp
->fx_r_type
;
2461 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2463 MAP (1, 0, BFD_RELOC_8
);
2464 MAP (2, 0, BFD_RELOC_16
);
2465 MAP (4, 0, BFD_RELOC_32
);
2466 MAP (1, 1, BFD_RELOC_8_PCREL
);
2467 MAP (2, 1, BFD_RELOC_16_PCREL
);
2468 MAP (4, 1, BFD_RELOC_32_PCREL
);
2470 code
= fixp
->fx_r_type
;
2471 as_bad (_("Can not do %d byte %srelocation"),
2473 fixp
->fx_pcrel
? _("pc-relative ") : "");
2478 rel
= XNEW (arelent
);
2479 rel
->sym_ptr_ptr
= XNEW (asymbol
*);
2481 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2482 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2484 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2486 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2487 /* Always pass the addend along! */
2488 rel
->addend
= fixp
->fx_offset
;
2489 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2491 if (rel
->howto
== NULL
)
2493 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2494 _("Cannot represent relocation type %s"),
2495 bfd_get_reloc_code_name (code
));
2497 /* Set howto to a garbage value so that we can keep going. */
2498 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2499 gas_assert (rel
->howto
!= NULL
);
2505 md_parse_option (int c
, const char * arg ATTRIBUTE_UNUSED
)
2510 target_big_endian
= 1;
2513 target_big_endian
= 0;
2522 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2524 /* fprintf(stream, _("\
2525 MicroBlaze options:\n\
2526 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2530 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2531 found a machine specific op in an expression,
2532 then we create relocs accordingly. */
2535 cons_fix_new_microblaze (fragS
* frag
,
2539 bfd_reloc_code_real_type r
)
2541 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2542 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2543 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2544 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2545 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2547 exp
->X_op
= O_symbol
;
2548 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2567 as_bad (_("unsupported BFD relocation size %u"), size
);
2572 fix_new_exp (frag
, where
, size
, exp
, 0, r
);