1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright 2009, 2010, 2012 Free Software Foundation.
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
86 /* Initialize the relax table. */
87 const relax_typeS md_relax_table
[] =
89 { 1, 1, 0, 0 }, /* 0: Unused. */
90 { 1, 1, 0, 0 }, /* 1: Unused. */
91 { 1, 1, 0, 0 }, /* 2: Unused. */
92 { 1, 1, 0, 0 }, /* 3: Unused. */
93 { 32767, -32768, INST_WORD_SIZE
, LARGE_DEFINED_PC_OFFSET
}, /* 4: DEFINED_PC_OFFSET. */
94 { 1, 1, 0, 0 }, /* 5: Unused. */
95 { 1, 1, 0, 0 }, /* 6: Unused. */
96 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
97 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 8: GOT_OFFSET. */
98 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 9: PLT_OFFSET. */
99 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 10: GOTOFF_OFFSET. */
102 static struct hash_control
* opcode_hash_control
; /* Opcode mnemonics. */
104 static segT sbss_segment
= 0; /* Small bss section. */
105 static segT sbss2_segment
= 0; /* Section not used. */
106 static segT sdata_segment
= 0; /* Small data section. */
107 static segT sdata2_segment
= 0; /* Small read-only section. */
108 static segT rodata_segment
= 0; /* read-only section. */
110 /* Generate a symbol for stabs information. */
113 microblaze_generate_symbol (char *sym
)
115 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
116 static int microblaze_label_count
;
117 sprintf (sym
, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME
, microblaze_label_count
);
118 ++microblaze_label_count
;
121 /* Handle the section changing pseudo-ops. */
124 microblaze_s_text (int ignore ATTRIBUTE_UNUSED
)
127 obj_elf_text (ignore
);
134 microblaze_s_data (int ignore ATTRIBUTE_UNUSED
)
137 obj_elf_change_section (".data", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
143 /* Things in the .sdata segment are always considered to be in the small data section. */
146 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED
)
149 obj_elf_change_section (".sdata", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
155 /* Pseudo op to make file scope bss items. */
158 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED
)
168 segT current_seg
= now_seg
;
169 subsegT current_subseg
= now_subseg
;
171 name
= input_line_pointer
;
172 c
= get_symbol_end ();
174 /* Just after name is now '\0'. */
175 p
= input_line_pointer
;
178 if (*input_line_pointer
!= ',')
180 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
181 ignore_rest_of_line ();
185 input_line_pointer
++; /* skip ',' */
186 if ((size
= get_absolute_expression ()) < 0)
188 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size
);
189 ignore_rest_of_line ();
193 /* The third argument to .lcomm is the alignment. */
194 if (*input_line_pointer
!= ',')
198 ++input_line_pointer
;
199 align
= get_absolute_expression ();
202 as_warn (_("ignoring bad alignment"));
208 symbolP
= symbol_find_or_make (name
);
211 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
213 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
214 S_GET_NAME (symbolP
));
215 ignore_rest_of_line ();
219 if (S_GET_VALUE (symbolP
) && S_GET_VALUE (symbolP
) != (valueT
) size
)
221 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
222 S_GET_NAME (symbolP
),
223 (long) S_GET_VALUE (symbolP
),
226 ignore_rest_of_line ();
233 /* Convert to a power of 2 alignment. */
234 for (align2
= 0; (align
& 1) == 0; align
>>= 1, ++align2
);
237 as_bad (_("Common alignment not a power of 2"));
238 ignore_rest_of_line ();
245 record_alignment (current_seg
, align2
);
246 subseg_set (current_seg
, current_subseg
);
248 frag_align (align2
, 0, 0);
249 if (S_GET_SEGMENT (symbolP
) == current_seg
)
250 symbol_get_frag (symbolP
)->fr_symbol
= 0;
251 symbol_set_frag (symbolP
, frag_now
);
252 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
255 S_SET_SIZE (symbolP
, size
);
256 S_SET_SEGMENT (symbolP
, current_seg
);
257 subseg_set (current_seg
, current_subseg
);
258 demand_empty_rest_of_line ();
262 microblaze_s_rdata (int localvar
)
268 obj_elf_change_section (".rodata", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
269 if (rodata_segment
== 0)
270 rodata_segment
= subseg_new (".rodata", 0);
275 obj_elf_change_section (".sdata2", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
283 microblaze_s_bss (int localvar
)
286 if (localvar
== 0) /* bss. */
287 obj_elf_change_section (".bss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
288 else if (localvar
== 1)
291 obj_elf_change_section (".sbss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
292 if (sbss_segment
== 0)
293 sbss_segment
= subseg_new (".sbss", 0);
300 /* endp_p is always 1 as this func is called only for .end <funcname>
301 This func consumes the <funcname> and calls regular processing
302 s_func(1) with arg 1 (1 for end). */
305 microblaze_s_func (int end_p ATTRIBUTE_UNUSED
)
307 *input_line_pointer
= get_symbol_end ();
311 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
314 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED
)
321 name
= input_line_pointer
;
322 c
= get_symbol_end ();
323 symbolP
= symbol_find_or_make (name
);
324 S_SET_WEAK (symbolP
);
325 *input_line_pointer
= c
;
329 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
331 if (S_IS_DEFINED (symbolP
))
333 as_bad ("Ignoring attempt to redefine symbol `%s'.",
334 S_GET_NAME (symbolP
));
335 ignore_rest_of_line ();
339 if (*input_line_pointer
== ',')
341 ++input_line_pointer
;
346 if (exp
.X_op
!= O_symbol
)
348 as_bad ("bad .weakext directive");
349 ignore_rest_of_line ();
352 symbol_set_value_expression (symbolP
, &exp
);
355 demand_empty_rest_of_line ();
358 /* This table describes all the machine specific pseudo-ops the assembler
359 has to support. The fields are:
360 Pseudo-op name without dot
361 Function to call to execute this pseudo-op
362 Integer arg to pass to the function. */
363 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
364 and then in the read.c table. */
365 const pseudo_typeS md_pseudo_table
[] =
367 {"lcomm", microblaze_s_lcomm
, 1},
368 {"data", microblaze_s_data
, 0},
369 {"data8", cons
, 1}, /* Same as byte. */
370 {"data16", cons
, 2}, /* Same as hword. */
371 {"data32", cons
, 4}, /* Same as word. */
372 {"ent", s_func
, 0}, /* Treat ent as function entry point. */
373 {"end", microblaze_s_func
, 1}, /* Treat end as function end point. */
374 {"gpword", s_rva
, 4}, /* gpword label => store resolved label address in data section. */
375 {"weakext", microblaze_s_weakext
, 0},
376 {"rodata", microblaze_s_rdata
, 0},
377 {"sdata2", microblaze_s_rdata
, 1},
378 {"sdata", microblaze_s_sdata
, 0},
379 {"bss", microblaze_s_bss
, 0},
380 {"sbss", microblaze_s_bss
, 1},
381 {"text", microblaze_s_text
, 0},
383 {"frame", s_ignore
, 0},
384 {"mask", s_ignore
, 0}, /* Emitted by gcc. */
388 /* This function is called once, at assembler startup time. This should
389 set up all the tables, etc that the MD part of the assembler needs. */
394 struct op_code_struct
* opcode
;
396 opcode_hash_control
= hash_new ();
398 /* Insert unique names into hash table. */
399 for (opcode
= opcodes
; opcode
->name
; opcode
++)
400 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
403 /* Try to parse a reg name. */
406 parse_reg (char * s
, unsigned * reg
)
410 /* Strip leading whitespace. */
411 while (ISSPACE (* s
))
414 if (strncasecmp (s
, "rpc", 3) == 0)
419 else if (strncasecmp (s
, "rmsr", 4) == 0)
424 else if (strncasecmp (s
, "rear", 4) == 0)
429 else if (strncasecmp (s
, "resr", 4) == 0)
434 else if (strncasecmp (s
, "rfsr", 4) == 0)
439 else if (strncasecmp (s
, "rbtr", 4) == 0)
444 else if (strncasecmp (s
, "redr", 4) == 0)
449 /* MMU registers start. */
450 else if (strncasecmp (s
, "rpid", 4) == 0)
455 else if (strncasecmp (s
, "rzpr", 4) == 0)
460 else if (strncasecmp (s
, "rtlbx", 5) == 0)
465 else if (strncasecmp (s
, "rtlblo", 6) == 0)
470 else if (strncasecmp (s
, "rtlbhi", 6) == 0)
475 else if (strncasecmp (s
, "rtlbsx", 6) == 0)
480 /* MMU registers end. */
481 else if (strncasecmp (s
, "rpvr", 4) == 0)
483 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
485 tmpreg
= (s
[4]-'0')*10 + s
[5] - '0';
489 else if (ISDIGIT (s
[4]))
495 as_bad (_("register expected, but saw '%.6s'"), s
);
496 if ((int) tmpreg
>= MIN_PVR_REGNUM
&& tmpreg
<= MAX_PVR_REGNUM
)
497 *reg
= REG_PVR
+ tmpreg
;
500 as_bad (_("Invalid register number at '%.6s'"), s
);
505 else if (strncasecmp (s
, "rsp", 3) == 0)
510 else if (strncasecmp (s
, "rfsl", 4) == 0)
512 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
514 tmpreg
= (s
[4] - '0') * 10 + s
[5] - '0';
517 else if (ISDIGIT (s
[4]))
523 as_bad (_("register expected, but saw '%.6s'"), s
);
525 if ((int) tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
529 as_bad (_("Invalid register number at '%.6s'"), s
);
536 if (TOLOWER (s
[0]) == 'r')
538 if (ISDIGIT (s
[1]) && ISDIGIT (s
[2]))
540 tmpreg
= (s
[1] - '0') * 10 + s
[2] - '0';
543 else if (ISDIGIT (s
[1]))
549 as_bad (_("register expected, but saw '%.6s'"), s
);
551 if ((int)tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
555 as_bad (_("Invalid register number at '%.6s'"), s
);
561 as_bad (_("register expected, but saw '%.6s'"), s
);
567 parse_exp (char *s
, expressionS
*e
)
572 /* Skip whitespace. */
573 while (ISSPACE (* s
))
576 save
= input_line_pointer
;
577 input_line_pointer
= s
;
581 if (e
->X_op
== O_absent
)
582 as_fatal (_("missing operand"));
584 new_pointer
= input_line_pointer
;
585 input_line_pointer
= save
;
590 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
595 static symbolS
* GOT_symbol
;
597 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
600 parse_imm (char * s
, expressionS
* e
, int min
, int max
)
605 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
606 for (atp
= s
; *atp
!= '@'; atp
++)
607 if (is_end_of_line
[(unsigned char) *atp
])
612 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
615 e
->X_md
= IMM_GOTOFF
;
617 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
622 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
640 if (atp
&& !GOT_symbol
)
642 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
645 new_pointer
= parse_exp (s
, e
);
647 if (e
->X_op
== O_absent
)
648 ; /* An error message has already been emitted. */
649 else if ((e
->X_op
!= O_constant
&& e
->X_op
!= O_symbol
) )
650 as_fatal (_("operand must be a constant or a label"));
651 else if ((e
->X_op
== O_constant
) && ((int) e
->X_add_number
< min
652 || (int) e
->X_add_number
> max
))
654 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
655 min
, max
, (int) e
->X_add_number
);
660 *atp
= '@'; /* restore back (needed?) */
661 if (new_pointer
>= atp
)
662 new_pointer
+= (e
->X_md
== IMM_GOTOFF
)?7:4;
663 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
670 check_got (int * got_type
, int * got_len
)
678 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
679 for (atp
= input_line_pointer
; *atp
!= '@'; atp
++)
680 if (is_end_of_line
[(unsigned char) *atp
])
683 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
686 *got_type
= IMM_GOTOFF
;
688 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
693 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
702 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
704 first
= atp
- input_line_pointer
;
706 past_got
= atp
+ *got_len
+ 1;
707 for (new_pointer
= past_got
; !is_end_of_line
[(unsigned char) *new_pointer
++];)
709 second
= new_pointer
- past_got
;
710 tmpbuf
= xmalloc (first
+ second
+ 2); /* One extra byte for ' ' and one for NUL. */
711 memcpy (tmpbuf
, input_line_pointer
, first
);
712 tmpbuf
[first
] = ' '; /* @GOTOFF is replaced with a single space. */
713 memcpy (tmpbuf
+ first
+ 1, past_got
, second
);
714 tmpbuf
[first
+ second
+ 1] = '\0';
720 parse_cons_expression_microblaze (expressionS
*exp
, int size
)
724 /* Handle @GOTOFF et.al. */
725 char *save
, *gotfree_copy
;
726 int got_len
, got_type
;
728 save
= input_line_pointer
;
729 gotfree_copy
= check_got (& got_type
, & got_len
);
731 input_line_pointer
= gotfree_copy
;
737 exp
->X_md
= got_type
;
738 input_line_pointer
= save
+ (input_line_pointer
- gotfree_copy
)
747 /* This is the guts of the machine-dependent assembler. STR points to a
748 machine dependent instruction. This function is supposed to emit
749 the frags/bytes it assembles to. */
751 static char * str_microblaze_ro_anchor
= "RO";
752 static char * str_microblaze_rw_anchor
= "RW";
755 check_spl_reg (unsigned * reg
)
757 if ((*reg
== REG_MSR
) || (*reg
== REG_PC
)
758 || (*reg
== REG_EAR
) || (*reg
== REG_ESR
)
759 || (*reg
== REG_FSR
) || (*reg
== REG_BTR
) || (*reg
== REG_EDR
)
760 || (*reg
== REG_PID
) || (*reg
== REG_ZPR
)
761 || (*reg
== REG_TLBX
) || (*reg
== REG_TLBLO
)
762 || (*reg
== REG_TLBHI
) || (*reg
== REG_TLBSX
)
763 || (*reg
>= REG_PVR
+MIN_PVR_REGNUM
&& *reg
<= REG_PVR
+MAX_PVR_REGNUM
))
769 /* Here we decide which fixups can be adjusted to make them relative to
770 the beginning of the section instead of the symbol. Basically we need
771 to make sure that the dynamic relocations are done correctly, so in
772 some cases we force the original symbol to be used. */
775 tc_microblaze_fix_adjustable (struct fix
*fixP
)
777 if (GOT_symbol
&& fixP
->fx_subsy
== GOT_symbol
)
780 if (fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOTOFF
781 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_GOTOFF
782 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOT
783 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_PLT
)
790 md_assemble (char * str
)
794 struct op_code_struct
* opcode
, *opcode1
;
795 char * output
= NULL
;
798 unsigned long inst
, inst1
;
803 unsigned int immed
, temp
;
807 /* Drop leading whitespace. */
808 while (ISSPACE (* str
))
811 /* Find the op code end. */
812 for (op_start
= op_end
= str
;
813 *op_end
&& !is_end_of_line
[(unsigned char) *op_end
] && *op_end
!= ' ';
816 name
[nlen
] = op_start
[nlen
];
818 if (nlen
== sizeof (name
) - 1)
826 as_bad (_("can't find opcode "));
830 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, name
);
833 as_bad (_("unknown opcode \"%s\""), name
);
837 inst
= opcode
->bit_sequence
;
840 switch (opcode
->inst_type
)
842 case INST_TYPE_RD_R1_R2
:
843 if (strcmp (op_end
, ""))
844 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
847 as_fatal (_("Error in statement syntax"));
850 if (strcmp (op_end
, ""))
851 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
854 as_fatal (_("Error in statement syntax"));
857 if (strcmp (op_end
, ""))
858 op_end
= parse_reg (op_end
+ 1, ®3
); /* Get r2. */
861 as_fatal (_("Error in statement syntax"));
865 /* Check for spl registers. */
866 if (check_spl_reg (& reg1
))
867 as_fatal (_("Cannot use special register with this instruction"));
868 if (check_spl_reg (& reg2
))
869 as_fatal (_("Cannot use special register with this instruction"));
870 if (check_spl_reg (& reg3
))
871 as_fatal (_("Cannot use special register with this instruction"));
873 if (streq (name
, "sub"))
875 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
876 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
877 inst
|= (reg3
<< RA_LOW
) & RA_MASK
;
878 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
882 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
883 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
884 inst
|= (reg3
<< RB_LOW
) & RB_MASK
;
886 output
= frag_more (isize
);
889 case INST_TYPE_RD_R1_IMM
:
890 if (strcmp (op_end
, ""))
891 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
894 as_fatal (_("Error in statement syntax"));
897 if (strcmp (op_end
, ""))
898 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
901 as_fatal (_("Error in statement syntax"));
904 if (strcmp (op_end
, ""))
905 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
907 as_fatal (_("Error in statement syntax"));
909 /* Check for spl registers. */
910 if (check_spl_reg (& reg1
))
911 as_fatal (_("Cannot use special register with this instruction"));
912 if (check_spl_reg (& reg2
))
913 as_fatal (_("Cannot use special register with this instruction"));
915 if (exp
.X_op
!= O_constant
)
918 relax_substateT subtype
;
920 if (streq (name
, "lmi"))
921 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
922 else if (streq (name
, "smi"))
923 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
925 if (reg2
== REG_ROSDP
)
926 opc
= str_microblaze_ro_anchor
;
927 else if (reg2
== REG_RWSDP
)
928 opc
= str_microblaze_rw_anchor
;
931 if (exp
.X_md
== IMM_GOT
)
932 subtype
= GOT_OFFSET
;
933 else if (exp
.X_md
== IMM_PLT
)
934 subtype
= PLT_OFFSET
;
935 else if (exp
.X_md
== IMM_GOTOFF
)
936 subtype
= GOTOFF_OFFSET
;
938 subtype
= opcode
->inst_offset_type
;
940 output
= frag_var (rs_machine_dependent
,
941 isize
* 2, /* maxm of 2 words. */
942 isize
, /* minm of 1 word. */
943 subtype
, /* PC-relative or not. */
951 output
= frag_more (isize
);
952 immed
= exp
.X_add_number
;
955 if (streq (name
, "lmi") || streq (name
, "smi"))
957 /* Load/store 32-d consecutive registers. Used on exit/entry
958 to subroutines to save and restore registers to stack.
959 Generate 32-d insts. */
963 if (streq (name
, "lmi"))
964 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "lwi");
966 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "swi");
969 as_bad (_("unknown opcode \"%s\""), "lwi");
972 inst
= opcode
->bit_sequence
;
973 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
974 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
975 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
977 for (i
= 0; i
< count
- 1; i
++)
979 output
[0] = INST_BYTE0 (inst
);
980 output
[1] = INST_BYTE1 (inst
);
981 output
[2] = INST_BYTE2 (inst
);
982 output
[3] = INST_BYTE3 (inst
);
983 output
= frag_more (isize
);
986 inst
= opcode
->bit_sequence
;
987 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
988 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
989 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
994 temp
= immed
& 0xFFFF8000;
995 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
997 /* Needs an immediate inst. */
998 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1001 as_bad (_("unknown opcode \"%s\""), "imm");
1005 inst1
= opcode1
->bit_sequence
;
1006 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1007 output
[0] = INST_BYTE0 (inst1
);
1008 output
[1] = INST_BYTE1 (inst1
);
1009 output
[2] = INST_BYTE2 (inst1
);
1010 output
[3] = INST_BYTE3 (inst1
);
1011 output
= frag_more (isize
);
1013 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1014 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1015 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1019 case INST_TYPE_RD_R1_IMM5
:
1020 if (strcmp (op_end
, ""))
1021 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1024 as_fatal (_("Error in statement syntax"));
1027 if (strcmp (op_end
, ""))
1028 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1031 as_fatal (_("Error in statement syntax"));
1034 if (strcmp (op_end
, ""))
1035 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1037 as_fatal (_("Error in statement syntax"));
1039 /* Check for spl registers. */
1040 if (check_spl_reg (®1
))
1041 as_fatal (_("Cannot use special register with this instruction"));
1042 if (check_spl_reg (®2
))
1043 as_fatal (_("Cannot use special register with this instruction"));
1045 if (exp
.X_op
!= O_constant
)
1046 as_warn (_("Symbol used as immediate for shift instruction"));
1049 output
= frag_more (isize
);
1050 immed
= exp
.X_add_number
;
1053 if (immed
!= (immed
% 32))
1055 as_warn (_("Shift value > 32. using <value %% 32>"));
1058 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1059 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1060 inst
|= (immed
<< IMM_LOW
) & IMM5_MASK
;
1063 case INST_TYPE_R1_R2
:
1064 if (strcmp (op_end
, ""))
1065 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1068 as_fatal (_("Error in statement syntax"));
1071 if (strcmp (op_end
, ""))
1072 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1075 as_fatal (_("Error in statement syntax"));
1079 /* Check for spl registers. */
1080 if (check_spl_reg (& reg1
))
1081 as_fatal (_("Cannot use special register with this instruction"));
1082 if (check_spl_reg (& reg2
))
1083 as_fatal (_("Cannot use special register with this instruction"));
1085 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1086 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1087 output
= frag_more (isize
);
1090 case INST_TYPE_RD_R1
:
1091 if (strcmp (op_end
, ""))
1092 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1095 as_fatal (_("Error in statement syntax"));
1098 if (strcmp (op_end
, ""))
1099 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1102 as_fatal (_("Error in statement syntax"));
1106 /* Check for spl registers. */
1107 if (check_spl_reg (®1
))
1108 as_fatal (_("Cannot use special register with this instruction"));
1109 if (check_spl_reg (®2
))
1110 as_fatal (_("Cannot use special register with this instruction"));
1112 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1113 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1114 output
= frag_more (isize
);
1117 case INST_TYPE_RD_RFSL
:
1118 if (strcmp (op_end
, ""))
1119 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1122 as_fatal (_("Error in statement syntax"));
1125 if (strcmp (op_end
, ""))
1126 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1129 as_fatal (_("Error in statement syntax"));
1133 /* Check for spl registers. */
1134 if (check_spl_reg (®1
))
1135 as_fatal (_("Cannot use special register with this instruction"));
1137 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1138 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1139 output
= frag_more (isize
);
1142 case INST_TYPE_RD_IMM15
:
1143 if (strcmp (op_end
, ""))
1144 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1147 as_fatal (_("Error in statement syntax"));
1151 if (strcmp (op_end
, ""))
1152 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1154 as_fatal (_("Error in statement syntax"));
1156 /* Check for spl registers. */
1157 if (check_spl_reg (®1
))
1158 as_fatal (_("Cannot use special register with this instruction"));
1160 if (exp
.X_op
!= O_constant
)
1161 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1164 output
= frag_more (isize
);
1165 immed
= exp
.X_add_number
;
1167 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1168 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1171 case INST_TYPE_R1_RFSL
:
1172 if (strcmp (op_end
, ""))
1173 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1176 as_fatal (_("Error in statement syntax"));
1179 if (strcmp (op_end
, ""))
1180 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1183 as_fatal (_("Error in statement syntax"));
1187 /* Check for spl registers. */
1188 if (check_spl_reg (®1
))
1189 as_fatal (_("Cannot use special register with this instruction"));
1191 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1192 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1193 output
= frag_more (isize
);
1196 case INST_TYPE_RFSL
:
1197 if (strcmp (op_end
, ""))
1198 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1201 as_fatal (_("Error in statement syntax"));
1204 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1205 output
= frag_more (isize
);
1209 if (strcmp (op_end
, ""))
1210 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1213 as_fatal (_("Error in statement syntax"));
1217 /* Check for spl registers. */
1218 if (check_spl_reg (®1
))
1219 as_fatal (_("Cannot use special register with this instruction"));
1221 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1222 output
= frag_more (isize
);
1225 /* For tuqula insn...:) */
1227 if (strcmp (op_end
, ""))
1228 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1231 as_fatal (_("Error in statement syntax"));
1235 /* Check for spl registers. */
1236 if (check_spl_reg (®1
))
1237 as_fatal (_("Cannot use special register with this instruction"));
1239 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1240 output
= frag_more (isize
);
1243 case INST_TYPE_RD_SPECIAL
:
1244 if (strcmp (op_end
, ""))
1245 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1248 as_fatal (_("Error in statement syntax"));
1251 if (strcmp (op_end
, ""))
1252 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1255 as_fatal (_("Error in statement syntax"));
1259 if (reg2
== REG_MSR
)
1260 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1261 else if (reg2
== REG_PC
)
1262 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1263 else if (reg2
== REG_EAR
)
1264 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1265 else if (reg2
== REG_ESR
)
1266 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1267 else if (reg2
== REG_FSR
)
1268 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1269 else if (reg2
== REG_BTR
)
1270 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1271 else if (reg2
== REG_EDR
)
1272 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1273 else if (reg2
== REG_PID
)
1274 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1275 else if (reg2
== REG_ZPR
)
1276 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1277 else if (reg2
== REG_TLBX
)
1278 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1279 else if (reg2
== REG_TLBLO
)
1280 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1281 else if (reg2
== REG_TLBHI
)
1282 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1283 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1284 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1286 as_fatal (_("invalid value for special purpose register"));
1287 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1288 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1289 output
= frag_more (isize
);
1292 case INST_TYPE_SPECIAL_R1
:
1293 if (strcmp (op_end
, ""))
1294 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1297 as_fatal (_("Error in statement syntax"));
1300 if (strcmp (op_end
, ""))
1301 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1304 as_fatal (_("Error in statement syntax"));
1308 if (reg1
== REG_MSR
)
1309 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1310 else if (reg1
== REG_PC
)
1311 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1312 else if (reg1
== REG_EAR
)
1313 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1314 else if (reg1
== REG_ESR
)
1315 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1316 else if (reg1
== REG_FSR
)
1317 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1318 else if (reg1
== REG_BTR
)
1319 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1320 else if (reg1
== REG_EDR
)
1321 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1322 else if (reg1
== REG_PID
)
1323 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1324 else if (reg1
== REG_ZPR
)
1325 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1326 else if (reg1
== REG_TLBX
)
1327 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1328 else if (reg1
== REG_TLBLO
)
1329 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1330 else if (reg1
== REG_TLBHI
)
1331 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1332 else if (reg1
== REG_TLBSX
)
1333 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1335 as_fatal (_("invalid value for special purpose register"));
1336 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1337 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1338 output
= frag_more (isize
);
1341 case INST_TYPE_RD_R1_SPECIAL
:
1342 if (strcmp (op_end
, ""))
1343 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1346 as_fatal (_("Error in statement syntax"));
1349 if (strcmp (op_end
, ""))
1350 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1353 as_fatal (_("Error in statement syntax"));
1357 /* Check for spl registers. */
1358 if (check_spl_reg (®1
))
1359 as_fatal (_("Cannot use special register with this instruction"));
1360 if (check_spl_reg (®2
))
1361 as_fatal (_("Cannot use special register with this instruction"));
1363 /* insn wic ra, rb => wic ra, ra, rb. */
1364 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1365 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1366 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1368 output
= frag_more (isize
);
1371 case INST_TYPE_RD_R2
:
1372 if (strcmp (op_end
, ""))
1373 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1376 as_fatal (_("Error in statement syntax"));
1379 if (strcmp (op_end
, ""))
1380 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1383 as_fatal (_("Error in statement syntax"));
1387 /* Check for spl registers. */
1388 if (check_spl_reg (®1
))
1389 as_fatal (_("Cannot use special register with this instruction"));
1390 if (check_spl_reg (®2
))
1391 as_fatal (_("Cannot use special register with this instruction"));
1393 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1394 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1395 output
= frag_more (isize
);
1398 case INST_TYPE_R1_IMM
:
1399 if (strcmp (op_end
, ""))
1400 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1403 as_fatal (_("Error in statement syntax"));
1406 if (strcmp (op_end
, ""))
1407 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1409 as_fatal (_("Error in statement syntax"));
1411 /* Check for spl registers. */
1412 if (check_spl_reg (®1
))
1413 as_fatal (_("Cannot use special register with this instruction"));
1415 if (exp
.X_op
!= O_constant
)
1418 relax_substateT subtype
;
1420 if (exp
.X_md
== IMM_GOT
)
1421 subtype
= GOT_OFFSET
;
1422 else if (exp
.X_md
== IMM_PLT
)
1423 subtype
= PLT_OFFSET
;
1425 subtype
= opcode
->inst_offset_type
;
1426 output
= frag_var (rs_machine_dependent
,
1427 isize
* 2, /* maxm of 2 words. */
1428 isize
, /* minm of 1 word. */
1429 subtype
, /* PC-relative or not. */
1437 output
= frag_more (isize
);
1438 immed
= exp
.X_add_number
;
1441 temp
= immed
& 0xFFFF8000;
1442 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1444 /* Needs an immediate inst. */
1445 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1446 if (opcode1
== NULL
)
1448 as_bad (_("unknown opcode \"%s\""), "imm");
1452 inst1
= opcode1
->bit_sequence
;
1453 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1454 output
[0] = INST_BYTE0 (inst1
);
1455 output
[1] = INST_BYTE1 (inst1
);
1456 output
[2] = INST_BYTE2 (inst1
);
1457 output
[3] = INST_BYTE3 (inst1
);
1458 output
= frag_more (isize
);
1461 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1462 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1465 case INST_TYPE_RD_IMM
:
1466 if (strcmp (op_end
, ""))
1467 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1470 as_fatal (_("Error in statement syntax"));
1473 if (strcmp (op_end
, ""))
1474 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1476 as_fatal (_("Error in statement syntax"));
1478 /* Check for spl registers. */
1479 if (check_spl_reg (®1
))
1480 as_fatal (_("Cannot use special register with this instruction"));
1482 if (exp
.X_op
!= O_constant
)
1485 relax_substateT subtype
;
1487 if (exp
.X_md
== IMM_GOT
)
1488 subtype
= GOT_OFFSET
;
1489 else if (exp
.X_md
== IMM_PLT
)
1490 subtype
= PLT_OFFSET
;
1492 subtype
= opcode
->inst_offset_type
;
1493 output
= frag_var (rs_machine_dependent
,
1494 isize
* 2, /* maxm of 2 words. */
1495 isize
, /* minm of 1 word. */
1496 subtype
, /* PC-relative or not. */
1504 output
= frag_more (isize
);
1505 immed
= exp
.X_add_number
;
1508 temp
= immed
& 0xFFFF8000;
1509 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1511 /* Needs an immediate inst. */
1512 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1513 if (opcode1
== NULL
)
1515 as_bad (_("unknown opcode \"%s\""), "imm");
1519 inst1
= opcode1
->bit_sequence
;
1520 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1521 output
[0] = INST_BYTE0 (inst1
);
1522 output
[1] = INST_BYTE1 (inst1
);
1523 output
[2] = INST_BYTE2 (inst1
);
1524 output
[3] = INST_BYTE3 (inst1
);
1525 output
= frag_more (isize
);
1528 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1529 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1533 if (strcmp (op_end
, ""))
1534 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1537 as_fatal (_("Error in statement syntax"));
1541 /* Check for spl registers. */
1542 if (check_spl_reg (®2
))
1543 as_fatal (_("Cannot use special register with this instruction"));
1545 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1546 output
= frag_more (isize
);
1550 if (streq (name
, "imm"))
1551 as_fatal (_("An IMM instruction should not be present in the .s file"));
1553 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1555 if (exp
.X_op
!= O_constant
)
1558 relax_substateT subtype
;
1560 if (exp
.X_md
== IMM_GOT
)
1561 subtype
= GOT_OFFSET
;
1562 else if (exp
.X_md
== IMM_PLT
)
1563 subtype
= PLT_OFFSET
;
1565 subtype
= opcode
->inst_offset_type
;
1566 output
= frag_var (rs_machine_dependent
,
1567 isize
* 2, /* maxm of 2 words. */
1568 isize
, /* minm of 1 word. */
1569 subtype
, /* PC-relative or not. */
1577 output
= frag_more (isize
);
1578 immed
= exp
.X_add_number
;
1582 temp
= immed
& 0xFFFF8000;
1583 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1585 /* Needs an immediate inst. */
1586 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1587 if (opcode1
== NULL
)
1589 as_bad (_("unknown opcode \"%s\""), "imm");
1593 inst1
= opcode1
->bit_sequence
;
1594 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1595 output
[0] = INST_BYTE0 (inst1
);
1596 output
[1] = INST_BYTE1 (inst1
);
1597 output
[2] = INST_BYTE2 (inst1
);
1598 output
[3] = INST_BYTE3 (inst1
);
1599 output
= frag_more (isize
);
1601 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1604 case INST_TYPE_NONE
:
1605 output
= frag_more (isize
);
1609 as_fatal (_("unimplemented opcode \"%s\""), name
);
1612 /* Drop whitespace after all the operands have been parsed. */
1613 while (ISSPACE (* op_end
))
1616 /* Give warning message if the insn has more operands than required. */
1617 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1618 as_warn (_("ignoring operands: %s "), op_end
);
1620 output
[0] = INST_BYTE0 (inst
);
1621 output
[1] = INST_BYTE1 (inst
);
1622 output
[2] = INST_BYTE2 (inst
);
1623 output
[3] = INST_BYTE3 (inst
);
1626 dwarf2_emit_insn (4);
1631 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1636 /* Various routines to kill one day. */
1637 /* Equal to MAX_PRECISION in atof-ieee.c */
1638 #define MAX_LITTLENUMS 6
1640 /* Turn a string in input_line_pointer into a floating point constant of type
1641 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1642 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1644 md_atof (int type
, char * litP
, int * sizeP
)
1647 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1679 return _("Bad call to MD_NTOF()");
1682 t
= atof_ieee (input_line_pointer
, type
, words
);
1685 input_line_pointer
= t
;
1687 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1689 if (! target_big_endian
)
1691 for (i
= prec
- 1; i
>= 0; i
--)
1693 md_number_to_chars (litP
, (valueT
) words
[i
],
1694 sizeof (LITTLENUM_TYPE
));
1695 litP
+= sizeof (LITTLENUM_TYPE
);
1699 for (i
= 0; i
< prec
; i
++)
1701 md_number_to_chars (litP
, (valueT
) words
[i
],
1702 sizeof (LITTLENUM_TYPE
));
1703 litP
+= sizeof (LITTLENUM_TYPE
);
1709 const char * md_shortopts
= "";
1711 struct option md_longopts
[] =
1713 {"EB", no_argument
, NULL
, OPTION_EB
},
1714 {"EL", no_argument
, NULL
, OPTION_EL
},
1715 { NULL
, no_argument
, NULL
, 0}
1718 size_t md_longopts_size
= sizeof (md_longopts
);
1720 int md_short_jump_size
;
1723 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED
,
1724 addressT from_Nddr ATTRIBUTE_UNUSED
,
1725 addressT to_Nddr ATTRIBUTE_UNUSED
,
1726 fragS
* frag ATTRIBUTE_UNUSED
,
1727 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1729 as_fatal (_("failed sanity check: short_jump"));
1733 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED
,
1734 addressT from_Nddr ATTRIBUTE_UNUSED
,
1735 addressT to_Nddr ATTRIBUTE_UNUSED
,
1736 fragS
* frag ATTRIBUTE_UNUSED
,
1737 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1739 as_fatal (_("failed sanity check: long_jump"));
1742 /* Called after relaxing, change the frags so they know how big they are. */
1745 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1746 segT sec ATTRIBUTE_UNUSED
,
1751 switch (fragP
->fr_subtype
)
1753 case UNDEFINED_PC_OFFSET
:
1754 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1755 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1756 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1759 case DEFINED_ABS_SEGMENT
:
1760 if (fragP
->fr_symbol
== GOT_symbol
)
1761 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1762 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_GOTPC
);
1764 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1765 fragP
->fr_offset
, FALSE
, BFD_RELOC_64
);
1766 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1769 case DEFINED_RO_SEGMENT
:
1770 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1771 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_ROSDA
);
1772 fragP
->fr_fix
+= INST_WORD_SIZE
;
1775 case DEFINED_RW_SEGMENT
:
1776 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1777 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_RWSDA
);
1778 fragP
->fr_fix
+= INST_WORD_SIZE
;
1781 case DEFINED_PC_OFFSET
:
1782 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1783 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_32_LO_PCREL
);
1784 fragP
->fr_fix
+= INST_WORD_SIZE
;
1787 case LARGE_DEFINED_PC_OFFSET
:
1788 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1789 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1790 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1794 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1795 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOT
);
1796 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1800 fixP
= fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1801 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_PLT
);
1802 /* fixP->fx_plt = 1; */
1804 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1808 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1809 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOTOFF
);
1810 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1819 /* Applies the desired value to the specified location.
1820 Also sets up addends for 'rela' type relocations. */
1822 md_apply_fix (fixS
* fixP
,
1826 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1827 char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
1828 const char * symname
;
1829 /* Note: use offsetT because it is signed, valueT is unsigned. */
1830 offsetT val
= (offsetT
) * valp
;
1832 struct op_code_struct
* opcode1
;
1833 unsigned long inst1
;
1835 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
1837 /* fixP->fx_offset is supposed to be set up correctly for all
1838 symbol relocations. */
1839 if (fixP
->fx_addsy
== NULL
)
1841 if (!fixP
->fx_pcrel
)
1842 fixP
->fx_offset
= val
; /* Absolute relocation. */
1844 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1845 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
1848 /* If we aren't adjusting this fixup to be against the section
1849 symbol, we need to adjust the value. */
1850 if (fixP
->fx_addsy
!= NULL
)
1852 if (S_IS_WEAK (fixP
->fx_addsy
)
1853 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
1854 && (((bfd_get_section_flags (stdoutput
,
1855 S_GET_SEGMENT (fixP
->fx_addsy
))
1856 & SEC_LINK_ONCE
) != 0)
1857 || !strncmp (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
1859 sizeof (".gnu.linkonce") - 1))))
1861 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1862 if (val
!= 0 && ! fixP
->fx_pcrel
)
1864 /* In this case, the bfd_install_relocation routine will
1865 incorrectly add the symbol value back in. We just want
1866 the addend to appear in the object file.
1867 FIXME: If this makes VALUE zero, we're toast. */
1868 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1873 /* If the fix is relative to a symbol which is not defined, or not
1874 in the same segment as the fix, we cannot resolve it here. */
1875 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1876 if (fixP
->fx_addsy
!= NULL
1877 && (!S_IS_DEFINED (fixP
->fx_addsy
)
1878 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
1882 /* For ELF we can just return and let the reloc that will be generated
1883 take care of everything. For COFF we still have to insert 'val'
1884 into the insn since the addend field will be ignored. */
1888 /* All fixups in the text section must be handled in the linker. */
1889 else if (segment
->flags
& SEC_CODE
)
1891 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
1896 switch (fixP
->fx_r_type
)
1898 case BFD_RELOC_MICROBLAZE_32_LO
:
1899 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
1900 if (target_big_endian
)
1902 buf
[2] |= ((val
>> 8) & 0xff);
1903 buf
[3] |= (val
& 0xff);
1907 buf
[1] |= ((val
>> 8) & 0xff);
1908 buf
[0] |= (val
& 0xff);
1911 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
1912 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
1913 /* Don't do anything if the symbol is not defined. */
1914 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1916 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
1917 as_bad_where (file
, fixP
->fx_line
,
1918 _("pcrel for branch to %s too far (0x%x)"),
1919 symname
, (int) val
);
1920 if (target_big_endian
)
1922 buf
[2] |= ((val
>> 8) & 0xff);
1923 buf
[3] |= (val
& 0xff);
1927 buf
[1] |= ((val
>> 8) & 0xff);
1928 buf
[0] |= (val
& 0xff);
1934 case BFD_RELOC_32_PCREL
:
1935 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
1936 /* Don't do anything if the symbol is not defined. */
1937 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1939 if (target_big_endian
)
1941 buf
[0] |= ((val
>> 24) & 0xff);
1942 buf
[1] |= ((val
>> 16) & 0xff);
1943 buf
[2] |= ((val
>> 8) & 0xff);
1944 buf
[3] |= (val
& 0xff);
1948 buf
[3] |= ((val
>> 24) & 0xff);
1949 buf
[2] |= ((val
>> 16) & 0xff);
1950 buf
[1] |= ((val
>> 8) & 0xff);
1951 buf
[0] |= (val
& 0xff);
1955 case BFD_RELOC_64_PCREL
:
1957 /* Add an imm instruction. First save the current instruction. */
1958 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
1959 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
1961 /* Generate the imm instruction. */
1962 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1963 if (opcode1
== NULL
)
1965 as_bad (_("unknown opcode \"%s\""), "imm");
1969 inst1
= opcode1
->bit_sequence
;
1970 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1971 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
1973 buf
[0] = INST_BYTE0 (inst1
);
1974 buf
[1] = INST_BYTE1 (inst1
);
1975 buf
[2] = INST_BYTE2 (inst1
);
1976 buf
[3] = INST_BYTE3 (inst1
);
1978 /* Add the value only if the symbol is defined. */
1979 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1981 if (target_big_endian
)
1983 buf
[6] |= ((val
>> 8) & 0xff);
1984 buf
[7] |= (val
& 0xff);
1988 buf
[5] |= ((val
>> 8) & 0xff);
1989 buf
[4] |= (val
& 0xff);
1994 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
1995 case BFD_RELOC_MICROBLAZE_64_GOT
:
1996 case BFD_RELOC_MICROBLAZE_64_PLT
:
1997 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
1998 /* Add an imm instruction. First save the current instruction. */
1999 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2000 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2002 /* Generate the imm instruction. */
2003 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2004 if (opcode1
== NULL
)
2006 as_bad (_("unknown opcode \"%s\""), "imm");
2010 inst1
= opcode1
->bit_sequence
;
2012 /* We can fixup call to a defined non-global address
2013 within the same section only. */
2014 buf
[0] = INST_BYTE0 (inst1
);
2015 buf
[1] = INST_BYTE1 (inst1
);
2016 buf
[2] = INST_BYTE2 (inst1
);
2017 buf
[3] = INST_BYTE3 (inst1
);
2024 if (fixP
->fx_addsy
== NULL
)
2026 /* This fixup has been resolved. Create a reloc in case the linker
2027 moves code around due to relaxing. */
2028 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2029 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2031 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2032 fixP
->fx_addsy
= section_symbol (absolute_section
);
2038 md_operand (expressionS
* expressionP
)
2040 /* Ignore leading hash symbol, if present. */
2041 if (*input_line_pointer
== '#')
2043 input_line_pointer
++;
2044 expression (expressionP
);
2048 /* Called just before address relaxation, return the length
2049 by which a fragment must grow to reach it's destination. */
2052 md_estimate_size_before_relax (fragS
* fragP
,
2055 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2056 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2057 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2058 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2060 switch (fragP
->fr_subtype
)
2062 case INST_PC_OFFSET
:
2063 /* Used to be a PC-relative branch. */
2064 if (!fragP
->fr_symbol
)
2066 /* We know the abs value: Should never happen. */
2067 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2070 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
&&
2071 !S_IS_WEAK (fragP
->fr_symbol
))
2073 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2074 /* Don't know now whether we need an imm instruction. */
2075 fragP
->fr_var
= INST_WORD_SIZE
;
2077 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2078 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2080 /* Cannot have a PC-relative branch to a diff segment. */
2081 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2082 S_GET_NAME (fragP
->fr_symbol
));
2083 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2084 fragP
->fr_var
= INST_WORD_SIZE
*2;
2088 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2089 fragP
->fr_var
= INST_WORD_SIZE
*2;
2093 case INST_NO_OFFSET
:
2094 /* Used to be a reference to somewhere which was unknown. */
2095 if (fragP
->fr_symbol
)
2097 if (fragP
->fr_opcode
== NULL
)
2099 /* Used as an absolute value. */
2100 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2101 /* Variable part does not change. */
2102 fragP
->fr_var
= INST_WORD_SIZE
*2;
2104 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2106 /* It is accessed using the small data read only anchor. */
2107 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2108 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2109 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2110 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2112 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2113 fragP
->fr_var
= INST_WORD_SIZE
;
2117 /* Variable not in small data read only segment accessed
2118 using small data read only anchor. */
2119 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2121 as_bad_where (file
, fragP
->fr_line
,
2122 _("Variable is accessed using small data read "
2123 "only anchor, but it is not in the small data "
2124 "read only section"));
2125 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2126 fragP
->fr_var
= INST_WORD_SIZE
;
2129 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2131 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2132 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2133 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2134 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2136 /* It is accessed using the small data read write anchor. */
2137 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2138 fragP
->fr_var
= INST_WORD_SIZE
;
2142 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2144 as_bad_where (file
, fragP
->fr_line
,
2145 _("Variable is accessed using small data read "
2146 "write anchor, but it is not in the small data "
2147 "read write section"));
2148 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2149 fragP
->fr_var
= INST_WORD_SIZE
;
2154 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2160 /* We know the abs value: Should never happen. */
2161 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2166 case UNDEFINED_PC_OFFSET
:
2167 case LARGE_DEFINED_PC_OFFSET
:
2168 case DEFINED_ABS_SEGMENT
:
2172 fragP
->fr_var
= INST_WORD_SIZE
*2;
2174 case DEFINED_RO_SEGMENT
:
2175 case DEFINED_RW_SEGMENT
:
2176 case DEFINED_PC_OFFSET
:
2177 fragP
->fr_var
= INST_WORD_SIZE
;
2183 return fragP
->fr_var
;
2186 /* Put number into target byte order. */
2189 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2191 if (target_big_endian
)
2192 number_to_chars_bigendian (ptr
, use
, nbytes
);
2194 number_to_chars_littleendian (ptr
, use
, nbytes
);
2197 /* Round up a section size to the appropriate boundary. */
2200 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2202 return size
; /* Byte alignment is fine. */
2206 /* The location from which a PC relative jump should be calculated,
2207 given a PC relative reloc. */
2210 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2213 /* If the symbol is undefined or defined in another section
2214 we leave the add number alone for the linker to fix it later.
2215 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2217 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2218 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2219 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2223 /* The case where we are going to resolve things... */
2224 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2225 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2227 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2233 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2234 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2237 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2240 bfd_reloc_code_real_type code
;
2242 switch (fixp
->fx_r_type
)
2244 case BFD_RELOC_NONE
:
2245 case BFD_RELOC_MICROBLAZE_64_NONE
:
2247 case BFD_RELOC_MICROBLAZE_32_LO
:
2248 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2251 case BFD_RELOC_64_PCREL
:
2252 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2253 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2254 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2255 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2256 case BFD_RELOC_MICROBLAZE_64_GOT
:
2257 case BFD_RELOC_MICROBLAZE_64_PLT
:
2258 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2259 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2260 code
= fixp
->fx_r_type
;
2264 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2266 MAP (1, 0, BFD_RELOC_8
);
2267 MAP (2, 0, BFD_RELOC_16
);
2268 MAP (4, 0, BFD_RELOC_32
);
2269 MAP (1, 1, BFD_RELOC_8_PCREL
);
2270 MAP (2, 1, BFD_RELOC_16_PCREL
);
2271 MAP (4, 1, BFD_RELOC_32_PCREL
);
2273 code
= fixp
->fx_r_type
;
2274 as_bad (_("Can not do %d byte %srelocation"),
2276 fixp
->fx_pcrel
? _("pc-relative") : "");
2281 rel
= (arelent
*) xmalloc (sizeof (arelent
));
2282 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2284 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2285 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2287 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2289 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2290 /* Always pass the addend along! */
2291 rel
->addend
= fixp
->fx_offset
;
2292 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2294 if (rel
->howto
== NULL
)
2296 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2297 _("Cannot represent relocation type %s"),
2298 bfd_get_reloc_code_name (code
));
2300 /* Set howto to a garbage value so that we can keep going. */
2301 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2302 gas_assert (rel
->howto
!= NULL
);
2308 md_parse_option (int c
, char * arg ATTRIBUTE_UNUSED
)
2313 target_big_endian
= 1;
2316 target_big_endian
= 0;
2325 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2327 /* fprintf(stream, _("\
2328 MicroBlaze options:\n\
2329 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2333 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2334 found a machine specific op in an expression,
2335 then we create relocs accordingly. */
2338 cons_fix_new_microblaze (fragS
* frag
,
2344 bfd_reloc_code_real_type r
;
2346 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2347 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2348 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2349 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2350 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2352 exp
->X_op
= O_symbol
;
2353 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2372 as_bad (_("unsupported BFD relocation size %u"), size
);
2377 fix_new_exp (frag
, where
, size
, exp
, 0, r
);