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
);
534 /* Stack protection registers. */
535 else if (strncasecmp (s
, "rshr", 4) == 0)
540 else if (strncasecmp (s
, "rslr", 4) == 0)
547 if (TOLOWER (s
[0]) == 'r')
549 if (ISDIGIT (s
[1]) && ISDIGIT (s
[2]))
551 tmpreg
= (s
[1] - '0') * 10 + s
[2] - '0';
554 else if (ISDIGIT (s
[1]))
560 as_bad (_("register expected, but saw '%.6s'"), s
);
562 if ((int)tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
566 as_bad (_("Invalid register number at '%.6s'"), s
);
572 as_bad (_("register expected, but saw '%.6s'"), s
);
578 parse_exp (char *s
, expressionS
*e
)
583 /* Skip whitespace. */
584 while (ISSPACE (* s
))
587 save
= input_line_pointer
;
588 input_line_pointer
= s
;
592 if (e
->X_op
== O_absent
)
593 as_fatal (_("missing operand"));
595 new_pointer
= input_line_pointer
;
596 input_line_pointer
= save
;
601 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
606 static symbolS
* GOT_symbol
;
608 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
611 parse_imm (char * s
, expressionS
* e
, int min
, int max
)
616 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
617 for (atp
= s
; *atp
!= '@'; atp
++)
618 if (is_end_of_line
[(unsigned char) *atp
])
623 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
626 e
->X_md
= IMM_GOTOFF
;
628 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
633 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
651 if (atp
&& !GOT_symbol
)
653 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
656 new_pointer
= parse_exp (s
, e
);
658 if (e
->X_op
== O_absent
)
659 ; /* An error message has already been emitted. */
660 else if ((e
->X_op
!= O_constant
&& e
->X_op
!= O_symbol
) )
661 as_fatal (_("operand must be a constant or a label"));
662 else if ((e
->X_op
== O_constant
) && ((int) e
->X_add_number
< min
663 || (int) e
->X_add_number
> max
))
665 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
666 min
, max
, (int) e
->X_add_number
);
671 *atp
= '@'; /* restore back (needed?) */
672 if (new_pointer
>= atp
)
673 new_pointer
+= (e
->X_md
== IMM_GOTOFF
)?7:4;
674 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
681 check_got (int * got_type
, int * got_len
)
689 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
690 for (atp
= input_line_pointer
; *atp
!= '@'; atp
++)
691 if (is_end_of_line
[(unsigned char) *atp
])
694 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
697 *got_type
= IMM_GOTOFF
;
699 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
704 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
713 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
715 first
= atp
- input_line_pointer
;
717 past_got
= atp
+ *got_len
+ 1;
718 for (new_pointer
= past_got
; !is_end_of_line
[(unsigned char) *new_pointer
++];)
720 second
= new_pointer
- past_got
;
721 tmpbuf
= xmalloc (first
+ second
+ 2); /* One extra byte for ' ' and one for NUL. */
722 memcpy (tmpbuf
, input_line_pointer
, first
);
723 tmpbuf
[first
] = ' '; /* @GOTOFF is replaced with a single space. */
724 memcpy (tmpbuf
+ first
+ 1, past_got
, second
);
725 tmpbuf
[first
+ second
+ 1] = '\0';
731 parse_cons_expression_microblaze (expressionS
*exp
, int size
)
735 /* Handle @GOTOFF et.al. */
736 char *save
, *gotfree_copy
;
737 int got_len
, got_type
;
739 save
= input_line_pointer
;
740 gotfree_copy
= check_got (& got_type
, & got_len
);
742 input_line_pointer
= gotfree_copy
;
748 exp
->X_md
= got_type
;
749 input_line_pointer
= save
+ (input_line_pointer
- gotfree_copy
)
758 /* This is the guts of the machine-dependent assembler. STR points to a
759 machine dependent instruction. This function is supposed to emit
760 the frags/bytes it assembles to. */
762 static char * str_microblaze_ro_anchor
= "RO";
763 static char * str_microblaze_rw_anchor
= "RW";
766 check_spl_reg (unsigned * reg
)
768 if ((*reg
== REG_MSR
) || (*reg
== REG_PC
)
769 || (*reg
== REG_EAR
) || (*reg
== REG_ESR
)
770 || (*reg
== REG_FSR
) || (*reg
== REG_BTR
) || (*reg
== REG_EDR
)
771 || (*reg
== REG_PID
) || (*reg
== REG_ZPR
)
772 || (*reg
== REG_TLBX
) || (*reg
== REG_TLBLO
)
773 || (*reg
== REG_TLBHI
) || (*reg
== REG_TLBSX
)
774 || (*reg
== REG_SHR
) || (*reg
== REG_SLR
)
775 || (*reg
>= REG_PVR
+MIN_PVR_REGNUM
&& *reg
<= REG_PVR
+MAX_PVR_REGNUM
))
781 /* Here we decide which fixups can be adjusted to make them relative to
782 the beginning of the section instead of the symbol. Basically we need
783 to make sure that the dynamic relocations are done correctly, so in
784 some cases we force the original symbol to be used. */
787 tc_microblaze_fix_adjustable (struct fix
*fixP
)
789 if (GOT_symbol
&& fixP
->fx_subsy
== GOT_symbol
)
792 if (fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOTOFF
793 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_GOTOFF
794 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOT
795 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_PLT
)
802 md_assemble (char * str
)
806 struct op_code_struct
* opcode
, *opcode1
;
807 char * output
= NULL
;
810 unsigned long inst
, inst1
;
815 unsigned int immed
, temp
;
819 /* Drop leading whitespace. */
820 while (ISSPACE (* str
))
823 /* Find the op code end. */
824 for (op_start
= op_end
= str
;
825 *op_end
&& !is_end_of_line
[(unsigned char) *op_end
] && *op_end
!= ' ';
828 name
[nlen
] = op_start
[nlen
];
830 if (nlen
== sizeof (name
) - 1)
838 as_bad (_("can't find opcode "));
842 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, name
);
845 as_bad (_("unknown opcode \"%s\""), name
);
849 inst
= opcode
->bit_sequence
;
852 switch (opcode
->inst_type
)
854 case INST_TYPE_RD_R1_R2
:
855 if (strcmp (op_end
, ""))
856 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
859 as_fatal (_("Error in statement syntax"));
862 if (strcmp (op_end
, ""))
863 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
866 as_fatal (_("Error in statement syntax"));
869 if (strcmp (op_end
, ""))
870 op_end
= parse_reg (op_end
+ 1, ®3
); /* Get r2. */
873 as_fatal (_("Error in statement syntax"));
877 /* Check for spl registers. */
878 if (check_spl_reg (& reg1
))
879 as_fatal (_("Cannot use special register with this instruction"));
880 if (check_spl_reg (& reg2
))
881 as_fatal (_("Cannot use special register with this instruction"));
882 if (check_spl_reg (& reg3
))
883 as_fatal (_("Cannot use special register with this instruction"));
885 if (streq (name
, "sub"))
887 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
888 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
889 inst
|= (reg3
<< RA_LOW
) & RA_MASK
;
890 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
894 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
895 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
896 inst
|= (reg3
<< RB_LOW
) & RB_MASK
;
898 output
= frag_more (isize
);
901 case INST_TYPE_RD_R1_IMM
:
902 if (strcmp (op_end
, ""))
903 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
906 as_fatal (_("Error in statement syntax"));
909 if (strcmp (op_end
, ""))
910 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
913 as_fatal (_("Error in statement syntax"));
916 if (strcmp (op_end
, ""))
917 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
919 as_fatal (_("Error in statement syntax"));
921 /* Check for spl registers. */
922 if (check_spl_reg (& reg1
))
923 as_fatal (_("Cannot use special register with this instruction"));
924 if (check_spl_reg (& reg2
))
925 as_fatal (_("Cannot use special register with this instruction"));
927 if (exp
.X_op
!= O_constant
)
930 relax_substateT subtype
;
932 if (streq (name
, "lmi"))
933 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
934 else if (streq (name
, "smi"))
935 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
937 if (reg2
== REG_ROSDP
)
938 opc
= str_microblaze_ro_anchor
;
939 else if (reg2
== REG_RWSDP
)
940 opc
= str_microblaze_rw_anchor
;
943 if (exp
.X_md
== IMM_GOT
)
944 subtype
= GOT_OFFSET
;
945 else if (exp
.X_md
== IMM_PLT
)
946 subtype
= PLT_OFFSET
;
947 else if (exp
.X_md
== IMM_GOTOFF
)
948 subtype
= GOTOFF_OFFSET
;
950 subtype
= opcode
->inst_offset_type
;
952 output
= frag_var (rs_machine_dependent
,
953 isize
* 2, /* maxm of 2 words. */
954 isize
, /* minm of 1 word. */
955 subtype
, /* PC-relative or not. */
963 output
= frag_more (isize
);
964 immed
= exp
.X_add_number
;
967 if (streq (name
, "lmi") || streq (name
, "smi"))
969 /* Load/store 32-d consecutive registers. Used on exit/entry
970 to subroutines to save and restore registers to stack.
971 Generate 32-d insts. */
975 if (streq (name
, "lmi"))
976 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "lwi");
978 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "swi");
981 as_bad (_("unknown opcode \"%s\""), "lwi");
984 inst
= opcode
->bit_sequence
;
985 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
986 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
987 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
989 for (i
= 0; i
< count
- 1; i
++)
991 output
[0] = INST_BYTE0 (inst
);
992 output
[1] = INST_BYTE1 (inst
);
993 output
[2] = INST_BYTE2 (inst
);
994 output
[3] = INST_BYTE3 (inst
);
995 output
= frag_more (isize
);
998 inst
= opcode
->bit_sequence
;
999 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1000 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1001 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1006 temp
= immed
& 0xFFFF8000;
1007 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1009 /* Needs an immediate inst. */
1010 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1011 if (opcode1
== NULL
)
1013 as_bad (_("unknown opcode \"%s\""), "imm");
1017 inst1
= opcode1
->bit_sequence
;
1018 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1019 output
[0] = INST_BYTE0 (inst1
);
1020 output
[1] = INST_BYTE1 (inst1
);
1021 output
[2] = INST_BYTE2 (inst1
);
1022 output
[3] = INST_BYTE3 (inst1
);
1023 output
= frag_more (isize
);
1025 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1026 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1027 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1031 case INST_TYPE_RD_R1_IMM5
:
1032 if (strcmp (op_end
, ""))
1033 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1036 as_fatal (_("Error in statement syntax"));
1039 if (strcmp (op_end
, ""))
1040 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1043 as_fatal (_("Error in statement syntax"));
1046 if (strcmp (op_end
, ""))
1047 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1049 as_fatal (_("Error in statement syntax"));
1051 /* Check for spl registers. */
1052 if (check_spl_reg (®1
))
1053 as_fatal (_("Cannot use special register with this instruction"));
1054 if (check_spl_reg (®2
))
1055 as_fatal (_("Cannot use special register with this instruction"));
1057 if (exp
.X_op
!= O_constant
)
1058 as_warn (_("Symbol used as immediate for shift instruction"));
1061 output
= frag_more (isize
);
1062 immed
= exp
.X_add_number
;
1065 if (immed
!= (immed
% 32))
1067 as_warn (_("Shift value > 32. using <value %% 32>"));
1070 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1071 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1072 inst
|= (immed
<< IMM_LOW
) & IMM5_MASK
;
1075 case INST_TYPE_R1_R2
:
1076 if (strcmp (op_end
, ""))
1077 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1080 as_fatal (_("Error in statement syntax"));
1083 if (strcmp (op_end
, ""))
1084 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1087 as_fatal (_("Error in statement syntax"));
1091 /* Check for spl registers. */
1092 if (check_spl_reg (& reg1
))
1093 as_fatal (_("Cannot use special register with this instruction"));
1094 if (check_spl_reg (& reg2
))
1095 as_fatal (_("Cannot use special register with this instruction"));
1097 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1098 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1099 output
= frag_more (isize
);
1102 case INST_TYPE_RD_R1
:
1103 if (strcmp (op_end
, ""))
1104 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1107 as_fatal (_("Error in statement syntax"));
1110 if (strcmp (op_end
, ""))
1111 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1114 as_fatal (_("Error in statement syntax"));
1118 /* Check for spl registers. */
1119 if (check_spl_reg (®1
))
1120 as_fatal (_("Cannot use special register with this instruction"));
1121 if (check_spl_reg (®2
))
1122 as_fatal (_("Cannot use special register with this instruction"));
1124 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1125 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1126 output
= frag_more (isize
);
1129 case INST_TYPE_RD_RFSL
:
1130 if (strcmp (op_end
, ""))
1131 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1134 as_fatal (_("Error in statement syntax"));
1137 if (strcmp (op_end
, ""))
1138 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1141 as_fatal (_("Error in statement syntax"));
1145 /* Check for spl registers. */
1146 if (check_spl_reg (®1
))
1147 as_fatal (_("Cannot use special register with this instruction"));
1149 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1150 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1151 output
= frag_more (isize
);
1154 case INST_TYPE_RD_IMM15
:
1155 if (strcmp (op_end
, ""))
1156 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1159 as_fatal (_("Error in statement syntax"));
1163 if (strcmp (op_end
, ""))
1164 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1166 as_fatal (_("Error in statement syntax"));
1168 /* Check for spl registers. */
1169 if (check_spl_reg (®1
))
1170 as_fatal (_("Cannot use special register with this instruction"));
1172 if (exp
.X_op
!= O_constant
)
1173 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1176 output
= frag_more (isize
);
1177 immed
= exp
.X_add_number
;
1179 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1180 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1183 case INST_TYPE_R1_RFSL
:
1184 if (strcmp (op_end
, ""))
1185 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1188 as_fatal (_("Error in statement syntax"));
1191 if (strcmp (op_end
, ""))
1192 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1195 as_fatal (_("Error in statement syntax"));
1199 /* Check for spl registers. */
1200 if (check_spl_reg (®1
))
1201 as_fatal (_("Cannot use special register with this instruction"));
1203 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1204 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1205 output
= frag_more (isize
);
1208 case INST_TYPE_RFSL
:
1209 if (strcmp (op_end
, ""))
1210 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1213 as_fatal (_("Error in statement syntax"));
1216 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1217 output
= frag_more (isize
);
1221 if (strcmp (op_end
, ""))
1222 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1225 as_fatal (_("Error in statement syntax"));
1229 /* Check for spl registers. */
1230 if (check_spl_reg (®1
))
1231 as_fatal (_("Cannot use special register with this instruction"));
1233 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1234 output
= frag_more (isize
);
1237 /* For tuqula insn...:) */
1239 if (strcmp (op_end
, ""))
1240 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1243 as_fatal (_("Error in statement syntax"));
1247 /* Check for spl registers. */
1248 if (check_spl_reg (®1
))
1249 as_fatal (_("Cannot use special register with this instruction"));
1251 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1252 output
= frag_more (isize
);
1255 case INST_TYPE_RD_SPECIAL
:
1256 if (strcmp (op_end
, ""))
1257 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1260 as_fatal (_("Error in statement syntax"));
1263 if (strcmp (op_end
, ""))
1264 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1267 as_fatal (_("Error in statement syntax"));
1271 if (reg2
== REG_MSR
)
1272 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1273 else if (reg2
== REG_PC
)
1274 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1275 else if (reg2
== REG_EAR
)
1276 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1277 else if (reg2
== REG_ESR
)
1278 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1279 else if (reg2
== REG_FSR
)
1280 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1281 else if (reg2
== REG_BTR
)
1282 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1283 else if (reg2
== REG_EDR
)
1284 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1285 else if (reg2
== REG_PID
)
1286 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1287 else if (reg2
== REG_ZPR
)
1288 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1289 else if (reg2
== REG_TLBX
)
1290 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1291 else if (reg2
== REG_TLBLO
)
1292 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1293 else if (reg2
== REG_TLBHI
)
1294 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1295 else if (reg2
== REG_SHR
)
1296 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1297 else if (reg2
== REG_SLR
)
1298 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1299 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1300 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1302 as_fatal (_("invalid value for special purpose register"));
1303 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1304 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1305 output
= frag_more (isize
);
1308 case INST_TYPE_SPECIAL_R1
:
1309 if (strcmp (op_end
, ""))
1310 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1313 as_fatal (_("Error in statement syntax"));
1316 if (strcmp (op_end
, ""))
1317 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1320 as_fatal (_("Error in statement syntax"));
1324 if (reg1
== REG_MSR
)
1325 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1326 else if (reg1
== REG_PC
)
1327 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1328 else if (reg1
== REG_EAR
)
1329 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1330 else if (reg1
== REG_ESR
)
1331 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1332 else if (reg1
== REG_FSR
)
1333 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1334 else if (reg1
== REG_BTR
)
1335 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1336 else if (reg1
== REG_EDR
)
1337 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1338 else if (reg1
== REG_PID
)
1339 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1340 else if (reg1
== REG_ZPR
)
1341 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1342 else if (reg1
== REG_TLBX
)
1343 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1344 else if (reg1
== REG_TLBLO
)
1345 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1346 else if (reg1
== REG_TLBHI
)
1347 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1348 else if (reg1
== REG_TLBSX
)
1349 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1350 else if (reg1
== REG_SHR
)
1351 immed
= opcode
->immval_mask
| REG_SHR_MASK
;
1352 else if (reg1
== REG_SLR
)
1353 immed
= opcode
->immval_mask
| REG_SLR_MASK
;
1355 as_fatal (_("invalid value for special purpose register"));
1356 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1357 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1358 output
= frag_more (isize
);
1361 case INST_TYPE_RD_R1_SPECIAL
:
1362 if (strcmp (op_end
, ""))
1363 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1366 as_fatal (_("Error in statement syntax"));
1369 if (strcmp (op_end
, ""))
1370 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1373 as_fatal (_("Error in statement syntax"));
1377 /* Check for spl registers. */
1378 if (check_spl_reg (®1
))
1379 as_fatal (_("Cannot use special register with this instruction"));
1380 if (check_spl_reg (®2
))
1381 as_fatal (_("Cannot use special register with this instruction"));
1383 /* insn wic ra, rb => wic ra, ra, rb. */
1384 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1385 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1386 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1388 output
= frag_more (isize
);
1391 case INST_TYPE_RD_R2
:
1392 if (strcmp (op_end
, ""))
1393 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1396 as_fatal (_("Error in statement syntax"));
1399 if (strcmp (op_end
, ""))
1400 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1403 as_fatal (_("Error in statement syntax"));
1407 /* Check for spl registers. */
1408 if (check_spl_reg (®1
))
1409 as_fatal (_("Cannot use special register with this instruction"));
1410 if (check_spl_reg (®2
))
1411 as_fatal (_("Cannot use special register with this instruction"));
1413 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1414 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1415 output
= frag_more (isize
);
1418 case INST_TYPE_R1_IMM
:
1419 if (strcmp (op_end
, ""))
1420 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1423 as_fatal (_("Error in statement syntax"));
1426 if (strcmp (op_end
, ""))
1427 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1429 as_fatal (_("Error in statement syntax"));
1431 /* Check for spl registers. */
1432 if (check_spl_reg (®1
))
1433 as_fatal (_("Cannot use special register with this instruction"));
1435 if (exp
.X_op
!= O_constant
)
1438 relax_substateT subtype
;
1440 if (exp
.X_md
== IMM_GOT
)
1441 subtype
= GOT_OFFSET
;
1442 else if (exp
.X_md
== IMM_PLT
)
1443 subtype
= PLT_OFFSET
;
1445 subtype
= opcode
->inst_offset_type
;
1446 output
= frag_var (rs_machine_dependent
,
1447 isize
* 2, /* maxm of 2 words. */
1448 isize
, /* minm of 1 word. */
1449 subtype
, /* PC-relative or not. */
1457 output
= frag_more (isize
);
1458 immed
= exp
.X_add_number
;
1461 temp
= immed
& 0xFFFF8000;
1462 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1464 /* Needs an immediate inst. */
1465 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1466 if (opcode1
== NULL
)
1468 as_bad (_("unknown opcode \"%s\""), "imm");
1472 inst1
= opcode1
->bit_sequence
;
1473 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1474 output
[0] = INST_BYTE0 (inst1
);
1475 output
[1] = INST_BYTE1 (inst1
);
1476 output
[2] = INST_BYTE2 (inst1
);
1477 output
[3] = INST_BYTE3 (inst1
);
1478 output
= frag_more (isize
);
1481 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1482 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1485 case INST_TYPE_RD_IMM
:
1486 if (strcmp (op_end
, ""))
1487 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1490 as_fatal (_("Error in statement syntax"));
1493 if (strcmp (op_end
, ""))
1494 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1496 as_fatal (_("Error in statement syntax"));
1498 /* Check for spl registers. */
1499 if (check_spl_reg (®1
))
1500 as_fatal (_("Cannot use special register with this instruction"));
1502 if (exp
.X_op
!= O_constant
)
1505 relax_substateT subtype
;
1507 if (exp
.X_md
== IMM_GOT
)
1508 subtype
= GOT_OFFSET
;
1509 else if (exp
.X_md
== IMM_PLT
)
1510 subtype
= PLT_OFFSET
;
1512 subtype
= opcode
->inst_offset_type
;
1513 output
= frag_var (rs_machine_dependent
,
1514 isize
* 2, /* maxm of 2 words. */
1515 isize
, /* minm of 1 word. */
1516 subtype
, /* PC-relative or not. */
1524 output
= frag_more (isize
);
1525 immed
= exp
.X_add_number
;
1528 temp
= immed
& 0xFFFF8000;
1529 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1531 /* Needs an immediate inst. */
1532 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1533 if (opcode1
== NULL
)
1535 as_bad (_("unknown opcode \"%s\""), "imm");
1539 inst1
= opcode1
->bit_sequence
;
1540 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1541 output
[0] = INST_BYTE0 (inst1
);
1542 output
[1] = INST_BYTE1 (inst1
);
1543 output
[2] = INST_BYTE2 (inst1
);
1544 output
[3] = INST_BYTE3 (inst1
);
1545 output
= frag_more (isize
);
1548 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1549 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1553 if (strcmp (op_end
, ""))
1554 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1557 as_fatal (_("Error in statement syntax"));
1561 /* Check for spl registers. */
1562 if (check_spl_reg (®2
))
1563 as_fatal (_("Cannot use special register with this instruction"));
1565 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1566 output
= frag_more (isize
);
1570 if (streq (name
, "imm"))
1571 as_fatal (_("An IMM instruction should not be present in the .s file"));
1573 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1575 if (exp
.X_op
!= O_constant
)
1578 relax_substateT subtype
;
1580 if (exp
.X_md
== IMM_GOT
)
1581 subtype
= GOT_OFFSET
;
1582 else if (exp
.X_md
== IMM_PLT
)
1583 subtype
= PLT_OFFSET
;
1585 subtype
= opcode
->inst_offset_type
;
1586 output
= frag_var (rs_machine_dependent
,
1587 isize
* 2, /* maxm of 2 words. */
1588 isize
, /* minm of 1 word. */
1589 subtype
, /* PC-relative or not. */
1597 output
= frag_more (isize
);
1598 immed
= exp
.X_add_number
;
1602 temp
= immed
& 0xFFFF8000;
1603 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1605 /* Needs an immediate inst. */
1606 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1607 if (opcode1
== NULL
)
1609 as_bad (_("unknown opcode \"%s\""), "imm");
1613 inst1
= opcode1
->bit_sequence
;
1614 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1615 output
[0] = INST_BYTE0 (inst1
);
1616 output
[1] = INST_BYTE1 (inst1
);
1617 output
[2] = INST_BYTE2 (inst1
);
1618 output
[3] = INST_BYTE3 (inst1
);
1619 output
= frag_more (isize
);
1621 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1624 case INST_TYPE_NONE
:
1625 output
= frag_more (isize
);
1628 case INST_TYPE_IMM5
:
1629 if (strcmp(op_end
, ""))
1630 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM5
, MAX_IMM5
);
1632 as_fatal(_("Error in statement syntax"));
1633 if (exp
.X_op
!= O_constant
) {
1634 as_warn(_("Symbol used as immediate for mbar instruction"));
1636 output
= frag_more (isize
);
1637 immed
= exp
.X_add_number
;
1639 if (immed
!= (immed
% 32)) {
1640 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1643 inst
|= (immed
<< IMM_MBAR
);
1647 as_fatal (_("unimplemented opcode \"%s\""), name
);
1650 /* Drop whitespace after all the operands have been parsed. */
1651 while (ISSPACE (* op_end
))
1654 /* Give warning message if the insn has more operands than required. */
1655 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1656 as_warn (_("ignoring operands: %s "), op_end
);
1658 output
[0] = INST_BYTE0 (inst
);
1659 output
[1] = INST_BYTE1 (inst
);
1660 output
[2] = INST_BYTE2 (inst
);
1661 output
[3] = INST_BYTE3 (inst
);
1664 dwarf2_emit_insn (4);
1669 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1674 /* Various routines to kill one day. */
1675 /* Equal to MAX_PRECISION in atof-ieee.c */
1676 #define MAX_LITTLENUMS 6
1678 /* Turn a string in input_line_pointer into a floating point constant of type
1679 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1680 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1682 md_atof (int type
, char * litP
, int * sizeP
)
1685 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1717 return _("Bad call to MD_NTOF()");
1720 t
= atof_ieee (input_line_pointer
, type
, words
);
1723 input_line_pointer
= t
;
1725 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1727 if (! target_big_endian
)
1729 for (i
= prec
- 1; i
>= 0; i
--)
1731 md_number_to_chars (litP
, (valueT
) words
[i
],
1732 sizeof (LITTLENUM_TYPE
));
1733 litP
+= sizeof (LITTLENUM_TYPE
);
1737 for (i
= 0; i
< prec
; i
++)
1739 md_number_to_chars (litP
, (valueT
) words
[i
],
1740 sizeof (LITTLENUM_TYPE
));
1741 litP
+= sizeof (LITTLENUM_TYPE
);
1747 const char * md_shortopts
= "";
1749 struct option md_longopts
[] =
1751 {"EB", no_argument
, NULL
, OPTION_EB
},
1752 {"EL", no_argument
, NULL
, OPTION_EL
},
1753 { NULL
, no_argument
, NULL
, 0}
1756 size_t md_longopts_size
= sizeof (md_longopts
);
1758 int md_short_jump_size
;
1761 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED
,
1762 addressT from_Nddr ATTRIBUTE_UNUSED
,
1763 addressT to_Nddr ATTRIBUTE_UNUSED
,
1764 fragS
* frag ATTRIBUTE_UNUSED
,
1765 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1767 as_fatal (_("failed sanity check: short_jump"));
1771 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED
,
1772 addressT from_Nddr ATTRIBUTE_UNUSED
,
1773 addressT to_Nddr ATTRIBUTE_UNUSED
,
1774 fragS
* frag ATTRIBUTE_UNUSED
,
1775 symbolS
* to_symbol ATTRIBUTE_UNUSED
)
1777 as_fatal (_("failed sanity check: long_jump"));
1780 /* Called after relaxing, change the frags so they know how big they are. */
1783 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
1784 segT sec ATTRIBUTE_UNUSED
,
1789 switch (fragP
->fr_subtype
)
1791 case UNDEFINED_PC_OFFSET
:
1792 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1793 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1794 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1797 case DEFINED_ABS_SEGMENT
:
1798 if (fragP
->fr_symbol
== GOT_symbol
)
1799 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1800 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_GOTPC
);
1802 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1803 fragP
->fr_offset
, FALSE
, BFD_RELOC_64
);
1804 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1807 case DEFINED_RO_SEGMENT
:
1808 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1809 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_ROSDA
);
1810 fragP
->fr_fix
+= INST_WORD_SIZE
;
1813 case DEFINED_RW_SEGMENT
:
1814 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1815 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_32_RWSDA
);
1816 fragP
->fr_fix
+= INST_WORD_SIZE
;
1819 case DEFINED_PC_OFFSET
:
1820 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
, fragP
->fr_symbol
,
1821 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_32_LO_PCREL
);
1822 fragP
->fr_fix
+= INST_WORD_SIZE
;
1825 case LARGE_DEFINED_PC_OFFSET
:
1826 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1827 fragP
->fr_offset
, TRUE
, BFD_RELOC_64_PCREL
);
1828 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1832 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1833 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOT
);
1834 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1838 fixP
= fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1839 fragP
->fr_offset
, TRUE
, BFD_RELOC_MICROBLAZE_64_PLT
);
1840 /* fixP->fx_plt = 1; */
1842 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1846 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1847 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOTOFF
);
1848 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1857 /* Applies the desired value to the specified location.
1858 Also sets up addends for 'rela' type relocations. */
1860 md_apply_fix (fixS
* fixP
,
1864 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1865 char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
1866 const char * symname
;
1867 /* Note: use offsetT because it is signed, valueT is unsigned. */
1868 offsetT val
= (offsetT
) * valp
;
1870 struct op_code_struct
* opcode1
;
1871 unsigned long inst1
;
1873 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
1875 /* fixP->fx_offset is supposed to be set up correctly for all
1876 symbol relocations. */
1877 if (fixP
->fx_addsy
== NULL
)
1879 if (!fixP
->fx_pcrel
)
1880 fixP
->fx_offset
= val
; /* Absolute relocation. */
1882 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1883 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
1886 /* If we aren't adjusting this fixup to be against the section
1887 symbol, we need to adjust the value. */
1888 if (fixP
->fx_addsy
!= NULL
)
1890 if (S_IS_WEAK (fixP
->fx_addsy
)
1891 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
1892 && (((bfd_get_section_flags (stdoutput
,
1893 S_GET_SEGMENT (fixP
->fx_addsy
))
1894 & SEC_LINK_ONCE
) != 0)
1895 || !strncmp (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
1897 sizeof (".gnu.linkonce") - 1))))
1899 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1900 if (val
!= 0 && ! fixP
->fx_pcrel
)
1902 /* In this case, the bfd_install_relocation routine will
1903 incorrectly add the symbol value back in. We just want
1904 the addend to appear in the object file.
1905 FIXME: If this makes VALUE zero, we're toast. */
1906 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1911 /* If the fix is relative to a symbol which is not defined, or not
1912 in the same segment as the fix, we cannot resolve it here. */
1913 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1914 if (fixP
->fx_addsy
!= NULL
1915 && (!S_IS_DEFINED (fixP
->fx_addsy
)
1916 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
1920 /* For ELF we can just return and let the reloc that will be generated
1921 take care of everything. For COFF we still have to insert 'val'
1922 into the insn since the addend field will be ignored. */
1926 /* All fixups in the text section must be handled in the linker. */
1927 else if (segment
->flags
& SEC_CODE
)
1929 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
1934 switch (fixP
->fx_r_type
)
1936 case BFD_RELOC_MICROBLAZE_32_LO
:
1937 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
1938 if (target_big_endian
)
1940 buf
[2] |= ((val
>> 8) & 0xff);
1941 buf
[3] |= (val
& 0xff);
1945 buf
[1] |= ((val
>> 8) & 0xff);
1946 buf
[0] |= (val
& 0xff);
1949 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
1950 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
1951 /* Don't do anything if the symbol is not defined. */
1952 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1954 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
1955 as_bad_where (file
, fixP
->fx_line
,
1956 _("pcrel for branch to %s too far (0x%x)"),
1957 symname
, (int) val
);
1958 if (target_big_endian
)
1960 buf
[2] |= ((val
>> 8) & 0xff);
1961 buf
[3] |= (val
& 0xff);
1965 buf
[1] |= ((val
>> 8) & 0xff);
1966 buf
[0] |= (val
& 0xff);
1972 case BFD_RELOC_32_PCREL
:
1973 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
1974 /* Don't do anything if the symbol is not defined. */
1975 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1977 if (target_big_endian
)
1979 buf
[0] |= ((val
>> 24) & 0xff);
1980 buf
[1] |= ((val
>> 16) & 0xff);
1981 buf
[2] |= ((val
>> 8) & 0xff);
1982 buf
[3] |= (val
& 0xff);
1986 buf
[3] |= ((val
>> 24) & 0xff);
1987 buf
[2] |= ((val
>> 16) & 0xff);
1988 buf
[1] |= ((val
>> 8) & 0xff);
1989 buf
[0] |= (val
& 0xff);
1993 case BFD_RELOC_64_PCREL
:
1995 /* Add an imm instruction. First save the current instruction. */
1996 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
1997 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
1999 /* Generate the imm instruction. */
2000 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2001 if (opcode1
== NULL
)
2003 as_bad (_("unknown opcode \"%s\""), "imm");
2007 inst1
= opcode1
->bit_sequence
;
2008 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2009 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
2011 buf
[0] = INST_BYTE0 (inst1
);
2012 buf
[1] = INST_BYTE1 (inst1
);
2013 buf
[2] = INST_BYTE2 (inst1
);
2014 buf
[3] = INST_BYTE3 (inst1
);
2016 /* Add the value only if the symbol is defined. */
2017 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
2019 if (target_big_endian
)
2021 buf
[6] |= ((val
>> 8) & 0xff);
2022 buf
[7] |= (val
& 0xff);
2026 buf
[5] |= ((val
>> 8) & 0xff);
2027 buf
[4] |= (val
& 0xff);
2032 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2033 case BFD_RELOC_MICROBLAZE_64_GOT
:
2034 case BFD_RELOC_MICROBLAZE_64_PLT
:
2035 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2036 /* Add an imm instruction. First save the current instruction. */
2037 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
2038 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2040 /* Generate the imm instruction. */
2041 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2042 if (opcode1
== NULL
)
2044 as_bad (_("unknown opcode \"%s\""), "imm");
2048 inst1
= opcode1
->bit_sequence
;
2050 /* We can fixup call to a defined non-global address
2051 within the same section only. */
2052 buf
[0] = INST_BYTE0 (inst1
);
2053 buf
[1] = INST_BYTE1 (inst1
);
2054 buf
[2] = INST_BYTE2 (inst1
);
2055 buf
[3] = INST_BYTE3 (inst1
);
2062 if (fixP
->fx_addsy
== NULL
)
2064 /* This fixup has been resolved. Create a reloc in case the linker
2065 moves code around due to relaxing. */
2066 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2067 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2069 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2070 fixP
->fx_addsy
= section_symbol (absolute_section
);
2076 md_operand (expressionS
* expressionP
)
2078 /* Ignore leading hash symbol, if present. */
2079 if (*input_line_pointer
== '#')
2081 input_line_pointer
++;
2082 expression (expressionP
);
2086 /* Called just before address relaxation, return the length
2087 by which a fragment must grow to reach it's destination. */
2090 md_estimate_size_before_relax (fragS
* fragP
,
2093 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2094 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2095 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2096 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2098 switch (fragP
->fr_subtype
)
2100 case INST_PC_OFFSET
:
2101 /* Used to be a PC-relative branch. */
2102 if (!fragP
->fr_symbol
)
2104 /* We know the abs value: Should never happen. */
2105 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2108 else if (S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
&&
2109 !S_IS_WEAK (fragP
->fr_symbol
))
2111 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2112 /* Don't know now whether we need an imm instruction. */
2113 fragP
->fr_var
= INST_WORD_SIZE
;
2115 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2116 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2118 /* Cannot have a PC-relative branch to a diff segment. */
2119 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2120 S_GET_NAME (fragP
->fr_symbol
));
2121 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2122 fragP
->fr_var
= INST_WORD_SIZE
*2;
2126 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2127 fragP
->fr_var
= INST_WORD_SIZE
*2;
2131 case INST_NO_OFFSET
:
2132 /* Used to be a reference to somewhere which was unknown. */
2133 if (fragP
->fr_symbol
)
2135 if (fragP
->fr_opcode
== NULL
)
2137 /* Used as an absolute value. */
2138 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2139 /* Variable part does not change. */
2140 fragP
->fr_var
= INST_WORD_SIZE
*2;
2142 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2144 /* It is accessed using the small data read only anchor. */
2145 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2146 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2147 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2148 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2150 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2151 fragP
->fr_var
= INST_WORD_SIZE
;
2155 /* Variable not in small data read only segment accessed
2156 using small data read only anchor. */
2157 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2159 as_bad_where (file
, fragP
->fr_line
,
2160 _("Variable is accessed using small data read "
2161 "only anchor, but it is not in the small data "
2162 "read only section"));
2163 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2164 fragP
->fr_var
= INST_WORD_SIZE
;
2167 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2169 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == bfd_com_section_ptr
)
2170 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2171 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2172 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2174 /* It is accessed using the small data read write anchor. */
2175 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2176 fragP
->fr_var
= INST_WORD_SIZE
;
2180 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2182 as_bad_where (file
, fragP
->fr_line
,
2183 _("Variable is accessed using small data read "
2184 "write anchor, but it is not in the small data "
2185 "read write section"));
2186 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2187 fragP
->fr_var
= INST_WORD_SIZE
;
2192 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2198 /* We know the abs value: Should never happen. */
2199 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2204 case UNDEFINED_PC_OFFSET
:
2205 case LARGE_DEFINED_PC_OFFSET
:
2206 case DEFINED_ABS_SEGMENT
:
2210 fragP
->fr_var
= INST_WORD_SIZE
*2;
2212 case DEFINED_RO_SEGMENT
:
2213 case DEFINED_RW_SEGMENT
:
2214 case DEFINED_PC_OFFSET
:
2215 fragP
->fr_var
= INST_WORD_SIZE
;
2221 return fragP
->fr_var
;
2224 /* Put number into target byte order. */
2227 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2229 if (target_big_endian
)
2230 number_to_chars_bigendian (ptr
, use
, nbytes
);
2232 number_to_chars_littleendian (ptr
, use
, nbytes
);
2235 /* Round up a section size to the appropriate boundary. */
2238 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2240 return size
; /* Byte alignment is fine. */
2244 /* The location from which a PC relative jump should be calculated,
2245 given a PC relative reloc. */
2248 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2251 /* If the symbol is undefined or defined in another section
2252 we leave the add number alone for the linker to fix it later.
2253 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2255 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2256 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2257 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2261 /* The case where we are going to resolve things... */
2262 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2263 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2265 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2271 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2272 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2275 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2278 bfd_reloc_code_real_type code
;
2280 switch (fixp
->fx_r_type
)
2282 case BFD_RELOC_NONE
:
2283 case BFD_RELOC_MICROBLAZE_64_NONE
:
2285 case BFD_RELOC_MICROBLAZE_32_LO
:
2286 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2289 case BFD_RELOC_64_PCREL
:
2290 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2291 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2292 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2293 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2294 case BFD_RELOC_MICROBLAZE_64_GOT
:
2295 case BFD_RELOC_MICROBLAZE_64_PLT
:
2296 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2297 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2298 code
= fixp
->fx_r_type
;
2302 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2304 MAP (1, 0, BFD_RELOC_8
);
2305 MAP (2, 0, BFD_RELOC_16
);
2306 MAP (4, 0, BFD_RELOC_32
);
2307 MAP (1, 1, BFD_RELOC_8_PCREL
);
2308 MAP (2, 1, BFD_RELOC_16_PCREL
);
2309 MAP (4, 1, BFD_RELOC_32_PCREL
);
2311 code
= fixp
->fx_r_type
;
2312 as_bad (_("Can not do %d byte %srelocation"),
2314 fixp
->fx_pcrel
? _("pc-relative") : "");
2319 rel
= (arelent
*) xmalloc (sizeof (arelent
));
2320 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2322 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2323 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2325 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2327 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2328 /* Always pass the addend along! */
2329 rel
->addend
= fixp
->fx_offset
;
2330 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2332 if (rel
->howto
== NULL
)
2334 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2335 _("Cannot represent relocation type %s"),
2336 bfd_get_reloc_code_name (code
));
2338 /* Set howto to a garbage value so that we can keep going. */
2339 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2340 gas_assert (rel
->howto
!= NULL
);
2346 md_parse_option (int c
, char * arg ATTRIBUTE_UNUSED
)
2351 target_big_endian
= 1;
2354 target_big_endian
= 0;
2363 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2365 /* fprintf(stream, _("\
2366 MicroBlaze options:\n\
2367 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2371 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2372 found a machine specific op in an expression,
2373 then we create relocs accordingly. */
2376 cons_fix_new_microblaze (fragS
* frag
,
2382 bfd_reloc_code_real_type r
;
2384 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2385 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2386 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2387 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2388 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2390 exp
->X_op
= O_symbol
;
2391 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2410 as_bad (_("unsupported BFD relocation size %u"), size
);
2415 fix_new_exp (frag
, where
, size
, exp
, 0, r
);