1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright (C) 2009-2017 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
, 0, SHF_ALLOC
+SHF_WRITE
,
155 /* Things in the .sdata segment are always considered to be in the small data section. */
158 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED
)
161 obj_elf_change_section (".sdata", SHT_PROGBITS
, 0, SHF_ALLOC
+SHF_WRITE
,
168 /* Pseudo op to make file scope bss items. */
171 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED
)
181 segT current_seg
= now_seg
;
182 subsegT current_subseg
= now_subseg
;
184 c
= get_symbol_name (&name
);
186 /* Just after name is now '\0'. */
187 p
= input_line_pointer
;
188 (void) restore_line_pointer (c
);
190 if (*input_line_pointer
!= ',')
192 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
193 ignore_rest_of_line ();
197 input_line_pointer
++; /* skip ',' */
198 if ((size
= get_absolute_expression ()) < 0)
200 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size
);
201 ignore_rest_of_line ();
205 /* The third argument to .lcomm is the alignment. */
206 if (*input_line_pointer
!= ',')
210 ++input_line_pointer
;
211 align
= get_absolute_expression ();
214 as_warn (_("ignoring bad alignment"));
220 symbolP
= symbol_find_or_make (name
);
223 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
225 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
226 S_GET_NAME (symbolP
));
227 ignore_rest_of_line ();
231 if (S_GET_VALUE (symbolP
) && S_GET_VALUE (symbolP
) != (valueT
) size
)
233 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
234 S_GET_NAME (symbolP
),
235 (long) S_GET_VALUE (symbolP
),
238 ignore_rest_of_line ();
245 /* Convert to a power of 2 alignment. */
246 for (align2
= 0; (align
& 1) == 0; align
>>= 1, ++align2
);
249 as_bad (_("Common alignment not a power of 2"));
250 ignore_rest_of_line ();
257 record_alignment (current_seg
, align2
);
258 subseg_set (current_seg
, current_subseg
);
260 frag_align (align2
, 0, 0);
261 if (S_GET_SEGMENT (symbolP
) == current_seg
)
262 symbol_get_frag (symbolP
)->fr_symbol
= 0;
263 symbol_set_frag (symbolP
, frag_now
);
264 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
267 S_SET_SIZE (symbolP
, size
);
268 S_SET_SEGMENT (symbolP
, current_seg
);
269 subseg_set (current_seg
, current_subseg
);
270 demand_empty_rest_of_line ();
274 microblaze_s_rdata (int localvar
)
280 obj_elf_change_section (".rodata", SHT_PROGBITS
, 0, SHF_ALLOC
,
282 if (rodata_segment
== 0)
283 rodata_segment
= subseg_new (".rodata", 0);
288 obj_elf_change_section (".sdata2", SHT_PROGBITS
, 0, SHF_ALLOC
,
297 microblaze_s_bss (int localvar
)
300 if (localvar
== 0) /* bss. */
301 obj_elf_change_section (".bss", SHT_NOBITS
, 0, SHF_ALLOC
+SHF_WRITE
,
303 else if (localvar
== 1)
306 obj_elf_change_section (".sbss", SHT_NOBITS
, 0, SHF_ALLOC
+SHF_WRITE
,
308 if (sbss_segment
== 0)
309 sbss_segment
= subseg_new (".sbss", 0);
316 /* endp_p is always 1 as this func is called only for .end <funcname>
317 This func consumes the <funcname> and calls regular processing
318 s_func(1) with arg 1 (1 for end). */
321 microblaze_s_func (int end_p ATTRIBUTE_UNUSED
)
324 restore_line_pointer (get_symbol_name (&name
));
328 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
331 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED
)
338 c
= get_symbol_name (&name
);
339 symbolP
= symbol_find_or_make (name
);
340 S_SET_WEAK (symbolP
);
341 (void) restore_line_pointer (c
);
345 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
347 if (S_IS_DEFINED (symbolP
))
349 as_bad ("Ignoring attempt to redefine symbol `%s'.",
350 S_GET_NAME (symbolP
));
351 ignore_rest_of_line ();
355 if (*input_line_pointer
== ',')
357 ++input_line_pointer
;
362 if (exp
.X_op
!= O_symbol
)
364 as_bad ("bad .weakext directive");
365 ignore_rest_of_line ();
368 symbol_set_value_expression (symbolP
, &exp
);
371 demand_empty_rest_of_line ();
374 /* This table describes all the machine specific pseudo-ops the assembler
375 has to support. The fields are:
376 Pseudo-op name without dot
377 Function to call to execute this pseudo-op
378 Integer arg to pass to the function. */
379 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
380 and then in the read.c table. */
381 const pseudo_typeS md_pseudo_table
[] =
383 {"lcomm", microblaze_s_lcomm
, 1},
384 {"data", microblaze_s_data
, 0},
385 {"data8", cons
, 1}, /* Same as byte. */
386 {"data16", cons
, 2}, /* Same as hword. */
387 {"data32", cons
, 4}, /* Same as word. */
388 {"ent", s_func
, 0}, /* Treat ent as function entry point. */
389 {"end", microblaze_s_func
, 1}, /* Treat end as function end point. */
390 {"gpword", s_rva
, 4}, /* gpword label => store resolved label address in data section. */
391 {"weakext", microblaze_s_weakext
, 0},
392 {"rodata", microblaze_s_rdata
, 0},
393 {"sdata2", microblaze_s_rdata
, 1},
394 {"sdata", microblaze_s_sdata
, 0},
395 {"bss", microblaze_s_bss
, 0},
396 {"sbss", microblaze_s_bss
, 1},
397 {"text", microblaze_s_text
, 0},
399 {"frame", s_ignore
, 0},
400 {"mask", s_ignore
, 0}, /* Emitted by gcc. */
404 /* This function is called once, at assembler startup time. This should
405 set up all the tables, etc that the MD part of the assembler needs. */
410 struct op_code_struct
* opcode
;
412 opcode_hash_control
= hash_new ();
414 /* Insert unique names into hash table. */
415 for (opcode
= opcodes
; opcode
->name
; opcode
++)
416 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
419 /* Try to parse a reg name. */
422 parse_reg (char * s
, unsigned * reg
)
426 /* Strip leading whitespace. */
427 while (ISSPACE (* s
))
430 if (strncasecmp (s
, "rpc", 3) == 0)
435 else if (strncasecmp (s
, "rmsr", 4) == 0)
440 else if (strncasecmp (s
, "rear", 4) == 0)
445 else if (strncasecmp (s
, "resr", 4) == 0)
450 else if (strncasecmp (s
, "rfsr", 4) == 0)
455 else if (strncasecmp (s
, "rbtr", 4) == 0)
460 else if (strncasecmp (s
, "redr", 4) == 0)
465 /* MMU registers start. */
466 else if (strncasecmp (s
, "rpid", 4) == 0)
471 else if (strncasecmp (s
, "rzpr", 4) == 0)
476 else if (strncasecmp (s
, "rtlbx", 5) == 0)
481 else if (strncasecmp (s
, "rtlblo", 6) == 0)
486 else if (strncasecmp (s
, "rtlbhi", 6) == 0)
491 else if (strncasecmp (s
, "rtlbsx", 6) == 0)
496 /* MMU registers end. */
497 else if (strncasecmp (s
, "rpvr", 4) == 0)
499 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
501 tmpreg
= (s
[4]-'0')*10 + s
[5] - '0';
505 else if (ISDIGIT (s
[4]))
511 as_bad (_("register expected, but saw '%.6s'"), s
);
512 if ((int) tmpreg
>= MIN_PVR_REGNUM
&& tmpreg
<= MAX_PVR_REGNUM
)
513 *reg
= REG_PVR
+ tmpreg
;
516 as_bad (_("Invalid register number at '%.6s'"), s
);
521 else if (strncasecmp (s
, "rsp", 3) == 0)
526 else if (strncasecmp (s
, "rfsl", 4) == 0)
528 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
530 tmpreg
= (s
[4] - '0') * 10 + s
[5] - '0';
533 else if (ISDIGIT (s
[4]))
539 as_bad (_("register expected, but saw '%.6s'"), s
);
541 if ((int) tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
545 as_bad (_("Invalid register number at '%.6s'"), s
);
550 /* Stack protection registers. */
551 else if (strncasecmp (s
, "rshr", 4) == 0)
556 else if (strncasecmp (s
, "rslr", 4) == 0)
563 if (TOLOWER (s
[0]) == 'r')
565 if (ISDIGIT (s
[1]) && ISDIGIT (s
[2]))
567 tmpreg
= (s
[1] - '0') * 10 + s
[2] - '0';
570 else if (ISDIGIT (s
[1]))
576 as_bad (_("register expected, but saw '%.6s'"), s
);
578 if ((int)tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
582 as_bad (_("Invalid register number at '%.6s'"), s
);
588 as_bad (_("register expected, but saw '%.6s'"), s
);
594 parse_exp (char *s
, expressionS
*e
)
599 /* Skip whitespace. */
600 while (ISSPACE (* s
))
603 save
= input_line_pointer
;
604 input_line_pointer
= s
;
608 if (e
->X_op
== O_absent
)
609 as_fatal (_("missing operand"));
611 new_pointer
= input_line_pointer
;
612 input_line_pointer
= save
;
617 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
624 #define IMM_TLSDTPMOD 6
625 #define IMM_TLSDTPREL 7
626 #define IMM_TLSTPREL 8
630 const char *isuffix
; /* Suffix String */
631 int itype
; /* Suffix Type */
632 int otype
; /* Offset Type */
635 /* These are NOT in ascending order of type, GOTOFF is ahead to make
636 sure @GOTOFF does not get matched with @GOT */
637 static struct imm_type imm_types
[] = {
638 { "NONE", IMM_NONE
, 0 },
639 { "GOTOFF", IMM_GOTOFF
, GOTOFF_OFFSET
},
640 { "GOT", IMM_GOT
, GOT_OFFSET
},
641 { "PLT", IMM_PLT
, PLT_OFFSET
},
642 { "TLSGD", IMM_TLSGD
, TLSGD_OFFSET
},
643 { "TLSLDM", IMM_TLSLD
, TLSLD_OFFSET
},
644 { "TLSDTPMOD", IMM_TLSDTPMOD
, TLSDTPMOD_OFFSET
},
645 { "TLSDTPREL", IMM_TLSDTPREL
, TLSDTPREL_OFFSET
},
646 { "TLSTPREL", IMM_TLSTPREL
, TLSTPREL_OFFSET
}
650 match_imm (const char *s
, int *ilen
)
655 /* Check for matching suffix */
656 for (i
= 1; i
< IMM_MAX
; i
++)
658 slen
= strlen (imm_types
[i
].isuffix
);
660 if (strncmp (imm_types
[i
].isuffix
, s
, slen
) == 0)
663 return imm_types
[i
].itype
;
671 get_imm_otype (int itype
)
676 /* Check for matching itype */
677 for (i
= 1; i
< IMM_MAX
; i
++)
679 if (imm_types
[i
].itype
== itype
)
681 otype
= imm_types
[i
].otype
;
688 static symbolS
* GOT_symbol
;
690 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
693 parse_imm (char * s
, expressionS
* e
, offsetT min
, offsetT max
)
701 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
702 for (atp
= s
; *atp
!= '@'; atp
++)
703 if (is_end_of_line
[(unsigned char) *atp
])
708 itype
= match_imm (atp
+ 1, &ilen
);
728 if (atp
&& !GOT_symbol
)
730 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
733 new_pointer
= parse_exp (s
, e
);
735 if (!GOT_symbol
&& ! strncmp (s
, GOT_SYMBOL_NAME
, 20))
737 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
740 if (e
->X_op
== O_absent
)
741 ; /* An error message has already been emitted. */
742 else if ((e
->X_op
!= O_constant
&& e
->X_op
!= O_symbol
) )
743 as_fatal (_("operand must be a constant or a label"));
744 else if (e
->X_op
== O_constant
)
746 /* Special case: sign extend negative 32-bit values to offsetT size. */
747 if ((e
->X_add_number
>> 31) == 1)
748 e
->X_add_number
|= -((addressT
) (1U << 31));
750 if (e
->X_add_number
< min
|| e
->X_add_number
> max
)
752 as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"),
753 (long) min
, (long) max
, (long) e
->X_add_number
);
759 *atp
= '@'; /* restore back (needed?) */
760 if (new_pointer
>= atp
)
761 new_pointer
+= ilen
+ 1; /* sizeof (imm_suffix) + 1 for '@' */
767 check_got (int * got_type
, int * got_len
)
775 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
776 for (atp
= input_line_pointer
; *atp
!= '@'; atp
++)
777 if (is_end_of_line
[(unsigned char) *atp
])
780 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
783 *got_type
= IMM_GOTOFF
;
785 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
790 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
799 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
801 first
= atp
- input_line_pointer
;
803 past_got
= atp
+ *got_len
+ 1;
804 for (new_pointer
= past_got
; !is_end_of_line
[(unsigned char) *new_pointer
++];)
806 second
= new_pointer
- past_got
;
807 /* One extra byte for ' ' and one for NUL. */
808 tmpbuf
= XNEWVEC (char, first
+ second
+ 2);
809 memcpy (tmpbuf
, input_line_pointer
, first
);
810 tmpbuf
[first
] = ' '; /* @GOTOFF is replaced with a single space. */
811 memcpy (tmpbuf
+ first
+ 1, past_got
, second
);
812 tmpbuf
[first
+ second
+ 1] = '\0';
817 extern bfd_reloc_code_real_type
818 parse_cons_expression_microblaze (expressionS
*exp
, int size
)
822 /* Handle @GOTOFF et.al. */
823 char *save
, *gotfree_copy
;
824 int got_len
, got_type
;
826 save
= input_line_pointer
;
827 gotfree_copy
= check_got (& got_type
, & got_len
);
829 input_line_pointer
= gotfree_copy
;
835 exp
->X_md
= got_type
;
836 input_line_pointer
= save
+ (input_line_pointer
- gotfree_copy
)
843 return BFD_RELOC_NONE
;
846 /* This is the guts of the machine-dependent assembler. STR points to a
847 machine dependent instruction. This function is supposed to emit
848 the frags/bytes it assembles to. */
850 static const char * str_microblaze_ro_anchor
= "RO";
851 static const char * str_microblaze_rw_anchor
= "RW";
854 check_spl_reg (unsigned * reg
)
856 if ((*reg
== REG_MSR
) || (*reg
== REG_PC
)
857 || (*reg
== REG_EAR
) || (*reg
== REG_ESR
)
858 || (*reg
== REG_FSR
) || (*reg
== REG_BTR
) || (*reg
== REG_EDR
)
859 || (*reg
== REG_PID
) || (*reg
== REG_ZPR
)
860 || (*reg
== REG_TLBX
) || (*reg
== REG_TLBLO
)
861 || (*reg
== REG_TLBHI
) || (*reg
== REG_TLBSX
)
862 || (*reg
== REG_SHR
) || (*reg
== REG_SLR
)
863 || (*reg
>= REG_PVR
+MIN_PVR_REGNUM
&& *reg
<= REG_PVR
+MAX_PVR_REGNUM
))
869 /* Here we decide which fixups can be adjusted to make them relative to
870 the beginning of the section instead of the symbol. Basically we need
871 to make sure that the dynamic relocations are done correctly, so in
872 some cases we force the original symbol to be used. */
875 tc_microblaze_fix_adjustable (struct fix
*fixP
)
877 if (GOT_symbol
&& fixP
->fx_subsy
== GOT_symbol
)
880 if (fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOTOFF
881 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_GOTOFF
882 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOT
883 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_PLT
884 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGD
885 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSLD
886 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
887 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_TLSDTPREL
888 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSDTPREL
889 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
890 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_TLSTPREL
)
897 md_assemble (char * str
)
901 struct op_code_struct
* opcode
, *opcode1
;
902 char * output
= NULL
;
905 unsigned long inst
, inst1
;
910 unsigned int immed
, temp
;
914 /* Drop leading whitespace. */
915 while (ISSPACE (* str
))
918 /* Find the op code end. */
919 for (op_start
= op_end
= str
;
920 *op_end
&& !is_end_of_line
[(unsigned char) *op_end
] && *op_end
!= ' ';
923 name
[nlen
] = op_start
[nlen
];
925 if (nlen
== sizeof (name
) - 1)
933 as_bad (_("can't find opcode "));
937 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, name
);
940 as_bad (_("unknown opcode \"%s\""), name
);
944 inst
= opcode
->bit_sequence
;
947 switch (opcode
->inst_type
)
949 case INST_TYPE_RD_R1_R2
:
950 if (strcmp (op_end
, ""))
951 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
954 as_fatal (_("Error in statement syntax"));
957 if (strcmp (op_end
, ""))
958 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
961 as_fatal (_("Error in statement syntax"));
964 if (strcmp (op_end
, ""))
965 op_end
= parse_reg (op_end
+ 1, ®3
); /* Get r2. */
968 as_fatal (_("Error in statement syntax"));
972 /* Check for spl registers. */
973 if (check_spl_reg (& reg1
))
974 as_fatal (_("Cannot use special register with this instruction"));
975 if (check_spl_reg (& reg2
))
976 as_fatal (_("Cannot use special register with this instruction"));
977 if (check_spl_reg (& reg3
))
978 as_fatal (_("Cannot use special register with this instruction"));
980 if (streq (name
, "sub"))
982 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
983 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
984 inst
|= (reg3
<< RA_LOW
) & RA_MASK
;
985 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
989 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
990 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
991 inst
|= (reg3
<< RB_LOW
) & RB_MASK
;
993 output
= frag_more (isize
);
996 case INST_TYPE_RD_R1_IMM
:
997 if (strcmp (op_end
, ""))
998 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1001 as_fatal (_("Error in statement syntax"));
1004 if (strcmp (op_end
, ""))
1005 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1008 as_fatal (_("Error in statement syntax"));
1011 if (strcmp (op_end
, ""))
1012 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1014 as_fatal (_("Error in statement syntax"));
1016 /* Check for spl registers. */
1017 if (check_spl_reg (& reg1
))
1018 as_fatal (_("Cannot use special register with this instruction"));
1019 if (check_spl_reg (& reg2
))
1020 as_fatal (_("Cannot use special register with this instruction"));
1022 if (exp
.X_op
!= O_constant
)
1025 relax_substateT subtype
;
1027 if (streq (name
, "lmi"))
1028 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
1029 else if (streq (name
, "smi"))
1030 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
1032 if (reg2
== REG_ROSDP
)
1033 opc
= str_microblaze_ro_anchor
;
1034 else if (reg2
== REG_RWSDP
)
1035 opc
= str_microblaze_rw_anchor
;
1039 subtype
= get_imm_otype(exp
.X_md
);
1041 subtype
= opcode
->inst_offset_type
;
1043 output
= frag_var (rs_machine_dependent
,
1044 isize
* 2, /* maxm of 2 words. */
1045 isize
, /* minm of 1 word. */
1046 subtype
, /* PC-relative or not. */
1054 output
= frag_more (isize
);
1055 immed
= exp
.X_add_number
;
1058 if (streq (name
, "lmi") || streq (name
, "smi"))
1060 /* Load/store 32-d consecutive registers. Used on exit/entry
1061 to subroutines to save and restore registers to stack.
1062 Generate 32-d insts. */
1066 if (streq (name
, "lmi"))
1067 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "lwi");
1069 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "swi");
1072 as_bad (_("unknown opcode \"%s\""), "lwi");
1075 inst
= opcode
->bit_sequence
;
1076 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1077 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1078 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1080 for (i
= 0; i
< count
- 1; i
++)
1082 output
[0] = INST_BYTE0 (inst
);
1083 output
[1] = INST_BYTE1 (inst
);
1084 output
[2] = INST_BYTE2 (inst
);
1085 output
[3] = INST_BYTE3 (inst
);
1086 output
= frag_more (isize
);
1089 inst
= opcode
->bit_sequence
;
1090 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1091 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1092 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1097 temp
= immed
& 0xFFFF8000;
1098 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1100 /* Needs an immediate inst. */
1101 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1102 if (opcode1
== NULL
)
1104 as_bad (_("unknown opcode \"%s\""), "imm");
1108 inst1
= opcode1
->bit_sequence
;
1109 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1110 output
[0] = INST_BYTE0 (inst1
);
1111 output
[1] = INST_BYTE1 (inst1
);
1112 output
[2] = INST_BYTE2 (inst1
);
1113 output
[3] = INST_BYTE3 (inst1
);
1114 output
= frag_more (isize
);
1116 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1117 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1118 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1122 case INST_TYPE_RD_R1_IMM5
:
1123 if (strcmp (op_end
, ""))
1124 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1127 as_fatal (_("Error in statement syntax"));
1130 if (strcmp (op_end
, ""))
1131 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1134 as_fatal (_("Error in statement syntax"));
1137 if (strcmp (op_end
, ""))
1138 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1140 as_fatal (_("Error in statement syntax"));
1142 /* Check for spl registers. */
1143 if (check_spl_reg (®1
))
1144 as_fatal (_("Cannot use special register with this instruction"));
1145 if (check_spl_reg (®2
))
1146 as_fatal (_("Cannot use special register with this instruction"));
1148 if (exp
.X_op
!= O_constant
)
1149 as_warn (_("Symbol used as immediate for shift instruction"));
1152 output
= frag_more (isize
);
1153 immed
= exp
.X_add_number
;
1156 if (immed
!= (immed
% 32))
1158 as_warn (_("Shift value > 32. using <value %% 32>"));
1161 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1162 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1163 inst
|= (immed
<< IMM_LOW
) & IMM5_MASK
;
1166 case INST_TYPE_R1_R2
:
1167 if (strcmp (op_end
, ""))
1168 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1171 as_fatal (_("Error in statement syntax"));
1174 if (strcmp (op_end
, ""))
1175 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1178 as_fatal (_("Error in statement syntax"));
1182 /* Check for spl registers. */
1183 if (check_spl_reg (& reg1
))
1184 as_fatal (_("Cannot use special register with this instruction"));
1185 if (check_spl_reg (& reg2
))
1186 as_fatal (_("Cannot use special register with this instruction"));
1188 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1189 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1190 output
= frag_more (isize
);
1193 case INST_TYPE_RD_R1
:
1194 if (strcmp (op_end
, ""))
1195 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1198 as_fatal (_("Error in statement syntax"));
1201 if (strcmp (op_end
, ""))
1202 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1205 as_fatal (_("Error in statement syntax"));
1209 /* Check for spl registers. */
1210 if (check_spl_reg (®1
))
1211 as_fatal (_("Cannot use special register with this instruction"));
1212 if (check_spl_reg (®2
))
1213 as_fatal (_("Cannot use special register with this instruction"));
1215 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1216 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1217 output
= frag_more (isize
);
1220 case INST_TYPE_RD_RFSL
:
1221 if (strcmp (op_end
, ""))
1222 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1225 as_fatal (_("Error in statement syntax"));
1228 if (strcmp (op_end
, ""))
1229 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1232 as_fatal (_("Error in statement syntax"));
1236 /* Check for spl registers. */
1237 if (check_spl_reg (®1
))
1238 as_fatal (_("Cannot use special register with this instruction"));
1240 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1241 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1242 output
= frag_more (isize
);
1245 case INST_TYPE_RD_IMM15
:
1246 if (strcmp (op_end
, ""))
1247 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1250 as_fatal (_("Error in statement syntax"));
1254 if (strcmp (op_end
, ""))
1255 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1257 as_fatal (_("Error in statement syntax"));
1259 /* Check for spl registers. */
1260 if (check_spl_reg (®1
))
1261 as_fatal (_("Cannot use special register with this instruction"));
1263 if (exp
.X_op
!= O_constant
)
1264 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1267 output
= frag_more (isize
);
1268 immed
= exp
.X_add_number
;
1270 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1271 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1274 case INST_TYPE_R1_RFSL
:
1275 if (strcmp (op_end
, ""))
1276 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1279 as_fatal (_("Error in statement syntax"));
1282 if (strcmp (op_end
, ""))
1283 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1286 as_fatal (_("Error in statement syntax"));
1290 /* Check for spl registers. */
1291 if (check_spl_reg (®1
))
1292 as_fatal (_("Cannot use special register with this instruction"));
1294 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1295 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1296 output
= frag_more (isize
);
1299 case INST_TYPE_RFSL
:
1300 if (strcmp (op_end
, ""))
1301 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1304 as_fatal (_("Error in statement syntax"));
1307 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1308 output
= frag_more (isize
);
1312 if (strcmp (op_end
, ""))
1313 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1316 as_fatal (_("Error in statement syntax"));
1320 /* Check for spl registers. */
1321 if (check_spl_reg (®1
))
1322 as_fatal (_("Cannot use special register with this instruction"));
1324 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1325 output
= frag_more (isize
);
1328 /* For tuqula insn...:) */
1330 if (strcmp (op_end
, ""))
1331 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1334 as_fatal (_("Error in statement syntax"));
1338 /* Check for spl registers. */
1339 if (check_spl_reg (®1
))
1340 as_fatal (_("Cannot use special register with this instruction"));
1342 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1343 output
= frag_more (isize
);
1346 case INST_TYPE_RD_SPECIAL
:
1347 if (strcmp (op_end
, ""))
1348 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1351 as_fatal (_("Error in statement syntax"));
1354 if (strcmp (op_end
, ""))
1355 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1358 as_fatal (_("Error in statement syntax"));
1362 if (reg2
== REG_MSR
)
1363 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1364 else if (reg2
== REG_PC
)
1365 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1366 else if (reg2
== REG_EAR
)
1367 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1368 else if (reg2
== REG_ESR
)
1369 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1370 else if (reg2
== REG_FSR
)
1371 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1372 else if (reg2
== REG_BTR
)
1373 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1374 else if (reg2
== REG_EDR
)
1375 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1376 else if (reg2
== REG_PID
)
1377 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1378 else if (reg2
== REG_ZPR
)
1379 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1380 else if (reg2
== REG_TLBX
)
1381 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1382 else if (reg2
== REG_TLBLO
)
1383 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1384 else if (reg2
== REG_TLBHI
)
1385 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1386 else if (reg2
== REG_SHR
)
1387 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1388 else if (reg2
== REG_SLR
)
1389 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1390 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1391 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1393 as_fatal (_("invalid value for special purpose register"));
1394 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1395 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1396 output
= frag_more (isize
);
1399 case INST_TYPE_SPECIAL_R1
:
1400 if (strcmp (op_end
, ""))
1401 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1404 as_fatal (_("Error in statement syntax"));
1407 if (strcmp (op_end
, ""))
1408 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1411 as_fatal (_("Error in statement syntax"));
1415 if (reg1
== REG_MSR
)
1416 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1417 else if (reg1
== REG_PC
)
1418 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1419 else if (reg1
== REG_EAR
)
1420 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1421 else if (reg1
== REG_ESR
)
1422 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1423 else if (reg1
== REG_FSR
)
1424 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1425 else if (reg1
== REG_BTR
)
1426 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1427 else if (reg1
== REG_EDR
)
1428 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1429 else if (reg1
== REG_PID
)
1430 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1431 else if (reg1
== REG_ZPR
)
1432 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1433 else if (reg1
== REG_TLBX
)
1434 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1435 else if (reg1
== REG_TLBLO
)
1436 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1437 else if (reg1
== REG_TLBHI
)
1438 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1439 else if (reg1
== REG_TLBSX
)
1440 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1441 else if (reg1
== REG_SHR
)
1442 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1443 else if (reg1
== REG_SLR
)
1444 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1446 as_fatal (_("invalid value for special purpose register"));
1447 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1448 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1449 output
= frag_more (isize
);
1452 case INST_TYPE_R1_R2_SPECIAL
:
1453 if (strcmp (op_end
, ""))
1454 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1457 as_fatal (_("Error in statement syntax"));
1460 if (strcmp (op_end
, ""))
1461 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1464 as_fatal (_("Error in statement syntax"));
1468 /* Check for spl registers. */
1469 if (check_spl_reg (®1
))
1470 as_fatal (_("Cannot use special register with this instruction"));
1471 if (check_spl_reg (®2
))
1472 as_fatal (_("Cannot use special register with this instruction"));
1474 /* insn wic ra, rb => wic ra, ra, rb. */
1475 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1476 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1478 output
= frag_more (isize
);
1481 case INST_TYPE_RD_R2
:
1482 if (strcmp (op_end
, ""))
1483 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1486 as_fatal (_("Error in statement syntax"));
1489 if (strcmp (op_end
, ""))
1490 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1493 as_fatal (_("Error in statement syntax"));
1497 /* Check for spl registers. */
1498 if (check_spl_reg (®1
))
1499 as_fatal (_("Cannot use special register with this instruction"));
1500 if (check_spl_reg (®2
))
1501 as_fatal (_("Cannot use special register with this instruction"));
1503 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1504 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1505 output
= frag_more (isize
);
1508 case INST_TYPE_R1_IMM
:
1509 if (strcmp (op_end
, ""))
1510 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1513 as_fatal (_("Error in statement syntax"));
1516 if (strcmp (op_end
, ""))
1517 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1519 as_fatal (_("Error in statement syntax"));
1521 /* Check for spl registers. */
1522 if (check_spl_reg (®1
))
1523 as_fatal (_("Cannot use special register with this instruction"));
1525 if (exp
.X_op
!= O_constant
)
1528 relax_substateT subtype
;
1531 subtype
= get_imm_otype(exp
.X_md
);
1533 subtype
= opcode
->inst_offset_type
;
1535 output
= frag_var (rs_machine_dependent
,
1536 isize
* 2, /* maxm of 2 words. */
1537 isize
, /* minm of 1 word. */
1538 subtype
, /* PC-relative or not. */
1546 output
= frag_more (isize
);
1547 immed
= exp
.X_add_number
;
1550 temp
= immed
& 0xFFFF8000;
1551 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1553 /* Needs an immediate inst. */
1554 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1555 if (opcode1
== NULL
)
1557 as_bad (_("unknown opcode \"%s\""), "imm");
1561 inst1
= opcode1
->bit_sequence
;
1562 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1563 output
[0] = INST_BYTE0 (inst1
);
1564 output
[1] = INST_BYTE1 (inst1
);
1565 output
[2] = INST_BYTE2 (inst1
);
1566 output
[3] = INST_BYTE3 (inst1
);
1567 output
= frag_more (isize
);
1570 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1571 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1574 case INST_TYPE_RD_IMM
:
1575 if (strcmp (op_end
, ""))
1576 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1579 as_fatal (_("Error in statement syntax"));
1582 if (strcmp (op_end
, ""))
1583 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1585 as_fatal (_("Error in statement syntax"));
1587 /* Check for spl registers. */
1588 if (check_spl_reg (®1
))
1589 as_fatal (_("Cannot use special register with this instruction"));
1591 if (exp
.X_op
!= O_constant
)
1594 relax_substateT subtype
;
1597 subtype
= get_imm_otype(exp
.X_md
);
1599 subtype
= opcode
->inst_offset_type
;
1601 output
= frag_var (rs_machine_dependent
,
1602 isize
* 2, /* maxm of 2 words. */
1603 isize
, /* minm of 1 word. */
1604 subtype
, /* PC-relative or not. */
1612 output
= frag_more (isize
);
1613 immed
= exp
.X_add_number
;
1616 temp
= immed
& 0xFFFF8000;
1617 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1619 /* Needs an immediate inst. */
1620 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1621 if (opcode1
== NULL
)
1623 as_bad (_("unknown opcode \"%s\""), "imm");
1627 inst1
= opcode1
->bit_sequence
;
1628 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1629 output
[0] = INST_BYTE0 (inst1
);
1630 output
[1] = INST_BYTE1 (inst1
);
1631 output
[2] = INST_BYTE2 (inst1
);
1632 output
[3] = INST_BYTE3 (inst1
);
1633 output
= frag_more (isize
);
1636 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1637 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1641 if (strcmp (op_end
, ""))
1642 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1645 as_fatal (_("Error in statement syntax"));
1649 /* Check for spl registers. */
1650 if (check_spl_reg (®2
))
1651 as_fatal (_("Cannot use special register with this instruction"));
1653 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1654 output
= frag_more (isize
);
1658 if (streq (name
, "imm"))
1659 as_fatal (_("An IMM instruction should not be present in the .s file"));
1661 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1663 if (exp
.X_op
!= O_constant
)
1666 relax_substateT subtype
;
1669 subtype
= get_imm_otype(exp
.X_md
);
1671 subtype
= opcode
->inst_offset_type
;
1673 output
= frag_var (rs_machine_dependent
,
1674 isize
* 2, /* maxm of 2 words. */
1675 isize
, /* minm of 1 word. */
1676 subtype
, /* PC-relative or not. */
1684 output
= frag_more (isize
);
1685 immed
= exp
.X_add_number
;
1689 temp
= immed
& 0xFFFF8000;
1690 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1692 /* Needs an immediate inst. */
1693 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1694 if (opcode1
== NULL
)
1696 as_bad (_("unknown opcode \"%s\""), "imm");
1700 inst1
= opcode1
->bit_sequence
;
1701 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1702 output
[0] = INST_BYTE0 (inst1
);
1703 output
[1] = INST_BYTE1 (inst1
);
1704 output
[2] = INST_BYTE2 (inst1
);
1705 output
[3] = INST_BYTE3 (inst1
);
1706 output
= frag_more (isize
);
1708 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1711 case INST_TYPE_NONE
:
1712 output
= frag_more (isize
);
1715 case INST_TYPE_IMM5
:
1716 if (strcmp(op_end
, ""))
1717 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM5
, MAX_IMM5
);
1719 as_fatal(_("Error in statement syntax"));
1720 if (exp
.X_op
!= O_constant
) {
1721 as_warn(_("Symbol used as immediate for mbar instruction"));
1723 output
= frag_more (isize
);
1724 immed
= exp
.X_add_number
;
1726 if (immed
!= (immed
% 32)) {
1727 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1730 inst
|= (immed
<< IMM_MBAR
);
1734 as_fatal (_("unimplemented opcode \"%s\""), name
);
1737 /* Drop whitespace after all the operands have been parsed. */
1738 while (ISSPACE (* op_end
))
1741 /* Give warning message if the insn has more operands than required. */
1742 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1743 as_warn (_("ignoring operands: %s "), op_end
);
1745 output
[0] = INST_BYTE0 (inst
);
1746 output
[1] = INST_BYTE1 (inst
);
1747 output
[2] = INST_BYTE2 (inst
);
1748 output
[3] = INST_BYTE3 (inst
);
1751 dwarf2_emit_insn (4);
1756 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1761 /* Various routines to kill one day. */
1762 /* Equal to MAX_PRECISION in atof-ieee.c */
1763 #define MAX_LITTLENUMS 6
1765 /* Turn a string in input_line_pointer into a floating point constant of type
1766 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1767 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1769 md_atof (int type
, char * litP
, int * sizeP
)
1772 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1804 return _("Bad call to MD_NTOF()");
1807 t
= atof_ieee (input_line_pointer
, type
, words
);
1810 input_line_pointer
= t
;
1812 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1814 if (! target_big_endian
)
1816 for (i
= prec
- 1; i
>= 0; i
--)
1818 md_number_to_chars (litP
, (valueT
) words
[i
],
1819 sizeof (LITTLENUM_TYPE
));
1820 litP
+= sizeof (LITTLENUM_TYPE
);
1824 for (i
= 0; i
< prec
; i
++)
1826 md_number_to_chars (litP
, (valueT
) words
[i
],
1827 sizeof (LITTLENUM_TYPE
));
1828 litP
+= sizeof (LITTLENUM_TYPE
);
1834 const char * md_shortopts
= "";
1836 struct option md_longopts
[] =
1838 {"EB", no_argument
, NULL
, OPTION_EB
},
1839 {"EL", no_argument
, NULL
, OPTION_EL
},
1840 { NULL
, no_argument
, NULL
, 0}
1843 size_t md_longopts_size
= sizeof (md_longopts
);
1845 int md_short_jump_size
;
1848 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED
,
1849 addressT from_Nddr ATTRIBUTE_UNUSED
,
1850 addressT to_Nddr ATTRIBUTE_UNUSED
,
1851 fragS
* frag ATTRIBUTE_UNUSED
,
1852 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1854 as_fatal (_("failed sanity check: short_jump"));
1858 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED
,
1859 addressT from_Nddr ATTRIBUTE_UNUSED
,
1860 addressT to_Nddr ATTRIBUTE_UNUSED
,
1861 fragS
* frag ATTRIBUTE_UNUSED
,
1862 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1864 as_fatal (_("failed sanity check: long_jump"));
1867 /* Called after relaxing, change the frags so they know how big they are. */
1870 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1871 segT sec ATTRIBUTE_UNUSED
,
1876 switch (fragP
->fr_subtype
)
1878 case UNDEFINED_PC_OFFSET
:
1879 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1880 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1881 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1884 case DEFINED_ABS_SEGMENT
:
1885 if (fragP
->fr_symbol
== GOT_symbol
)
1886 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1887 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_GOTPC
);
1889 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1890 fragP
->fr_offset
, FALSE
, BFD_RELOC_64
);
1891 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1894 case DEFINED_RO_SEGMENT
:
1895 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1896 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_ROSDA
);
1897 fragP
->fr_fix
+= INST_WORD_SIZE
;
1900 case DEFINED_RW_SEGMENT
:
1901 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1902 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_RWSDA
);
1903 fragP
->fr_fix
+= INST_WORD_SIZE
;
1906 case DEFINED_PC_OFFSET
:
1907 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1908 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_32_LO_PCREL
);
1909 fragP
->fr_fix
+= INST_WORD_SIZE
;
1912 case LARGE_DEFINED_PC_OFFSET
:
1913 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1914 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1915 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1919 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1920 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOT
);
1921 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1925 fixP
= fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1926 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_PLT
);
1927 /* fixP->fx_plt = 1; */
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_GOTOFF
);
1935 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1939 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1940 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSGD
);
1941 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1945 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1946 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSLD
);
1947 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1950 case TLSDTPREL_OFFSET
:
1951 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1952 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_TLSDTPREL
);
1953 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1962 /* Applies the desired value to the specified location.
1963 Also sets up addends for 'rela' type relocations. */
1965 md_apply_fix (fixS
* fixP
,
1969 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1970 const char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
1971 const char * symname
;
1972 /* Note: use offsetT because it is signed, valueT is unsigned. */
1973 offsetT val
= (offsetT
) * valp
;
1975 struct op_code_struct
* opcode1
;
1976 unsigned long inst1
;
1978 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
1980 /* fixP->fx_offset is supposed to be set up correctly for all
1981 symbol relocations. */
1982 if (fixP
->fx_addsy
== NULL
)
1984 if (!fixP
->fx_pcrel
)
1985 fixP
->fx_offset
= val
; /* Absolute relocation. */
1987 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1988 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
1991 /* If we aren't adjusting this fixup to be against the section
1992 symbol, we need to adjust the value. */
1993 if (fixP
->fx_addsy
!= NULL
)
1995 if (S_IS_WEAK (fixP
->fx_addsy
)
1996 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
1997 && (((bfd_get_section_flags (stdoutput
,
1998 S_GET_SEGMENT (fixP
->fx_addsy
))
1999 & SEC_LINK_ONCE
) != 0)
2000 || !strncmp (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
2002 sizeof (".gnu.linkonce") - 1))))
2004 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2005 if (val
!= 0 && ! fixP
->fx_pcrel
)
2007 /* In this case, the bfd_install_relocation routine will
2008 incorrectly add the symbol value back in. We just want
2009 the addend to appear in the object file.
2010 FIXME: If this makes VALUE zero, we're toast. */
2011 val
-= S_GET_VALUE (fixP
->fx_addsy
);
2016 /* If the fix is relative to a symbol which is not defined, or not
2017 in the same segment as the fix, we cannot resolve it here. */
2018 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
2019 if (fixP
->fx_addsy
!= NULL
2020 && (!S_IS_DEFINED (fixP
->fx_addsy
)
2021 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
2025 /* For ELF we can just return and let the reloc that will be generated
2026 take care of everything. For COFF we still have to insert 'val'
2027 into the insn since the addend field will be ignored. */
2031 /* All fixups in the text section must be handled in the linker. */
2032 else if (segment
->flags
& SEC_CODE
)
2034 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
2039 switch (fixP
->fx_r_type
)
2041 case BFD_RELOC_MICROBLAZE_32_LO
:
2042 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2043 if (target_big_endian
)
2045 buf
[2] |= ((val
>> 8) & 0xff);
2046 buf
[3] |= (val
& 0xff);
2050 buf
[1] |= ((val
>> 8) & 0xff);
2051 buf
[0] |= (val
& 0xff);
2054 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2055 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2056 /* Don't do anything if the symbol is not defined. */
2057 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2059 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
2060 as_bad_where (file
, fixP
->fx_line
,
2061 _("pcrel for branch to %s too far (0x%x)"),
2062 symname
, (int) val
);
2063 if (target_big_endian
)
2065 buf
[2] |= ((val
>> 8) & 0xff);
2066 buf
[3] |= (val
& 0xff);
2070 buf
[1] |= ((val
>> 8) & 0xff);
2071 buf
[0] |= (val
& 0xff);
2077 case BFD_RELOC_32_PCREL
:
2078 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2079 /* Don't do anything if the symbol is not defined. */
2080 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2082 if (target_big_endian
)
2084 buf
[0] |= ((val
>> 24) & 0xff);
2085 buf
[1] |= ((val
>> 16) & 0xff);
2086 buf
[2] |= ((val
>> 8) & 0xff);
2087 buf
[3] |= (val
& 0xff);
2091 buf
[3] |= ((val
>> 24) & 0xff);
2092 buf
[2] |= ((val
>> 16) & 0xff);
2093 buf
[1] |= ((val
>> 8) & 0xff);
2094 buf
[0] |= (val
& 0xff);
2098 case BFD_RELOC_64_PCREL
:
2100 /* Add an imm instruction. First save the current instruction. */
2101 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2102 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2104 /* Generate the imm instruction. */
2105 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2106 if (opcode1
== NULL
)
2108 as_bad (_("unknown opcode \"%s\""), "imm");
2112 inst1
= opcode1
->bit_sequence
;
2113 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2114 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
2116 buf
[0] = INST_BYTE0 (inst1
);
2117 buf
[1] = INST_BYTE1 (inst1
);
2118 buf
[2] = INST_BYTE2 (inst1
);
2119 buf
[3] = INST_BYTE3 (inst1
);
2121 /* Add the value only if the symbol is defined. */
2122 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2124 if (target_big_endian
)
2126 buf
[6] |= ((val
>> 8) & 0xff);
2127 buf
[7] |= (val
& 0xff);
2131 buf
[5] |= ((val
>> 8) & 0xff);
2132 buf
[4] |= (val
& 0xff);
2137 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2138 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2139 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2140 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2143 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2144 case BFD_RELOC_MICROBLAZE_64_GOT
:
2145 case BFD_RELOC_MICROBLAZE_64_PLT
:
2146 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2147 /* Add an imm instruction. First save the current instruction. */
2148 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2149 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2151 /* Generate the imm instruction. */
2152 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2153 if (opcode1
== NULL
)
2155 as_bad (_("unknown opcode \"%s\""), "imm");
2159 inst1
= opcode1
->bit_sequence
;
2161 /* We can fixup call to a defined non-global address
2162 within the same section only. */
2163 buf
[0] = INST_BYTE0 (inst1
);
2164 buf
[1] = INST_BYTE1 (inst1
);
2165 buf
[2] = INST_BYTE2 (inst1
);
2166 buf
[3] = INST_BYTE3 (inst1
);
2173 if (fixP
->fx_addsy
== NULL
)
2175 /* This fixup has been resolved. Create a reloc in case the linker
2176 moves code around due to relaxing. */
2177 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2178 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2180 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2181 fixP
->fx_addsy
= section_symbol (absolute_section
);
2187 md_operand (expressionS
* expressionP
)
2189 /* Ignore leading hash symbol, if present. */
2190 if (*input_line_pointer
== '#')
2192 input_line_pointer
++;
2193 expression (expressionP
);
2197 /* Called just before address relaxation, return the length
2198 by which a fragment must grow to reach it's destination. */
2201 md_estimate_size_before_relax (fragS
* fragP
,
2204 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2205 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2206 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2207 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2209 switch (fragP
->fr_subtype
)
2211 case INST_PC_OFFSET
:
2212 /* Used to be a PC-relative branch. */
2213 if (!fragP
->fr_symbol
)
2215 /* We know the abs value: Should never happen. */
2216 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2219 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
&&
2220 !S_IS_WEAK (fragP
->fr_symbol
))
2222 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2223 /* Don't know now whether we need an imm instruction. */
2224 fragP
->fr_var
= INST_WORD_SIZE
;
2226 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2227 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2229 /* Cannot have a PC-relative branch to a diff segment. */
2230 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2231 S_GET_NAME (fragP
->fr_symbol
));
2232 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2233 fragP
->fr_var
= INST_WORD_SIZE
*2;
2237 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2238 fragP
->fr_var
= INST_WORD_SIZE
*2;
2242 case INST_NO_OFFSET
:
2243 /* Used to be a reference to somewhere which was unknown. */
2244 if (fragP
->fr_symbol
)
2246 if (fragP
->fr_opcode
== NULL
)
2248 /* Used as an absolute value. */
2249 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2250 /* Variable part does not change. */
2251 fragP
->fr_var
= INST_WORD_SIZE
*2;
2253 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2255 /* It is accessed using the small data read only anchor. */
2256 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2257 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2258 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2259 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2261 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2262 fragP
->fr_var
= INST_WORD_SIZE
;
2266 /* Variable not in small data read only segment accessed
2267 using small data read only anchor. */
2268 const char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2270 as_bad_where (file
, fragP
->fr_line
,
2271 _("Variable is accessed using small data read "
2272 "only anchor, but it is not in the small data "
2273 "read only section"));
2274 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2275 fragP
->fr_var
= INST_WORD_SIZE
;
2278 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2280 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2281 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2282 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2283 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2285 /* It is accessed using the small data read write anchor. */
2286 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2287 fragP
->fr_var
= INST_WORD_SIZE
;
2291 const char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2293 as_bad_where (file
, fragP
->fr_line
,
2294 _("Variable is accessed using small data read "
2295 "write anchor, but it is not in the small data "
2296 "read write section"));
2297 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2298 fragP
->fr_var
= INST_WORD_SIZE
;
2303 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2309 /* We know the abs value: Should never happen. */
2310 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2315 case UNDEFINED_PC_OFFSET
:
2316 case LARGE_DEFINED_PC_OFFSET
:
2317 case DEFINED_ABS_SEGMENT
:
2323 case TLSTPREL_OFFSET
:
2324 case TLSDTPREL_OFFSET
:
2325 fragP
->fr_var
= INST_WORD_SIZE
*2;
2327 case DEFINED_RO_SEGMENT
:
2328 case DEFINED_RW_SEGMENT
:
2329 case DEFINED_PC_OFFSET
:
2330 case TLSDTPMOD_OFFSET
:
2331 fragP
->fr_var
= INST_WORD_SIZE
;
2337 return fragP
->fr_var
;
2340 /* Put number into target byte order. */
2343 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2345 if (target_big_endian
)
2346 number_to_chars_bigendian (ptr
, use
, nbytes
);
2348 number_to_chars_littleendian (ptr
, use
, nbytes
);
2351 /* Round up a section size to the appropriate boundary. */
2354 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2356 return size
; /* Byte alignment is fine. */
2360 /* The location from which a PC relative jump should be calculated,
2361 given a PC relative reloc. */
2364 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2367 /* If the symbol is undefined or defined in another section
2368 we leave the add number alone for the linker to fix it later.
2369 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2371 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2372 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2373 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2377 /* The case where we are going to resolve things... */
2378 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2379 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2381 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2387 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2388 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2391 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2394 bfd_reloc_code_real_type code
;
2396 switch (fixp
->fx_r_type
)
2398 case BFD_RELOC_NONE
:
2399 case BFD_RELOC_MICROBLAZE_64_NONE
:
2401 case BFD_RELOC_MICROBLAZE_32_LO
:
2402 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2405 case BFD_RELOC_64_PCREL
:
2406 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2407 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2408 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2409 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2410 case BFD_RELOC_MICROBLAZE_64_GOT
:
2411 case BFD_RELOC_MICROBLAZE_64_PLT
:
2412 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2413 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2414 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
2415 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
2416 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
2417 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
2418 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
2419 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
2420 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
2421 code
= fixp
->fx_r_type
;
2425 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2427 MAP (1, 0, BFD_RELOC_8
);
2428 MAP (2, 0, BFD_RELOC_16
);
2429 MAP (4, 0, BFD_RELOC_32
);
2430 MAP (1, 1, BFD_RELOC_8_PCREL
);
2431 MAP (2, 1, BFD_RELOC_16_PCREL
);
2432 MAP (4, 1, BFD_RELOC_32_PCREL
);
2434 code
= fixp
->fx_r_type
;
2435 as_bad (_("Can not do %d byte %srelocation"),
2437 fixp
->fx_pcrel
? _("pc-relative ") : "");
2442 rel
= XNEW (arelent
);
2443 rel
->sym_ptr_ptr
= XNEW (asymbol
*);
2445 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2446 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2448 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2450 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2451 /* Always pass the addend along! */
2452 rel
->addend
= fixp
->fx_offset
;
2453 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2455 if (rel
->howto
== NULL
)
2457 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2458 _("Cannot represent relocation type %s"),
2459 bfd_get_reloc_code_name (code
));
2461 /* Set howto to a garbage value so that we can keep going. */
2462 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2463 gas_assert (rel
->howto
!= NULL
);
2469 md_parse_option (int c
, const char * arg ATTRIBUTE_UNUSED
)
2474 target_big_endian
= 1;
2477 target_big_endian
= 0;
2486 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2488 /* fprintf(stream, _("\
2489 MicroBlaze options:\n\
2490 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2494 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2495 found a machine specific op in an expression,
2496 then we create relocs accordingly. */
2499 cons_fix_new_microblaze (fragS
* frag
,
2503 bfd_reloc_code_real_type r
)
2505 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2506 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2507 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2508 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2509 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2511 exp
->X_op
= O_symbol
;
2512 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2531 as_bad (_("unsupported BFD relocation size %u"), size
);
2536 fix_new_exp (frag
, where
, size
, exp
, 0, r
);