PR gas/12848
[binutils.git] / gas / config / tc-microblaze.c
blob7c6357e8e88007a0e71c31d35573b3588a2086df
1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
3 Copyright 2009, 2010 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)
10 any later version.
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
20 02110-1301, USA. */
22 #include <stdio.h>
23 #include "as.h"
24 #include "bfd.h"
25 #include "subsegs.h"
26 #define DEFINE_TABLE
27 #include "../opcodes/microblaze-opc.h"
28 #include "../opcodes/microblaze-opcm.h"
29 #include "safe-ctype.h"
30 #include <string.h>
31 #include <dwarf2dbg.h>
32 #include "aout/stab_gnu.h"
34 #ifndef streq
35 #define streq(a,b) (strcmp (a, b) == 0)
36 #endif
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
57 a line. */
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
67 As in 0f12.456
68 or 0d1.2345e12. */
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
78 #define GOT_OFFSET 8
79 #define PLT_OFFSET 9
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. */
109 void
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. */
120 static void
121 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
123 #ifdef OBJ_ELF
124 obj_elf_text (ignore);
125 #else
126 s_text (ignore);
127 #endif
130 static void
131 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
133 #ifdef OBJ_ELF
134 obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
135 #else
136 s_data (ignore);
137 #endif
140 /* Things in the .sdata segment are always considered to be in the small data section. */
142 static void
143 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
145 #ifdef OBJ_ELF
146 obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
147 #else
148 s_data (ignore);
149 #endif
152 /* Pseudo op to make file scope bss items. */
154 static void
155 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
157 char *name;
158 char c;
159 char *p;
160 offsetT size;
161 symbolS *symbolP;
162 offsetT align;
163 char *pfrag;
164 int align2;
165 segT current_seg = now_seg;
166 subsegT current_subseg = now_subseg;
168 name = input_line_pointer;
169 c = get_symbol_end ();
171 /* Just after name is now '\0'. */
172 p = input_line_pointer;
173 *p = c;
174 SKIP_WHITESPACE ();
175 if (*input_line_pointer != ',')
177 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
178 ignore_rest_of_line ();
179 return;
182 input_line_pointer++; /* skip ',' */
183 if ((size = get_absolute_expression ()) < 0)
185 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
186 ignore_rest_of_line ();
187 return;
190 /* The third argument to .lcomm is the alignment. */
191 if (*input_line_pointer != ',')
192 align = 8;
193 else
195 ++input_line_pointer;
196 align = get_absolute_expression ();
197 if (align <= 0)
199 as_warn (_("ignoring bad alignment"));
200 align = 8;
204 *p = 0;
205 symbolP = symbol_find_or_make (name);
206 *p = c;
208 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
210 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
211 S_GET_NAME (symbolP));
212 ignore_rest_of_line ();
213 return;
216 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
218 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
219 S_GET_NAME (symbolP),
220 (long) S_GET_VALUE (symbolP),
221 (long) size);
223 ignore_rest_of_line ();
224 return;
227 /* Allocate_bss. */
228 if (align)
230 /* Convert to a power of 2 alignment. */
231 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
232 if (align != 1)
234 as_bad (_("Common alignment not a power of 2"));
235 ignore_rest_of_line ();
236 return;
239 else
240 align2 = 0;
242 record_alignment (current_seg, align2);
243 subseg_set (current_seg, current_subseg);
244 if (align2)
245 frag_align (align2, 0, 0);
246 if (S_GET_SEGMENT (symbolP) == current_seg)
247 symbol_get_frag (symbolP)->fr_symbol = 0;
248 symbol_set_frag (symbolP, frag_now);
249 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
250 (char *) 0);
251 *pfrag = 0;
252 S_SET_SIZE (symbolP, size);
253 S_SET_SEGMENT (symbolP, current_seg);
254 subseg_set (current_seg, current_subseg);
255 demand_empty_rest_of_line ();
258 static void
259 microblaze_s_rdata (int localvar)
261 #ifdef OBJ_ELF
262 if (localvar == 0)
264 /* rodata. */
265 obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
266 if (rodata_segment == 0)
267 rodata_segment = subseg_new (".rodata", 0);
269 else
271 /* 1 .sdata2. */
272 obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
274 #else
275 s_data (ignore);
276 #endif
279 static void
280 microblaze_s_bss (int localvar)
282 #ifdef OBJ_ELF
283 if (localvar == 0) /* bss. */
284 obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
285 else if (localvar == 1)
287 /* sbss. */
288 obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
289 if (sbss_segment == 0)
290 sbss_segment = subseg_new (".sbss", 0);
292 #else
293 s_data (ignore);
294 #endif
297 /* endp_p is always 1 as this func is called only for .end <funcname>
298 This func consumes the <funcname> and calls regular processing
299 s_func(1) with arg 1 (1 for end). */
301 static void
302 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
304 *input_line_pointer = get_symbol_end ();
305 s_func (1);
308 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
310 static void
311 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
313 char *name;
314 int c;
315 symbolS *symbolP;
316 expressionS exp;
318 name = input_line_pointer;
319 c = get_symbol_end ();
320 symbolP = symbol_find_or_make (name);
321 S_SET_WEAK (symbolP);
322 *input_line_pointer = c;
324 SKIP_WHITESPACE ();
326 if (!is_end_of_line[(unsigned char) *input_line_pointer])
328 if (S_IS_DEFINED (symbolP))
330 as_bad ("Ignoring attempt to redefine symbol `%s'.",
331 S_GET_NAME (symbolP));
332 ignore_rest_of_line ();
333 return;
336 if (*input_line_pointer == ',')
338 ++input_line_pointer;
339 SKIP_WHITESPACE ();
342 expression (&exp);
343 if (exp.X_op != O_symbol)
345 as_bad ("bad .weakext directive");
346 ignore_rest_of_line ();
347 return;
349 symbol_set_value_expression (symbolP, &exp);
352 demand_empty_rest_of_line ();
355 /* This table describes all the machine specific pseudo-ops the assembler
356 has to support. The fields are:
357 Pseudo-op name without dot
358 Function to call to execute this pseudo-op
359 Integer arg to pass to the function. */
360 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
361 and then in the read.c table. */
362 const pseudo_typeS md_pseudo_table[] =
364 {"lcomm", microblaze_s_lcomm, 1},
365 {"data", microblaze_s_data, 0},
366 {"data8", cons, 1}, /* Same as byte. */
367 {"data16", cons, 2}, /* Same as hword. */
368 {"data32", cons, 4}, /* Same as word. */
369 {"ent", s_func, 0}, /* Treat ent as function entry point. */
370 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
371 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
372 {"weakext", microblaze_s_weakext, 0},
373 {"rodata", microblaze_s_rdata, 0},
374 {"sdata2", microblaze_s_rdata, 1},
375 {"sdata", microblaze_s_sdata, 0},
376 {"bss", microblaze_s_bss, 0},
377 {"sbss", microblaze_s_bss, 1},
378 {"text", microblaze_s_text, 0},
379 {"word", cons, 4},
380 {"frame", s_ignore, 0},
381 {"mask", s_ignore, 0}, /* Emitted by gcc. */
382 {NULL, NULL, 0}
385 /* This function is called once, at assembler startup time. This should
386 set up all the tables, etc that the MD part of the assembler needs. */
388 void
389 md_begin (void)
391 struct op_code_struct * opcode;
393 opcode_hash_control = hash_new ();
395 /* Insert unique names into hash table. */
396 for (opcode = opcodes; opcode->name; opcode ++)
397 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
400 /* Try to parse a reg name. */
402 static char *
403 parse_reg (char * s, unsigned * reg)
405 unsigned tmpreg = 0;
407 /* Strip leading whitespace. */
408 while (ISSPACE (* s))
409 ++ s;
411 if (strncasecmp (s, "rpc", 3) == 0)
413 *reg = REG_PC;
414 return s + 3;
416 else if (strncasecmp (s, "rmsr", 4) == 0)
418 *reg = REG_MSR;
419 return s + 4;
421 else if (strncasecmp (s, "rear", 4) == 0)
423 *reg = REG_EAR;
424 return s + 4;
426 else if (strncasecmp (s, "resr", 4) == 0)
428 *reg = REG_ESR;
429 return s + 4;
431 else if (strncasecmp (s, "rfsr", 4) == 0)
433 *reg = REG_FSR;
434 return s + 4;
436 else if (strncasecmp (s, "rbtr", 4) == 0)
438 *reg = REG_BTR;
439 return s + 4;
441 else if (strncasecmp (s, "redr", 4) == 0)
443 *reg = REG_EDR;
444 return s + 4;
446 /* MMU registers start. */
447 else if (strncasecmp (s, "rpid", 4) == 0)
449 *reg = REG_PID;
450 return s + 4;
452 else if (strncasecmp (s, "rzpr", 4) == 0)
454 *reg = REG_ZPR;
455 return s + 4;
457 else if (strncasecmp (s, "rtlbx", 5) == 0)
459 *reg = REG_TLBX;
460 return s + 5;
462 else if (strncasecmp (s, "rtlblo", 6) == 0)
464 *reg = REG_TLBLO;
465 return s + 6;
467 else if (strncasecmp (s, "rtlbhi", 6) == 0)
469 *reg = REG_TLBHI;
470 return s + 6;
472 else if (strncasecmp (s, "rtlbsx", 6) == 0)
474 *reg = REG_TLBSX;
475 return s + 6;
477 /* MMU registers end. */
478 else if (strncasecmp (s, "rpvr", 4) == 0)
480 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
482 tmpreg = (s[4]-'0')*10 + s[5] - '0';
483 s += 6;
486 else if (ISDIGIT (s[4]))
488 tmpreg = s[4] - '0';
489 s += 5;
491 else
492 as_bad (_("register expected, but saw '%.6s'"), s);
493 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
494 *reg = REG_PVR + tmpreg;
495 else
497 as_bad (_("Invalid register number at '%.6s'"), s);
498 *reg = REG_PVR;
500 return s;
502 else if (strncasecmp (s, "rsp", 3) == 0)
504 *reg = REG_SP;
505 return s + 3;
507 else if (strncasecmp (s, "rfsl", 4) == 0)
509 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
511 tmpreg = (s[4] - '0') * 10 + s[5] - '0';
512 s += 6;
514 else if (ISDIGIT (s[4]))
516 tmpreg = s[4] - '0';
517 s += 5;
519 else
520 as_bad (_("register expected, but saw '%.6s'"), s);
522 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
523 *reg = tmpreg;
524 else
526 as_bad (_("Invalid register number at '%.6s'"), s);
527 *reg = 0;
529 return s;
531 else
533 if (TOLOWER (s[0]) == 'r')
535 if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
537 tmpreg = (s[1] - '0') * 10 + s[2] - '0';
538 s += 3;
540 else if (ISDIGIT (s[1]))
542 tmpreg = s[1] - '0';
543 s += 2;
545 else
546 as_bad (_("register expected, but saw '%.6s'"), s);
548 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
549 *reg = tmpreg;
550 else
552 as_bad (_("Invalid register number at '%.6s'"), s);
553 *reg = 0;
555 return s;
558 as_bad (_("register expected, but saw '%.6s'"), s);
559 *reg = 0;
560 return s;
563 static char *
564 parse_exp (char *s, expressionS *e)
566 char *save;
567 char *new_pointer;
569 /* Skip whitespace. */
570 while (ISSPACE (* s))
571 ++ s;
573 save = input_line_pointer;
574 input_line_pointer = s;
576 expression (e);
578 if (e->X_op == O_absent)
579 as_fatal (_("missing operand"));
581 new_pointer = input_line_pointer;
582 input_line_pointer = save;
584 return new_pointer;
587 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
588 #define IMM_GOT 1
589 #define IMM_PLT 2
590 #define IMM_GOTOFF 3
592 static symbolS * GOT_symbol;
594 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
596 static char *
597 parse_imm (char * s, expressionS * e, int min, int max)
599 char *new_pointer;
600 char *atp;
602 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
603 for (atp = s; *atp != '@'; atp++)
604 if (is_end_of_line[(unsigned char) *atp])
605 break;
607 if (*atp == '@')
609 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
611 *atp = 0;
612 e->X_md = IMM_GOTOFF;
614 else if (strncmp (atp + 1, "GOT", 3) == 0)
616 *atp = 0;
617 e->X_md = IMM_GOT;
619 else if (strncmp (atp + 1, "PLT", 3) == 0)
621 *atp = 0;
622 e->X_md = IMM_PLT;
624 else
626 atp = NULL;
627 e->X_md = 0;
629 *atp = 0;
631 else
633 atp = NULL;
634 e->X_md = 0;
637 if (atp && !GOT_symbol)
639 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
642 new_pointer = parse_exp (s, e);
644 if (e->X_op == O_absent)
645 ; /* An error message has already been emitted. */
646 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
647 as_fatal (_("operand must be a constant or a label"));
648 else if ((e->X_op == O_constant) && ((int) e->X_add_number < min
649 || (int) e->X_add_number > max))
651 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
652 min, max, (int) e->X_add_number);
655 if (atp)
657 *atp = '@'; /* restore back (needed?) */
658 if (new_pointer >= atp)
659 new_pointer += (e->X_md == IMM_GOTOFF)?7:4;
660 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
663 return new_pointer;
666 static char *
667 check_got (int * got_type, int * got_len)
669 char *new_pointer;
670 char *atp;
671 char *past_got;
672 int first, second;
673 char *tmpbuf;
675 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
676 for (atp = input_line_pointer; *atp != '@'; atp++)
677 if (is_end_of_line[(unsigned char) *atp])
678 return NULL;
680 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
682 *got_len = 6;
683 *got_type = IMM_GOTOFF;
685 else if (strncmp (atp + 1, "GOT", 3) == 0)
687 *got_len = 3;
688 *got_type = IMM_GOT;
690 else if (strncmp (atp + 1, "PLT", 3) == 0)
692 *got_len = 3;
693 *got_type = IMM_PLT;
695 else
696 return NULL;
698 if (!GOT_symbol)
699 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
701 first = atp - input_line_pointer;
703 past_got = atp + *got_len + 1;
704 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
706 second = new_pointer - past_got;
707 tmpbuf = xmalloc (first + second + 2); /* One extra byte for ' ' and one for NUL. */
708 memcpy (tmpbuf, input_line_pointer, first);
709 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
710 memcpy (tmpbuf + first + 1, past_got, second);
711 tmpbuf[first + second + 1] = '\0';
713 return tmpbuf;
716 extern void
717 parse_cons_expression_microblaze (expressionS *exp, int size)
719 if (size == 4)
721 /* Handle @GOTOFF et.al. */
722 char *save, *gotfree_copy;
723 int got_len, got_type;
725 save = input_line_pointer;
726 gotfree_copy = check_got (& got_type, & got_len);
727 if (gotfree_copy)
728 input_line_pointer = gotfree_copy;
730 expression (exp);
732 if (gotfree_copy)
734 exp->X_md = got_type;
735 input_line_pointer = save + (input_line_pointer - gotfree_copy)
736 + got_len;
737 free (gotfree_copy);
740 else
741 expression (exp);
744 /* This is the guts of the machine-dependent assembler. STR points to a
745 machine dependent instruction. This function is supposed to emit
746 the frags/bytes it assembles to. */
748 static char * str_microblaze_ro_anchor = "RO";
749 static char * str_microblaze_rw_anchor = "RW";
751 static bfd_boolean
752 check_spl_reg (unsigned * reg)
754 if ((*reg == REG_MSR) || (*reg == REG_PC)
755 || (*reg == REG_EAR) || (*reg == REG_ESR)
756 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
757 || (*reg == REG_PID) || (*reg == REG_ZPR)
758 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
759 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
760 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
761 return TRUE;
763 return FALSE;
766 /* Here we decide which fixups can be adjusted to make them relative to
767 the beginning of the section instead of the symbol. Basically we need
768 to make sure that the dynamic relocations are done correctly, so in
769 some cases we force the original symbol to be used. */
772 tc_microblaze_fix_adjustable (struct fix *fixP)
774 if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
775 return 0;
777 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
778 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
779 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
780 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT)
781 return 0;
783 return 1;
786 void
787 md_assemble (char * str)
789 char * op_start;
790 char * op_end;
791 struct op_code_struct * opcode, *opcode1;
792 char * output = NULL;
793 int nlen = 0;
794 int i;
795 unsigned long inst, inst1;
796 unsigned reg1;
797 unsigned reg2;
798 unsigned reg3;
799 unsigned isize;
800 unsigned int immed, temp;
801 expressionS exp;
802 char name[20];
804 /* Drop leading whitespace. */
805 while (ISSPACE (* str))
806 str ++;
808 /* Find the op code end. */
809 for (op_start = op_end = str;
810 *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
811 op_end++)
813 name[nlen] = op_start[nlen];
814 nlen++;
815 if (nlen == sizeof (name) - 1)
816 break;
819 name [nlen] = 0;
821 if (nlen == 0)
823 as_bad (_("can't find opcode "));
824 return;
827 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
828 if (opcode == NULL)
830 as_bad (_("unknown opcode \"%s\""), name);
831 return;
834 inst = opcode->bit_sequence;
835 isize = 4;
837 switch (opcode->inst_type)
839 case INST_TYPE_RD_R1_R2:
840 if (strcmp (op_end, ""))
841 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
842 else
844 as_fatal (_("Error in statement syntax"));
845 reg1 = 0;
847 if (strcmp (op_end, ""))
848 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
849 else
851 as_fatal (_("Error in statement syntax"));
852 reg2 = 0;
854 if (strcmp (op_end, ""))
855 op_end = parse_reg (op_end + 1, &reg3); /* Get r2. */
856 else
858 as_fatal (_("Error in statement syntax"));
859 reg3 = 0;
862 /* Check for spl registers. */
863 if (check_spl_reg (& reg1))
864 as_fatal (_("Cannot use special register with this instruction"));
865 if (check_spl_reg (& reg2))
866 as_fatal (_("Cannot use special register with this instruction"));
867 if (check_spl_reg (& reg3))
868 as_fatal (_("Cannot use special register with this instruction"));
870 if (streq (name, "sub"))
872 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
873 inst |= (reg1 << RD_LOW) & RD_MASK;
874 inst |= (reg3 << RA_LOW) & RA_MASK;
875 inst |= (reg2 << RB_LOW) & RB_MASK;
877 else
879 inst |= (reg1 << RD_LOW) & RD_MASK;
880 inst |= (reg2 << RA_LOW) & RA_MASK;
881 inst |= (reg3 << RB_LOW) & RB_MASK;
883 output = frag_more (isize);
884 break;
886 case INST_TYPE_RD_R1_IMM:
887 if (strcmp (op_end, ""))
888 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
889 else
891 as_fatal (_("Error in statement syntax"));
892 reg1 = 0;
894 if (strcmp (op_end, ""))
895 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
896 else
898 as_fatal (_("Error in statement syntax"));
899 reg2 = 0;
901 if (strcmp (op_end, ""))
902 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
903 else
904 as_fatal (_("Error in statement syntax"));
906 /* Check for spl registers. */
907 if (check_spl_reg (& reg1))
908 as_fatal (_("Cannot use special register with this instruction"));
909 if (check_spl_reg (& reg2))
910 as_fatal (_("Cannot use special register with this instruction"));
912 if (exp.X_op != O_constant)
914 char *opc;
915 relax_substateT subtype;
917 if (streq (name, "lmi"))
918 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
919 else if (streq (name, "smi"))
920 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
922 if (reg2 == REG_ROSDP)
923 opc = str_microblaze_ro_anchor;
924 else if (reg2 == REG_RWSDP)
925 opc = str_microblaze_rw_anchor;
926 else
927 opc = NULL;
928 if (exp.X_md == IMM_GOT)
929 subtype = GOT_OFFSET;
930 else if (exp.X_md == IMM_PLT)
931 subtype = PLT_OFFSET;
932 else if (exp.X_md == IMM_GOTOFF)
933 subtype = GOTOFF_OFFSET;
934 else
935 subtype = opcode->inst_offset_type;
937 output = frag_var (rs_machine_dependent,
938 isize * 2, /* maxm of 2 words. */
939 isize, /* minm of 1 word. */
940 subtype, /* PC-relative or not. */
941 exp.X_add_symbol,
942 exp.X_add_number,
943 opc);
944 immed = 0;
946 else
948 output = frag_more (isize);
949 immed = exp.X_add_number;
952 if (streq (name, "lmi") || streq (name, "smi"))
954 /* Load/store 32-d consecutive registers. Used on exit/entry
955 to subroutines to save and restore registers to stack.
956 Generate 32-d insts. */
957 int count;
959 count = 32 - reg1;
960 if (streq (name, "lmi"))
961 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
962 else
963 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
964 if (opcode == NULL)
966 as_bad (_("unknown opcode \"%s\""), "lwi");
967 return;
969 inst = opcode->bit_sequence;
970 inst |= (reg1 << RD_LOW) & RD_MASK;
971 inst |= (reg2 << RA_LOW) & RA_MASK;
972 inst |= (immed << IMM_LOW) & IMM_MASK;
974 for (i = 0; i < count - 1; i++)
976 output[0] = INST_BYTE0 (inst);
977 output[1] = INST_BYTE1 (inst);
978 output[2] = INST_BYTE2 (inst);
979 output[3] = INST_BYTE3 (inst);
980 output = frag_more (isize);
981 immed = immed + 4;
982 reg1++;
983 inst = opcode->bit_sequence;
984 inst |= (reg1 << RD_LOW) & RD_MASK;
985 inst |= (reg2 << RA_LOW) & RA_MASK;
986 inst |= (immed << IMM_LOW) & IMM_MASK;
989 else
991 temp = immed & 0xFFFF8000;
992 if ((temp != 0) && (temp != 0xFFFF8000))
994 /* Needs an immediate inst. */
995 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
996 if (opcode1 == NULL)
998 as_bad (_("unknown opcode \"%s\""), "imm");
999 return;
1002 inst1 = opcode1->bit_sequence;
1003 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1004 output[0] = INST_BYTE0 (inst1);
1005 output[1] = INST_BYTE1 (inst1);
1006 output[2] = INST_BYTE2 (inst1);
1007 output[3] = INST_BYTE3 (inst1);
1008 output = frag_more (isize);
1010 inst |= (reg1 << RD_LOW) & RD_MASK;
1011 inst |= (reg2 << RA_LOW) & RA_MASK;
1012 inst |= (immed << IMM_LOW) & IMM_MASK;
1014 break;
1016 case INST_TYPE_RD_R1_IMM5:
1017 if (strcmp (op_end, ""))
1018 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1019 else
1021 as_fatal (_("Error in statement syntax"));
1022 reg1 = 0;
1024 if (strcmp (op_end, ""))
1025 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1026 else
1028 as_fatal (_("Error in statement syntax"));
1029 reg2 = 0;
1031 if (strcmp (op_end, ""))
1032 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1033 else
1034 as_fatal (_("Error in statement syntax"));
1036 /* Check for spl registers. */
1037 if (check_spl_reg (&reg1))
1038 as_fatal (_("Cannot use special register with this instruction"));
1039 if (check_spl_reg (&reg2))
1040 as_fatal (_("Cannot use special register with this instruction"));
1042 if (exp.X_op != O_constant)
1043 as_warn (_("Symbol used as immediate for shift instruction"));
1044 else
1046 output = frag_more (isize);
1047 immed = exp.X_add_number;
1050 if (immed != (immed % 32))
1052 as_warn (_("Shift value > 32. using <value %% 32>"));
1053 immed = immed % 32;
1055 inst |= (reg1 << RD_LOW) & RD_MASK;
1056 inst |= (reg2 << RA_LOW) & RA_MASK;
1057 inst |= (immed << IMM_LOW) & IMM5_MASK;
1058 break;
1060 case INST_TYPE_R1_R2:
1061 if (strcmp (op_end, ""))
1062 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1063 else
1065 as_fatal (_("Error in statement syntax"));
1066 reg1 = 0;
1068 if (strcmp (op_end, ""))
1069 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1070 else
1072 as_fatal (_("Error in statement syntax"));
1073 reg2 = 0;
1076 /* Check for spl registers. */
1077 if (check_spl_reg (& reg1))
1078 as_fatal (_("Cannot use special register with this instruction"));
1079 if (check_spl_reg (& reg2))
1080 as_fatal (_("Cannot use special register with this instruction"));
1082 inst |= (reg1 << RA_LOW) & RA_MASK;
1083 inst |= (reg2 << RB_LOW) & RB_MASK;
1084 output = frag_more (isize);
1085 break;
1087 case INST_TYPE_RD_R1:
1088 if (strcmp (op_end, ""))
1089 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1090 else
1092 as_fatal (_("Error in statement syntax"));
1093 reg1 = 0;
1095 if (strcmp (op_end, ""))
1096 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1097 else
1099 as_fatal (_("Error in statement syntax"));
1100 reg2 =0;
1103 /* Check for spl registers. */
1104 if (check_spl_reg (&reg1))
1105 as_fatal (_("Cannot use special register with this instruction"));
1106 if (check_spl_reg (&reg2))
1107 as_fatal (_("Cannot use special register with this instruction"));
1109 inst |= (reg1 << RD_LOW) & RD_MASK;
1110 inst |= (reg2 << RA_LOW) & RA_MASK;
1111 output = frag_more (isize);
1112 break;
1114 case INST_TYPE_RD_RFSL:
1115 if (strcmp (op_end, ""))
1116 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1117 else
1119 as_fatal (_("Error in statement syntax"));
1120 reg1 = 0;
1122 if (strcmp (op_end, ""))
1123 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1124 else
1126 as_fatal (_("Error in statement syntax"));
1127 immed = 0;
1130 /* Check for spl registers. */
1131 if (check_spl_reg (&reg1))
1132 as_fatal (_("Cannot use special register with this instruction"));
1134 inst |= (reg1 << RD_LOW) & RD_MASK;
1135 inst |= (immed << IMM_LOW) & RFSL_MASK;
1136 output = frag_more (isize);
1137 break;
1139 case INST_TYPE_RD_IMM15:
1140 if (strcmp (op_end, ""))
1141 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1142 else
1144 as_fatal (_("Error in statement syntax"));
1145 reg1 = 0;
1148 if (strcmp (op_end, ""))
1149 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1150 else
1151 as_fatal (_("Error in statement syntax"));
1153 /* Check for spl registers. */
1154 if (check_spl_reg (&reg1))
1155 as_fatal (_("Cannot use special register with this instruction"));
1157 if (exp.X_op != O_constant)
1158 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1159 else
1161 output = frag_more (isize);
1162 immed = exp.X_add_number;
1164 inst |= (reg1 << RD_LOW) & RD_MASK;
1165 inst |= (immed << IMM_LOW) & IMM15_MASK;
1166 break;
1168 case INST_TYPE_R1_RFSL:
1169 if (strcmp (op_end, ""))
1170 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1171 else
1173 as_fatal (_("Error in statement syntax"));
1174 reg1 = 0;
1176 if (strcmp (op_end, ""))
1177 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1178 else
1180 as_fatal (_("Error in statement syntax"));
1181 immed = 0;
1184 /* Check for spl registers. */
1185 if (check_spl_reg (&reg1))
1186 as_fatal (_("Cannot use special register with this instruction"));
1188 inst |= (reg1 << RA_LOW) & RA_MASK;
1189 inst |= (immed << IMM_LOW) & RFSL_MASK;
1190 output = frag_more (isize);
1191 break;
1193 case INST_TYPE_RFSL:
1194 if (strcmp (op_end, ""))
1195 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1196 else
1198 as_fatal (_("Error in statement syntax"));
1199 immed = 0;
1201 /* Check for spl registers. */
1202 if (check_spl_reg (&reg1))
1203 as_fatal (_("Cannot use special register with this instruction"));
1204 inst |= (immed << IMM_LOW) & RFSL_MASK;
1205 output = frag_more (isize);
1206 break;
1208 case INST_TYPE_R1:
1209 if (strcmp (op_end, ""))
1210 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1211 else
1213 as_fatal (_("Error in statement syntax"));
1214 reg1 = 0;
1217 /* Check for spl registers. */
1218 if (check_spl_reg (&reg1))
1219 as_fatal (_("Cannot use special register with this instruction"));
1221 inst |= (reg1 << RA_LOW) & RA_MASK;
1222 output = frag_more (isize);
1223 break;
1225 /* For tuqula insn...:) */
1226 case INST_TYPE_RD:
1227 if (strcmp (op_end, ""))
1228 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1229 else
1231 as_fatal (_("Error in statement syntax"));
1232 reg1 = 0;
1235 /* Check for spl registers. */
1236 if (check_spl_reg (&reg1))
1237 as_fatal (_("Cannot use special register with this instruction"));
1239 inst |= (reg1 << RD_LOW) & RD_MASK;
1240 output = frag_more (isize);
1241 break;
1243 case INST_TYPE_RD_SPECIAL:
1244 if (strcmp (op_end, ""))
1245 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1246 else
1248 as_fatal (_("Error in statement syntax"));
1249 reg1 = 0;
1251 if (strcmp (op_end, ""))
1252 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1253 else
1255 as_fatal (_("Error in statement syntax"));
1256 reg2 = 0;
1259 if (reg2 == REG_MSR)
1260 immed = opcode->immval_mask | REG_MSR_MASK;
1261 else if (reg2 == REG_PC)
1262 immed = opcode->immval_mask | REG_PC_MASK;
1263 else if (reg2 == REG_EAR)
1264 immed = opcode->immval_mask | REG_EAR_MASK;
1265 else if (reg2 == REG_ESR)
1266 immed = opcode->immval_mask | REG_ESR_MASK;
1267 else if (reg2 == REG_FSR)
1268 immed = opcode->immval_mask | REG_FSR_MASK;
1269 else if (reg2 == REG_BTR)
1270 immed = opcode->immval_mask | REG_BTR_MASK;
1271 else if (reg2 == REG_EDR)
1272 immed = opcode->immval_mask | REG_EDR_MASK;
1273 else if (reg2 == REG_PID)
1274 immed = opcode->immval_mask | REG_PID_MASK;
1275 else if (reg2 == REG_ZPR)
1276 immed = opcode->immval_mask | REG_ZPR_MASK;
1277 else if (reg2 == REG_TLBX)
1278 immed = opcode->immval_mask | REG_TLBX_MASK;
1279 else if (reg2 == REG_TLBLO)
1280 immed = opcode->immval_mask | REG_TLBLO_MASK;
1281 else if (reg2 == REG_TLBHI)
1282 immed = opcode->immval_mask | REG_TLBHI_MASK;
1283 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1284 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1285 else
1286 as_fatal (_("invalid value for special purpose register"));
1287 inst |= (reg1 << RD_LOW) & RD_MASK;
1288 inst |= (immed << IMM_LOW) & IMM_MASK;
1289 output = frag_more (isize);
1290 break;
1292 case INST_TYPE_SPECIAL_R1:
1293 if (strcmp (op_end, ""))
1294 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1295 else
1297 as_fatal (_("Error in statement syntax"));
1298 reg1 = 0;
1300 if (strcmp (op_end, ""))
1301 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1302 else
1304 as_fatal (_("Error in statement syntax"));
1305 reg2 = 0;
1308 if (reg1 == REG_MSR)
1309 immed = opcode->immval_mask | REG_MSR_MASK;
1310 else if (reg1 == REG_PC)
1311 immed = opcode->immval_mask | REG_PC_MASK;
1312 else if (reg1 == REG_EAR)
1313 immed = opcode->immval_mask | REG_EAR_MASK;
1314 else if (reg1 == REG_ESR)
1315 immed = opcode->immval_mask | REG_ESR_MASK;
1316 else if (reg1 == REG_FSR)
1317 immed = opcode->immval_mask | REG_FSR_MASK;
1318 else if (reg1 == REG_BTR)
1319 immed = opcode->immval_mask | REG_BTR_MASK;
1320 else if (reg1 == REG_EDR)
1321 immed = opcode->immval_mask | REG_EDR_MASK;
1322 else if (reg1 == REG_PID)
1323 immed = opcode->immval_mask | REG_PID_MASK;
1324 else if (reg1 == REG_ZPR)
1325 immed = opcode->immval_mask | REG_ZPR_MASK;
1326 else if (reg1 == REG_TLBX)
1327 immed = opcode->immval_mask | REG_TLBX_MASK;
1328 else if (reg1 == REG_TLBLO)
1329 immed = opcode->immval_mask | REG_TLBLO_MASK;
1330 else if (reg1 == REG_TLBHI)
1331 immed = opcode->immval_mask | REG_TLBHI_MASK;
1332 else if (reg1 == REG_TLBSX)
1333 immed = opcode->immval_mask | REG_TLBSX_MASK;
1334 else
1335 as_fatal (_("invalid value for special purpose register"));
1336 inst |= (reg2 << RA_LOW) & RA_MASK;
1337 inst |= (immed << IMM_LOW) & IMM_MASK;
1338 output = frag_more (isize);
1339 break;
1341 case INST_TYPE_RD_R1_SPECIAL:
1342 if (strcmp (op_end, ""))
1343 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1344 else
1346 as_fatal (_("Error in statement syntax"));
1347 reg1 = 0;
1349 if (strcmp (op_end, ""))
1350 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1351 else
1353 as_fatal (_("Error in statement syntax"));
1354 reg2 =0;
1357 /* Check for spl registers. */
1358 if (check_spl_reg (&reg1))
1359 as_fatal (_("Cannot use special register with this instruction"));
1360 if (check_spl_reg (&reg2))
1361 as_fatal (_("Cannot use special register with this instruction"));
1363 /* insn wic ra, rb => wic ra, ra, rb. */
1364 inst |= (reg1 << RD_LOW) & RD_MASK;
1365 inst |= (reg1 << RA_LOW) & RA_MASK;
1366 inst |= (reg2 << RB_LOW) & RB_MASK;
1368 output = frag_more (isize);
1369 break;
1371 case INST_TYPE_RD_R2:
1372 if (strcmp (op_end, ""))
1373 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1374 else
1376 as_fatal (_("Error in statement syntax"));
1377 reg1 = 0;
1379 if (strcmp (op_end, ""))
1380 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1381 else
1383 as_fatal (_("Error in statement syntax"));
1384 reg2 = 0;
1387 /* Check for spl registers. */
1388 if (check_spl_reg (&reg1))
1389 as_fatal (_("Cannot use special register with this instruction"));
1390 if (check_spl_reg (&reg2))
1391 as_fatal (_("Cannot use special register with this instruction"));
1393 inst |= (reg1 << RD_LOW) & RD_MASK;
1394 inst |= (reg2 << RB_LOW) & RB_MASK;
1395 output = frag_more (isize);
1396 break;
1398 case INST_TYPE_R1_IMM:
1399 if (strcmp (op_end, ""))
1400 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1401 else
1403 as_fatal (_("Error in statement syntax"));
1404 reg1 = 0;
1406 if (strcmp (op_end, ""))
1407 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1408 else
1409 as_fatal (_("Error in statement syntax"));
1411 /* Check for spl registers. */
1412 if (check_spl_reg (&reg1))
1413 as_fatal (_("Cannot use special register with this instruction"));
1415 if (exp.X_op != O_constant)
1417 char *opc = NULL;
1418 relax_substateT subtype;
1420 if (exp.X_md == IMM_GOT)
1421 subtype = GOT_OFFSET;
1422 else if (exp.X_md == IMM_PLT)
1423 subtype = PLT_OFFSET;
1424 else
1425 subtype = opcode->inst_offset_type;
1426 output = frag_var (rs_machine_dependent,
1427 isize * 2, /* maxm of 2 words. */
1428 isize, /* minm of 1 word. */
1429 subtype, /* PC-relative or not. */
1430 exp.X_add_symbol,
1431 exp.X_add_number,
1432 opc);
1433 immed = 0;
1435 else
1437 output = frag_more (isize);
1438 immed = exp.X_add_number;
1441 temp = immed & 0xFFFF8000;
1442 if ((temp != 0) && (temp != 0xFFFF8000))
1444 /* Needs an immediate inst. */
1445 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1446 if (opcode1 == NULL)
1448 as_bad (_("unknown opcode \"%s\""), "imm");
1449 return;
1452 inst1 = opcode1->bit_sequence;
1453 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1454 output[0] = INST_BYTE0 (inst1);
1455 output[1] = INST_BYTE1 (inst1);
1456 output[2] = INST_BYTE2 (inst1);
1457 output[3] = INST_BYTE3 (inst1);
1458 output = frag_more (isize);
1461 inst |= (reg1 << RA_LOW) & RA_MASK;
1462 inst |= (immed << IMM_LOW) & IMM_MASK;
1463 break;
1465 case INST_TYPE_RD_IMM:
1466 if (strcmp (op_end, ""))
1467 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1468 else
1470 as_fatal (_("Error in statement syntax"));
1471 reg1 = 0;
1473 if (strcmp (op_end, ""))
1474 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1475 else
1476 as_fatal (_("Error in statement syntax"));
1478 /* Check for spl registers. */
1479 if (check_spl_reg (&reg1))
1480 as_fatal (_("Cannot use special register with this instruction"));
1482 if (exp.X_op != O_constant)
1484 char *opc = NULL;
1485 relax_substateT subtype;
1487 if (exp.X_md == IMM_GOT)
1488 subtype = GOT_OFFSET;
1489 else if (exp.X_md == IMM_PLT)
1490 subtype = PLT_OFFSET;
1491 else
1492 subtype = opcode->inst_offset_type;
1493 output = frag_var (rs_machine_dependent,
1494 isize * 2, /* maxm of 2 words. */
1495 isize, /* minm of 1 word. */
1496 subtype, /* PC-relative or not. */
1497 exp.X_add_symbol,
1498 exp.X_add_number,
1499 opc);
1500 immed = 0;
1502 else
1504 output = frag_more (isize);
1505 immed = exp.X_add_number;
1508 temp = immed & 0xFFFF8000;
1509 if ((temp != 0) && (temp != 0xFFFF8000))
1511 /* Needs an immediate inst. */
1512 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1513 if (opcode1 == NULL)
1515 as_bad (_("unknown opcode \"%s\""), "imm");
1516 return;
1519 inst1 = opcode1->bit_sequence;
1520 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1521 output[0] = INST_BYTE0 (inst1);
1522 output[1] = INST_BYTE1 (inst1);
1523 output[2] = INST_BYTE2 (inst1);
1524 output[3] = INST_BYTE3 (inst1);
1525 output = frag_more (isize);
1528 inst |= (reg1 << RD_LOW) & RD_MASK;
1529 inst |= (immed << IMM_LOW) & IMM_MASK;
1530 break;
1532 case INST_TYPE_R2:
1533 if (strcmp (op_end, ""))
1534 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1535 else
1537 as_fatal (_("Error in statement syntax"));
1538 reg2 = 0;
1541 /* Check for spl registers. */
1542 if (check_spl_reg (&reg2))
1543 as_fatal (_("Cannot use special register with this instruction"));
1545 inst |= (reg2 << RB_LOW) & RB_MASK;
1546 output = frag_more (isize);
1547 break;
1549 case INST_TYPE_IMM:
1550 if (streq (name, "imm"))
1551 as_fatal (_("An IMM instruction should not be present in the .s file"));
1553 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1555 if (exp.X_op != O_constant)
1557 char *opc = NULL;
1558 relax_substateT subtype;
1560 if (exp.X_md == IMM_GOT)
1561 subtype = GOT_OFFSET;
1562 else if (exp.X_md == IMM_PLT)
1563 subtype = PLT_OFFSET;
1564 else
1565 subtype = opcode->inst_offset_type;
1566 output = frag_var (rs_machine_dependent,
1567 isize * 2, /* maxm of 2 words. */
1568 isize, /* minm of 1 word. */
1569 subtype, /* PC-relative or not. */
1570 exp.X_add_symbol,
1571 exp.X_add_number,
1572 opc);
1573 immed = 0;
1575 else
1577 output = frag_more (isize);
1578 immed = exp.X_add_number;
1582 temp = immed & 0xFFFF8000;
1583 if ((temp != 0) && (temp != 0xFFFF8000))
1585 /* Needs an immediate inst. */
1586 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1587 if (opcode1 == NULL)
1589 as_bad (_("unknown opcode \"%s\""), "imm");
1590 return;
1593 inst1 = opcode1->bit_sequence;
1594 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1595 output[0] = INST_BYTE0 (inst1);
1596 output[1] = INST_BYTE1 (inst1);
1597 output[2] = INST_BYTE2 (inst1);
1598 output[3] = INST_BYTE3 (inst1);
1599 output = frag_more (isize);
1601 inst |= (immed << IMM_LOW) & IMM_MASK;
1602 break;
1604 case INST_TYPE_NONE:
1605 output = frag_more (isize);
1606 break;
1608 default:
1609 as_fatal (_("unimplemented opcode \"%s\""), name);
1612 /* Drop whitespace after all the operands have been parsed. */
1613 while (ISSPACE (* op_end))
1614 op_end ++;
1616 /* Give warning message if the insn has more operands than required. */
1617 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1618 as_warn (_("ignoring operands: %s "), op_end);
1620 output[0] = INST_BYTE0 (inst);
1621 output[1] = INST_BYTE1 (inst);
1622 output[2] = INST_BYTE2 (inst);
1623 output[3] = INST_BYTE3 (inst);
1625 #ifdef OBJ_ELF
1626 dwarf2_emit_insn (4);
1627 #endif
1630 symbolS *
1631 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1633 return NULL;
1636 /* Various routines to kill one day. */
1637 /* Equal to MAX_PRECISION in atof-ieee.c */
1638 #define MAX_LITTLENUMS 6
1640 /* Turn a string in input_line_pointer into a floating point constant of type
1641 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1642 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1643 char *
1644 md_atof (int type, char * litP, int * sizeP)
1646 int prec;
1647 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1648 int i;
1649 char * t;
1651 switch (type)
1653 case 'f':
1654 case 'F':
1655 case 's':
1656 case 'S':
1657 prec = 2;
1658 break;
1660 case 'd':
1661 case 'D':
1662 case 'r':
1663 case 'R':
1664 prec = 4;
1665 break;
1667 case 'x':
1668 case 'X':
1669 prec = 6;
1670 break;
1672 case 'p':
1673 case 'P':
1674 prec = 6;
1675 break;
1677 default:
1678 *sizeP = 0;
1679 return _("Bad call to MD_NTOF()");
1682 t = atof_ieee (input_line_pointer, type, words);
1684 if (t)
1685 input_line_pointer = t;
1687 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1689 if (! target_big_endian)
1691 for (i = prec - 1; i >= 0; i--)
1693 md_number_to_chars (litP, (valueT) words[i],
1694 sizeof (LITTLENUM_TYPE));
1695 litP += sizeof (LITTLENUM_TYPE);
1698 else
1699 for (i = 0; i < prec; i++)
1701 md_number_to_chars (litP, (valueT) words[i],
1702 sizeof (LITTLENUM_TYPE));
1703 litP += sizeof (LITTLENUM_TYPE);
1706 return NULL;
1709 const char * md_shortopts = "";
1711 struct option md_longopts[] =
1713 { NULL, no_argument, NULL, 0}
1716 size_t md_longopts_size = sizeof (md_longopts);
1718 int md_short_jump_size;
1720 void
1721 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1722 addressT from_Nddr ATTRIBUTE_UNUSED,
1723 addressT to_Nddr ATTRIBUTE_UNUSED,
1724 fragS * frag ATTRIBUTE_UNUSED,
1725 symbolS * to_symbol ATTRIBUTE_UNUSED)
1727 as_fatal (_("failed sanity check: short_jump"));
1730 void
1731 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1732 addressT from_Nddr ATTRIBUTE_UNUSED,
1733 addressT to_Nddr ATTRIBUTE_UNUSED,
1734 fragS * frag ATTRIBUTE_UNUSED,
1735 symbolS * to_symbol ATTRIBUTE_UNUSED)
1737 as_fatal (_("failed sanity check: long_jump"));
1740 /* Called after relaxing, change the frags so they know how big they are. */
1742 void
1743 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1744 segT sec ATTRIBUTE_UNUSED,
1745 fragS * fragP)
1747 fixS *fixP;
1749 switch (fragP->fr_subtype)
1751 case UNDEFINED_PC_OFFSET:
1752 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1753 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1754 fragP->fr_fix += INST_WORD_SIZE * 2;
1755 fragP->fr_var = 0;
1756 break;
1757 case DEFINED_ABS_SEGMENT:
1758 if (fragP->fr_symbol == GOT_symbol)
1759 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1760 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1761 else
1762 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1763 fragP->fr_offset, FALSE, BFD_RELOC_64);
1764 fragP->fr_fix += INST_WORD_SIZE * 2;
1765 fragP->fr_var = 0;
1766 break;
1767 case DEFINED_RO_SEGMENT:
1768 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1769 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1770 fragP->fr_fix += INST_WORD_SIZE;
1771 fragP->fr_var = 0;
1772 break;
1773 case DEFINED_RW_SEGMENT:
1774 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1775 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1776 fragP->fr_fix += INST_WORD_SIZE;
1777 fragP->fr_var = 0;
1778 break;
1779 case DEFINED_PC_OFFSET:
1780 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1781 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1782 fragP->fr_fix += INST_WORD_SIZE;
1783 fragP->fr_var = 0;
1784 break;
1785 case LARGE_DEFINED_PC_OFFSET:
1786 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1787 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1788 fragP->fr_fix += INST_WORD_SIZE * 2;
1789 fragP->fr_var = 0;
1790 break;
1791 case GOT_OFFSET:
1792 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1793 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1794 fragP->fr_fix += INST_WORD_SIZE * 2;
1795 fragP->fr_var = 0;
1796 break;
1797 case PLT_OFFSET:
1798 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1799 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1800 /* fixP->fx_plt = 1; */
1801 (void) fixP;
1802 fragP->fr_fix += INST_WORD_SIZE * 2;
1803 fragP->fr_var = 0;
1804 break;
1805 case GOTOFF_OFFSET:
1806 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1807 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1808 fragP->fr_fix += INST_WORD_SIZE * 2;
1809 fragP->fr_var = 0;
1810 break;
1812 default:
1813 abort ();
1817 /* Applies the desired value to the specified location.
1818 Also sets up addends for 'rela' type relocations. */
1819 void
1820 md_apply_fix (fixS * fixP,
1821 valueT * valp,
1822 segT segment)
1824 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1825 char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1826 const char * symname;
1827 /* Note: use offsetT because it is signed, valueT is unsigned. */
1828 offsetT val = (offsetT) * valp;
1829 int i;
1830 struct op_code_struct * opcode1;
1831 unsigned long inst1;
1833 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
1835 /* fixP->fx_offset is supposed to be set up correctly for all
1836 symbol relocations. */
1837 if (fixP->fx_addsy == NULL)
1839 if (!fixP->fx_pcrel)
1840 fixP->fx_offset = val; /* Absolute relocation. */
1841 else
1842 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1843 (unsigned int) fixP->fx_offset, (unsigned int) val);
1846 /* If we aren't adjusting this fixup to be against the section
1847 symbol, we need to adjust the value. */
1848 if (fixP->fx_addsy != NULL)
1850 if (S_IS_WEAK (fixP->fx_addsy)
1851 || (symbol_used_in_reloc_p (fixP->fx_addsy)
1852 && (((bfd_get_section_flags (stdoutput,
1853 S_GET_SEGMENT (fixP->fx_addsy))
1854 & SEC_LINK_ONCE) != 0)
1855 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
1856 ".gnu.linkonce",
1857 sizeof (".gnu.linkonce") - 1))))
1859 val -= S_GET_VALUE (fixP->fx_addsy);
1860 if (val != 0 && ! fixP->fx_pcrel)
1862 /* In this case, the bfd_install_relocation routine will
1863 incorrectly add the symbol value back in. We just want
1864 the addend to appear in the object file.
1865 FIXME: If this makes VALUE zero, we're toast. */
1866 val -= S_GET_VALUE (fixP->fx_addsy);
1871 /* If the fix is relative to a symbol which is not defined, or not
1872 in the same segment as the fix, we cannot resolve it here. */
1873 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1874 if (fixP->fx_addsy != NULL
1875 && (!S_IS_DEFINED (fixP->fx_addsy)
1876 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
1878 fixP->fx_done = 0;
1879 #ifdef OBJ_ELF
1880 /* For ELF we can just return and let the reloc that will be generated
1881 take care of everything. For COFF we still have to insert 'val'
1882 into the insn since the addend field will be ignored. */
1883 /* return; */
1884 #endif
1886 /* All fixups in the text section must be handled in the linker. */
1887 else if (segment->flags & SEC_CODE)
1888 fixP->fx_done = 0;
1889 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
1890 fixP->fx_done = 0;
1891 else
1892 fixP->fx_done = 1;
1894 switch (fixP->fx_r_type)
1896 case BFD_RELOC_MICROBLAZE_32_LO:
1897 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
1898 if (target_big_endian)
1900 buf[2] |= ((val >> 8) & 0xff);
1901 buf[3] |= (val & 0xff);
1903 else
1905 buf[1] |= ((val >> 8) & 0xff);
1906 buf[0] |= (val & 0xff);
1908 break;
1909 case BFD_RELOC_MICROBLAZE_32_ROSDA:
1910 case BFD_RELOC_MICROBLAZE_32_RWSDA:
1911 /* Don't do anything if the symbol is not defined. */
1912 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1914 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
1915 as_bad_where (file, fixP->fx_line,
1916 _("pcrel for branch to %s too far (0x%x)"),
1917 symname, (int) val);
1918 if (target_big_endian)
1920 buf[2] |= ((val >> 8) & 0xff);
1921 buf[3] |= (val & 0xff);
1923 else
1925 buf[1] |= ((val >> 8) & 0xff);
1926 buf[0] |= (val & 0xff);
1929 break;
1930 case BFD_RELOC_32:
1931 case BFD_RELOC_RVA:
1932 case BFD_RELOC_32_PCREL:
1933 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
1934 /* Don't do anything if the symbol is not defined. */
1935 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1937 if (target_big_endian)
1939 buf[0] |= ((val >> 24) & 0xff);
1940 buf[1] |= ((val >> 16) & 0xff);
1941 buf[2] |= ((val >> 8) & 0xff);
1942 buf[3] |= (val & 0xff);
1944 else
1946 buf[3] |= ((val >> 24) & 0xff);
1947 buf[2] |= ((val >> 16) & 0xff);
1948 buf[1] |= ((val >> 8) & 0xff);
1949 buf[0] |= (val & 0xff);
1952 break;
1953 case BFD_RELOC_64_PCREL:
1954 case BFD_RELOC_64:
1955 /* Add an imm instruction. First save the current instruction. */
1956 for (i = 0; i < INST_WORD_SIZE; i++)
1957 buf[i + INST_WORD_SIZE] = buf[i];
1959 /* Generate the imm instruction. */
1960 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1961 if (opcode1 == NULL)
1963 as_bad (_("unknown opcode \"%s\""), "imm");
1964 return;
1967 inst1 = opcode1->bit_sequence;
1968 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1969 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
1971 buf[0] = INST_BYTE0 (inst1);
1972 buf[1] = INST_BYTE1 (inst1);
1973 buf[2] = INST_BYTE2 (inst1);
1974 buf[3] = INST_BYTE3 (inst1);
1976 /* Add the value only if the symbol is defined. */
1977 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1979 if (target_big_endian)
1981 buf[6] |= ((val >> 8) & 0xff);
1982 buf[7] |= (val & 0xff);
1984 else
1986 buf[5] |= ((val >> 8) & 0xff);
1987 buf[4] |= (val & 0xff);
1990 break;
1992 case BFD_RELOC_MICROBLAZE_64_GOTPC:
1993 case BFD_RELOC_MICROBLAZE_64_GOT:
1994 case BFD_RELOC_MICROBLAZE_64_PLT:
1995 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
1996 /* Add an imm instruction. First save the current instruction. */
1997 for (i = 0; i < INST_WORD_SIZE; i++)
1998 buf[i + INST_WORD_SIZE] = buf[i];
2000 /* Generate the imm instruction. */
2001 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2002 if (opcode1 == NULL)
2004 as_bad (_("unknown opcode \"%s\""), "imm");
2005 return;
2008 inst1 = opcode1->bit_sequence;
2010 /* We can fixup call to a defined non-global address
2011 within the same section only. */
2012 buf[0] = INST_BYTE0 (inst1);
2013 buf[1] = INST_BYTE1 (inst1);
2014 buf[2] = INST_BYTE2 (inst1);
2015 buf[3] = INST_BYTE3 (inst1);
2016 return;
2018 default:
2019 break;
2022 if (fixP->fx_addsy == NULL)
2024 /* This fixup has been resolved. Create a reloc in case the linker
2025 moves code around due to relaxing. */
2026 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2027 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2028 else
2029 fixP->fx_r_type = BFD_RELOC_NONE;
2030 fixP->fx_addsy = section_symbol (absolute_section);
2032 return;
2035 void
2036 md_operand (expressionS * expressionP)
2038 /* Ignore leading hash symbol, if present. */
2039 if (*input_line_pointer == '#')
2041 input_line_pointer ++;
2042 expression (expressionP);
2046 /* Called just before address relaxation, return the length
2047 by which a fragment must grow to reach it's destination. */
2050 md_estimate_size_before_relax (fragS * fragP,
2051 segT segment_type)
2053 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2054 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2055 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2056 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2058 switch (fragP->fr_subtype)
2060 case INST_PC_OFFSET:
2061 /* Used to be a PC-relative branch. */
2062 if (!fragP->fr_symbol)
2064 /* We know the abs value: Should never happen. */
2065 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2066 abort ();
2068 else if ((S_GET_SEGMENT (fragP->fr_symbol) == segment_type))
2070 fragP->fr_subtype = DEFINED_PC_OFFSET;
2071 /* Don't know now whether we need an imm instruction. */
2072 fragP->fr_var = INST_WORD_SIZE;
2074 else if (S_IS_DEFINED (fragP->fr_symbol)
2075 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2077 /* Cannot have a PC-relative branch to a diff segment. */
2078 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2079 S_GET_NAME (fragP->fr_symbol));
2080 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2081 fragP->fr_var = INST_WORD_SIZE*2;
2083 else
2085 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2086 fragP->fr_var = INST_WORD_SIZE*2;
2088 break;
2090 case INST_NO_OFFSET:
2091 /* Used to be a reference to somewhere which was unknown. */
2092 if (fragP->fr_symbol)
2094 if (fragP->fr_opcode == NULL)
2096 /* Used as an absolute value. */
2097 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2098 /* Variable part does not change. */
2099 fragP->fr_var = INST_WORD_SIZE*2;
2101 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2103 /* It is accessed using the small data read only anchor. */
2104 if ((S_GET_SEGMENT (fragP->fr_symbol) == &bfd_com_section)
2105 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2106 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2107 || (! S_IS_DEFINED (fragP->fr_symbol)))
2109 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2110 fragP->fr_var = INST_WORD_SIZE;
2112 else
2114 /* Variable not in small data read only segment accessed
2115 using small data read only anchor. */
2116 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2118 as_bad_where (file, fragP->fr_line,
2119 _("Variable is accessed using small data read "
2120 "only anchor, but it is not in the small data "
2121 "read only section"));
2122 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2123 fragP->fr_var = INST_WORD_SIZE;
2126 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2128 if ((S_GET_SEGMENT (fragP->fr_symbol) == &bfd_com_section)
2129 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2130 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2131 || (!S_IS_DEFINED (fragP->fr_symbol)))
2133 /* It is accessed using the small data read write anchor. */
2134 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2135 fragP->fr_var = INST_WORD_SIZE;
2137 else
2139 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2141 as_bad_where (file, fragP->fr_line,
2142 _("Variable is accessed using small data read "
2143 "write anchor, but it is not in the small data "
2144 "read write section"));
2145 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2146 fragP->fr_var = INST_WORD_SIZE;
2149 else
2151 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2152 abort ();
2155 else
2157 /* We know the abs value: Should never happen. */
2158 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2159 abort ();
2161 break;
2163 case UNDEFINED_PC_OFFSET:
2164 case LARGE_DEFINED_PC_OFFSET:
2165 case DEFINED_ABS_SEGMENT:
2166 case GOT_OFFSET:
2167 case PLT_OFFSET:
2168 case GOTOFF_OFFSET:
2169 fragP->fr_var = INST_WORD_SIZE*2;
2170 break;
2171 case DEFINED_RO_SEGMENT:
2172 case DEFINED_RW_SEGMENT:
2173 case DEFINED_PC_OFFSET:
2174 fragP->fr_var = INST_WORD_SIZE;
2175 break;
2176 default:
2177 abort ();
2180 return fragP->fr_var;
2183 /* Put number into target byte order. */
2185 void
2186 md_number_to_chars (char * ptr, valueT use, int nbytes)
2188 if (target_big_endian)
2189 number_to_chars_bigendian (ptr, use, nbytes);
2190 else
2191 number_to_chars_littleendian (ptr, use, nbytes);
2194 /* Round up a section size to the appropriate boundary. */
2196 valueT
2197 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2199 return size; /* Byte alignment is fine. */
2203 /* The location from which a PC relative jump should be calculated,
2204 given a PC relative reloc. */
2206 long
2207 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2209 #ifdef OBJ_ELF
2210 /* If the symbol is undefined or defined in another section
2211 we leave the add number alone for the linker to fix it later.
2212 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2214 if (fixp->fx_addsy != (symbolS *) NULL
2215 && (!S_IS_DEFINED (fixp->fx_addsy)
2216 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2217 return 0;
2218 else
2220 /* The case where we are going to resolve things... */
2221 if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2222 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2223 else
2224 return fixp->fx_where + fixp->fx_frag->fr_address;
2226 #endif
2230 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2231 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2233 arelent *
2234 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2236 arelent * rel;
2237 bfd_reloc_code_real_type code;
2239 switch (fixp->fx_r_type)
2241 case BFD_RELOC_NONE:
2242 case BFD_RELOC_MICROBLAZE_64_NONE:
2243 case BFD_RELOC_32:
2244 case BFD_RELOC_MICROBLAZE_32_LO:
2245 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2246 case BFD_RELOC_RVA:
2247 case BFD_RELOC_64:
2248 case BFD_RELOC_64_PCREL:
2249 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2250 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2251 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2252 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2253 case BFD_RELOC_MICROBLAZE_64_GOT:
2254 case BFD_RELOC_MICROBLAZE_64_PLT:
2255 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2256 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2257 code = fixp->fx_r_type;
2258 break;
2260 default:
2261 switch (F (fixp->fx_size, fixp->fx_pcrel))
2263 MAP (1, 0, BFD_RELOC_8);
2264 MAP (2, 0, BFD_RELOC_16);
2265 MAP (4, 0, BFD_RELOC_32);
2266 MAP (1, 1, BFD_RELOC_8_PCREL);
2267 MAP (2, 1, BFD_RELOC_16_PCREL);
2268 MAP (4, 1, BFD_RELOC_32_PCREL);
2269 default:
2270 code = fixp->fx_r_type;
2271 as_bad (_("Can not do %d byte %srelocation"),
2272 fixp->fx_size,
2273 fixp->fx_pcrel ? _("pc-relative") : "");
2275 break;
2278 rel = (arelent *) xmalloc (sizeof (arelent));
2279 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2281 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2282 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2283 else
2284 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2286 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2287 /* Always pass the addend along! */
2288 rel->addend = fixp->fx_offset;
2289 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2291 if (rel->howto == NULL)
2293 as_bad_where (fixp->fx_file, fixp->fx_line,
2294 _("Cannot represent relocation type %s"),
2295 bfd_get_reloc_code_name (code));
2297 /* Set howto to a garbage value so that we can keep going. */
2298 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2299 gas_assert (rel->howto != NULL);
2301 return rel;
2305 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
2307 switch (c)
2309 default:
2310 return 0;
2312 return 1;
2315 void
2316 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2318 /* fprintf(stream, _("\
2319 MicroBlaze options:\n\
2320 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2324 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2325 found a machine specific op in an expression,
2326 then we create relocs accordingly. */
2328 void
2329 cons_fix_new_microblaze (fragS * frag,
2330 int where,
2331 int size,
2332 expressionS *exp)
2335 bfd_reloc_code_real_type r;
2337 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2338 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2339 && (!S_IS_LOCAL (exp->X_op_symbol)))
2340 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2341 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2343 exp->X_op = O_symbol;
2344 r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2346 else
2348 switch (size)
2350 case 1:
2351 r = BFD_RELOC_8;
2352 break;
2353 case 2:
2354 r = BFD_RELOC_16;
2355 break;
2356 case 4:
2357 r = BFD_RELOC_32;
2358 break;
2359 case 8:
2360 r = BFD_RELOC_64;
2361 break;
2362 default:
2363 as_bad (_("unsupported BFD relocation size %u"), size);
2364 r = BFD_RELOC_32;
2365 break;
2368 fix_new_exp (frag, where, size, exp, 0, r);