1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright (C) 2009-2014 Free Software Foundation, Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to the Free
19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
27 #include "../opcodes/microblaze-opc.h"
28 #include "../opcodes/microblaze-opcm.h"
29 #include "safe-ctype.h"
31 #include <dwarf2dbg.h>
32 #include "aout/stab_gnu.h"
35 #define streq(a,b) (strcmp (a, b) == 0)
38 #define OPTION_EB (OPTION_MD_BASE + 0)
39 #define OPTION_EL (OPTION_MD_BASE + 1)
41 void microblaze_generate_symbol (char *sym
);
42 static bfd_boolean
check_spl_reg (unsigned *);
44 /* Several places in this file insert raw instructions into the
45 object. They should generate the instruction
46 and then use these four macros to crack the instruction value into
47 the appropriate byte values. */
48 #define INST_BYTE0(x) (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF))
49 #define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
50 #define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
51 #define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
53 /* This array holds the chars that always start a comment. If the
54 pre-processor is disabled, these aren't very useful. */
55 const char comment_chars
[] = "#";
57 const char line_separator_chars
[] = ";";
59 /* This array holds the chars that only start a comment at the beginning of
61 const char line_comment_chars
[] = "#";
63 const int md_reloc_size
= 8; /* Size of relocation record. */
65 /* Chars that can be used to separate mant
66 from exp in floating point numbers. */
67 const char EXP_CHARS
[] = "eE";
69 /* Chars that mean this number is a floating point constant
72 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
74 /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1. */
75 #define UNDEFINED_PC_OFFSET 2
76 #define DEFINED_ABS_SEGMENT 3
77 #define DEFINED_PC_OFFSET 4
78 #define DEFINED_RO_SEGMENT 5
79 #define DEFINED_RW_SEGMENT 6
80 #define LARGE_DEFINED_PC_OFFSET 7
83 #define GOTOFF_OFFSET 10
84 #define TLSGD_OFFSET 11
85 #define TLSLD_OFFSET 12
86 #define TLSDTPMOD_OFFSET 13
87 #define TLSDTPREL_OFFSET 14
88 #define TLSGOTTPREL_OFFSET 15
89 #define TLSTPREL_OFFSET 16
91 /* Initialize the relax table. */
92 const relax_typeS md_relax_table
[] =
94 { 1, 1, 0, 0 }, /* 0: Unused. */
95 { 1, 1, 0, 0 }, /* 1: Unused. */
96 { 1, 1, 0, 0 }, /* 2: Unused. */
97 { 1, 1, 0, 0 }, /* 3: Unused. */
98 { 32767, -32768, INST_WORD_SIZE
, LARGE_DEFINED_PC_OFFSET
}, /* 4: DEFINED_PC_OFFSET. */
99 { 1, 1, 0, 0 }, /* 5: Unused. */
100 { 1, 1, 0, 0 }, /* 6: Unused. */
101 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
102 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 8: GOT_OFFSET. */
103 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 9: PLT_OFFSET. */
104 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 10: GOTOFF_OFFSET. */
105 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 11: TLSGD_OFFSET. */
106 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 12: TLSLD_OFFSET. */
107 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */
108 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 14: TLSDTPREL_OFFSET. */
109 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */
110 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 } /* 16: TLSTPREL_OFFSET. */
113 static struct hash_control
* opcode_hash_control
; /* Opcode mnemonics. */
115 static segT sbss_segment
= 0; /* Small bss section. */
116 static segT sbss2_segment
= 0; /* Section not used. */
117 static segT sdata_segment
= 0; /* Small data section. */
118 static segT sdata2_segment
= 0; /* Small read-only section. */
119 static segT rodata_segment
= 0; /* read-only section. */
121 /* Generate a symbol for stabs information. */
124 microblaze_generate_symbol (char *sym
)
126 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
127 static int microblaze_label_count
;
128 sprintf (sym
, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME
, microblaze_label_count
);
129 ++microblaze_label_count
;
132 /* Handle the section changing pseudo-ops. */
135 microblaze_s_text (int ignore ATTRIBUTE_UNUSED
)
138 obj_elf_text (ignore
);
145 microblaze_s_data (int ignore ATTRIBUTE_UNUSED
)
148 obj_elf_change_section (".data", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
154 /* Things in the .sdata segment are always considered to be in the small data section. */
157 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED
)
160 obj_elf_change_section (".sdata", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
166 /* Pseudo op to make file scope bss items. */
169 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED
)
179 segT current_seg
= now_seg
;
180 subsegT current_subseg
= now_subseg
;
182 name
= input_line_pointer
;
183 c
= get_symbol_end ();
185 /* Just after name is now '\0'. */
186 p
= input_line_pointer
;
189 if (*input_line_pointer
!= ',')
191 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
192 ignore_rest_of_line ();
196 input_line_pointer
++; /* skip ',' */
197 if ((size
= get_absolute_expression ()) < 0)
199 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size
);
200 ignore_rest_of_line ();
204 /* The third argument to .lcomm is the alignment. */
205 if (*input_line_pointer
!= ',')
209 ++input_line_pointer
;
210 align
= get_absolute_expression ();
213 as_warn (_("ignoring bad alignment"));
219 symbolP
= symbol_find_or_make (name
);
222 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
224 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
225 S_GET_NAME (symbolP
));
226 ignore_rest_of_line ();
230 if (S_GET_VALUE (symbolP
) && S_GET_VALUE (symbolP
) != (valueT
) size
)
232 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
233 S_GET_NAME (symbolP
),
234 (long) S_GET_VALUE (symbolP
),
237 ignore_rest_of_line ();
244 /* Convert to a power of 2 alignment. */
245 for (align2
= 0; (align
& 1) == 0; align
>>= 1, ++align2
);
248 as_bad (_("Common alignment not a power of 2"));
249 ignore_rest_of_line ();
256 record_alignment (current_seg
, align2
);
257 subseg_set (current_seg
, current_subseg
);
259 frag_align (align2
, 0, 0);
260 if (S_GET_SEGMENT (symbolP
) == current_seg
)
261 symbol_get_frag (symbolP
)->fr_symbol
= 0;
262 symbol_set_frag (symbolP
, frag_now
);
263 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
266 S_SET_SIZE (symbolP
, size
);
267 S_SET_SEGMENT (symbolP
, current_seg
);
268 subseg_set (current_seg
, current_subseg
);
269 demand_empty_rest_of_line ();
273 microblaze_s_rdata (int localvar
)
279 obj_elf_change_section (".rodata", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
280 if (rodata_segment
== 0)
281 rodata_segment
= subseg_new (".rodata", 0);
286 obj_elf_change_section (".sdata2", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
294 microblaze_s_bss (int localvar
)
297 if (localvar
== 0) /* bss. */
298 obj_elf_change_section (".bss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
299 else if (localvar
== 1)
302 obj_elf_change_section (".sbss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
303 if (sbss_segment
== 0)
304 sbss_segment
= subseg_new (".sbss", 0);
311 /* endp_p is always 1 as this func is called only for .end <funcname>
312 This func consumes the <funcname> and calls regular processing
313 s_func(1) with arg 1 (1 for end). */
316 microblaze_s_func (int end_p ATTRIBUTE_UNUSED
)
318 *input_line_pointer
= get_symbol_end ();
322 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
325 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED
)
332 name
= input_line_pointer
;
333 c
= get_symbol_end ();
334 symbolP
= symbol_find_or_make (name
);
335 S_SET_WEAK (symbolP
);
336 *input_line_pointer
= c
;
340 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
342 if (S_IS_DEFINED (symbolP
))
344 as_bad ("Ignoring attempt to redefine symbol `%s'.",
345 S_GET_NAME (symbolP
));
346 ignore_rest_of_line ();
350 if (*input_line_pointer
== ',')
352 ++input_line_pointer
;
357 if (exp
.X_op
!= O_symbol
)
359 as_bad ("bad .weakext directive");
360 ignore_rest_of_line ();
363 symbol_set_value_expression (symbolP
, &exp
);
366 demand_empty_rest_of_line ();
369 /* This table describes all the machine specific pseudo-ops the assembler
370 has to support. The fields are:
371 Pseudo-op name without dot
372 Function to call to execute this pseudo-op
373 Integer arg to pass to the function. */
374 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
375 and then in the read.c table. */
376 const pseudo_typeS md_pseudo_table
[] =
378 {"lcomm", microblaze_s_lcomm
, 1},
379 {"data", microblaze_s_data
, 0},
380 {"data8", cons
, 1}, /* Same as byte. */
381 {"data16", cons
, 2}, /* Same as hword. */
382 {"data32", cons
, 4}, /* Same as word. */
383 {"ent", s_func
, 0}, /* Treat ent as function entry point. */
384 {"end", microblaze_s_func
, 1}, /* Treat end as function end point. */
385 {"gpword", s_rva
, 4}, /* gpword label => store resolved label address in data section. */
386 {"weakext", microblaze_s_weakext
, 0},
387 {"rodata", microblaze_s_rdata
, 0},
388 {"sdata2", microblaze_s_rdata
, 1},
389 {"sdata", microblaze_s_sdata
, 0},
390 {"bss", microblaze_s_bss
, 0},
391 {"sbss", microblaze_s_bss
, 1},
392 {"text", microblaze_s_text
, 0},
394 {"frame", s_ignore
, 0},
395 {"mask", s_ignore
, 0}, /* Emitted by gcc. */
399 /* This function is called once, at assembler startup time. This should
400 set up all the tables, etc that the MD part of the assembler needs. */
405 struct op_code_struct
* opcode
;
407 opcode_hash_control
= hash_new ();
409 /* Insert unique names into hash table. */
410 for (opcode
= opcodes
; opcode
->name
; opcode
++)
411 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
414 /* Try to parse a reg name. */
417 parse_reg (char * s
, unsigned * reg
)
421 /* Strip leading whitespace. */
422 while (ISSPACE (* s
))
425 if (strncasecmp (s
, "rpc", 3) == 0)
430 else if (strncasecmp (s
, "rmsr", 4) == 0)
435 else if (strncasecmp (s
, "rear", 4) == 0)
440 else if (strncasecmp (s
, "resr", 4) == 0)
445 else if (strncasecmp (s
, "rfsr", 4) == 0)
450 else if (strncasecmp (s
, "rbtr", 4) == 0)
455 else if (strncasecmp (s
, "redr", 4) == 0)
460 /* MMU registers start. */
461 else if (strncasecmp (s
, "rpid", 4) == 0)
466 else if (strncasecmp (s
, "rzpr", 4) == 0)
471 else if (strncasecmp (s
, "rtlbx", 5) == 0)
476 else if (strncasecmp (s
, "rtlblo", 6) == 0)
481 else if (strncasecmp (s
, "rtlbhi", 6) == 0)
486 else if (strncasecmp (s
, "rtlbsx", 6) == 0)
491 /* MMU registers end. */
492 else if (strncasecmp (s
, "rpvr", 4) == 0)
494 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
496 tmpreg
= (s
[4]-'0')*10 + s
[5] - '0';
500 else if (ISDIGIT (s
[4]))
506 as_bad (_("register expected, but saw '%.6s'"), s
);
507 if ((int) tmpreg
>= MIN_PVR_REGNUM
&& tmpreg
<= MAX_PVR_REGNUM
)
508 *reg
= REG_PVR
+ tmpreg
;
511 as_bad (_("Invalid register number at '%.6s'"), s
);
516 else if (strncasecmp (s
, "rsp", 3) == 0)
521 else if (strncasecmp (s
, "rfsl", 4) == 0)
523 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
525 tmpreg
= (s
[4] - '0') * 10 + s
[5] - '0';
528 else if (ISDIGIT (s
[4]))
534 as_bad (_("register expected, but saw '%.6s'"), s
);
536 if ((int) tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
540 as_bad (_("Invalid register number at '%.6s'"), s
);
545 /* Stack protection registers. */
546 else if (strncasecmp (s
, "rshr", 4) == 0)
551 else if (strncasecmp (s
, "rslr", 4) == 0)
558 if (TOLOWER (s
[0]) == 'r')
560 if (ISDIGIT (s
[1]) && ISDIGIT (s
[2]))
562 tmpreg
= (s
[1] - '0') * 10 + s
[2] - '0';
565 else if (ISDIGIT (s
[1]))
571 as_bad (_("register expected, but saw '%.6s'"), s
);
573 if ((int)tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
577 as_bad (_("Invalid register number at '%.6s'"), s
);
583 as_bad (_("register expected, but saw '%.6s'"), s
);
589 parse_exp (char *s
, expressionS
*e
)
594 /* Skip whitespace. */
595 while (ISSPACE (* s
))
598 save
= input_line_pointer
;
599 input_line_pointer
= s
;
603 if (e
->X_op
== O_absent
)
604 as_fatal (_("missing operand"));
606 new_pointer
= input_line_pointer
;
607 input_line_pointer
= save
;
612 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
619 #define IMM_TLSDTPMOD 6
620 #define IMM_TLSDTPREL 7
621 #define IMM_TLSTPREL 8
625 char *isuffix
; /* Suffix String */
626 int itype
; /* Suffix Type */
627 int otype
; /* Offset Type */
630 /* These are NOT in assending order of type, GOTOFF is ahead to make
631 sure @GOTOFF does not get matched with @GOT */
632 static struct imm_type imm_types
[] = {
633 { "NONE", IMM_NONE
, 0 },
634 { "GOTOFF", IMM_GOTOFF
, GOTOFF_OFFSET
},
635 { "GOT", IMM_GOT
, GOT_OFFSET
},
636 { "PLT", IMM_PLT
, PLT_OFFSET
},
637 { "TLSGD", IMM_TLSGD
, TLSGD_OFFSET
},
638 { "TLSLDM", IMM_TLSLD
, TLSLD_OFFSET
},
639 { "TLSDTPMOD", IMM_TLSDTPMOD
, TLSDTPMOD_OFFSET
},
640 { "TLSDTPREL", IMM_TLSDTPREL
, TLSDTPREL_OFFSET
},
641 { "TLSTPREL", IMM_TLSTPREL
, TLSTPREL_OFFSET
}
645 match_imm (const char *s
, int *ilen
)
650 /* Check for matching suffix */
651 for (i
= 1; i
< IMM_MAX
; i
++)
653 slen
= strlen (imm_types
[i
].isuffix
);
655 if (strncmp (imm_types
[i
].isuffix
, s
, slen
) == 0)
658 return imm_types
[i
].itype
;
666 get_imm_otype (int itype
)
671 /* Check for matching itype */
672 for (i
= 1; i
< IMM_MAX
; i
++)
674 if (imm_types
[i
].itype
== itype
)
676 otype
= imm_types
[i
].otype
;
683 static symbolS
* GOT_symbol
;
685 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
688 parse_imm (char * s
, expressionS
* e
, int min
, int max
)
696 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
697 for (atp
= s
; *atp
!= '@'; atp
++)
698 if (is_end_of_line
[(unsigned char) *atp
])
703 itype
= match_imm (atp
+ 1, &ilen
);
723 if (atp
&& !GOT_symbol
)
725 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
728 new_pointer
= parse_exp (s
, e
);
730 if (!GOT_symbol
&& ! strncmp (s
, GOT_SYMBOL_NAME
, 20))
732 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
735 if (e
->X_op
== O_absent
)
736 ; /* An error message has already been emitted. */
737 else if ((e
->X_op
!= O_constant
&& e
->X_op
!= O_symbol
) )
738 as_fatal (_("operand must be a constant or a label"));
739 else if ((e
->X_op
== O_constant
) && ((int) e
->X_add_number
< min
740 || (int) e
->X_add_number
> max
))
742 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
743 min
, max
, (int) e
->X_add_number
);
748 *atp
= '@'; /* restore back (needed?) */
749 if (new_pointer
>= atp
)
750 new_pointer
+= ilen
+ 1; /* sizeof (imm_suffix) + 1 for '@' */
756 check_got (int * got_type
, int * got_len
)
764 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
765 for (atp
= input_line_pointer
; *atp
!= '@'; atp
++)
766 if (is_end_of_line
[(unsigned char) *atp
])
769 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
772 *got_type
= IMM_GOTOFF
;
774 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
779 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
788 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
790 first
= atp
- input_line_pointer
;
792 past_got
= atp
+ *got_len
+ 1;
793 for (new_pointer
= past_got
; !is_end_of_line
[(unsigned char) *new_pointer
++];)
795 second
= new_pointer
- past_got
;
796 tmpbuf
= xmalloc (first
+ second
+ 2); /* One extra byte for ' ' and one for NUL. */
797 memcpy (tmpbuf
, input_line_pointer
, first
);
798 tmpbuf
[first
] = ' '; /* @GOTOFF is replaced with a single space. */
799 memcpy (tmpbuf
+ first
+ 1, past_got
, second
);
800 tmpbuf
[first
+ second
+ 1] = '\0';
805 extern bfd_reloc_code_real_type
806 parse_cons_expression_microblaze (expressionS
*exp
, int size
)
810 /* Handle @GOTOFF et.al. */
811 char *save
, *gotfree_copy
;
812 int got_len
, got_type
;
814 save
= input_line_pointer
;
815 gotfree_copy
= check_got (& got_type
, & got_len
);
817 input_line_pointer
= gotfree_copy
;
823 exp
->X_md
= got_type
;
824 input_line_pointer
= save
+ (input_line_pointer
- gotfree_copy
)
831 return BFD_RELOC_NONE
;
834 /* This is the guts of the machine-dependent assembler. STR points to a
835 machine dependent instruction. This function is supposed to emit
836 the frags/bytes it assembles to. */
838 static char * str_microblaze_ro_anchor
= "RO";
839 static char * str_microblaze_rw_anchor
= "RW";
842 check_spl_reg (unsigned * reg
)
844 if ((*reg
== REG_MSR
) || (*reg
== REG_PC
)
845 || (*reg
== REG_EAR
) || (*reg
== REG_ESR
)
846 || (*reg
== REG_FSR
) || (*reg
== REG_BTR
) || (*reg
== REG_EDR
)
847 || (*reg
== REG_PID
) || (*reg
== REG_ZPR
)
848 || (*reg
== REG_TLBX
) || (*reg
== REG_TLBLO
)
849 || (*reg
== REG_TLBHI
) || (*reg
== REG_TLBSX
)
850 || (*reg
== REG_SHR
) || (*reg
== REG_SLR
)
851 || (*reg
>= REG_PVR
+MIN_PVR_REGNUM
&& *reg
<= REG_PVR
+MAX_PVR_REGNUM
))
857 /* Here we decide which fixups can be adjusted to make them relative to
858 the beginning of the section instead of the symbol. Basically we need
859 to make sure that the dynamic relocations are done correctly, so in
860 some cases we force the original symbol to be used. */
863 tc_microblaze_fix_adjustable (struct fix
*fixP
)
865 if (GOT_symbol
&& fixP
->fx_subsy
== GOT_symbol
)
868 if (fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOTOFF
869 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_GOTOFF
870 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOT
871 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_PLT
872 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGD
873 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSLD
874 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
875 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPREL
876 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSDTPREL
877 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
878 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSTPREL
)
885 md_assemble (char * str
)
889 struct op_code_struct
* opcode
, *opcode1
;
890 char * output
= NULL
;
893 unsigned long inst
, inst1
;
898 unsigned int immed
, temp
;
902 /* Drop leading whitespace. */
903 while (ISSPACE (* str
))
906 /* Find the op code end. */
907 for (op_start
= op_end
= str
;
908 *op_end
&& !is_end_of_line
[(unsigned char) *op_end
] && *op_end
!= ' ';
911 name
[nlen
] = op_start
[nlen
];
913 if (nlen
== sizeof (name
) - 1)
921 as_bad (_("can't find opcode "));
925 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, name
);
928 as_bad (_("unknown opcode \"%s\""), name
);
932 inst
= opcode
->bit_sequence
;
935 switch (opcode
->inst_type
)
937 case INST_TYPE_RD_R1_R2
:
938 if (strcmp (op_end
, ""))
939 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
942 as_fatal (_("Error in statement syntax"));
945 if (strcmp (op_end
, ""))
946 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
949 as_fatal (_("Error in statement syntax"));
952 if (strcmp (op_end
, ""))
953 op_end
= parse_reg (op_end
+ 1, ®3
); /* Get r2. */
956 as_fatal (_("Error in statement syntax"));
960 /* Check for spl registers. */
961 if (check_spl_reg (& reg1
))
962 as_fatal (_("Cannot use special register with this instruction"));
963 if (check_spl_reg (& reg2
))
964 as_fatal (_("Cannot use special register with this instruction"));
965 if (check_spl_reg (& reg3
))
966 as_fatal (_("Cannot use special register with this instruction"));
968 if (streq (name
, "sub"))
970 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
971 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
972 inst
|= (reg3
<< RA_LOW
) & RA_MASK
;
973 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
977 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
978 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
979 inst
|= (reg3
<< RB_LOW
) & RB_MASK
;
981 output
= frag_more (isize
);
984 case INST_TYPE_RD_R1_IMM
:
985 if (strcmp (op_end
, ""))
986 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
989 as_fatal (_("Error in statement syntax"));
992 if (strcmp (op_end
, ""))
993 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
996 as_fatal (_("Error in statement syntax"));
999 if (strcmp (op_end
, ""))
1000 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1002 as_fatal (_("Error in statement syntax"));
1004 /* Check for spl registers. */
1005 if (check_spl_reg (& reg1
))
1006 as_fatal (_("Cannot use special register with this instruction"));
1007 if (check_spl_reg (& reg2
))
1008 as_fatal (_("Cannot use special register with this instruction"));
1010 if (exp
.X_op
!= O_constant
)
1013 relax_substateT subtype
;
1015 if (streq (name
, "lmi"))
1016 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
1017 else if (streq (name
, "smi"))
1018 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
1020 if (reg2
== REG_ROSDP
)
1021 opc
= str_microblaze_ro_anchor
;
1022 else if (reg2
== REG_RWSDP
)
1023 opc
= str_microblaze_rw_anchor
;
1027 subtype
= get_imm_otype(exp
.X_md
);
1029 subtype
= opcode
->inst_offset_type
;
1031 output
= frag_var (rs_machine_dependent
,
1032 isize
* 2, /* maxm of 2 words. */
1033 isize
, /* minm of 1 word. */
1034 subtype
, /* PC-relative or not. */
1042 output
= frag_more (isize
);
1043 immed
= exp
.X_add_number
;
1046 if (streq (name
, "lmi") || streq (name
, "smi"))
1048 /* Load/store 32-d consecutive registers. Used on exit/entry
1049 to subroutines to save and restore registers to stack.
1050 Generate 32-d insts. */
1054 if (streq (name
, "lmi"))
1055 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "lwi");
1057 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "swi");
1060 as_bad (_("unknown opcode \"%s\""), "lwi");
1063 inst
= opcode
->bit_sequence
;
1064 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1065 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1066 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1068 for (i
= 0; i
< count
- 1; i
++)
1070 output
[0] = INST_BYTE0 (inst
);
1071 output
[1] = INST_BYTE1 (inst
);
1072 output
[2] = INST_BYTE2 (inst
);
1073 output
[3] = INST_BYTE3 (inst
);
1074 output
= frag_more (isize
);
1077 inst
= opcode
->bit_sequence
;
1078 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1079 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1080 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1085 temp
= immed
& 0xFFFF8000;
1086 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1088 /* Needs an immediate inst. */
1089 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1090 if (opcode1
== NULL
)
1092 as_bad (_("unknown opcode \"%s\""), "imm");
1096 inst1
= opcode1
->bit_sequence
;
1097 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1098 output
[0] = INST_BYTE0 (inst1
);
1099 output
[1] = INST_BYTE1 (inst1
);
1100 output
[2] = INST_BYTE2 (inst1
);
1101 output
[3] = INST_BYTE3 (inst1
);
1102 output
= frag_more (isize
);
1104 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1105 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1106 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1110 case INST_TYPE_RD_R1_IMM5
:
1111 if (strcmp (op_end
, ""))
1112 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1115 as_fatal (_("Error in statement syntax"));
1118 if (strcmp (op_end
, ""))
1119 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1122 as_fatal (_("Error in statement syntax"));
1125 if (strcmp (op_end
, ""))
1126 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1128 as_fatal (_("Error in statement syntax"));
1130 /* Check for spl registers. */
1131 if (check_spl_reg (®1
))
1132 as_fatal (_("Cannot use special register with this instruction"));
1133 if (check_spl_reg (®2
))
1134 as_fatal (_("Cannot use special register with this instruction"));
1136 if (exp
.X_op
!= O_constant
)
1137 as_warn (_("Symbol used as immediate for shift instruction"));
1140 output
= frag_more (isize
);
1141 immed
= exp
.X_add_number
;
1144 if (immed
!= (immed
% 32))
1146 as_warn (_("Shift value > 32. using <value %% 32>"));
1149 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1150 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1151 inst
|= (immed
<< IMM_LOW
) & IMM5_MASK
;
1154 case INST_TYPE_R1_R2
:
1155 if (strcmp (op_end
, ""))
1156 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1159 as_fatal (_("Error in statement syntax"));
1162 if (strcmp (op_end
, ""))
1163 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1166 as_fatal (_("Error in statement syntax"));
1170 /* Check for spl registers. */
1171 if (check_spl_reg (& reg1
))
1172 as_fatal (_("Cannot use special register with this instruction"));
1173 if (check_spl_reg (& reg2
))
1174 as_fatal (_("Cannot use special register with this instruction"));
1176 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1177 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1178 output
= frag_more (isize
);
1181 case INST_TYPE_RD_R1
:
1182 if (strcmp (op_end
, ""))
1183 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1186 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 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1204 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1205 output
= frag_more (isize
);
1208 case INST_TYPE_RD_RFSL
:
1209 if (strcmp (op_end
, ""))
1210 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1213 as_fatal (_("Error in statement syntax"));
1216 if (strcmp (op_end
, ""))
1217 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1220 as_fatal (_("Error in statement syntax"));
1224 /* Check for spl registers. */
1225 if (check_spl_reg (®1
))
1226 as_fatal (_("Cannot use special register with this instruction"));
1228 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1229 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1230 output
= frag_more (isize
);
1233 case INST_TYPE_RD_IMM15
:
1234 if (strcmp (op_end
, ""))
1235 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1238 as_fatal (_("Error in statement syntax"));
1242 if (strcmp (op_end
, ""))
1243 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1245 as_fatal (_("Error in statement syntax"));
1247 /* Check for spl registers. */
1248 if (check_spl_reg (®1
))
1249 as_fatal (_("Cannot use special register with this instruction"));
1251 if (exp
.X_op
!= O_constant
)
1252 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1255 output
= frag_more (isize
);
1256 immed
= exp
.X_add_number
;
1258 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1259 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1262 case INST_TYPE_R1_RFSL
:
1263 if (strcmp (op_end
, ""))
1264 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1267 as_fatal (_("Error in statement syntax"));
1270 if (strcmp (op_end
, ""))
1271 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1274 as_fatal (_("Error in statement syntax"));
1278 /* Check for spl registers. */
1279 if (check_spl_reg (®1
))
1280 as_fatal (_("Cannot use special register with this instruction"));
1282 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1283 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1284 output
= frag_more (isize
);
1287 case INST_TYPE_RFSL
:
1288 if (strcmp (op_end
, ""))
1289 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1292 as_fatal (_("Error in statement syntax"));
1295 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1296 output
= frag_more (isize
);
1300 if (strcmp (op_end
, ""))
1301 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1304 as_fatal (_("Error in statement syntax"));
1308 /* Check for spl registers. */
1309 if (check_spl_reg (®1
))
1310 as_fatal (_("Cannot use special register with this instruction"));
1312 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1313 output
= frag_more (isize
);
1316 /* For tuqula insn...:) */
1318 if (strcmp (op_end
, ""))
1319 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1322 as_fatal (_("Error in statement syntax"));
1326 /* Check for spl registers. */
1327 if (check_spl_reg (®1
))
1328 as_fatal (_("Cannot use special register with this instruction"));
1330 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1331 output
= frag_more (isize
);
1334 case INST_TYPE_RD_SPECIAL
:
1335 if (strcmp (op_end
, ""))
1336 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1339 as_fatal (_("Error in statement syntax"));
1342 if (strcmp (op_end
, ""))
1343 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1346 as_fatal (_("Error in statement syntax"));
1350 if (reg2
== REG_MSR
)
1351 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1352 else if (reg2
== REG_PC
)
1353 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1354 else if (reg2
== REG_EAR
)
1355 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1356 else if (reg2
== REG_ESR
)
1357 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1358 else if (reg2
== REG_FSR
)
1359 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1360 else if (reg2
== REG_BTR
)
1361 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1362 else if (reg2
== REG_EDR
)
1363 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1364 else if (reg2
== REG_PID
)
1365 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1366 else if (reg2
== REG_ZPR
)
1367 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1368 else if (reg2
== REG_TLBX
)
1369 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1370 else if (reg2
== REG_TLBLO
)
1371 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1372 else if (reg2
== REG_TLBHI
)
1373 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1374 else if (reg2
== REG_SHR
)
1375 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1376 else if (reg2
== REG_SLR
)
1377 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1378 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1379 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1381 as_fatal (_("invalid value for special purpose register"));
1382 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1383 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1384 output
= frag_more (isize
);
1387 case INST_TYPE_SPECIAL_R1
:
1388 if (strcmp (op_end
, ""))
1389 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1392 as_fatal (_("Error in statement syntax"));
1395 if (strcmp (op_end
, ""))
1396 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1399 as_fatal (_("Error in statement syntax"));
1403 if (reg1
== REG_MSR
)
1404 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1405 else if (reg1
== REG_PC
)
1406 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1407 else if (reg1
== REG_EAR
)
1408 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1409 else if (reg1
== REG_ESR
)
1410 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1411 else if (reg1
== REG_FSR
)
1412 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1413 else if (reg1
== REG_BTR
)
1414 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1415 else if (reg1
== REG_EDR
)
1416 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1417 else if (reg1
== REG_PID
)
1418 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1419 else if (reg1
== REG_ZPR
)
1420 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1421 else if (reg1
== REG_TLBX
)
1422 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1423 else if (reg1
== REG_TLBLO
)
1424 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1425 else if (reg1
== REG_TLBHI
)
1426 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1427 else if (reg1
== REG_TLBSX
)
1428 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1429 else if (reg1
== REG_SHR
)
1430 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1431 else if (reg1
== REG_SLR
)
1432 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1434 as_fatal (_("invalid value for special purpose register"));
1435 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1436 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1437 output
= frag_more (isize
);
1440 case INST_TYPE_R1_R2_SPECIAL
:
1441 if (strcmp (op_end
, ""))
1442 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1445 as_fatal (_("Error in statement syntax"));
1448 if (strcmp (op_end
, ""))
1449 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1452 as_fatal (_("Error in statement syntax"));
1456 /* Check for spl registers. */
1457 if (check_spl_reg (®1
))
1458 as_fatal (_("Cannot use special register with this instruction"));
1459 if (check_spl_reg (®2
))
1460 as_fatal (_("Cannot use special register with this instruction"));
1462 /* insn wic ra, rb => wic ra, ra, rb. */
1463 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1464 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1466 output
= frag_more (isize
);
1469 case INST_TYPE_RD_R2
:
1470 if (strcmp (op_end
, ""))
1471 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1474 as_fatal (_("Error in statement syntax"));
1477 if (strcmp (op_end
, ""))
1478 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1481 as_fatal (_("Error in statement syntax"));
1485 /* Check for spl registers. */
1486 if (check_spl_reg (®1
))
1487 as_fatal (_("Cannot use special register with this instruction"));
1488 if (check_spl_reg (®2
))
1489 as_fatal (_("Cannot use special register with this instruction"));
1491 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1492 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1493 output
= frag_more (isize
);
1496 case INST_TYPE_R1_IMM
:
1497 if (strcmp (op_end
, ""))
1498 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1501 as_fatal (_("Error in statement syntax"));
1504 if (strcmp (op_end
, ""))
1505 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1507 as_fatal (_("Error in statement syntax"));
1509 /* Check for spl registers. */
1510 if (check_spl_reg (®1
))
1511 as_fatal (_("Cannot use special register with this instruction"));
1513 if (exp
.X_op
!= O_constant
)
1516 relax_substateT subtype
;
1519 subtype
= get_imm_otype(exp
.X_md
);
1521 subtype
= opcode
->inst_offset_type
;
1523 output
= frag_var (rs_machine_dependent
,
1524 isize
* 2, /* maxm of 2 words. */
1525 isize
, /* minm of 1 word. */
1526 subtype
, /* PC-relative or not. */
1534 output
= frag_more (isize
);
1535 immed
= exp
.X_add_number
;
1538 temp
= immed
& 0xFFFF8000;
1539 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1541 /* Needs an immediate inst. */
1542 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1543 if (opcode1
== NULL
)
1545 as_bad (_("unknown opcode \"%s\""), "imm");
1549 inst1
= opcode1
->bit_sequence
;
1550 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1551 output
[0] = INST_BYTE0 (inst1
);
1552 output
[1] = INST_BYTE1 (inst1
);
1553 output
[2] = INST_BYTE2 (inst1
);
1554 output
[3] = INST_BYTE3 (inst1
);
1555 output
= frag_more (isize
);
1558 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1559 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1562 case INST_TYPE_RD_IMM
:
1563 if (strcmp (op_end
, ""))
1564 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1567 as_fatal (_("Error in statement syntax"));
1570 if (strcmp (op_end
, ""))
1571 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1573 as_fatal (_("Error in statement syntax"));
1575 /* Check for spl registers. */
1576 if (check_spl_reg (®1
))
1577 as_fatal (_("Cannot use special register with this instruction"));
1579 if (exp
.X_op
!= O_constant
)
1582 relax_substateT subtype
;
1585 subtype
= get_imm_otype(exp
.X_md
);
1587 subtype
= opcode
->inst_offset_type
;
1589 output
= frag_var (rs_machine_dependent
,
1590 isize
* 2, /* maxm of 2 words. */
1591 isize
, /* minm of 1 word. */
1592 subtype
, /* PC-relative or not. */
1600 output
= frag_more (isize
);
1601 immed
= exp
.X_add_number
;
1604 temp
= immed
& 0xFFFF8000;
1605 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1607 /* Needs an immediate inst. */
1608 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1609 if (opcode1
== NULL
)
1611 as_bad (_("unknown opcode \"%s\""), "imm");
1615 inst1
= opcode1
->bit_sequence
;
1616 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1617 output
[0] = INST_BYTE0 (inst1
);
1618 output
[1] = INST_BYTE1 (inst1
);
1619 output
[2] = INST_BYTE2 (inst1
);
1620 output
[3] = INST_BYTE3 (inst1
);
1621 output
= frag_more (isize
);
1624 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1625 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1629 if (strcmp (op_end
, ""))
1630 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1633 as_fatal (_("Error in statement syntax"));
1637 /* Check for spl registers. */
1638 if (check_spl_reg (®2
))
1639 as_fatal (_("Cannot use special register with this instruction"));
1641 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1642 output
= frag_more (isize
);
1646 if (streq (name
, "imm"))
1647 as_fatal (_("An IMM instruction should not be present in the .s file"));
1649 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1651 if (exp
.X_op
!= O_constant
)
1654 relax_substateT subtype
;
1657 subtype
= get_imm_otype(exp
.X_md
);
1659 subtype
= opcode
->inst_offset_type
;
1661 output
= frag_var (rs_machine_dependent
,
1662 isize
* 2, /* maxm of 2 words. */
1663 isize
, /* minm of 1 word. */
1664 subtype
, /* PC-relative or not. */
1672 output
= frag_more (isize
);
1673 immed
= exp
.X_add_number
;
1677 temp
= immed
& 0xFFFF8000;
1678 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1680 /* Needs an immediate inst. */
1681 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1682 if (opcode1
== NULL
)
1684 as_bad (_("unknown opcode \"%s\""), "imm");
1688 inst1
= opcode1
->bit_sequence
;
1689 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1690 output
[0] = INST_BYTE0 (inst1
);
1691 output
[1] = INST_BYTE1 (inst1
);
1692 output
[2] = INST_BYTE2 (inst1
);
1693 output
[3] = INST_BYTE3 (inst1
);
1694 output
= frag_more (isize
);
1696 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1699 case INST_TYPE_NONE
:
1700 output
= frag_more (isize
);
1703 case INST_TYPE_IMM5
:
1704 if (strcmp(op_end
, ""))
1705 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM5
, MAX_IMM5
);
1707 as_fatal(_("Error in statement syntax"));
1708 if (exp
.X_op
!= O_constant
) {
1709 as_warn(_("Symbol used as immediate for mbar instruction"));
1711 output
= frag_more (isize
);
1712 immed
= exp
.X_add_number
;
1714 if (immed
!= (immed
% 32)) {
1715 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1718 inst
|= (immed
<< IMM_MBAR
);
1722 as_fatal (_("unimplemented opcode \"%s\""), name
);
1725 /* Drop whitespace after all the operands have been parsed. */
1726 while (ISSPACE (* op_end
))
1729 /* Give warning message if the insn has more operands than required. */
1730 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1731 as_warn (_("ignoring operands: %s "), op_end
);
1733 output
[0] = INST_BYTE0 (inst
);
1734 output
[1] = INST_BYTE1 (inst
);
1735 output
[2] = INST_BYTE2 (inst
);
1736 output
[3] = INST_BYTE3 (inst
);
1739 dwarf2_emit_insn (4);
1744 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1749 /* Various routines to kill one day. */
1750 /* Equal to MAX_PRECISION in atof-ieee.c */
1751 #define MAX_LITTLENUMS 6
1753 /* Turn a string in input_line_pointer into a floating point constant of type
1754 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1755 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1757 md_atof (int type
, char * litP
, int * sizeP
)
1760 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1792 return _("Bad call to MD_NTOF()");
1795 t
= atof_ieee (input_line_pointer
, type
, words
);
1798 input_line_pointer
= t
;
1800 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1802 if (! target_big_endian
)
1804 for (i
= prec
- 1; i
>= 0; i
--)
1806 md_number_to_chars (litP
, (valueT
) words
[i
],
1807 sizeof (LITTLENUM_TYPE
));
1808 litP
+= sizeof (LITTLENUM_TYPE
);
1812 for (i
= 0; i
< prec
; i
++)
1814 md_number_to_chars (litP
, (valueT
) words
[i
],
1815 sizeof (LITTLENUM_TYPE
));
1816 litP
+= sizeof (LITTLENUM_TYPE
);
1822 const char * md_shortopts
= "";
1824 struct option md_longopts
[] =
1826 {"EB", no_argument
, NULL
, OPTION_EB
},
1827 {"EL", no_argument
, NULL
, OPTION_EL
},
1828 { NULL
, no_argument
, NULL
, 0}
1831 size_t md_longopts_size
= sizeof (md_longopts
);
1833 int md_short_jump_size
;
1836 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED
,
1837 addressT from_Nddr ATTRIBUTE_UNUSED
,
1838 addressT to_Nddr ATTRIBUTE_UNUSED
,
1839 fragS
* frag ATTRIBUTE_UNUSED
,
1840 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1842 as_fatal (_("failed sanity check: short_jump"));
1846 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED
,
1847 addressT from_Nddr ATTRIBUTE_UNUSED
,
1848 addressT to_Nddr ATTRIBUTE_UNUSED
,
1849 fragS
* frag ATTRIBUTE_UNUSED
,
1850 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1852 as_fatal (_("failed sanity check: long_jump"));
1855 /* Called after relaxing, change the frags so they know how big they are. */
1858 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1859 segT sec ATTRIBUTE_UNUSED
,
1864 switch (fragP
->fr_subtype
)
1866 case UNDEFINED_PC_OFFSET
:
1867 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1868 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1869 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1872 case DEFINED_ABS_SEGMENT
:
1873 if (fragP
->fr_symbol
== GOT_symbol
)
1874 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1875 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_GOTPC
);
1877 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1878 fragP
->fr_offset
, FALSE
, BFD_RELOC_64
);
1879 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1882 case DEFINED_RO_SEGMENT
:
1883 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1884 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_ROSDA
);
1885 fragP
->fr_fix
+= INST_WORD_SIZE
;
1888 case DEFINED_RW_SEGMENT
:
1889 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1890 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_RWSDA
);
1891 fragP
->fr_fix
+= INST_WORD_SIZE
;
1894 case DEFINED_PC_OFFSET
:
1895 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1896 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_32_LO_PCREL
);
1897 fragP
->fr_fix
+= INST_WORD_SIZE
;
1900 case LARGE_DEFINED_PC_OFFSET
:
1901 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1902 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1903 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1907 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1908 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOT
);
1909 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1913 fixP
= fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1914 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_PLT
);
1915 /* fixP->fx_plt = 1; */
1917 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1921 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1922 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOTOFF
);
1923 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1927 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1928 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSGD
);
1929 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1933 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1934 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSLD
);
1935 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1938 case TLSDTPREL_OFFSET
:
1939 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1940 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSDTPREL
);
1941 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1950 /* Applies the desired value to the specified location.
1951 Also sets up addends for 'rela' type relocations. */
1953 md_apply_fix (fixS
* fixP
,
1957 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1958 char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
1959 const char * symname
;
1960 /* Note: use offsetT because it is signed, valueT is unsigned. */
1961 offsetT val
= (offsetT
) * valp
;
1963 struct op_code_struct
* opcode1
;
1964 unsigned long inst1
;
1966 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
1968 /* fixP->fx_offset is supposed to be set up correctly for all
1969 symbol relocations. */
1970 if (fixP
->fx_addsy
== NULL
)
1972 if (!fixP
->fx_pcrel
)
1973 fixP
->fx_offset
= val
; /* Absolute relocation. */
1975 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1976 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
1979 /* If we aren't adjusting this fixup to be against the section
1980 symbol, we need to adjust the value. */
1981 if (fixP
->fx_addsy
!= NULL
)
1983 if (S_IS_WEAK (fixP
->fx_addsy
)
1984 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
1985 && (((bfd_get_section_flags (stdoutput
,
1986 S_GET_SEGMENT (fixP
->fx_addsy
))
1987 & SEC_LINK_ONCE
) != 0)
1988 || !strncmp (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
1990 sizeof (".gnu.linkonce") - 1))))
1992 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1993 if (val
!= 0 && ! fixP
->fx_pcrel
)
1995 /* In this case, the bfd_install_relocation routine will
1996 incorrectly add the symbol value back in. We just want
1997 the addend to appear in the object file.
1998 FIXME: If this makes VALUE zero, we're toast. */
1999 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2004 /* If the fix is relative to a symbol which is not defined, or not
2005 in the same segment as the fix, we cannot resolve it here. */
2006 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
2007 if (fixP
->fx_addsy
!= NULL
2008 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2009 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
2013 /* For ELF we can just return and let the reloc that will be generated
2014 take care of everything. For COFF we still have to insert 'val'
2015 into the insn since the addend field will be ignored. */
2019 /* All fixups in the text section must be handled in the linker. */
2020 else if (segment
->flags
& SEC_CODE
)
2022 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
2027 switch (fixP
->fx_r_type
)
2029 case BFD_RELOC_MICROBLAZE_32_LO
:
2030 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2031 if (target_big_endian
)
2033 buf
[2] |= ((val
>> 8) & 0xff);
2034 buf
[3] |= (val
& 0xff);
2038 buf
[1] |= ((val
>> 8) & 0xff);
2039 buf
[0] |= (val
& 0xff);
2042 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2043 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2044 /* Don't do anything if the symbol is not defined. */
2045 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2047 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
2048 as_bad_where (file
, fixP
->fx_line
,
2049 _("pcrel for branch to %s too far (0x%x)"),
2050 symname
, (int) val
);
2051 if (target_big_endian
)
2053 buf
[2] |= ((val
>> 8) & 0xff);
2054 buf
[3] |= (val
& 0xff);
2058 buf
[1] |= ((val
>> 8) & 0xff);
2059 buf
[0] |= (val
& 0xff);
2065 case BFD_RELOC_32_PCREL
:
2066 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2067 /* Don't do anything if the symbol is not defined. */
2068 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2070 if (target_big_endian
)
2072 buf
[0] |= ((val
>> 24) & 0xff);
2073 buf
[1] |= ((val
>> 16) & 0xff);
2074 buf
[2] |= ((val
>> 8) & 0xff);
2075 buf
[3] |= (val
& 0xff);
2079 buf
[3] |= ((val
>> 24) & 0xff);
2080 buf
[2] |= ((val
>> 16) & 0xff);
2081 buf
[1] |= ((val
>> 8) & 0xff);
2082 buf
[0] |= (val
& 0xff);
2086 case BFD_RELOC_64_PCREL
:
2088 /* Add an imm instruction. First save the current instruction. */
2089 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2090 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2092 /* Generate the imm instruction. */
2093 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2094 if (opcode1
== NULL
)
2096 as_bad (_("unknown opcode \"%s\""), "imm");
2100 inst1
= opcode1
->bit_sequence
;
2101 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2102 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
2104 buf
[0] = INST_BYTE0 (inst1
);
2105 buf
[1] = INST_BYTE1 (inst1
);
2106 buf
[2] = INST_BYTE2 (inst1
);
2107 buf
[3] = INST_BYTE3 (inst1
);
2109 /* Add the value only if the symbol is defined. */
2110 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2112 if (target_big_endian
)
2114 buf
[6] |= ((val
>> 8) & 0xff);
2115 buf
[7] |= (val
& 0xff);
2119 buf
[5] |= ((val
>> 8) & 0xff);
2120 buf
[4] |= (val
& 0xff);
2125 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2126 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2127 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2128 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2130 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2131 case BFD_RELOC_MICROBLAZE_64_GOT
:
2132 case BFD_RELOC_MICROBLAZE_64_PLT
:
2133 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2134 /* Add an imm instruction. First save the current instruction. */
2135 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2136 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2138 /* Generate the imm instruction. */
2139 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2140 if (opcode1
== NULL
)
2142 as_bad (_("unknown opcode \"%s\""), "imm");
2146 inst1
= opcode1
->bit_sequence
;
2148 /* We can fixup call to a defined non-global address
2149 within the same section only. */
2150 buf
[0] = INST_BYTE0 (inst1
);
2151 buf
[1] = INST_BYTE1 (inst1
);
2152 buf
[2] = INST_BYTE2 (inst1
);
2153 buf
[3] = INST_BYTE3 (inst1
);
2160 if (fixP
->fx_addsy
== NULL
)
2162 /* This fixup has been resolved. Create a reloc in case the linker
2163 moves code around due to relaxing. */
2164 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2165 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2167 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2168 fixP
->fx_addsy
= section_symbol (absolute_section
);
2174 md_operand (expressionS
* expressionP
)
2176 /* Ignore leading hash symbol, if present. */
2177 if (*input_line_pointer
== '#')
2179 input_line_pointer
++;
2180 expression (expressionP
);
2184 /* Called just before address relaxation, return the length
2185 by which a fragment must grow to reach it's destination. */
2188 md_estimate_size_before_relax (fragS
* fragP
,
2191 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2192 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2193 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2194 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2196 switch (fragP
->fr_subtype
)
2198 case INST_PC_OFFSET
:
2199 /* Used to be a PC-relative branch. */
2200 if (!fragP
->fr_symbol
)
2202 /* We know the abs value: Should never happen. */
2203 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2206 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
&&
2207 !S_IS_WEAK (fragP
->fr_symbol
))
2209 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2210 /* Don't know now whether we need an imm instruction. */
2211 fragP
->fr_var
= INST_WORD_SIZE
;
2213 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2214 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2216 /* Cannot have a PC-relative branch to a diff segment. */
2217 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2218 S_GET_NAME (fragP
->fr_symbol
));
2219 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2220 fragP
->fr_var
= INST_WORD_SIZE
*2;
2224 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2225 fragP
->fr_var
= INST_WORD_SIZE
*2;
2229 case INST_NO_OFFSET
:
2230 /* Used to be a reference to somewhere which was unknown. */
2231 if (fragP
->fr_symbol
)
2233 if (fragP
->fr_opcode
== NULL
)
2235 /* Used as an absolute value. */
2236 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2237 /* Variable part does not change. */
2238 fragP
->fr_var
= INST_WORD_SIZE
*2;
2240 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2242 /* It is accessed using the small data read only anchor. */
2243 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2244 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2245 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2246 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2248 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2249 fragP
->fr_var
= INST_WORD_SIZE
;
2253 /* Variable not in small data read only segment accessed
2254 using small data read only anchor. */
2255 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2257 as_bad_where (file
, fragP
->fr_line
,
2258 _("Variable is accessed using small data read "
2259 "only anchor, but it is not in the small data "
2260 "read only section"));
2261 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2262 fragP
->fr_var
= INST_WORD_SIZE
;
2265 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2267 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2268 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2269 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2270 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2272 /* It is accessed using the small data read write anchor. */
2273 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2274 fragP
->fr_var
= INST_WORD_SIZE
;
2278 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2280 as_bad_where (file
, fragP
->fr_line
,
2281 _("Variable is accessed using small data read "
2282 "write anchor, but it is not in the small data "
2283 "read write section"));
2284 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2285 fragP
->fr_var
= INST_WORD_SIZE
;
2290 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2296 /* We know the abs value: Should never happen. */
2297 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2302 case UNDEFINED_PC_OFFSET
:
2303 case LARGE_DEFINED_PC_OFFSET
:
2304 case DEFINED_ABS_SEGMENT
:
2310 case TLSTPREL_OFFSET
:
2311 case TLSDTPREL_OFFSET
:
2312 fragP
->fr_var
= INST_WORD_SIZE
*2;
2314 case DEFINED_RO_SEGMENT
:
2315 case DEFINED_RW_SEGMENT
:
2316 case DEFINED_PC_OFFSET
:
2317 case TLSDTPMOD_OFFSET
:
2318 fragP
->fr_var
= INST_WORD_SIZE
;
2324 return fragP
->fr_var
;
2327 /* Put number into target byte order. */
2330 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2332 if (target_big_endian
)
2333 number_to_chars_bigendian (ptr
, use
, nbytes
);
2335 number_to_chars_littleendian (ptr
, use
, nbytes
);
2338 /* Round up a section size to the appropriate boundary. */
2341 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2343 return size
; /* Byte alignment is fine. */
2347 /* The location from which a PC relative jump should be calculated,
2348 given a PC relative reloc. */
2351 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2354 /* If the symbol is undefined or defined in another section
2355 we leave the add number alone for the linker to fix it later.
2356 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2358 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2359 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2360 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2364 /* The case where we are going to resolve things... */
2365 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2366 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2368 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2374 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2375 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2378 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2381 bfd_reloc_code_real_type code
;
2383 switch (fixp
->fx_r_type
)
2385 case BFD_RELOC_NONE
:
2386 case BFD_RELOC_MICROBLAZE_64_NONE
:
2388 case BFD_RELOC_MICROBLAZE_32_LO
:
2389 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2392 case BFD_RELOC_64_PCREL
:
2393 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2394 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2395 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2396 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2397 case BFD_RELOC_MICROBLAZE_64_GOT
:
2398 case BFD_RELOC_MICROBLAZE_64_PLT
:
2399 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2400 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2401 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2402 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2403 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
2404 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
2405 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2406 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
2407 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
2408 code
= fixp
->fx_r_type
;
2412 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2414 MAP (1, 0, BFD_RELOC_8
);
2415 MAP (2, 0, BFD_RELOC_16
);
2416 MAP (4, 0, BFD_RELOC_32
);
2417 MAP (1, 1, BFD_RELOC_8_PCREL
);
2418 MAP (2, 1, BFD_RELOC_16_PCREL
);
2419 MAP (4, 1, BFD_RELOC_32_PCREL
);
2421 code
= fixp
->fx_r_type
;
2422 as_bad (_("Can not do %d byte %srelocation"),
2424 fixp
->fx_pcrel
? _("pc-relative") : "");
2429 rel
= (arelent
*) xmalloc (sizeof (arelent
));
2430 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2432 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2433 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2435 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2437 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2438 /* Always pass the addend along! */
2439 rel
->addend
= fixp
->fx_offset
;
2440 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2442 if (rel
->howto
== NULL
)
2444 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2445 _("Cannot represent relocation type %s"),
2446 bfd_get_reloc_code_name (code
));
2448 /* Set howto to a garbage value so that we can keep going. */
2449 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2450 gas_assert (rel
->howto
!= NULL
);
2456 md_parse_option (int c
, char * arg ATTRIBUTE_UNUSED
)
2461 target_big_endian
= 1;
2464 target_big_endian
= 0;
2473 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2475 /* fprintf(stream, _("\
2476 MicroBlaze options:\n\
2477 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2481 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2482 found a machine specific op in an expression,
2483 then we create relocs accordingly. */
2486 cons_fix_new_microblaze (fragS
* frag
,
2490 bfd_reloc_code_real_type r
)
2492 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2493 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2494 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2495 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2496 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2498 exp
->X_op
= O_symbol
;
2499 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2518 as_bad (_("unsupported BFD relocation size %u"), size
);
2523 fix_new_exp (frag
, where
, size
, exp
, 0, r
);