1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright 2009 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 void microblaze_generate_symbol (char *sym
);
39 static bfd_boolean
check_spl_reg (unsigned *);
41 /* Several places in this file insert raw instructions into the
42 object. They should generate the instruction
43 and then use these four macros to crack the instruction value into
44 the appropriate byte values. */
45 #define INST_BYTE0(x) (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF))
46 #define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
47 #define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
48 #define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
50 /* This array holds the chars that always start a comment. If the
51 pre-processor is disabled, these aren't very useful. */
52 const char comment_chars
[] = "#";
54 const char line_separator_chars
[] = ";";
56 /* This array holds the chars that only start a comment at the beginning of
58 const char line_comment_chars
[] = "#";
60 const int md_reloc_size
= 8; /* Size of relocation record. */
62 /* Chars that can be used to separate mant
63 from exp in floating point numbers. */
64 const char EXP_CHARS
[] = "eE";
66 /* Chars that mean this number is a floating point constant
69 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
71 /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1. */
72 #define UNDEFINED_PC_OFFSET 2
73 #define DEFINED_ABS_SEGMENT 3
74 #define DEFINED_PC_OFFSET 4
75 #define DEFINED_RO_SEGMENT 5
76 #define DEFINED_RW_SEGMENT 6
77 #define LARGE_DEFINED_PC_OFFSET 7
80 #define GOTOFF_OFFSET 10
83 /* Initialize the relax table. */
84 const relax_typeS md_relax_table
[] =
86 { 1, 1, 0, 0 }, /* 0: Unused. */
87 { 1, 1, 0, 0 }, /* 1: Unused. */
88 { 1, 1, 0, 0 }, /* 2: Unused. */
89 { 1, 1, 0, 0 }, /* 3: Unused. */
90 { 32767, -32768, INST_WORD_SIZE
, LARGE_DEFINED_PC_OFFSET
}, /* 4: DEFINED_PC_OFFSET. */
91 { 1, 1, 0, 0 }, /* 5: Unused. */
92 { 1, 1, 0, 0 }, /* 6: Unused. */
93 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
94 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 8: GOT_OFFSET. */
95 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 9: PLT_OFFSET. */
96 { 0x7fffffff, 0x80000000, INST_WORD_SIZE
*2, 0 }, /* 10: GOTOFF_OFFSET. */
99 static struct hash_control
* opcode_hash_control
; /* Opcode mnemonics. */
101 static segT sbss_segment
= 0; /* Small bss section. */
102 static segT sbss2_segment
= 0; /* Section not used. */
103 static segT sdata_segment
= 0; /* Small data section. */
104 static segT sdata2_segment
= 0; /* Small read-only section. */
105 static segT rodata_segment
= 0; /* read-only section. */
107 /* Generate a symbol for stabs information. */
110 microblaze_generate_symbol (char *sym
)
112 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
113 static int microblaze_label_count
;
114 sprintf (sym
, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME
, microblaze_label_count
);
115 ++microblaze_label_count
;
118 /* Handle the section changing pseudo-ops. */
121 microblaze_s_text (int ignore ATTRIBUTE_UNUSED
)
124 obj_elf_text (ignore
);
131 microblaze_s_data (int ignore ATTRIBUTE_UNUSED
)
134 obj_elf_change_section (".data", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
140 /* Things in the .sdata segment are always considered to be in the small data section. */
143 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED
)
146 obj_elf_change_section (".sdata", SHT_PROGBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
152 /* Pseudo op to make file scope bss items. */
155 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED
)
167 segT current_seg
= now_seg
;
168 subsegT current_subseg
= now_subseg
;
170 name
= input_line_pointer
;
171 c
= get_symbol_end ();
173 /* Just after name is now '\0'. */
174 p
= input_line_pointer
;
177 if (*input_line_pointer
!= ',')
179 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
180 ignore_rest_of_line ();
184 input_line_pointer
++; /* skip ',' */
185 if ((size
= get_absolute_expression ()) < 0)
187 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size
);
188 ignore_rest_of_line ();
192 /* The third argument to .lcomm is the alignment. */
193 if (*input_line_pointer
!= ',')
197 ++input_line_pointer
;
198 align
= get_absolute_expression ();
201 as_warn (_("ignoring bad alignment"));
207 symbolP
= symbol_find_or_make (name
);
210 if (S_IS_DEFINED (symbolP
) && ! S_IS_COMMON (symbolP
))
212 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
213 S_GET_NAME (symbolP
));
214 ignore_rest_of_line ();
218 if (S_GET_VALUE (symbolP
) && S_GET_VALUE (symbolP
) != (valueT
) size
)
220 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
221 S_GET_NAME (symbolP
),
222 (long) S_GET_VALUE (symbolP
),
225 ignore_rest_of_line ();
231 old_subsec
= now_subseg
;
234 /* Convert to a power of 2 alignment. */
235 for (align2
= 0; (align
& 1) == 0; align
>>= 1, ++align2
);
238 as_bad (_("Common alignment not a power of 2"));
239 ignore_rest_of_line ();
246 record_alignment (current_seg
, align2
);
247 subseg_set (current_seg
, current_subseg
);
249 frag_align (align2
, 0, 0);
250 if (S_GET_SEGMENT (symbolP
) == current_seg
)
251 symbol_get_frag (symbolP
)->fr_symbol
= 0;
252 symbol_set_frag (symbolP
, frag_now
);
253 pfrag
= frag_var (rs_org
, 1, 1, (relax_substateT
) 0, symbolP
, size
,
256 S_SET_SIZE (symbolP
, size
);
257 S_SET_SEGMENT (symbolP
, current_seg
);
258 subseg_set (current_seg
, current_subseg
);
259 demand_empty_rest_of_line ();
263 microblaze_s_rdata (int localvar
)
269 obj_elf_change_section (".rodata", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
270 if (rodata_segment
== 0)
271 rodata_segment
= subseg_new (".rodata", 0);
276 obj_elf_change_section (".sdata2", SHT_PROGBITS
, SHF_ALLOC
, 0, 0, 0, 0);
284 microblaze_s_bss (int localvar
)
287 if (localvar
== 0) /* bss. */
288 obj_elf_change_section (".bss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
289 else if (localvar
== 1)
292 obj_elf_change_section (".sbss", SHT_NOBITS
, SHF_ALLOC
+SHF_WRITE
, 0, 0, 0, 0);
293 if (sbss_segment
== 0)
294 sbss_segment
= subseg_new (".sbss", 0);
301 /* endp_p is always 1 as this func is called only for .end <funcname>
302 This func consumes the <funcname> and calls regular processing
303 s_func(1) with arg 1 (1 for end). */
306 microblaze_s_func (int end_p ATTRIBUTE_UNUSED
)
308 *input_line_pointer
= get_symbol_end ();
312 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
315 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED
)
322 name
= input_line_pointer
;
323 c
= get_symbol_end ();
324 symbolP
= symbol_find_or_make (name
);
325 S_SET_WEAK (symbolP
);
326 *input_line_pointer
= c
;
330 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
332 if (S_IS_DEFINED (symbolP
))
334 as_bad ("Ignoring attempt to redefine symbol `%s'.",
335 S_GET_NAME (symbolP
));
336 ignore_rest_of_line ();
340 if (*input_line_pointer
== ',')
342 ++input_line_pointer
;
347 if (exp
.X_op
!= O_symbol
)
349 as_bad ("bad .weakext directive");
350 ignore_rest_of_line ();
353 symbol_set_value_expression (symbolP
, &exp
);
356 demand_empty_rest_of_line ();
359 /* This table describes all the machine specific pseudo-ops the assembler
360 has to support. The fields are:
361 Pseudo-op name without dot
362 Function to call to execute this pseudo-op
363 Integer arg to pass to the function. */
364 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
365 and then in the read.c table. */
366 const pseudo_typeS md_pseudo_table
[] =
368 {"lcomm", microblaze_s_lcomm
, 1},
369 {"data", microblaze_s_data
, 0},
370 {"data8", cons
, 1}, /* Same as byte. */
371 {"data16", cons
, 2}, /* Same as hword. */
372 {"data32", cons
, 4}, /* Same as word. */
373 {"ent", s_func
, 0}, /* Treat ent as function entry point. */
374 {"end", microblaze_s_func
, 1}, /* Treat end as function end point. */
375 {"gpword", s_rva
, 4}, /* gpword label => store resolved label address in data section. */
376 {"weakext", microblaze_s_weakext
, 0},
377 {"rodata", microblaze_s_rdata
, 0},
378 {"sdata2", microblaze_s_rdata
, 1},
379 {"sdata", microblaze_s_sdata
, 0},
380 {"bss", microblaze_s_bss
, 0},
381 {"sbss", microblaze_s_bss
, 1},
382 {"text", microblaze_s_text
, 0},
384 {"frame", s_ignore
, 0},
385 {"mask", s_ignore
, 0}, /* Emitted by gcc. */
389 /* This function is called once, at assembler startup time. This should
390 set up all the tables, etc that the MD part of the assembler needs. */
395 struct op_code_struct
* opcode
;
397 opcode_hash_control
= hash_new ();
399 /* Insert unique names into hash table. */
400 for (opcode
= opcodes
; opcode
->name
; opcode
++)
401 hash_insert (opcode_hash_control
, opcode
->name
, (char *) opcode
);
404 /* Try to parse a reg name. */
407 parse_reg (char * s
, unsigned * reg
)
411 /* Strip leading whitespace. */
412 while (ISSPACE (* s
))
415 if (strncasecmp (s
, "rpc", 3) == 0)
420 else if (strncasecmp (s
, "rmsr", 4) == 0)
425 else if (strncasecmp (s
, "rear", 4) == 0)
430 else if (strncasecmp (s
, "resr", 4) == 0)
435 else if (strncasecmp (s
, "rfsr", 4) == 0)
440 else if (strncasecmp (s
, "rbtr", 4) == 0)
445 else if (strncasecmp (s
, "redr", 4) == 0)
450 /* MMU registers start. */
451 else if (strncasecmp (s
, "rpid", 4) == 0)
456 else if (strncasecmp (s
, "rzpr", 4) == 0)
461 else if (strncasecmp (s
, "rtlbx", 5) == 0)
466 else if (strncasecmp (s
, "rtlblo", 6) == 0)
471 else if (strncasecmp (s
, "rtlbhi", 6) == 0)
476 else if (strncasecmp (s
, "rtlbsx", 6) == 0)
481 /* MMU registers end. */
482 else if (strncasecmp (s
, "rpvr", 4) == 0)
484 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
486 tmpreg
= (s
[4]-'0')*10 + s
[5] - '0';
490 else if (ISDIGIT (s
[4]))
496 as_bad (_("register expected, but saw '%.6s'"), s
);
497 if ((int) tmpreg
>= MIN_PVR_REGNUM
&& tmpreg
<= MAX_PVR_REGNUM
)
498 *reg
= REG_PVR
+ tmpreg
;
501 as_bad (_("Invalid register number at '%.6s'"), s
);
506 else if (strncasecmp (s
, "rsp", 3) == 0)
511 else if (strncasecmp (s
, "rfsl", 4) == 0)
513 if (ISDIGIT (s
[4]) && ISDIGIT (s
[5]))
515 tmpreg
= (s
[4] - '0') * 10 + s
[5] - '0';
518 else if (ISDIGIT (s
[4]))
524 as_bad (_("register expected, but saw '%.6s'"), s
);
526 if ((int) tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
530 as_bad (_("Invalid register number at '%.6s'"), s
);
537 if (TOLOWER (s
[0]) == 'r')
539 if (ISDIGIT (s
[1]) && ISDIGIT (s
[2]))
541 tmpreg
= (s
[1] - '0') * 10 + s
[2] - '0';
544 else if (ISDIGIT (s
[1]))
550 as_bad (_("register expected, but saw '%.6s'"), s
);
552 if ((int)tmpreg
>= MIN_REGNUM
&& tmpreg
<= MAX_REGNUM
)
556 as_bad (_("Invalid register number at '%.6s'"), s
);
562 as_bad (_("register expected, but saw '%.6s'"), s
);
568 parse_exp (char *s
, expressionS
*e
)
573 /* Skip whitespace. */
574 while (ISSPACE (* s
))
577 save
= input_line_pointer
;
578 input_line_pointer
= s
;
582 if (e
->X_op
== O_absent
)
583 as_fatal (_("missing operand"));
585 new_pointer
= input_line_pointer
;
586 input_line_pointer
= save
;
591 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
596 static symbolS
* GOT_symbol
;
598 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
601 parse_imm (char * s
, expressionS
* e
, int min
, int max
)
606 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
607 for (atp
= s
; *atp
!= '@'; atp
++)
608 if (is_end_of_line
[(unsigned char) *atp
])
613 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
616 e
->X_md
= IMM_GOTOFF
;
618 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
623 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
641 if (atp
&& !GOT_symbol
)
643 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
646 new_pointer
= parse_exp (s
, e
);
648 if (e
->X_op
== O_absent
)
649 ; /* An error message has already been emitted. */
650 else if ((e
->X_op
!= O_constant
&& e
->X_op
!= O_symbol
) )
651 as_fatal (_("operand must be a constant or a label"));
652 else if ((e
->X_op
== O_constant
) && ((int) e
->X_add_number
< min
653 || (int) e
->X_add_number
> max
))
655 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
656 min
, max
, (int) e
->X_add_number
);
661 *atp
= '@'; /* restore back (needed?) */
662 if (new_pointer
>= atp
)
663 new_pointer
+= (e
->X_md
== IMM_GOTOFF
)?7:4;
664 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
671 check_got (int * got_type
, int * got_len
)
679 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
680 for (atp
= input_line_pointer
; *atp
!= '@'; atp
++)
681 if (is_end_of_line
[(unsigned char) *atp
])
684 if (strncmp (atp
+ 1, "GOTOFF", 5) == 0)
687 *got_type
= IMM_GOTOFF
;
689 else if (strncmp (atp
+ 1, "GOT", 3) == 0)
694 else if (strncmp (atp
+ 1, "PLT", 3) == 0)
703 GOT_symbol
= symbol_find_or_make (GOT_SYMBOL_NAME
);
705 first
= atp
- input_line_pointer
;
707 past_got
= atp
+ *got_len
+ 1;
708 for (new_pointer
= past_got
; !is_end_of_line
[(unsigned char) *new_pointer
++];)
710 second
= new_pointer
- past_got
;
711 tmpbuf
= xmalloc (first
+ second
+ 2); /* One extra byte for ' ' and one for NUL. */
712 memcpy (tmpbuf
, input_line_pointer
, first
);
713 tmpbuf
[first
] = ' '; /* @GOTOFF is replaced with a single space. */
714 memcpy (tmpbuf
+ first
+ 1, past_got
, second
);
715 tmpbuf
[first
+ second
+ 1] = '\0';
721 parse_cons_expression_microblaze (expressionS
*exp
, int size
)
725 /* Handle @GOTOFF et.al. */
726 char *save
, *gotfree_copy
;
727 int got_len
, got_type
;
729 save
= input_line_pointer
;
730 gotfree_copy
= check_got (& got_type
, & got_len
);
732 input_line_pointer
= gotfree_copy
;
738 exp
->X_md
= got_type
;
739 input_line_pointer
= save
+ (input_line_pointer
- gotfree_copy
)
748 /* This is the guts of the machine-dependent assembler. STR points to a
749 machine dependent instruction. This function is supposed to emit
750 the frags/bytes it assembles to. */
752 static char * str_microblaze_ro_anchor
= "RO";
753 static char * str_microblaze_rw_anchor
= "RW";
756 check_spl_reg (unsigned * reg
)
758 if ((*reg
== REG_MSR
) || (*reg
== REG_PC
)
759 || (*reg
== REG_EAR
) || (*reg
== REG_ESR
)
760 || (*reg
== REG_FSR
) || (*reg
== REG_BTR
) || (*reg
== REG_EDR
)
761 || (*reg
== REG_PID
) || (*reg
== REG_ZPR
)
762 || (*reg
== REG_TLBX
) || (*reg
== REG_TLBLO
)
763 || (*reg
== REG_TLBHI
) || (*reg
== REG_TLBSX
)
764 || (*reg
>= REG_PVR
+MIN_PVR_REGNUM
&& *reg
<= REG_PVR
+MAX_PVR_REGNUM
))
770 /* Here we decide which fixups can be adjusted to make them relative to
771 the beginning of the section instead of the symbol. Basically we need
772 to make sure that the dynamic relocations are done correctly, so in
773 some cases we force the original symbol to be used. */
776 tc_microblaze_fix_adjustable (struct fix
*fixP
)
778 if (GOT_symbol
&& fixP
->fx_subsy
== GOT_symbol
)
781 if (fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOTOFF
782 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_32_GOTOFF
783 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_GOT
784 || fixP
->fx_r_type
== BFD_RELOC_MICROBLAZE_64_PLT
)
791 md_assemble (char * str
)
795 struct op_code_struct
* opcode
, *opcode1
;
796 char * output
= NULL
;
799 unsigned long inst
, inst1
;
804 unsigned int immed
, temp
;
808 /* Drop leading whitespace. */
809 while (ISSPACE (* str
))
812 /* Find the op code end. */
813 for (op_start
= op_end
= str
;
814 * op_end
&& nlen
< 20 && !is_end_of_line
[(int)*op_end
] && *op_end
!= ' ';
817 name
[nlen
] = op_start
[nlen
];
825 as_bad (_("can't find opcode "));
829 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, name
);
832 as_bad (_("unknown opcode \"%s\""), name
);
836 inst
= opcode
->bit_sequence
;
839 switch (opcode
->inst_type
)
841 case INST_TYPE_RD_R1_R2
:
842 if (strcmp (op_end
, ""))
843 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
846 as_fatal (_("Error in statement syntax"));
849 if (strcmp (op_end
, ""))
850 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
853 as_fatal (_("Error in statement syntax"));
856 if (strcmp (op_end
, ""))
857 op_end
= parse_reg (op_end
+ 1, ®3
); /* Get r2. */
860 as_fatal (_("Error in statement syntax"));
864 /* Check for spl registers. */
865 if (check_spl_reg (& reg1
))
866 as_fatal (_("Cannot use special register with this instruction"));
867 if (check_spl_reg (& reg2
))
868 as_fatal (_("Cannot use special register with this instruction"));
869 if (check_spl_reg (& reg3
))
870 as_fatal (_("Cannot use special register with this instruction"));
872 if (streq (name
, "sub"))
874 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
875 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
876 inst
|= (reg3
<< RA_LOW
) & RA_MASK
;
877 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
881 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
882 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
883 inst
|= (reg3
<< RB_LOW
) & RB_MASK
;
885 output
= frag_more (isize
);
888 case INST_TYPE_RD_R1_IMM
:
889 if (strcmp (op_end
, ""))
890 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
893 as_fatal (_("Error in statement syntax"));
896 if (strcmp (op_end
, ""))
897 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
900 as_fatal (_("Error in statement syntax"));
903 if (strcmp (op_end
, ""))
904 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
906 as_fatal (_("Error in statement syntax"));
908 /* Check for spl registers. */
909 if (check_spl_reg (& reg1
))
910 as_fatal (_("Cannot use special register with this instruction"));
911 if (check_spl_reg (& reg2
))
912 as_fatal (_("Cannot use special register with this instruction"));
914 if (exp
.X_op
!= O_constant
)
917 relax_substateT subtype
;
919 if (streq (name
, "lmi"))
920 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
921 else if (streq (name
, "smi"))
922 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
924 if (reg2
== REG_ROSDP
)
925 opc
= str_microblaze_ro_anchor
;
926 else if (reg2
== REG_RWSDP
)
927 opc
= str_microblaze_rw_anchor
;
930 if (exp
.X_md
== IMM_GOT
)
931 subtype
= GOT_OFFSET
;
932 else if (exp
.X_md
== IMM_PLT
)
933 subtype
= PLT_OFFSET
;
934 else if (exp
.X_md
== IMM_GOTOFF
)
935 subtype
= GOTOFF_OFFSET
;
937 subtype
= opcode
->inst_offset_type
;
939 output
= frag_var (rs_machine_dependent
,
940 isize
* 2, /* maxm of 2 words. */
941 isize
, /* minm of 1 word. */
942 subtype
, /* PC-relative or not. */
950 output
= frag_more (isize
);
951 immed
= exp
.X_add_number
;
954 if (streq (name
, "lmi") || streq (name
, "smi"))
956 /* Load/store 32-d consecutive registers. Used on exit/entry
957 to subroutines to save and restore registers to stack.
958 Generate 32-d insts. */
962 if (streq (name
, "lmi"))
963 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "lwi");
965 opcode
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "swi");
968 as_bad (_("unknown opcode \"%s\""), "lwi");
971 inst
= opcode
->bit_sequence
;
972 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
973 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
974 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
976 for (i
= 0; i
< count
- 1; i
++)
978 output
[0] = INST_BYTE0 (inst
);
979 output
[1] = INST_BYTE1 (inst
);
980 output
[2] = INST_BYTE2 (inst
);
981 output
[3] = INST_BYTE3 (inst
);
982 output
= frag_more (isize
);
985 inst
= opcode
->bit_sequence
;
986 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
987 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
988 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
993 temp
= immed
& 0xFFFF8000;
994 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
996 /* Needs an immediate inst. */
997 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1000 as_bad (_("unknown opcode \"%s\""), "imm");
1004 inst1
= opcode1
->bit_sequence
;
1005 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1006 output
[0] = INST_BYTE0 (inst1
);
1007 output
[1] = INST_BYTE1 (inst1
);
1008 output
[2] = INST_BYTE2 (inst1
);
1009 output
[3] = INST_BYTE3 (inst1
);
1010 output
= frag_more (isize
);
1012 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1013 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1014 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1018 case INST_TYPE_RD_R1_IMM5
:
1019 if (strcmp (op_end
, ""))
1020 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1023 as_fatal (_("Error in statement syntax"));
1026 if (strcmp (op_end
, ""))
1027 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1030 as_fatal (_("Error in statement syntax"));
1033 if (strcmp (op_end
, ""))
1034 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1036 as_fatal (_("Error in statement syntax"));
1038 /* Check for spl registers. */
1039 if (check_spl_reg (®1
))
1040 as_fatal (_("Cannot use special register with this instruction"));
1041 if (check_spl_reg (®2
))
1042 as_fatal (_("Cannot use special register with this instruction"));
1044 if (exp
.X_op
!= O_constant
)
1045 as_warn (_("Symbol used as immediate for shift instruction"));
1048 output
= frag_more (isize
);
1049 immed
= exp
.X_add_number
;
1052 if (immed
!= (immed
% 32))
1054 as_warn (_("Shift value > 32. using <value %% 32>"));
1057 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1058 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1059 inst
|= (immed
<< IMM_LOW
) & IMM5_MASK
;
1062 case INST_TYPE_R1_R2
:
1063 if (strcmp (op_end
, ""))
1064 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1067 as_fatal (_("Error in statement syntax"));
1070 if (strcmp (op_end
, ""))
1071 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1074 as_fatal (_("Error in statement syntax"));
1078 /* Check for spl registers. */
1079 if (check_spl_reg (& reg1
))
1080 as_fatal (_("Cannot use special register with this instruction"));
1081 if (check_spl_reg (& reg2
))
1082 as_fatal (_("Cannot use special register with this instruction"));
1084 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1085 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1086 output
= frag_more (isize
);
1089 case INST_TYPE_RD_R1
:
1090 if (strcmp (op_end
, ""))
1091 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1094 as_fatal (_("Error in statement syntax"));
1097 if (strcmp (op_end
, ""))
1098 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1101 as_fatal (_("Error in statement syntax"));
1105 /* Check for spl registers. */
1106 if (check_spl_reg (®1
))
1107 as_fatal (_("Cannot use special register with this instruction"));
1108 if (check_spl_reg (®2
))
1109 as_fatal (_("Cannot use special register with this instruction"));
1111 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1112 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1113 output
= frag_more (isize
);
1116 case INST_TYPE_RD_RFSL
:
1117 if (strcmp (op_end
, ""))
1118 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1121 as_fatal (_("Error in statement syntax"));
1124 if (strcmp (op_end
, ""))
1125 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1128 as_fatal (_("Error in statement syntax"));
1132 /* Check for spl registers. */
1133 if (check_spl_reg (®1
))
1134 as_fatal (_("Cannot use special register with this instruction"));
1136 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1137 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1138 output
= frag_more (isize
);
1141 case INST_TYPE_RD_IMM15
:
1142 if (strcmp (op_end
, ""))
1143 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1146 as_fatal (_("Error in statement syntax"));
1150 if (strcmp (op_end
, ""))
1151 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM15
, MAX_IMM15
);
1153 as_fatal (_("Error in statement syntax"));
1155 /* Check for spl registers. */
1156 if (check_spl_reg (®1
))
1157 as_fatal (_("Cannot use special register with this instruction"));
1159 if (exp
.X_op
!= O_constant
)
1160 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1163 output
= frag_more (isize
);
1164 immed
= exp
.X_add_number
;
1166 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1167 inst
|= (immed
<< IMM_LOW
) & IMM15_MASK
;
1170 case INST_TYPE_R1_RFSL
:
1171 if (strcmp (op_end
, ""))
1172 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1175 as_fatal (_("Error in statement syntax"));
1178 if (strcmp (op_end
, ""))
1179 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1182 as_fatal (_("Error in statement syntax"));
1186 /* Check for spl registers. */
1187 if (check_spl_reg (®1
))
1188 as_fatal (_("Cannot use special register with this instruction"));
1190 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1191 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1192 output
= frag_more (isize
);
1195 case INST_TYPE_RFSL
:
1196 if (strcmp (op_end
, ""))
1197 op_end
= parse_reg (op_end
+ 1, &immed
); /* Get rfslN. */
1200 as_fatal (_("Error in statement syntax"));
1203 /* Check for spl registers. */
1204 if (check_spl_reg (®1
))
1205 as_fatal (_("Cannot use special register with this instruction"));
1206 inst
|= (immed
<< IMM_LOW
) & RFSL_MASK
;
1207 output
= frag_more (isize
);
1211 if (strcmp (op_end
, ""))
1212 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1215 as_fatal (_("Error in statement syntax"));
1219 /* Check for spl registers. */
1220 if (check_spl_reg (®1
))
1221 as_fatal (_("Cannot use special register with this instruction"));
1223 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1224 output
= frag_more (isize
);
1227 /* For tuqula insn...:) */
1229 if (strcmp (op_end
, ""))
1230 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1233 as_fatal (_("Error in statement syntax"));
1237 /* Check for spl registers. */
1238 if (check_spl_reg (®1
))
1239 as_fatal (_("Cannot use special register with this instruction"));
1241 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1242 output
= frag_more (isize
);
1245 case INST_TYPE_RD_SPECIAL
:
1246 if (strcmp (op_end
, ""))
1247 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1250 as_fatal (_("Error in statement syntax"));
1253 if (strcmp (op_end
, ""))
1254 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1257 as_fatal (_("Error in statement syntax"));
1261 if (reg2
== REG_MSR
)
1262 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1263 else if (reg2
== REG_PC
)
1264 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1265 else if (reg2
== REG_EAR
)
1266 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1267 else if (reg2
== REG_ESR
)
1268 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1269 else if (reg2
== REG_FSR
)
1270 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1271 else if (reg2
== REG_BTR
)
1272 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1273 else if (reg2
== REG_EDR
)
1274 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1275 else if (reg2
== REG_PID
)
1276 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1277 else if (reg2
== REG_ZPR
)
1278 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1279 else if (reg2
== REG_TLBX
)
1280 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1281 else if (reg2
== REG_TLBLO
)
1282 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1283 else if (reg2
== REG_TLBHI
)
1284 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1285 else if (reg2
>= (REG_PVR
+MIN_PVR_REGNUM
) && reg2
<= (REG_PVR
+MAX_PVR_REGNUM
))
1286 immed
= opcode
->immval_mask
| REG_PVR_MASK
| reg2
;
1288 as_fatal (_("invalid value for special purpose register"));
1289 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1290 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1291 output
= frag_more (isize
);
1294 case INST_TYPE_SPECIAL_R1
:
1295 if (strcmp (op_end
, ""))
1296 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1299 as_fatal (_("Error in statement syntax"));
1302 if (strcmp (op_end
, ""))
1303 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1306 as_fatal (_("Error in statement syntax"));
1310 if (reg1
== REG_MSR
)
1311 immed
= opcode
->immval_mask
| REG_MSR_MASK
;
1312 else if (reg1
== REG_PC
)
1313 immed
= opcode
->immval_mask
| REG_PC_MASK
;
1314 else if (reg1
== REG_EAR
)
1315 immed
= opcode
->immval_mask
| REG_EAR_MASK
;
1316 else if (reg1
== REG_ESR
)
1317 immed
= opcode
->immval_mask
| REG_ESR_MASK
;
1318 else if (reg1
== REG_FSR
)
1319 immed
= opcode
->immval_mask
| REG_FSR_MASK
;
1320 else if (reg1
== REG_BTR
)
1321 immed
= opcode
->immval_mask
| REG_BTR_MASK
;
1322 else if (reg1
== REG_EDR
)
1323 immed
= opcode
->immval_mask
| REG_EDR_MASK
;
1324 else if (reg1
== REG_PID
)
1325 immed
= opcode
->immval_mask
| REG_PID_MASK
;
1326 else if (reg1
== REG_ZPR
)
1327 immed
= opcode
->immval_mask
| REG_ZPR_MASK
;
1328 else if (reg1
== REG_TLBX
)
1329 immed
= opcode
->immval_mask
| REG_TLBX_MASK
;
1330 else if (reg1
== REG_TLBLO
)
1331 immed
= opcode
->immval_mask
| REG_TLBLO_MASK
;
1332 else if (reg1
== REG_TLBHI
)
1333 immed
= opcode
->immval_mask
| REG_TLBHI_MASK
;
1334 else if (reg1
== REG_TLBSX
)
1335 immed
= opcode
->immval_mask
| REG_TLBSX_MASK
;
1337 as_fatal (_("invalid value for special purpose register"));
1338 inst
|= (reg2
<< RA_LOW
) & RA_MASK
;
1339 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1340 output
= frag_more (isize
);
1343 case INST_TYPE_RD_R1_SPECIAL
:
1344 if (strcmp (op_end
, ""))
1345 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1348 as_fatal (_("Error in statement syntax"));
1351 if (strcmp (op_end
, ""))
1352 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r1. */
1355 as_fatal (_("Error in statement syntax"));
1359 /* Check for spl registers. */
1360 if (check_spl_reg (®1
))
1361 as_fatal (_("Cannot use special register with this instruction"));
1362 if (check_spl_reg (®2
))
1363 as_fatal (_("Cannot use special register with this instruction"));
1365 /* insn wic ra, rb => wic ra, ra, rb. */
1366 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1367 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1368 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1370 output
= frag_more (isize
);
1373 case INST_TYPE_RD_R2
:
1374 if (strcmp (op_end
, ""))
1375 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1378 as_fatal (_("Error in statement syntax"));
1381 if (strcmp (op_end
, ""))
1382 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1385 as_fatal (_("Error in statement syntax"));
1389 /* Check for spl registers. */
1390 if (check_spl_reg (®1
))
1391 as_fatal (_("Cannot use special register with this instruction"));
1392 if (check_spl_reg (®2
))
1393 as_fatal (_("Cannot use special register with this instruction"));
1395 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1396 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1397 output
= frag_more (isize
);
1400 case INST_TYPE_R1_IMM
:
1401 if (strcmp (op_end
, ""))
1402 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get r1. */
1405 as_fatal (_("Error in statement syntax"));
1408 if (strcmp (op_end
, ""))
1409 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1411 as_fatal (_("Error in statement syntax"));
1413 /* Check for spl registers. */
1414 if (check_spl_reg (®1
))
1415 as_fatal (_("Cannot use special register with this instruction"));
1417 if (exp
.X_op
!= O_constant
)
1420 relax_substateT subtype
;
1422 if (exp
.X_md
== IMM_GOT
)
1423 subtype
= GOT_OFFSET
;
1424 else if (exp
.X_md
== IMM_PLT
)
1425 subtype
= PLT_OFFSET
;
1427 subtype
= opcode
->inst_offset_type
;
1428 output
= frag_var (rs_machine_dependent
,
1429 isize
* 2, /* maxm of 2 words. */
1430 isize
, /* minm of 1 word. */
1431 subtype
, /* PC-relative or not. */
1439 output
= frag_more (isize
);
1440 immed
= exp
.X_add_number
;
1443 temp
= immed
& 0xFFFF8000;
1444 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1446 /* Needs an immediate inst. */
1447 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1448 if (opcode1
== NULL
)
1450 as_bad (_("unknown opcode \"%s\""), "imm");
1454 inst1
= opcode1
->bit_sequence
;
1455 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1456 output
[0] = INST_BYTE0 (inst1
);
1457 output
[1] = INST_BYTE1 (inst1
);
1458 output
[2] = INST_BYTE2 (inst1
);
1459 output
[3] = INST_BYTE3 (inst1
);
1460 output
= frag_more (isize
);
1463 inst
|= (reg1
<< RA_LOW
) & RA_MASK
;
1464 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1467 case INST_TYPE_RD_IMM
:
1468 if (strcmp (op_end
, ""))
1469 op_end
= parse_reg (op_end
+ 1, ®1
); /* Get rd. */
1472 as_fatal (_("Error in statement syntax"));
1475 if (strcmp (op_end
, ""))
1476 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1478 as_fatal (_("Error in statement syntax"));
1480 /* Check for spl registers. */
1481 if (check_spl_reg (®1
))
1482 as_fatal (_("Cannot use special register with this instruction"));
1484 if (exp
.X_op
!= O_constant
)
1487 relax_substateT subtype
;
1489 if (exp
.X_md
== IMM_GOT
)
1490 subtype
= GOT_OFFSET
;
1491 else if (exp
.X_md
== IMM_PLT
)
1492 subtype
= PLT_OFFSET
;
1494 subtype
= opcode
->inst_offset_type
;
1495 output
= frag_var (rs_machine_dependent
,
1496 isize
* 2, /* maxm of 2 words. */
1497 isize
, /* minm of 1 word. */
1498 subtype
, /* PC-relative or not. */
1506 output
= frag_more (isize
);
1507 immed
= exp
.X_add_number
;
1510 temp
= immed
& 0xFFFF8000;
1511 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1513 /* Needs an immediate inst. */
1514 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1515 if (opcode1
== NULL
)
1517 as_bad (_("unknown opcode \"%s\""), "imm");
1521 inst1
= opcode1
->bit_sequence
;
1522 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1523 output
[0] = INST_BYTE0 (inst1
);
1524 output
[1] = INST_BYTE1 (inst1
);
1525 output
[2] = INST_BYTE2 (inst1
);
1526 output
[3] = INST_BYTE3 (inst1
);
1527 output
= frag_more (isize
);
1530 inst
|= (reg1
<< RD_LOW
) & RD_MASK
;
1531 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1535 if (strcmp (op_end
, ""))
1536 op_end
= parse_reg (op_end
+ 1, ®2
); /* Get r2. */
1539 as_fatal (_("Error in statement syntax"));
1543 /* Check for spl registers. */
1544 if (check_spl_reg (®2
))
1545 as_fatal (_("Cannot use special register with this instruction"));
1547 inst
|= (reg2
<< RB_LOW
) & RB_MASK
;
1548 output
= frag_more (isize
);
1552 if (streq (name
, "imm"))
1553 as_fatal (_("An IMM instruction should not be present in the .s file"));
1555 op_end
= parse_imm (op_end
+ 1, & exp
, MIN_IMM
, MAX_IMM
);
1557 if (exp
.X_op
!= O_constant
)
1560 relax_substateT subtype
;
1562 if (exp
.X_md
== IMM_GOT
)
1563 subtype
= GOT_OFFSET
;
1564 else if (exp
.X_md
== IMM_PLT
)
1565 subtype
= PLT_OFFSET
;
1567 subtype
= opcode
->inst_offset_type
;
1568 output
= frag_var (rs_machine_dependent
,
1569 isize
* 2, /* maxm of 2 words. */
1570 isize
, /* minm of 1 word. */
1571 subtype
, /* PC-relative or not. */
1579 output
= frag_more (isize
);
1580 immed
= exp
.X_add_number
;
1584 temp
= immed
& 0xFFFF8000;
1585 if ((temp
!= 0) && (temp
!= 0xFFFF8000))
1587 /* Needs an immediate inst. */
1588 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1589 if (opcode1
== NULL
)
1591 as_bad (_("unknown opcode \"%s\""), "imm");
1595 inst1
= opcode1
->bit_sequence
;
1596 inst1
|= ((immed
& 0xFFFF0000) >> 16) & IMM_MASK
;
1597 output
[0] = INST_BYTE0 (inst1
);
1598 output
[1] = INST_BYTE1 (inst1
);
1599 output
[2] = INST_BYTE2 (inst1
);
1600 output
[3] = INST_BYTE3 (inst1
);
1601 output
= frag_more (isize
);
1603 inst
|= (immed
<< IMM_LOW
) & IMM_MASK
;
1606 case INST_TYPE_NONE
:
1607 output
= frag_more (isize
);
1611 as_fatal (_("unimplemented opcode \"%s\""), name
);
1614 /* Drop whitespace after all the operands have been parsed. */
1615 while (ISSPACE (* op_end
))
1618 /* Give warning message if the insn has more operands than required. */
1619 if (strcmp (op_end
, opcode
->name
) && strcmp (op_end
, ""))
1620 as_warn (_("ignoring operands: %s "), op_end
);
1622 output
[0] = INST_BYTE0 (inst
);
1623 output
[1] = INST_BYTE1 (inst
);
1624 output
[2] = INST_BYTE2 (inst
);
1625 output
[3] = INST_BYTE3 (inst
);
1628 dwarf2_emit_insn (4);
1633 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
1638 /* Various routines to kill one day. */
1639 /* Equal to MAX_PRECISION in atof-ieee.c */
1640 #define MAX_LITTLENUMS 6
1642 /* Turn a string in input_line_pointer into a floating point constant of type
1643 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1644 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1646 md_atof (int type
, char * litP
, int * sizeP
)
1649 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1681 return _("Bad call to MD_NTOF()");
1684 t
= atof_ieee (input_line_pointer
, type
, words
);
1687 input_line_pointer
= t
;
1689 *sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1691 if (! target_big_endian
)
1693 for (i
= prec
- 1; i
>= 0; i
--)
1695 md_number_to_chars (litP
, (valueT
) words
[i
],
1696 sizeof (LITTLENUM_TYPE
));
1697 litP
+= sizeof (LITTLENUM_TYPE
);
1701 for (i
= 0; i
< prec
; i
++)
1703 md_number_to_chars (litP
, (valueT
) words
[i
],
1704 sizeof (LITTLENUM_TYPE
));
1705 litP
+= sizeof (LITTLENUM_TYPE
);
1711 const char * md_shortopts
= "";
1713 struct option md_longopts
[] =
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; */
1803 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1807 fix_new (fragP
, fragP
->fr_fix
, INST_WORD_SIZE
* 2, fragP
->fr_symbol
,
1808 fragP
->fr_offset
, FALSE
, BFD_RELOC_MICROBLAZE_64_GOTOFF
);
1809 fragP
->fr_fix
+= INST_WORD_SIZE
* 2;
1818 /* Applies the desired value to the specified location.
1819 Also sets up addends for 'rela' type relocations. */
1821 md_apply_fix (fixS
* fixP
,
1825 char * buf
= fixP
->fx_where
+ fixP
->fx_frag
->fr_literal
;
1826 char * file
= fixP
->fx_file
? fixP
->fx_file
: _("unknown");
1827 const char * symname
;
1828 /* Note: use offsetT because it is signed, valueT is unsigned. */
1829 offsetT val
= (offsetT
) * valp
;
1831 struct op_code_struct
* opcode1
;
1832 unsigned long inst1
;
1834 symname
= fixP
->fx_addsy
? S_GET_NAME (fixP
->fx_addsy
) : _("<unknown>");
1836 /* fixP->fx_offset is supposed to be set up correctly for all
1837 symbol relocations. */
1838 if (fixP
->fx_addsy
== NULL
)
1840 if (!fixP
->fx_pcrel
)
1841 fixP
->fx_offset
= val
; /* Absolute relocation. */
1843 fprintf (stderr
, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1844 (unsigned int) fixP
->fx_offset
, (unsigned int) val
);
1847 /* If we aren't adjusting this fixup to be against the section
1848 symbol, we need to adjust the value. */
1849 if (fixP
->fx_addsy
!= NULL
)
1851 if (S_IS_WEAK (fixP
->fx_addsy
)
1852 || (symbol_used_in_reloc_p (fixP
->fx_addsy
)
1853 && (((bfd_get_section_flags (stdoutput
,
1854 S_GET_SEGMENT (fixP
->fx_addsy
))
1855 & SEC_LINK_ONCE
) != 0)
1856 || !strncmp (segment_name (S_GET_SEGMENT (fixP
->fx_addsy
)),
1858 sizeof (".gnu.linkonce") - 1))))
1860 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1861 if (val
!= 0 && ! fixP
->fx_pcrel
)
1863 /* In this case, the bfd_install_relocation routine will
1864 incorrectly add the symbol value back in. We just want
1865 the addend to appear in the object file.
1866 FIXME: If this makes VALUE zero, we're toast. */
1867 val
-= S_GET_VALUE (fixP
->fx_addsy
);
1872 /* If the fix is relative to a symbol which is not defined, or not
1873 in the same segment as the fix, we cannot resolve it here. */
1874 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1875 if (fixP
->fx_addsy
!= NULL
1876 && (!S_IS_DEFINED (fixP
->fx_addsy
)
1877 || (S_GET_SEGMENT (fixP
->fx_addsy
) != segment
)))
1881 /* For ELF we can just return and let the reloc that will be generated
1882 take care of everything. For COFF we still have to insert 'val'
1883 into the insn since the addend field will be ignored. */
1887 /* All fixups in the text section must be handled in the linker. */
1888 else if (segment
->flags
& SEC_CODE
)
1890 else if (!fixP
->fx_pcrel
&& fixP
->fx_addsy
!= NULL
)
1895 switch (fixP
->fx_r_type
)
1897 case BFD_RELOC_MICROBLAZE_32_LO
:
1898 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
1899 if (target_big_endian
)
1901 buf
[2] |= ((val
>> 8) & 0xff);
1902 buf
[3] |= (val
& 0xff);
1906 buf
[1] |= ((val
>> 8) & 0xff);
1907 buf
[0] |= (val
& 0xff);
1910 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
1911 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
1912 /* Don't do anything if the symbol is not defined. */
1913 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1915 if (((val
& 0xFFFF8000) != 0) && ((val
& 0xFFFF8000) != 0xFFFF8000))
1916 as_bad_where (file
, fixP
->fx_line
,
1917 _("pcrel for branch to %s too far (0x%x)"),
1918 symname
, (int) val
);
1919 if (target_big_endian
)
1921 buf
[2] |= ((val
>> 8) & 0xff);
1922 buf
[3] |= (val
& 0xff);
1926 buf
[1] |= ((val
>> 8) & 0xff);
1927 buf
[0] |= (val
& 0xff);
1933 case BFD_RELOC_32_PCREL
:
1934 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
1935 /* Don't do anything if the symbol is not defined. */
1936 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1938 if (target_big_endian
)
1940 buf
[0] |= ((val
>> 24) & 0xff);
1941 buf
[1] |= ((val
>> 16) & 0xff);
1942 buf
[2] |= ((val
>> 8) & 0xff);
1943 buf
[3] |= (val
& 0xff);
1947 buf
[3] |= ((val
>> 24) & 0xff);
1948 buf
[2] |= ((val
>> 16) & 0xff);
1949 buf
[1] |= ((val
>> 8) & 0xff);
1950 buf
[0] |= (val
& 0xff);
1954 case BFD_RELOC_64_PCREL
:
1956 /* Add an imm instruction. First save the current instruction. */
1957 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
1958 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
1960 /* Generate the imm instruction. */
1961 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
1962 if (opcode1
== NULL
)
1964 as_bad (_("unknown opcode \"%s\""), "imm");
1968 inst1
= opcode1
->bit_sequence
;
1969 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1970 inst1
|= ((val
& 0xFFFF0000) >> 16) & IMM_MASK
;
1972 buf
[0] = INST_BYTE0 (inst1
);
1973 buf
[1] = INST_BYTE1 (inst1
);
1974 buf
[2] = INST_BYTE2 (inst1
);
1975 buf
[3] = INST_BYTE3 (inst1
);
1977 /* Add the value only if the symbol is defined. */
1978 if (fixP
->fx_addsy
== NULL
|| S_IS_DEFINED (fixP
->fx_addsy
))
1980 if (target_big_endian
)
1982 buf
[6] |= ((val
>> 8) & 0xff);
1983 buf
[7] |= (val
& 0xff);
1987 buf
[5] |= ((val
>> 8) & 0xff);
1988 buf
[4] |= (val
& 0xff);
1993 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
1994 case BFD_RELOC_MICROBLAZE_64_GOT
:
1995 case BFD_RELOC_MICROBLAZE_64_PLT
:
1996 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
1997 /* Add an imm instruction. First save the current instruction. */
1998 for (i
= 0; i
< INST_WORD_SIZE
; i
++)
1999 buf
[i
+ INST_WORD_SIZE
] = buf
[i
];
2001 /* Generate the imm instruction. */
2002 opcode1
= (struct op_code_struct
*) hash_find (opcode_hash_control
, "imm");
2003 if (opcode1
== NULL
)
2005 as_bad (_("unknown opcode \"%s\""), "imm");
2009 inst1
= opcode1
->bit_sequence
;
2011 /* We can fixup call to a defined non-global address
2012 within the same section only. */
2013 buf
[0] = INST_BYTE0 (inst1
);
2014 buf
[1] = INST_BYTE1 (inst1
);
2015 buf
[2] = INST_BYTE2 (inst1
);
2016 buf
[3] = INST_BYTE3 (inst1
);
2023 if (fixP
->fx_addsy
== NULL
)
2025 /* This fixup has been resolved. Create a reloc in case the linker
2026 moves code around due to relaxing. */
2027 if (fixP
->fx_r_type
== BFD_RELOC_64_PCREL
)
2028 fixP
->fx_r_type
= BFD_RELOC_MICROBLAZE_64_NONE
;
2030 fixP
->fx_r_type
= BFD_RELOC_NONE
;
2031 fixP
->fx_addsy
= section_symbol (absolute_section
);
2037 md_operand (expressionS
* expressionP
)
2039 /* Ignore leading hash symbol, if present. */
2040 if (*input_line_pointer
== '#')
2042 input_line_pointer
++;
2043 expression (expressionP
);
2047 /* Called just before address relaxation, return the length
2048 by which a fragment must grow to reach it's destination. */
2051 md_estimate_size_before_relax (fragS
* fragP
,
2054 sbss_segment
= bfd_get_section_by_name (stdoutput
, ".sbss");
2055 sbss2_segment
= bfd_get_section_by_name (stdoutput
, ".sbss2");
2056 sdata_segment
= bfd_get_section_by_name (stdoutput
, ".sdata");
2057 sdata2_segment
= bfd_get_section_by_name (stdoutput
, ".sdata2");
2059 switch (fragP
->fr_subtype
)
2061 case INST_PC_OFFSET
:
2062 /* Used to be a PC-relative branch. */
2063 if (!fragP
->fr_symbol
)
2065 /* We know the abs value: Should never happen. */
2066 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2069 else if ((S_GET_SEGMENT (fragP
->fr_symbol
) == segment_type
))
2071 fragP
->fr_subtype
= DEFINED_PC_OFFSET
;
2072 /* Don't know now whether we need an imm instruction. */
2073 fragP
->fr_var
= INST_WORD_SIZE
;
2075 else if (S_IS_DEFINED (fragP
->fr_symbol
)
2076 && (((S_GET_SEGMENT (fragP
->fr_symbol
))->flags
& SEC_CODE
) == 0))
2078 /* Cannot have a PC-relative branch to a diff segment. */
2079 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2080 S_GET_NAME (fragP
->fr_symbol
));
2081 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2082 fragP
->fr_var
= INST_WORD_SIZE
*2;
2086 fragP
->fr_subtype
= UNDEFINED_PC_OFFSET
;
2087 fragP
->fr_var
= INST_WORD_SIZE
*2;
2091 case INST_NO_OFFSET
:
2092 /* Used to be a reference to somewhere which was unknown. */
2093 if (fragP
->fr_symbol
)
2095 if (fragP
->fr_opcode
== NULL
)
2097 /* Used as an absolute value. */
2098 fragP
->fr_subtype
= DEFINED_ABS_SEGMENT
;
2099 /* Variable part does not change. */
2100 fragP
->fr_var
= INST_WORD_SIZE
*2;
2102 else if (streq (fragP
->fr_opcode
, str_microblaze_ro_anchor
))
2104 /* It is accessed using the small data read only anchor. */
2105 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == &bfd_com_section
)
2106 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata2_segment
)
2107 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss2_segment
)
2108 || (! S_IS_DEFINED (fragP
->fr_symbol
)))
2110 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2111 fragP
->fr_var
= INST_WORD_SIZE
;
2115 /* Variable not in small data read only segment accessed
2116 using small data read only anchor. */
2117 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2119 as_bad_where (file
, fragP
->fr_line
,
2120 _("Variable is accessed using small data read "
2121 "only anchor, but it is not in the small data "
2122 "read only section"));
2123 fragP
->fr_subtype
= DEFINED_RO_SEGMENT
;
2124 fragP
->fr_var
= INST_WORD_SIZE
;
2127 else if (streq (fragP
->fr_opcode
, str_microblaze_rw_anchor
))
2129 if ((S_GET_SEGMENT (fragP
->fr_symbol
) == &bfd_com_section
)
2130 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sdata_segment
)
2131 || (S_GET_SEGMENT (fragP
->fr_symbol
) == sbss_segment
)
2132 || (!S_IS_DEFINED (fragP
->fr_symbol
)))
2134 /* It is accessed using the small data read write anchor. */
2135 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2136 fragP
->fr_var
= INST_WORD_SIZE
;
2140 char *file
= fragP
->fr_file
? fragP
->fr_file
: _("unknown");
2142 as_bad_where (file
, fragP
->fr_line
,
2143 _("Variable is accessed using small data read "
2144 "write anchor, but it is not in the small data "
2145 "read write section"));
2146 fragP
->fr_subtype
= DEFINED_RW_SEGMENT
;
2147 fragP
->fr_var
= INST_WORD_SIZE
;
2152 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2158 /* We know the abs value: Should never happen. */
2159 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2164 case UNDEFINED_PC_OFFSET
:
2165 case LARGE_DEFINED_PC_OFFSET
:
2166 case DEFINED_ABS_SEGMENT
:
2170 fragP
->fr_var
= INST_WORD_SIZE
*2;
2172 case DEFINED_RO_SEGMENT
:
2173 case DEFINED_RW_SEGMENT
:
2174 case DEFINED_PC_OFFSET
:
2175 fragP
->fr_var
= INST_WORD_SIZE
;
2181 return fragP
->fr_var
;
2184 /* Put number into target byte order. */
2187 md_number_to_chars (char * ptr
, valueT use
, int nbytes
)
2189 if (target_big_endian
)
2190 number_to_chars_bigendian (ptr
, use
, nbytes
);
2192 number_to_chars_littleendian (ptr
, use
, nbytes
);
2195 /* Round up a section size to the appropriate boundary. */
2198 md_section_align (segT segment ATTRIBUTE_UNUSED
, valueT size
)
2200 return size
; /* Byte alignment is fine. */
2204 /* The location from which a PC relative jump should be calculated,
2205 given a PC relative reloc. */
2208 md_pcrel_from_section (fixS
* fixp
, segT sec ATTRIBUTE_UNUSED
)
2211 /* If the symbol is undefined or defined in another section
2212 we leave the add number alone for the linker to fix it later.
2213 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2215 if (fixp
->fx_addsy
!= (symbolS
*) NULL
2216 && (!S_IS_DEFINED (fixp
->fx_addsy
)
2217 || (S_GET_SEGMENT (fixp
->fx_addsy
) != sec
)))
2221 /* The case where we are going to resolve things... */
2222 if (fixp
->fx_r_type
== BFD_RELOC_64_PCREL
)
2223 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
+ INST_WORD_SIZE
;
2225 return fixp
->fx_where
+ fixp
->fx_frag
->fr_address
;
2231 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2232 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2235 tc_gen_reloc (asection
* section ATTRIBUTE_UNUSED
, fixS
* fixp
)
2238 bfd_reloc_code_real_type code
;
2240 switch (fixp
->fx_r_type
)
2242 case BFD_RELOC_NONE
:
2243 case BFD_RELOC_MICROBLAZE_64_NONE
:
2245 case BFD_RELOC_MICROBLAZE_32_LO
:
2246 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
2249 case BFD_RELOC_64_PCREL
:
2250 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
2251 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
2252 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
2253 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
2254 case BFD_RELOC_MICROBLAZE_64_GOT
:
2255 case BFD_RELOC_MICROBLAZE_64_PLT
:
2256 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
2257 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
2258 code
= fixp
->fx_r_type
;
2262 switch (F (fixp
->fx_size
, fixp
->fx_pcrel
))
2264 MAP (1, 0, BFD_RELOC_8
);
2265 MAP (2, 0, BFD_RELOC_16
);
2266 MAP (4, 0, BFD_RELOC_32
);
2267 MAP (1, 1, BFD_RELOC_8_PCREL
);
2268 MAP (2, 1, BFD_RELOC_16_PCREL
);
2269 MAP (4, 1, BFD_RELOC_32_PCREL
);
2271 code
= fixp
->fx_r_type
;
2272 as_bad (_("Can not do %d byte %srelocation"),
2274 fixp
->fx_pcrel
? _("pc-relative") : "");
2279 rel
= (arelent
*) xmalloc (sizeof (arelent
));
2280 rel
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2282 if (code
== BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
)
2283 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_subsy
);
2285 *rel
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2287 rel
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2288 /* Always pass the addend along! */
2289 rel
->addend
= fixp
->fx_offset
;
2290 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, code
);
2292 if (rel
->howto
== NULL
)
2294 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2295 _("Cannot represent relocation type %s"),
2296 bfd_get_reloc_code_name (code
));
2298 /* Set howto to a garbage value so that we can keep going. */
2299 rel
->howto
= bfd_reloc_type_lookup (stdoutput
, BFD_RELOC_32
);
2300 gas_assert (rel
->howto
!= NULL
);
2306 md_parse_option (int c
, char * arg ATTRIBUTE_UNUSED
)
2317 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
2319 /* fprintf(stream, _("\
2320 MicroBlaze options:\n\
2321 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2325 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2326 found a machine specific op in an expression,
2327 then we create relocs accordingly. */
2330 cons_fix_new_microblaze (fragS
* frag
,
2336 bfd_reloc_code_real_type r
;
2338 if ((exp
->X_op
== O_subtract
) && (exp
->X_add_symbol
) &&
2339 (exp
->X_op_symbol
) && (now_seg
!= absolute_section
) && (size
== 4)
2340 && (!S_IS_LOCAL (exp
->X_op_symbol
)))
2341 r
= BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
;
2342 else if (exp
->X_md
== IMM_GOTOFF
&& exp
->X_op
== O_symbol_rva
)
2344 exp
->X_op
= O_symbol
;
2345 r
= BFD_RELOC_MICROBLAZE_32_GOTOFF
;
2364 as_bad (_("unsupported BFD relocation size %u"), size
);
2369 fix_new_exp (frag
, where
, size
, exp
, 0, r
);