Add stack high register and stack low register for MicroBlaze
[deliverable/binutils-gdb.git] / gas / config / tc-microblaze.c
1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
2
3 Copyright 2009, 2010, 2012 Free Software Foundation.
4
5 This file is part of GAS, the GNU Assembler.
6
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.
11
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.
16
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. */
21
22 #include "as.h"
23 #include <stdio.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"
33
34 #ifndef streq
35 #define streq(a,b) (strcmp (a, b) == 0)
36 #endif
37
38 #define OPTION_EB (OPTION_MD_BASE + 0)
39 #define OPTION_EL (OPTION_MD_BASE + 1)
40
41 void microblaze_generate_symbol (char *sym);
42 static bfd_boolean check_spl_reg (unsigned *);
43
44 /* Several places in this file insert raw instructions into the
45 object. They should generate the instruction
46 and then use these four macros to crack the instruction value into
47 the appropriate byte values. */
48 #define INST_BYTE0(x) (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF))
49 #define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF))
50 #define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF))
51 #define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF))
52
53 /* This array holds the chars that always start a comment. If the
54 pre-processor is disabled, these aren't very useful. */
55 const char comment_chars[] = "#";
56
57 const char line_separator_chars[] = ";";
58
59 /* This array holds the chars that only start a comment at the beginning of
60 a line. */
61 const char line_comment_chars[] = "#";
62
63 const int md_reloc_size = 8; /* Size of relocation record. */
64
65 /* Chars that can be used to separate mant
66 from exp in floating point numbers. */
67 const char EXP_CHARS[] = "eE";
68
69 /* Chars that mean this number is a floating point constant
70 As in 0f12.456
71 or 0d1.2345e12. */
72 const char FLT_CHARS[] = "rRsSfFdDxXpP";
73
74 /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1. */
75 #define UNDEFINED_PC_OFFSET 2
76 #define DEFINED_ABS_SEGMENT 3
77 #define DEFINED_PC_OFFSET 4
78 #define DEFINED_RO_SEGMENT 5
79 #define DEFINED_RW_SEGMENT 6
80 #define LARGE_DEFINED_PC_OFFSET 7
81 #define GOT_OFFSET 8
82 #define PLT_OFFSET 9
83 #define GOTOFF_OFFSET 10
84
85
86 /* Initialize the relax table. */
87 const relax_typeS md_relax_table[] =
88 {
89 { 1, 1, 0, 0 }, /* 0: Unused. */
90 { 1, 1, 0, 0 }, /* 1: Unused. */
91 { 1, 1, 0, 0 }, /* 2: Unused. */
92 { 1, 1, 0, 0 }, /* 3: Unused. */
93 { 32767, -32768, INST_WORD_SIZE, LARGE_DEFINED_PC_OFFSET }, /* 4: DEFINED_PC_OFFSET. */
94 { 1, 1, 0, 0 }, /* 5: Unused. */
95 { 1, 1, 0, 0 }, /* 6: Unused. */
96 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */
97 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */
98 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */
99 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */
100 };
101
102 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */
103
104 static segT sbss_segment = 0; /* Small bss section. */
105 static segT sbss2_segment = 0; /* Section not used. */
106 static segT sdata_segment = 0; /* Small data section. */
107 static segT sdata2_segment = 0; /* Small read-only section. */
108 static segT rodata_segment = 0; /* read-only section. */
109
110 /* Generate a symbol for stabs information. */
111
112 void
113 microblaze_generate_symbol (char *sym)
114 {
115 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001"
116 static int microblaze_label_count;
117 sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count);
118 ++microblaze_label_count;
119 }
120
121 /* Handle the section changing pseudo-ops. */
122
123 static void
124 microblaze_s_text (int ignore ATTRIBUTE_UNUSED)
125 {
126 #ifdef OBJ_ELF
127 obj_elf_text (ignore);
128 #else
129 s_text (ignore);
130 #endif
131 }
132
133 static void
134 microblaze_s_data (int ignore ATTRIBUTE_UNUSED)
135 {
136 #ifdef OBJ_ELF
137 obj_elf_change_section (".data", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
138 #else
139 s_data (ignore);
140 #endif
141 }
142
143 /* Things in the .sdata segment are always considered to be in the small data section. */
144
145 static void
146 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED)
147 {
148 #ifdef OBJ_ELF
149 obj_elf_change_section (".sdata", SHT_PROGBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
150 #else
151 s_data (ignore);
152 #endif
153 }
154
155 /* Pseudo op to make file scope bss items. */
156
157 static void
158 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED)
159 {
160 char *name;
161 char c;
162 char *p;
163 offsetT size;
164 symbolS *symbolP;
165 offsetT align;
166 char *pfrag;
167 int align2;
168 segT current_seg = now_seg;
169 subsegT current_subseg = now_subseg;
170
171 name = input_line_pointer;
172 c = get_symbol_end ();
173
174 /* Just after name is now '\0'. */
175 p = input_line_pointer;
176 *p = c;
177 SKIP_WHITESPACE ();
178 if (*input_line_pointer != ',')
179 {
180 as_bad (_("Expected comma after symbol-name: rest of line ignored."));
181 ignore_rest_of_line ();
182 return;
183 }
184
185 input_line_pointer++; /* skip ',' */
186 if ((size = get_absolute_expression ()) < 0)
187 {
188 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size);
189 ignore_rest_of_line ();
190 return;
191 }
192
193 /* The third argument to .lcomm is the alignment. */
194 if (*input_line_pointer != ',')
195 align = 8;
196 else
197 {
198 ++input_line_pointer;
199 align = get_absolute_expression ();
200 if (align <= 0)
201 {
202 as_warn (_("ignoring bad alignment"));
203 align = 8;
204 }
205 }
206
207 *p = 0;
208 symbolP = symbol_find_or_make (name);
209 *p = c;
210
211 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
212 {
213 as_bad (_("Ignoring attempt to re-define symbol `%s'."),
214 S_GET_NAME (symbolP));
215 ignore_rest_of_line ();
216 return;
217 }
218
219 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size)
220 {
221 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."),
222 S_GET_NAME (symbolP),
223 (long) S_GET_VALUE (symbolP),
224 (long) size);
225
226 ignore_rest_of_line ();
227 return;
228 }
229
230 /* Allocate_bss. */
231 if (align)
232 {
233 /* Convert to a power of 2 alignment. */
234 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2);
235 if (align != 1)
236 {
237 as_bad (_("Common alignment not a power of 2"));
238 ignore_rest_of_line ();
239 return;
240 }
241 }
242 else
243 align2 = 0;
244
245 record_alignment (current_seg, align2);
246 subseg_set (current_seg, current_subseg);
247 if (align2)
248 frag_align (align2, 0, 0);
249 if (S_GET_SEGMENT (symbolP) == current_seg)
250 symbol_get_frag (symbolP)->fr_symbol = 0;
251 symbol_set_frag (symbolP, frag_now);
252 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size,
253 (char *) 0);
254 *pfrag = 0;
255 S_SET_SIZE (symbolP, size);
256 S_SET_SEGMENT (symbolP, current_seg);
257 subseg_set (current_seg, current_subseg);
258 demand_empty_rest_of_line ();
259 }
260
261 static void
262 microblaze_s_rdata (int localvar)
263 {
264 #ifdef OBJ_ELF
265 if (localvar == 0)
266 {
267 /* rodata. */
268 obj_elf_change_section (".rodata", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
269 if (rodata_segment == 0)
270 rodata_segment = subseg_new (".rodata", 0);
271 }
272 else
273 {
274 /* 1 .sdata2. */
275 obj_elf_change_section (".sdata2", SHT_PROGBITS, SHF_ALLOC, 0, 0, 0, 0);
276 }
277 #else
278 s_data (ignore);
279 #endif
280 }
281
282 static void
283 microblaze_s_bss (int localvar)
284 {
285 #ifdef OBJ_ELF
286 if (localvar == 0) /* bss. */
287 obj_elf_change_section (".bss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
288 else if (localvar == 1)
289 {
290 /* sbss. */
291 obj_elf_change_section (".sbss", SHT_NOBITS, SHF_ALLOC+SHF_WRITE, 0, 0, 0, 0);
292 if (sbss_segment == 0)
293 sbss_segment = subseg_new (".sbss", 0);
294 }
295 #else
296 s_data (ignore);
297 #endif
298 }
299
300 /* endp_p is always 1 as this func is called only for .end <funcname>
301 This func consumes the <funcname> and calls regular processing
302 s_func(1) with arg 1 (1 for end). */
303
304 static void
305 microblaze_s_func (int end_p ATTRIBUTE_UNUSED)
306 {
307 *input_line_pointer = get_symbol_end ();
308 s_func (1);
309 }
310
311 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */
312
313 static void
314 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED)
315 {
316 char *name;
317 int c;
318 symbolS *symbolP;
319 expressionS exp;
320
321 name = input_line_pointer;
322 c = get_symbol_end ();
323 symbolP = symbol_find_or_make (name);
324 S_SET_WEAK (symbolP);
325 *input_line_pointer = c;
326
327 SKIP_WHITESPACE ();
328
329 if (!is_end_of_line[(unsigned char) *input_line_pointer])
330 {
331 if (S_IS_DEFINED (symbolP))
332 {
333 as_bad ("Ignoring attempt to redefine symbol `%s'.",
334 S_GET_NAME (symbolP));
335 ignore_rest_of_line ();
336 return;
337 }
338
339 if (*input_line_pointer == ',')
340 {
341 ++input_line_pointer;
342 SKIP_WHITESPACE ();
343 }
344
345 expression (&exp);
346 if (exp.X_op != O_symbol)
347 {
348 as_bad ("bad .weakext directive");
349 ignore_rest_of_line ();
350 return;
351 }
352 symbol_set_value_expression (symbolP, &exp);
353 }
354
355 demand_empty_rest_of_line ();
356 }
357
358 /* This table describes all the machine specific pseudo-ops the assembler
359 has to support. The fields are:
360 Pseudo-op name without dot
361 Function to call to execute this pseudo-op
362 Integer arg to pass to the function. */
363 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c,
364 and then in the read.c table. */
365 const pseudo_typeS md_pseudo_table[] =
366 {
367 {"lcomm", microblaze_s_lcomm, 1},
368 {"data", microblaze_s_data, 0},
369 {"data8", cons, 1}, /* Same as byte. */
370 {"data16", cons, 2}, /* Same as hword. */
371 {"data32", cons, 4}, /* Same as word. */
372 {"ent", s_func, 0}, /* Treat ent as function entry point. */
373 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */
374 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */
375 {"weakext", microblaze_s_weakext, 0},
376 {"rodata", microblaze_s_rdata, 0},
377 {"sdata2", microblaze_s_rdata, 1},
378 {"sdata", microblaze_s_sdata, 0},
379 {"bss", microblaze_s_bss, 0},
380 {"sbss", microblaze_s_bss, 1},
381 {"text", microblaze_s_text, 0},
382 {"word", cons, 4},
383 {"frame", s_ignore, 0},
384 {"mask", s_ignore, 0}, /* Emitted by gcc. */
385 {NULL, NULL, 0}
386 };
387
388 /* This function is called once, at assembler startup time. This should
389 set up all the tables, etc that the MD part of the assembler needs. */
390
391 void
392 md_begin (void)
393 {
394 struct op_code_struct * opcode;
395
396 opcode_hash_control = hash_new ();
397
398 /* Insert unique names into hash table. */
399 for (opcode = opcodes; opcode->name; opcode ++)
400 hash_insert (opcode_hash_control, opcode->name, (char *) opcode);
401 }
402
403 /* Try to parse a reg name. */
404
405 static char *
406 parse_reg (char * s, unsigned * reg)
407 {
408 unsigned tmpreg = 0;
409
410 /* Strip leading whitespace. */
411 while (ISSPACE (* s))
412 ++ s;
413
414 if (strncasecmp (s, "rpc", 3) == 0)
415 {
416 *reg = REG_PC;
417 return s + 3;
418 }
419 else if (strncasecmp (s, "rmsr", 4) == 0)
420 {
421 *reg = REG_MSR;
422 return s + 4;
423 }
424 else if (strncasecmp (s, "rear", 4) == 0)
425 {
426 *reg = REG_EAR;
427 return s + 4;
428 }
429 else if (strncasecmp (s, "resr", 4) == 0)
430 {
431 *reg = REG_ESR;
432 return s + 4;
433 }
434 else if (strncasecmp (s, "rfsr", 4) == 0)
435 {
436 *reg = REG_FSR;
437 return s + 4;
438 }
439 else if (strncasecmp (s, "rbtr", 4) == 0)
440 {
441 *reg = REG_BTR;
442 return s + 4;
443 }
444 else if (strncasecmp (s, "redr", 4) == 0)
445 {
446 *reg = REG_EDR;
447 return s + 4;
448 }
449 /* MMU registers start. */
450 else if (strncasecmp (s, "rpid", 4) == 0)
451 {
452 *reg = REG_PID;
453 return s + 4;
454 }
455 else if (strncasecmp (s, "rzpr", 4) == 0)
456 {
457 *reg = REG_ZPR;
458 return s + 4;
459 }
460 else if (strncasecmp (s, "rtlbx", 5) == 0)
461 {
462 *reg = REG_TLBX;
463 return s + 5;
464 }
465 else if (strncasecmp (s, "rtlblo", 6) == 0)
466 {
467 *reg = REG_TLBLO;
468 return s + 6;
469 }
470 else if (strncasecmp (s, "rtlbhi", 6) == 0)
471 {
472 *reg = REG_TLBHI;
473 return s + 6;
474 }
475 else if (strncasecmp (s, "rtlbsx", 6) == 0)
476 {
477 *reg = REG_TLBSX;
478 return s + 6;
479 }
480 /* MMU registers end. */
481 else if (strncasecmp (s, "rpvr", 4) == 0)
482 {
483 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
484 {
485 tmpreg = (s[4]-'0')*10 + s[5] - '0';
486 s += 6;
487 }
488
489 else if (ISDIGIT (s[4]))
490 {
491 tmpreg = s[4] - '0';
492 s += 5;
493 }
494 else
495 as_bad (_("register expected, but saw '%.6s'"), s);
496 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM)
497 *reg = REG_PVR + tmpreg;
498 else
499 {
500 as_bad (_("Invalid register number at '%.6s'"), s);
501 *reg = REG_PVR;
502 }
503 return s;
504 }
505 else if (strncasecmp (s, "rsp", 3) == 0)
506 {
507 *reg = REG_SP;
508 return s + 3;
509 }
510 else if (strncasecmp (s, "rfsl", 4) == 0)
511 {
512 if (ISDIGIT (s[4]) && ISDIGIT (s[5]))
513 {
514 tmpreg = (s[4] - '0') * 10 + s[5] - '0';
515 s += 6;
516 }
517 else if (ISDIGIT (s[4]))
518 {
519 tmpreg = s[4] - '0';
520 s += 5;
521 }
522 else
523 as_bad (_("register expected, but saw '%.6s'"), s);
524
525 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
526 *reg = tmpreg;
527 else
528 {
529 as_bad (_("Invalid register number at '%.6s'"), s);
530 *reg = 0;
531 }
532 return s;
533 }
534 /* Stack protection registers. */
535 else if (strncasecmp (s, "rshr", 4) == 0)
536 {
537 *reg = REG_SHR;
538 return s + 4;
539 }
540 else if (strncasecmp (s, "rslr", 4) == 0)
541 {
542 *reg = REG_SLR;
543 return s + 4;
544 }
545 else
546 {
547 if (TOLOWER (s[0]) == 'r')
548 {
549 if (ISDIGIT (s[1]) && ISDIGIT (s[2]))
550 {
551 tmpreg = (s[1] - '0') * 10 + s[2] - '0';
552 s += 3;
553 }
554 else if (ISDIGIT (s[1]))
555 {
556 tmpreg = s[1] - '0';
557 s += 2;
558 }
559 else
560 as_bad (_("register expected, but saw '%.6s'"), s);
561
562 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM)
563 *reg = tmpreg;
564 else
565 {
566 as_bad (_("Invalid register number at '%.6s'"), s);
567 *reg = 0;
568 }
569 return s;
570 }
571 }
572 as_bad (_("register expected, but saw '%.6s'"), s);
573 *reg = 0;
574 return s;
575 }
576
577 static char *
578 parse_exp (char *s, expressionS *e)
579 {
580 char *save;
581 char *new_pointer;
582
583 /* Skip whitespace. */
584 while (ISSPACE (* s))
585 ++ s;
586
587 save = input_line_pointer;
588 input_line_pointer = s;
589
590 expression (e);
591
592 if (e->X_op == O_absent)
593 as_fatal (_("missing operand"));
594
595 new_pointer = input_line_pointer;
596 input_line_pointer = save;
597
598 return new_pointer;
599 }
600
601 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */
602 #define IMM_GOT 1
603 #define IMM_PLT 2
604 #define IMM_GOTOFF 3
605
606 static symbolS * GOT_symbol;
607
608 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_"
609
610 static char *
611 parse_imm (char * s, expressionS * e, int min, int max)
612 {
613 char *new_pointer;
614 char *atp;
615
616 /* Find the start of "@GOT" or "@PLT" suffix (if any) */
617 for (atp = s; *atp != '@'; atp++)
618 if (is_end_of_line[(unsigned char) *atp])
619 break;
620
621 if (*atp == '@')
622 {
623 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
624 {
625 *atp = 0;
626 e->X_md = IMM_GOTOFF;
627 }
628 else if (strncmp (atp + 1, "GOT", 3) == 0)
629 {
630 *atp = 0;
631 e->X_md = IMM_GOT;
632 }
633 else if (strncmp (atp + 1, "PLT", 3) == 0)
634 {
635 *atp = 0;
636 e->X_md = IMM_PLT;
637 }
638 else
639 {
640 atp = NULL;
641 e->X_md = 0;
642 }
643 *atp = 0;
644 }
645 else
646 {
647 atp = NULL;
648 e->X_md = 0;
649 }
650
651 if (atp && !GOT_symbol)
652 {
653 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
654 }
655
656 new_pointer = parse_exp (s, e);
657
658 if (e->X_op == O_absent)
659 ; /* An error message has already been emitted. */
660 else if ((e->X_op != O_constant && e->X_op != O_symbol) )
661 as_fatal (_("operand must be a constant or a label"));
662 else if ((e->X_op == O_constant) && ((int) e->X_add_number < min
663 || (int) e->X_add_number > max))
664 {
665 as_fatal (_("operand must be absolute in range %d..%d, not %d"),
666 min, max, (int) e->X_add_number);
667 }
668
669 if (atp)
670 {
671 *atp = '@'; /* restore back (needed?) */
672 if (new_pointer >= atp)
673 new_pointer += (e->X_md == IMM_GOTOFF)?7:4;
674 /* sizeof("@GOTOFF", "@GOT" or "@PLT") */
675
676 }
677 return new_pointer;
678 }
679
680 static char *
681 check_got (int * got_type, int * got_len)
682 {
683 char *new_pointer;
684 char *atp;
685 char *past_got;
686 int first, second;
687 char *tmpbuf;
688
689 /* Find the start of "@GOT" or "@PLT" suffix (if any). */
690 for (atp = input_line_pointer; *atp != '@'; atp++)
691 if (is_end_of_line[(unsigned char) *atp])
692 return NULL;
693
694 if (strncmp (atp + 1, "GOTOFF", 5) == 0)
695 {
696 *got_len = 6;
697 *got_type = IMM_GOTOFF;
698 }
699 else if (strncmp (atp + 1, "GOT", 3) == 0)
700 {
701 *got_len = 3;
702 *got_type = IMM_GOT;
703 }
704 else if (strncmp (atp + 1, "PLT", 3) == 0)
705 {
706 *got_len = 3;
707 *got_type = IMM_PLT;
708 }
709 else
710 return NULL;
711
712 if (!GOT_symbol)
713 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME);
714
715 first = atp - input_line_pointer;
716
717 past_got = atp + *got_len + 1;
718 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];)
719 ;
720 second = new_pointer - past_got;
721 tmpbuf = xmalloc (first + second + 2); /* One extra byte for ' ' and one for NUL. */
722 memcpy (tmpbuf, input_line_pointer, first);
723 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */
724 memcpy (tmpbuf + first + 1, past_got, second);
725 tmpbuf[first + second + 1] = '\0';
726
727 return tmpbuf;
728 }
729
730 extern void
731 parse_cons_expression_microblaze (expressionS *exp, int size)
732 {
733 if (size == 4)
734 {
735 /* Handle @GOTOFF et.al. */
736 char *save, *gotfree_copy;
737 int got_len, got_type;
738
739 save = input_line_pointer;
740 gotfree_copy = check_got (& got_type, & got_len);
741 if (gotfree_copy)
742 input_line_pointer = gotfree_copy;
743
744 expression (exp);
745
746 if (gotfree_copy)
747 {
748 exp->X_md = got_type;
749 input_line_pointer = save + (input_line_pointer - gotfree_copy)
750 + got_len;
751 free (gotfree_copy);
752 }
753 }
754 else
755 expression (exp);
756 }
757
758 /* This is the guts of the machine-dependent assembler. STR points to a
759 machine dependent instruction. This function is supposed to emit
760 the frags/bytes it assembles to. */
761
762 static char * str_microblaze_ro_anchor = "RO";
763 static char * str_microblaze_rw_anchor = "RW";
764
765 static bfd_boolean
766 check_spl_reg (unsigned * reg)
767 {
768 if ((*reg == REG_MSR) || (*reg == REG_PC)
769 || (*reg == REG_EAR) || (*reg == REG_ESR)
770 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR)
771 || (*reg == REG_PID) || (*reg == REG_ZPR)
772 || (*reg == REG_TLBX) || (*reg == REG_TLBLO)
773 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX)
774 || (*reg == REG_SHR) || (*reg == REG_SLR)
775 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM))
776 return TRUE;
777
778 return FALSE;
779 }
780
781 /* Here we decide which fixups can be adjusted to make them relative to
782 the beginning of the section instead of the symbol. Basically we need
783 to make sure that the dynamic relocations are done correctly, so in
784 some cases we force the original symbol to be used. */
785
786 int
787 tc_microblaze_fix_adjustable (struct fix *fixP)
788 {
789 if (GOT_symbol && fixP->fx_subsy == GOT_symbol)
790 return 0;
791
792 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF
793 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF
794 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT
795 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT)
796 return 0;
797
798 return 1;
799 }
800
801 void
802 md_assemble (char * str)
803 {
804 char * op_start;
805 char * op_end;
806 struct op_code_struct * opcode, *opcode1;
807 char * output = NULL;
808 int nlen = 0;
809 int i;
810 unsigned long inst, inst1;
811 unsigned reg1;
812 unsigned reg2;
813 unsigned reg3;
814 unsigned isize;
815 unsigned int immed, temp;
816 expressionS exp;
817 char name[20];
818
819 /* Drop leading whitespace. */
820 while (ISSPACE (* str))
821 str ++;
822
823 /* Find the op code end. */
824 for (op_start = op_end = str;
825 *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' ';
826 op_end++)
827 {
828 name[nlen] = op_start[nlen];
829 nlen++;
830 if (nlen == sizeof (name) - 1)
831 break;
832 }
833
834 name [nlen] = 0;
835
836 if (nlen == 0)
837 {
838 as_bad (_("can't find opcode "));
839 return;
840 }
841
842 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
843 if (opcode == NULL)
844 {
845 as_bad (_("unknown opcode \"%s\""), name);
846 return;
847 }
848
849 inst = opcode->bit_sequence;
850 isize = 4;
851
852 switch (opcode->inst_type)
853 {
854 case INST_TYPE_RD_R1_R2:
855 if (strcmp (op_end, ""))
856 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
857 else
858 {
859 as_fatal (_("Error in statement syntax"));
860 reg1 = 0;
861 }
862 if (strcmp (op_end, ""))
863 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
864 else
865 {
866 as_fatal (_("Error in statement syntax"));
867 reg2 = 0;
868 }
869 if (strcmp (op_end, ""))
870 op_end = parse_reg (op_end + 1, &reg3); /* Get r2. */
871 else
872 {
873 as_fatal (_("Error in statement syntax"));
874 reg3 = 0;
875 }
876
877 /* Check for spl registers. */
878 if (check_spl_reg (& reg1))
879 as_fatal (_("Cannot use special register with this instruction"));
880 if (check_spl_reg (& reg2))
881 as_fatal (_("Cannot use special register with this instruction"));
882 if (check_spl_reg (& reg3))
883 as_fatal (_("Cannot use special register with this instruction"));
884
885 if (streq (name, "sub"))
886 {
887 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
888 inst |= (reg1 << RD_LOW) & RD_MASK;
889 inst |= (reg3 << RA_LOW) & RA_MASK;
890 inst |= (reg2 << RB_LOW) & RB_MASK;
891 }
892 else
893 {
894 inst |= (reg1 << RD_LOW) & RD_MASK;
895 inst |= (reg2 << RA_LOW) & RA_MASK;
896 inst |= (reg3 << RB_LOW) & RB_MASK;
897 }
898 output = frag_more (isize);
899 break;
900
901 case INST_TYPE_RD_R1_IMM:
902 if (strcmp (op_end, ""))
903 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
904 else
905 {
906 as_fatal (_("Error in statement syntax"));
907 reg1 = 0;
908 }
909 if (strcmp (op_end, ""))
910 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
911 else
912 {
913 as_fatal (_("Error in statement syntax"));
914 reg2 = 0;
915 }
916 if (strcmp (op_end, ""))
917 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
918 else
919 as_fatal (_("Error in statement syntax"));
920
921 /* Check for spl registers. */
922 if (check_spl_reg (& reg1))
923 as_fatal (_("Cannot use special register with this instruction"));
924 if (check_spl_reg (& reg2))
925 as_fatal (_("Cannot use special register with this instruction"));
926
927 if (exp.X_op != O_constant)
928 {
929 char *opc;
930 relax_substateT subtype;
931
932 if (streq (name, "lmi"))
933 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
934 else if (streq (name, "smi"))
935 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
936
937 if (reg2 == REG_ROSDP)
938 opc = str_microblaze_ro_anchor;
939 else if (reg2 == REG_RWSDP)
940 opc = str_microblaze_rw_anchor;
941 else
942 opc = NULL;
943 if (exp.X_md == IMM_GOT)
944 subtype = GOT_OFFSET;
945 else if (exp.X_md == IMM_PLT)
946 subtype = PLT_OFFSET;
947 else if (exp.X_md == IMM_GOTOFF)
948 subtype = GOTOFF_OFFSET;
949 else
950 subtype = opcode->inst_offset_type;
951
952 output = frag_var (rs_machine_dependent,
953 isize * 2, /* maxm of 2 words. */
954 isize, /* minm of 1 word. */
955 subtype, /* PC-relative or not. */
956 exp.X_add_symbol,
957 exp.X_add_number,
958 opc);
959 immed = 0;
960 }
961 else
962 {
963 output = frag_more (isize);
964 immed = exp.X_add_number;
965 }
966
967 if (streq (name, "lmi") || streq (name, "smi"))
968 {
969 /* Load/store 32-d consecutive registers. Used on exit/entry
970 to subroutines to save and restore registers to stack.
971 Generate 32-d insts. */
972 int count;
973
974 count = 32 - reg1;
975 if (streq (name, "lmi"))
976 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
977 else
978 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
979 if (opcode == NULL)
980 {
981 as_bad (_("unknown opcode \"%s\""), "lwi");
982 return;
983 }
984 inst = opcode->bit_sequence;
985 inst |= (reg1 << RD_LOW) & RD_MASK;
986 inst |= (reg2 << RA_LOW) & RA_MASK;
987 inst |= (immed << IMM_LOW) & IMM_MASK;
988
989 for (i = 0; i < count - 1; i++)
990 {
991 output[0] = INST_BYTE0 (inst);
992 output[1] = INST_BYTE1 (inst);
993 output[2] = INST_BYTE2 (inst);
994 output[3] = INST_BYTE3 (inst);
995 output = frag_more (isize);
996 immed = immed + 4;
997 reg1++;
998 inst = opcode->bit_sequence;
999 inst |= (reg1 << RD_LOW) & RD_MASK;
1000 inst |= (reg2 << RA_LOW) & RA_MASK;
1001 inst |= (immed << IMM_LOW) & IMM_MASK;
1002 }
1003 }
1004 else
1005 {
1006 temp = immed & 0xFFFF8000;
1007 if ((temp != 0) && (temp != 0xFFFF8000))
1008 {
1009 /* Needs an immediate inst. */
1010 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1011 if (opcode1 == NULL)
1012 {
1013 as_bad (_("unknown opcode \"%s\""), "imm");
1014 return;
1015 }
1016
1017 inst1 = opcode1->bit_sequence;
1018 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1019 output[0] = INST_BYTE0 (inst1);
1020 output[1] = INST_BYTE1 (inst1);
1021 output[2] = INST_BYTE2 (inst1);
1022 output[3] = INST_BYTE3 (inst1);
1023 output = frag_more (isize);
1024 }
1025 inst |= (reg1 << RD_LOW) & RD_MASK;
1026 inst |= (reg2 << RA_LOW) & RA_MASK;
1027 inst |= (immed << IMM_LOW) & IMM_MASK;
1028 }
1029 break;
1030
1031 case INST_TYPE_RD_R1_IMM5:
1032 if (strcmp (op_end, ""))
1033 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1034 else
1035 {
1036 as_fatal (_("Error in statement syntax"));
1037 reg1 = 0;
1038 }
1039 if (strcmp (op_end, ""))
1040 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1041 else
1042 {
1043 as_fatal (_("Error in statement syntax"));
1044 reg2 = 0;
1045 }
1046 if (strcmp (op_end, ""))
1047 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1048 else
1049 as_fatal (_("Error in statement syntax"));
1050
1051 /* Check for spl registers. */
1052 if (check_spl_reg (&reg1))
1053 as_fatal (_("Cannot use special register with this instruction"));
1054 if (check_spl_reg (&reg2))
1055 as_fatal (_("Cannot use special register with this instruction"));
1056
1057 if (exp.X_op != O_constant)
1058 as_warn (_("Symbol used as immediate for shift instruction"));
1059 else
1060 {
1061 output = frag_more (isize);
1062 immed = exp.X_add_number;
1063 }
1064
1065 if (immed != (immed % 32))
1066 {
1067 as_warn (_("Shift value > 32. using <value %% 32>"));
1068 immed = immed % 32;
1069 }
1070 inst |= (reg1 << RD_LOW) & RD_MASK;
1071 inst |= (reg2 << RA_LOW) & RA_MASK;
1072 inst |= (immed << IMM_LOW) & IMM5_MASK;
1073 break;
1074
1075 case INST_TYPE_R1_R2:
1076 if (strcmp (op_end, ""))
1077 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1078 else
1079 {
1080 as_fatal (_("Error in statement syntax"));
1081 reg1 = 0;
1082 }
1083 if (strcmp (op_end, ""))
1084 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1085 else
1086 {
1087 as_fatal (_("Error in statement syntax"));
1088 reg2 = 0;
1089 }
1090
1091 /* Check for spl registers. */
1092 if (check_spl_reg (& reg1))
1093 as_fatal (_("Cannot use special register with this instruction"));
1094 if (check_spl_reg (& reg2))
1095 as_fatal (_("Cannot use special register with this instruction"));
1096
1097 inst |= (reg1 << RA_LOW) & RA_MASK;
1098 inst |= (reg2 << RB_LOW) & RB_MASK;
1099 output = frag_more (isize);
1100 break;
1101
1102 case INST_TYPE_RD_R1:
1103 if (strcmp (op_end, ""))
1104 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1105 else
1106 {
1107 as_fatal (_("Error in statement syntax"));
1108 reg1 = 0;
1109 }
1110 if (strcmp (op_end, ""))
1111 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1112 else
1113 {
1114 as_fatal (_("Error in statement syntax"));
1115 reg2 =0;
1116 }
1117
1118 /* Check for spl registers. */
1119 if (check_spl_reg (&reg1))
1120 as_fatal (_("Cannot use special register with this instruction"));
1121 if (check_spl_reg (&reg2))
1122 as_fatal (_("Cannot use special register with this instruction"));
1123
1124 inst |= (reg1 << RD_LOW) & RD_MASK;
1125 inst |= (reg2 << RA_LOW) & RA_MASK;
1126 output = frag_more (isize);
1127 break;
1128
1129 case INST_TYPE_RD_RFSL:
1130 if (strcmp (op_end, ""))
1131 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1132 else
1133 {
1134 as_fatal (_("Error in statement syntax"));
1135 reg1 = 0;
1136 }
1137 if (strcmp (op_end, ""))
1138 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1139 else
1140 {
1141 as_fatal (_("Error in statement syntax"));
1142 immed = 0;
1143 }
1144
1145 /* Check for spl registers. */
1146 if (check_spl_reg (&reg1))
1147 as_fatal (_("Cannot use special register with this instruction"));
1148
1149 inst |= (reg1 << RD_LOW) & RD_MASK;
1150 inst |= (immed << IMM_LOW) & RFSL_MASK;
1151 output = frag_more (isize);
1152 break;
1153
1154 case INST_TYPE_RD_IMM15:
1155 if (strcmp (op_end, ""))
1156 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1157 else
1158 {
1159 as_fatal (_("Error in statement syntax"));
1160 reg1 = 0;
1161 }
1162
1163 if (strcmp (op_end, ""))
1164 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1165 else
1166 as_fatal (_("Error in statement syntax"));
1167
1168 /* Check for spl registers. */
1169 if (check_spl_reg (&reg1))
1170 as_fatal (_("Cannot use special register with this instruction"));
1171
1172 if (exp.X_op != O_constant)
1173 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1174 else
1175 {
1176 output = frag_more (isize);
1177 immed = exp.X_add_number;
1178 }
1179 inst |= (reg1 << RD_LOW) & RD_MASK;
1180 inst |= (immed << IMM_LOW) & IMM15_MASK;
1181 break;
1182
1183 case INST_TYPE_R1_RFSL:
1184 if (strcmp (op_end, ""))
1185 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1186 else
1187 {
1188 as_fatal (_("Error in statement syntax"));
1189 reg1 = 0;
1190 }
1191 if (strcmp (op_end, ""))
1192 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1193 else
1194 {
1195 as_fatal (_("Error in statement syntax"));
1196 immed = 0;
1197 }
1198
1199 /* Check for spl registers. */
1200 if (check_spl_reg (&reg1))
1201 as_fatal (_("Cannot use special register with this instruction"));
1202
1203 inst |= (reg1 << RA_LOW) & RA_MASK;
1204 inst |= (immed << IMM_LOW) & RFSL_MASK;
1205 output = frag_more (isize);
1206 break;
1207
1208 case INST_TYPE_RFSL:
1209 if (strcmp (op_end, ""))
1210 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1211 else
1212 {
1213 as_fatal (_("Error in statement syntax"));
1214 immed = 0;
1215 }
1216 inst |= (immed << IMM_LOW) & RFSL_MASK;
1217 output = frag_more (isize);
1218 break;
1219
1220 case INST_TYPE_R1:
1221 if (strcmp (op_end, ""))
1222 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1223 else
1224 {
1225 as_fatal (_("Error in statement syntax"));
1226 reg1 = 0;
1227 }
1228
1229 /* Check for spl registers. */
1230 if (check_spl_reg (&reg1))
1231 as_fatal (_("Cannot use special register with this instruction"));
1232
1233 inst |= (reg1 << RA_LOW) & RA_MASK;
1234 output = frag_more (isize);
1235 break;
1236
1237 /* For tuqula insn...:) */
1238 case INST_TYPE_RD:
1239 if (strcmp (op_end, ""))
1240 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1241 else
1242 {
1243 as_fatal (_("Error in statement syntax"));
1244 reg1 = 0;
1245 }
1246
1247 /* Check for spl registers. */
1248 if (check_spl_reg (&reg1))
1249 as_fatal (_("Cannot use special register with this instruction"));
1250
1251 inst |= (reg1 << RD_LOW) & RD_MASK;
1252 output = frag_more (isize);
1253 break;
1254
1255 case INST_TYPE_RD_SPECIAL:
1256 if (strcmp (op_end, ""))
1257 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1258 else
1259 {
1260 as_fatal (_("Error in statement syntax"));
1261 reg1 = 0;
1262 }
1263 if (strcmp (op_end, ""))
1264 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1265 else
1266 {
1267 as_fatal (_("Error in statement syntax"));
1268 reg2 = 0;
1269 }
1270
1271 if (reg2 == REG_MSR)
1272 immed = opcode->immval_mask | REG_MSR_MASK;
1273 else if (reg2 == REG_PC)
1274 immed = opcode->immval_mask | REG_PC_MASK;
1275 else if (reg2 == REG_EAR)
1276 immed = opcode->immval_mask | REG_EAR_MASK;
1277 else if (reg2 == REG_ESR)
1278 immed = opcode->immval_mask | REG_ESR_MASK;
1279 else if (reg2 == REG_FSR)
1280 immed = opcode->immval_mask | REG_FSR_MASK;
1281 else if (reg2 == REG_BTR)
1282 immed = opcode->immval_mask | REG_BTR_MASK;
1283 else if (reg2 == REG_EDR)
1284 immed = opcode->immval_mask | REG_EDR_MASK;
1285 else if (reg2 == REG_PID)
1286 immed = opcode->immval_mask | REG_PID_MASK;
1287 else if (reg2 == REG_ZPR)
1288 immed = opcode->immval_mask | REG_ZPR_MASK;
1289 else if (reg2 == REG_TLBX)
1290 immed = opcode->immval_mask | REG_TLBX_MASK;
1291 else if (reg2 == REG_TLBLO)
1292 immed = opcode->immval_mask | REG_TLBLO_MASK;
1293 else if (reg2 == REG_TLBHI)
1294 immed = opcode->immval_mask | REG_TLBHI_MASK;
1295 else if (reg2 == REG_SHR)
1296 immed = opcode->immval_mask | REG_SHR_MASK;
1297 else if (reg2 == REG_SLR)
1298 immed = opcode->immval_mask | REG_SLR_MASK;
1299 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1300 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1301 else
1302 as_fatal (_("invalid value for special purpose register"));
1303 inst |= (reg1 << RD_LOW) & RD_MASK;
1304 inst |= (immed << IMM_LOW) & IMM_MASK;
1305 output = frag_more (isize);
1306 break;
1307
1308 case INST_TYPE_SPECIAL_R1:
1309 if (strcmp (op_end, ""))
1310 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1311 else
1312 {
1313 as_fatal (_("Error in statement syntax"));
1314 reg1 = 0;
1315 }
1316 if (strcmp (op_end, ""))
1317 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1318 else
1319 {
1320 as_fatal (_("Error in statement syntax"));
1321 reg2 = 0;
1322 }
1323
1324 if (reg1 == REG_MSR)
1325 immed = opcode->immval_mask | REG_MSR_MASK;
1326 else if (reg1 == REG_PC)
1327 immed = opcode->immval_mask | REG_PC_MASK;
1328 else if (reg1 == REG_EAR)
1329 immed = opcode->immval_mask | REG_EAR_MASK;
1330 else if (reg1 == REG_ESR)
1331 immed = opcode->immval_mask | REG_ESR_MASK;
1332 else if (reg1 == REG_FSR)
1333 immed = opcode->immval_mask | REG_FSR_MASK;
1334 else if (reg1 == REG_BTR)
1335 immed = opcode->immval_mask | REG_BTR_MASK;
1336 else if (reg1 == REG_EDR)
1337 immed = opcode->immval_mask | REG_EDR_MASK;
1338 else if (reg1 == REG_PID)
1339 immed = opcode->immval_mask | REG_PID_MASK;
1340 else if (reg1 == REG_ZPR)
1341 immed = opcode->immval_mask | REG_ZPR_MASK;
1342 else if (reg1 == REG_TLBX)
1343 immed = opcode->immval_mask | REG_TLBX_MASK;
1344 else if (reg1 == REG_TLBLO)
1345 immed = opcode->immval_mask | REG_TLBLO_MASK;
1346 else if (reg1 == REG_TLBHI)
1347 immed = opcode->immval_mask | REG_TLBHI_MASK;
1348 else if (reg1 == REG_TLBSX)
1349 immed = opcode->immval_mask | REG_TLBSX_MASK;
1350 else if (reg1 == REG_SHR)
1351 immed = opcode->immval_mask | REG_SHR_MASK;
1352 else if (reg1 == REG_SLR)
1353 immed = opcode->immval_mask | REG_SLR_MASK;
1354 else
1355 as_fatal (_("invalid value for special purpose register"));
1356 inst |= (reg2 << RA_LOW) & RA_MASK;
1357 inst |= (immed << IMM_LOW) & IMM_MASK;
1358 output = frag_more (isize);
1359 break;
1360
1361 case INST_TYPE_RD_R1_SPECIAL:
1362 if (strcmp (op_end, ""))
1363 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1364 else
1365 {
1366 as_fatal (_("Error in statement syntax"));
1367 reg1 = 0;
1368 }
1369 if (strcmp (op_end, ""))
1370 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1371 else
1372 {
1373 as_fatal (_("Error in statement syntax"));
1374 reg2 =0;
1375 }
1376
1377 /* Check for spl registers. */
1378 if (check_spl_reg (&reg1))
1379 as_fatal (_("Cannot use special register with this instruction"));
1380 if (check_spl_reg (&reg2))
1381 as_fatal (_("Cannot use special register with this instruction"));
1382
1383 /* insn wic ra, rb => wic ra, ra, rb. */
1384 inst |= (reg1 << RD_LOW) & RD_MASK;
1385 inst |= (reg1 << RA_LOW) & RA_MASK;
1386 inst |= (reg2 << RB_LOW) & RB_MASK;
1387
1388 output = frag_more (isize);
1389 break;
1390
1391 case INST_TYPE_RD_R2:
1392 if (strcmp (op_end, ""))
1393 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1394 else
1395 {
1396 as_fatal (_("Error in statement syntax"));
1397 reg1 = 0;
1398 }
1399 if (strcmp (op_end, ""))
1400 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1401 else
1402 {
1403 as_fatal (_("Error in statement syntax"));
1404 reg2 = 0;
1405 }
1406
1407 /* Check for spl registers. */
1408 if (check_spl_reg (&reg1))
1409 as_fatal (_("Cannot use special register with this instruction"));
1410 if (check_spl_reg (&reg2))
1411 as_fatal (_("Cannot use special register with this instruction"));
1412
1413 inst |= (reg1 << RD_LOW) & RD_MASK;
1414 inst |= (reg2 << RB_LOW) & RB_MASK;
1415 output = frag_more (isize);
1416 break;
1417
1418 case INST_TYPE_R1_IMM:
1419 if (strcmp (op_end, ""))
1420 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1421 else
1422 {
1423 as_fatal (_("Error in statement syntax"));
1424 reg1 = 0;
1425 }
1426 if (strcmp (op_end, ""))
1427 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1428 else
1429 as_fatal (_("Error in statement syntax"));
1430
1431 /* Check for spl registers. */
1432 if (check_spl_reg (&reg1))
1433 as_fatal (_("Cannot use special register with this instruction"));
1434
1435 if (exp.X_op != O_constant)
1436 {
1437 char *opc = NULL;
1438 relax_substateT subtype;
1439
1440 if (exp.X_md == IMM_GOT)
1441 subtype = GOT_OFFSET;
1442 else if (exp.X_md == IMM_PLT)
1443 subtype = PLT_OFFSET;
1444 else
1445 subtype = opcode->inst_offset_type;
1446 output = frag_var (rs_machine_dependent,
1447 isize * 2, /* maxm of 2 words. */
1448 isize, /* minm of 1 word. */
1449 subtype, /* PC-relative or not. */
1450 exp.X_add_symbol,
1451 exp.X_add_number,
1452 opc);
1453 immed = 0;
1454 }
1455 else
1456 {
1457 output = frag_more (isize);
1458 immed = exp.X_add_number;
1459 }
1460
1461 temp = immed & 0xFFFF8000;
1462 if ((temp != 0) && (temp != 0xFFFF8000))
1463 {
1464 /* Needs an immediate inst. */
1465 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1466 if (opcode1 == NULL)
1467 {
1468 as_bad (_("unknown opcode \"%s\""), "imm");
1469 return;
1470 }
1471
1472 inst1 = opcode1->bit_sequence;
1473 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1474 output[0] = INST_BYTE0 (inst1);
1475 output[1] = INST_BYTE1 (inst1);
1476 output[2] = INST_BYTE2 (inst1);
1477 output[3] = INST_BYTE3 (inst1);
1478 output = frag_more (isize);
1479 }
1480
1481 inst |= (reg1 << RA_LOW) & RA_MASK;
1482 inst |= (immed << IMM_LOW) & IMM_MASK;
1483 break;
1484
1485 case INST_TYPE_RD_IMM:
1486 if (strcmp (op_end, ""))
1487 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1488 else
1489 {
1490 as_fatal (_("Error in statement syntax"));
1491 reg1 = 0;
1492 }
1493 if (strcmp (op_end, ""))
1494 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1495 else
1496 as_fatal (_("Error in statement syntax"));
1497
1498 /* Check for spl registers. */
1499 if (check_spl_reg (&reg1))
1500 as_fatal (_("Cannot use special register with this instruction"));
1501
1502 if (exp.X_op != O_constant)
1503 {
1504 char *opc = NULL;
1505 relax_substateT subtype;
1506
1507 if (exp.X_md == IMM_GOT)
1508 subtype = GOT_OFFSET;
1509 else if (exp.X_md == IMM_PLT)
1510 subtype = PLT_OFFSET;
1511 else
1512 subtype = opcode->inst_offset_type;
1513 output = frag_var (rs_machine_dependent,
1514 isize * 2, /* maxm of 2 words. */
1515 isize, /* minm of 1 word. */
1516 subtype, /* PC-relative or not. */
1517 exp.X_add_symbol,
1518 exp.X_add_number,
1519 opc);
1520 immed = 0;
1521 }
1522 else
1523 {
1524 output = frag_more (isize);
1525 immed = exp.X_add_number;
1526 }
1527
1528 temp = immed & 0xFFFF8000;
1529 if ((temp != 0) && (temp != 0xFFFF8000))
1530 {
1531 /* Needs an immediate inst. */
1532 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1533 if (opcode1 == NULL)
1534 {
1535 as_bad (_("unknown opcode \"%s\""), "imm");
1536 return;
1537 }
1538
1539 inst1 = opcode1->bit_sequence;
1540 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1541 output[0] = INST_BYTE0 (inst1);
1542 output[1] = INST_BYTE1 (inst1);
1543 output[2] = INST_BYTE2 (inst1);
1544 output[3] = INST_BYTE3 (inst1);
1545 output = frag_more (isize);
1546 }
1547
1548 inst |= (reg1 << RD_LOW) & RD_MASK;
1549 inst |= (immed << IMM_LOW) & IMM_MASK;
1550 break;
1551
1552 case INST_TYPE_R2:
1553 if (strcmp (op_end, ""))
1554 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1555 else
1556 {
1557 as_fatal (_("Error in statement syntax"));
1558 reg2 = 0;
1559 }
1560
1561 /* Check for spl registers. */
1562 if (check_spl_reg (&reg2))
1563 as_fatal (_("Cannot use special register with this instruction"));
1564
1565 inst |= (reg2 << RB_LOW) & RB_MASK;
1566 output = frag_more (isize);
1567 break;
1568
1569 case INST_TYPE_IMM:
1570 if (streq (name, "imm"))
1571 as_fatal (_("An IMM instruction should not be present in the .s file"));
1572
1573 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1574
1575 if (exp.X_op != O_constant)
1576 {
1577 char *opc = NULL;
1578 relax_substateT subtype;
1579
1580 if (exp.X_md == IMM_GOT)
1581 subtype = GOT_OFFSET;
1582 else if (exp.X_md == IMM_PLT)
1583 subtype = PLT_OFFSET;
1584 else
1585 subtype = opcode->inst_offset_type;
1586 output = frag_var (rs_machine_dependent,
1587 isize * 2, /* maxm of 2 words. */
1588 isize, /* minm of 1 word. */
1589 subtype, /* PC-relative or not. */
1590 exp.X_add_symbol,
1591 exp.X_add_number,
1592 opc);
1593 immed = 0;
1594 }
1595 else
1596 {
1597 output = frag_more (isize);
1598 immed = exp.X_add_number;
1599 }
1600
1601
1602 temp = immed & 0xFFFF8000;
1603 if ((temp != 0) && (temp != 0xFFFF8000))
1604 {
1605 /* Needs an immediate inst. */
1606 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1607 if (opcode1 == NULL)
1608 {
1609 as_bad (_("unknown opcode \"%s\""), "imm");
1610 return;
1611 }
1612
1613 inst1 = opcode1->bit_sequence;
1614 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1615 output[0] = INST_BYTE0 (inst1);
1616 output[1] = INST_BYTE1 (inst1);
1617 output[2] = INST_BYTE2 (inst1);
1618 output[3] = INST_BYTE3 (inst1);
1619 output = frag_more (isize);
1620 }
1621 inst |= (immed << IMM_LOW) & IMM_MASK;
1622 break;
1623
1624 case INST_TYPE_NONE:
1625 output = frag_more (isize);
1626 break;
1627
1628 case INST_TYPE_IMM5:
1629 if (strcmp(op_end, ""))
1630 op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5);
1631 else
1632 as_fatal(_("Error in statement syntax"));
1633 if (exp.X_op != O_constant) {
1634 as_warn(_("Symbol used as immediate for mbar instruction"));
1635 } else {
1636 output = frag_more (isize);
1637 immed = exp.X_add_number;
1638 }
1639 if (immed != (immed % 32)) {
1640 as_warn(_("Immediate value for mbar > 32. using <value %% 32>"));
1641 immed = immed % 32;
1642 }
1643 inst |= (immed << IMM_MBAR);
1644 break;
1645
1646 default:
1647 as_fatal (_("unimplemented opcode \"%s\""), name);
1648 }
1649
1650 /* Drop whitespace after all the operands have been parsed. */
1651 while (ISSPACE (* op_end))
1652 op_end ++;
1653
1654 /* Give warning message if the insn has more operands than required. */
1655 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1656 as_warn (_("ignoring operands: %s "), op_end);
1657
1658 output[0] = INST_BYTE0 (inst);
1659 output[1] = INST_BYTE1 (inst);
1660 output[2] = INST_BYTE2 (inst);
1661 output[3] = INST_BYTE3 (inst);
1662
1663 #ifdef OBJ_ELF
1664 dwarf2_emit_insn (4);
1665 #endif
1666 }
1667
1668 symbolS *
1669 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1670 {
1671 return NULL;
1672 }
1673
1674 /* Various routines to kill one day. */
1675 /* Equal to MAX_PRECISION in atof-ieee.c */
1676 #define MAX_LITTLENUMS 6
1677
1678 /* Turn a string in input_line_pointer into a floating point constant of type
1679 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1680 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1681 char *
1682 md_atof (int type, char * litP, int * sizeP)
1683 {
1684 int prec;
1685 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1686 int i;
1687 char * t;
1688
1689 switch (type)
1690 {
1691 case 'f':
1692 case 'F':
1693 case 's':
1694 case 'S':
1695 prec = 2;
1696 break;
1697
1698 case 'd':
1699 case 'D':
1700 case 'r':
1701 case 'R':
1702 prec = 4;
1703 break;
1704
1705 case 'x':
1706 case 'X':
1707 prec = 6;
1708 break;
1709
1710 case 'p':
1711 case 'P':
1712 prec = 6;
1713 break;
1714
1715 default:
1716 *sizeP = 0;
1717 return _("Bad call to MD_NTOF()");
1718 }
1719
1720 t = atof_ieee (input_line_pointer, type, words);
1721
1722 if (t)
1723 input_line_pointer = t;
1724
1725 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1726
1727 if (! target_big_endian)
1728 {
1729 for (i = prec - 1; i >= 0; i--)
1730 {
1731 md_number_to_chars (litP, (valueT) words[i],
1732 sizeof (LITTLENUM_TYPE));
1733 litP += sizeof (LITTLENUM_TYPE);
1734 }
1735 }
1736 else
1737 for (i = 0; i < prec; i++)
1738 {
1739 md_number_to_chars (litP, (valueT) words[i],
1740 sizeof (LITTLENUM_TYPE));
1741 litP += sizeof (LITTLENUM_TYPE);
1742 }
1743
1744 return NULL;
1745 }
1746 \f
1747 const char * md_shortopts = "";
1748
1749 struct option md_longopts[] =
1750 {
1751 {"EB", no_argument, NULL, OPTION_EB},
1752 {"EL", no_argument, NULL, OPTION_EL},
1753 { NULL, no_argument, NULL, 0}
1754 };
1755
1756 size_t md_longopts_size = sizeof (md_longopts);
1757
1758 int md_short_jump_size;
1759
1760 void
1761 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1762 addressT from_Nddr ATTRIBUTE_UNUSED,
1763 addressT to_Nddr ATTRIBUTE_UNUSED,
1764 fragS * frag ATTRIBUTE_UNUSED,
1765 symbolS * to_symbol ATTRIBUTE_UNUSED)
1766 {
1767 as_fatal (_("failed sanity check: short_jump"));
1768 }
1769
1770 void
1771 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1772 addressT from_Nddr ATTRIBUTE_UNUSED,
1773 addressT to_Nddr ATTRIBUTE_UNUSED,
1774 fragS * frag ATTRIBUTE_UNUSED,
1775 symbolS * to_symbol ATTRIBUTE_UNUSED)
1776 {
1777 as_fatal (_("failed sanity check: long_jump"));
1778 }
1779
1780 /* Called after relaxing, change the frags so they know how big they are. */
1781
1782 void
1783 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1784 segT sec ATTRIBUTE_UNUSED,
1785 fragS * fragP)
1786 {
1787 fixS *fixP;
1788
1789 switch (fragP->fr_subtype)
1790 {
1791 case UNDEFINED_PC_OFFSET:
1792 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1793 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1794 fragP->fr_fix += INST_WORD_SIZE * 2;
1795 fragP->fr_var = 0;
1796 break;
1797 case DEFINED_ABS_SEGMENT:
1798 if (fragP->fr_symbol == GOT_symbol)
1799 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1800 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1801 else
1802 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1803 fragP->fr_offset, FALSE, BFD_RELOC_64);
1804 fragP->fr_fix += INST_WORD_SIZE * 2;
1805 fragP->fr_var = 0;
1806 break;
1807 case DEFINED_RO_SEGMENT:
1808 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1809 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1810 fragP->fr_fix += INST_WORD_SIZE;
1811 fragP->fr_var = 0;
1812 break;
1813 case DEFINED_RW_SEGMENT:
1814 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1815 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1816 fragP->fr_fix += INST_WORD_SIZE;
1817 fragP->fr_var = 0;
1818 break;
1819 case DEFINED_PC_OFFSET:
1820 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1821 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1822 fragP->fr_fix += INST_WORD_SIZE;
1823 fragP->fr_var = 0;
1824 break;
1825 case LARGE_DEFINED_PC_OFFSET:
1826 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1827 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1828 fragP->fr_fix += INST_WORD_SIZE * 2;
1829 fragP->fr_var = 0;
1830 break;
1831 case GOT_OFFSET:
1832 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1833 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1834 fragP->fr_fix += INST_WORD_SIZE * 2;
1835 fragP->fr_var = 0;
1836 break;
1837 case PLT_OFFSET:
1838 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1839 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1840 /* fixP->fx_plt = 1; */
1841 (void) fixP;
1842 fragP->fr_fix += INST_WORD_SIZE * 2;
1843 fragP->fr_var = 0;
1844 break;
1845 case GOTOFF_OFFSET:
1846 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1847 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1848 fragP->fr_fix += INST_WORD_SIZE * 2;
1849 fragP->fr_var = 0;
1850 break;
1851
1852 default:
1853 abort ();
1854 }
1855 }
1856
1857 /* Applies the desired value to the specified location.
1858 Also sets up addends for 'rela' type relocations. */
1859 void
1860 md_apply_fix (fixS * fixP,
1861 valueT * valp,
1862 segT segment)
1863 {
1864 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1865 char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1866 const char * symname;
1867 /* Note: use offsetT because it is signed, valueT is unsigned. */
1868 offsetT val = (offsetT) * valp;
1869 int i;
1870 struct op_code_struct * opcode1;
1871 unsigned long inst1;
1872
1873 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
1874
1875 /* fixP->fx_offset is supposed to be set up correctly for all
1876 symbol relocations. */
1877 if (fixP->fx_addsy == NULL)
1878 {
1879 if (!fixP->fx_pcrel)
1880 fixP->fx_offset = val; /* Absolute relocation. */
1881 else
1882 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1883 (unsigned int) fixP->fx_offset, (unsigned int) val);
1884 }
1885
1886 /* If we aren't adjusting this fixup to be against the section
1887 symbol, we need to adjust the value. */
1888 if (fixP->fx_addsy != NULL)
1889 {
1890 if (S_IS_WEAK (fixP->fx_addsy)
1891 || (symbol_used_in_reloc_p (fixP->fx_addsy)
1892 && (((bfd_get_section_flags (stdoutput,
1893 S_GET_SEGMENT (fixP->fx_addsy))
1894 & SEC_LINK_ONCE) != 0)
1895 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
1896 ".gnu.linkonce",
1897 sizeof (".gnu.linkonce") - 1))))
1898 {
1899 val -= S_GET_VALUE (fixP->fx_addsy);
1900 if (val != 0 && ! fixP->fx_pcrel)
1901 {
1902 /* In this case, the bfd_install_relocation routine will
1903 incorrectly add the symbol value back in. We just want
1904 the addend to appear in the object file.
1905 FIXME: If this makes VALUE zero, we're toast. */
1906 val -= S_GET_VALUE (fixP->fx_addsy);
1907 }
1908 }
1909 }
1910
1911 /* If the fix is relative to a symbol which is not defined, or not
1912 in the same segment as the fix, we cannot resolve it here. */
1913 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1914 if (fixP->fx_addsy != NULL
1915 && (!S_IS_DEFINED (fixP->fx_addsy)
1916 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
1917 {
1918 fixP->fx_done = 0;
1919 #ifdef OBJ_ELF
1920 /* For ELF we can just return and let the reloc that will be generated
1921 take care of everything. For COFF we still have to insert 'val'
1922 into the insn since the addend field will be ignored. */
1923 /* return; */
1924 #endif
1925 }
1926 /* All fixups in the text section must be handled in the linker. */
1927 else if (segment->flags & SEC_CODE)
1928 fixP->fx_done = 0;
1929 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
1930 fixP->fx_done = 0;
1931 else
1932 fixP->fx_done = 1;
1933
1934 switch (fixP->fx_r_type)
1935 {
1936 case BFD_RELOC_MICROBLAZE_32_LO:
1937 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
1938 if (target_big_endian)
1939 {
1940 buf[2] |= ((val >> 8) & 0xff);
1941 buf[3] |= (val & 0xff);
1942 }
1943 else
1944 {
1945 buf[1] |= ((val >> 8) & 0xff);
1946 buf[0] |= (val & 0xff);
1947 }
1948 break;
1949 case BFD_RELOC_MICROBLAZE_32_ROSDA:
1950 case BFD_RELOC_MICROBLAZE_32_RWSDA:
1951 /* Don't do anything if the symbol is not defined. */
1952 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1953 {
1954 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
1955 as_bad_where (file, fixP->fx_line,
1956 _("pcrel for branch to %s too far (0x%x)"),
1957 symname, (int) val);
1958 if (target_big_endian)
1959 {
1960 buf[2] |= ((val >> 8) & 0xff);
1961 buf[3] |= (val & 0xff);
1962 }
1963 else
1964 {
1965 buf[1] |= ((val >> 8) & 0xff);
1966 buf[0] |= (val & 0xff);
1967 }
1968 }
1969 break;
1970 case BFD_RELOC_32:
1971 case BFD_RELOC_RVA:
1972 case BFD_RELOC_32_PCREL:
1973 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
1974 /* Don't do anything if the symbol is not defined. */
1975 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1976 {
1977 if (target_big_endian)
1978 {
1979 buf[0] |= ((val >> 24) & 0xff);
1980 buf[1] |= ((val >> 16) & 0xff);
1981 buf[2] |= ((val >> 8) & 0xff);
1982 buf[3] |= (val & 0xff);
1983 }
1984 else
1985 {
1986 buf[3] |= ((val >> 24) & 0xff);
1987 buf[2] |= ((val >> 16) & 0xff);
1988 buf[1] |= ((val >> 8) & 0xff);
1989 buf[0] |= (val & 0xff);
1990 }
1991 }
1992 break;
1993 case BFD_RELOC_64_PCREL:
1994 case BFD_RELOC_64:
1995 /* Add an imm instruction. First save the current instruction. */
1996 for (i = 0; i < INST_WORD_SIZE; i++)
1997 buf[i + INST_WORD_SIZE] = buf[i];
1998
1999 /* Generate the imm instruction. */
2000 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2001 if (opcode1 == NULL)
2002 {
2003 as_bad (_("unknown opcode \"%s\""), "imm");
2004 return;
2005 }
2006
2007 inst1 = opcode1->bit_sequence;
2008 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2009 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
2010
2011 buf[0] = INST_BYTE0 (inst1);
2012 buf[1] = INST_BYTE1 (inst1);
2013 buf[2] = INST_BYTE2 (inst1);
2014 buf[3] = INST_BYTE3 (inst1);
2015
2016 /* Add the value only if the symbol is defined. */
2017 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
2018 {
2019 if (target_big_endian)
2020 {
2021 buf[6] |= ((val >> 8) & 0xff);
2022 buf[7] |= (val & 0xff);
2023 }
2024 else
2025 {
2026 buf[5] |= ((val >> 8) & 0xff);
2027 buf[4] |= (val & 0xff);
2028 }
2029 }
2030 break;
2031
2032 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2033 case BFD_RELOC_MICROBLAZE_64_GOT:
2034 case BFD_RELOC_MICROBLAZE_64_PLT:
2035 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2036 /* Add an imm instruction. First save the current instruction. */
2037 for (i = 0; i < INST_WORD_SIZE; i++)
2038 buf[i + INST_WORD_SIZE] = buf[i];
2039
2040 /* Generate the imm instruction. */
2041 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2042 if (opcode1 == NULL)
2043 {
2044 as_bad (_("unknown opcode \"%s\""), "imm");
2045 return;
2046 }
2047
2048 inst1 = opcode1->bit_sequence;
2049
2050 /* We can fixup call to a defined non-global address
2051 within the same section only. */
2052 buf[0] = INST_BYTE0 (inst1);
2053 buf[1] = INST_BYTE1 (inst1);
2054 buf[2] = INST_BYTE2 (inst1);
2055 buf[3] = INST_BYTE3 (inst1);
2056 return;
2057
2058 default:
2059 break;
2060 }
2061
2062 if (fixP->fx_addsy == NULL)
2063 {
2064 /* This fixup has been resolved. Create a reloc in case the linker
2065 moves code around due to relaxing. */
2066 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2067 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2068 else
2069 fixP->fx_r_type = BFD_RELOC_NONE;
2070 fixP->fx_addsy = section_symbol (absolute_section);
2071 }
2072 return;
2073 }
2074
2075 void
2076 md_operand (expressionS * expressionP)
2077 {
2078 /* Ignore leading hash symbol, if present. */
2079 if (*input_line_pointer == '#')
2080 {
2081 input_line_pointer ++;
2082 expression (expressionP);
2083 }
2084 }
2085
2086 /* Called just before address relaxation, return the length
2087 by which a fragment must grow to reach it's destination. */
2088
2089 int
2090 md_estimate_size_before_relax (fragS * fragP,
2091 segT segment_type)
2092 {
2093 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2094 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2095 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2096 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2097
2098 switch (fragP->fr_subtype)
2099 {
2100 case INST_PC_OFFSET:
2101 /* Used to be a PC-relative branch. */
2102 if (!fragP->fr_symbol)
2103 {
2104 /* We know the abs value: Should never happen. */
2105 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2106 abort ();
2107 }
2108 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type &&
2109 !S_IS_WEAK (fragP->fr_symbol))
2110 {
2111 fragP->fr_subtype = DEFINED_PC_OFFSET;
2112 /* Don't know now whether we need an imm instruction. */
2113 fragP->fr_var = INST_WORD_SIZE;
2114 }
2115 else if (S_IS_DEFINED (fragP->fr_symbol)
2116 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0))
2117 {
2118 /* Cannot have a PC-relative branch to a diff segment. */
2119 as_bad (_("PC relative branch to label %s which is not in the instruction space"),
2120 S_GET_NAME (fragP->fr_symbol));
2121 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2122 fragP->fr_var = INST_WORD_SIZE*2;
2123 }
2124 else
2125 {
2126 fragP->fr_subtype = UNDEFINED_PC_OFFSET;
2127 fragP->fr_var = INST_WORD_SIZE*2;
2128 }
2129 break;
2130
2131 case INST_NO_OFFSET:
2132 /* Used to be a reference to somewhere which was unknown. */
2133 if (fragP->fr_symbol)
2134 {
2135 if (fragP->fr_opcode == NULL)
2136 {
2137 /* Used as an absolute value. */
2138 fragP->fr_subtype = DEFINED_ABS_SEGMENT;
2139 /* Variable part does not change. */
2140 fragP->fr_var = INST_WORD_SIZE*2;
2141 }
2142 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor))
2143 {
2144 /* It is accessed using the small data read only anchor. */
2145 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2146 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment)
2147 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment)
2148 || (! S_IS_DEFINED (fragP->fr_symbol)))
2149 {
2150 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2151 fragP->fr_var = INST_WORD_SIZE;
2152 }
2153 else
2154 {
2155 /* Variable not in small data read only segment accessed
2156 using small data read only anchor. */
2157 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2158
2159 as_bad_where (file, fragP->fr_line,
2160 _("Variable is accessed using small data read "
2161 "only anchor, but it is not in the small data "
2162 "read only section"));
2163 fragP->fr_subtype = DEFINED_RO_SEGMENT;
2164 fragP->fr_var = INST_WORD_SIZE;
2165 }
2166 }
2167 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor))
2168 {
2169 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr)
2170 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment)
2171 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment)
2172 || (!S_IS_DEFINED (fragP->fr_symbol)))
2173 {
2174 /* It is accessed using the small data read write anchor. */
2175 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2176 fragP->fr_var = INST_WORD_SIZE;
2177 }
2178 else
2179 {
2180 char *file = fragP->fr_file ? fragP->fr_file : _("unknown");
2181
2182 as_bad_where (file, fragP->fr_line,
2183 _("Variable is accessed using small data read "
2184 "write anchor, but it is not in the small data "
2185 "read write section"));
2186 fragP->fr_subtype = DEFINED_RW_SEGMENT;
2187 fragP->fr_var = INST_WORD_SIZE;
2188 }
2189 }
2190 else
2191 {
2192 as_bad (_("Incorrect fr_opcode value in frag. Internal error....."));
2193 abort ();
2194 }
2195 }
2196 else
2197 {
2198 /* We know the abs value: Should never happen. */
2199 as_bad (_("Absolute value in relaxation code. Assembler error....."));
2200 abort ();
2201 }
2202 break;
2203
2204 case UNDEFINED_PC_OFFSET:
2205 case LARGE_DEFINED_PC_OFFSET:
2206 case DEFINED_ABS_SEGMENT:
2207 case GOT_OFFSET:
2208 case PLT_OFFSET:
2209 case GOTOFF_OFFSET:
2210 fragP->fr_var = INST_WORD_SIZE*2;
2211 break;
2212 case DEFINED_RO_SEGMENT:
2213 case DEFINED_RW_SEGMENT:
2214 case DEFINED_PC_OFFSET:
2215 fragP->fr_var = INST_WORD_SIZE;
2216 break;
2217 default:
2218 abort ();
2219 }
2220
2221 return fragP->fr_var;
2222 }
2223
2224 /* Put number into target byte order. */
2225
2226 void
2227 md_number_to_chars (char * ptr, valueT use, int nbytes)
2228 {
2229 if (target_big_endian)
2230 number_to_chars_bigendian (ptr, use, nbytes);
2231 else
2232 number_to_chars_littleendian (ptr, use, nbytes);
2233 }
2234
2235 /* Round up a section size to the appropriate boundary. */
2236
2237 valueT
2238 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size)
2239 {
2240 return size; /* Byte alignment is fine. */
2241 }
2242
2243
2244 /* The location from which a PC relative jump should be calculated,
2245 given a PC relative reloc. */
2246
2247 long
2248 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED)
2249 {
2250 #ifdef OBJ_ELF
2251 /* If the symbol is undefined or defined in another section
2252 we leave the add number alone for the linker to fix it later.
2253 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */
2254
2255 if (fixp->fx_addsy != (symbolS *) NULL
2256 && (!S_IS_DEFINED (fixp->fx_addsy)
2257 || (S_GET_SEGMENT (fixp->fx_addsy) != sec)))
2258 return 0;
2259 else
2260 {
2261 /* The case where we are going to resolve things... */
2262 if (fixp->fx_r_type == BFD_RELOC_64_PCREL)
2263 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE;
2264 else
2265 return fixp->fx_where + fixp->fx_frag->fr_address;
2266 }
2267 #endif
2268 }
2269
2270
2271 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL))
2272 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break
2273
2274 arelent *
2275 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp)
2276 {
2277 arelent * rel;
2278 bfd_reloc_code_real_type code;
2279
2280 switch (fixp->fx_r_type)
2281 {
2282 case BFD_RELOC_NONE:
2283 case BFD_RELOC_MICROBLAZE_64_NONE:
2284 case BFD_RELOC_32:
2285 case BFD_RELOC_MICROBLAZE_32_LO:
2286 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
2287 case BFD_RELOC_RVA:
2288 case BFD_RELOC_64:
2289 case BFD_RELOC_64_PCREL:
2290 case BFD_RELOC_MICROBLAZE_32_ROSDA:
2291 case BFD_RELOC_MICROBLAZE_32_RWSDA:
2292 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
2293 case BFD_RELOC_MICROBLAZE_64_GOTPC:
2294 case BFD_RELOC_MICROBLAZE_64_GOT:
2295 case BFD_RELOC_MICROBLAZE_64_PLT:
2296 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
2297 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
2298 code = fixp->fx_r_type;
2299 break;
2300
2301 default:
2302 switch (F (fixp->fx_size, fixp->fx_pcrel))
2303 {
2304 MAP (1, 0, BFD_RELOC_8);
2305 MAP (2, 0, BFD_RELOC_16);
2306 MAP (4, 0, BFD_RELOC_32);
2307 MAP (1, 1, BFD_RELOC_8_PCREL);
2308 MAP (2, 1, BFD_RELOC_16_PCREL);
2309 MAP (4, 1, BFD_RELOC_32_PCREL);
2310 default:
2311 code = fixp->fx_r_type;
2312 as_bad (_("Can not do %d byte %srelocation"),
2313 fixp->fx_size,
2314 fixp->fx_pcrel ? _("pc-relative") : "");
2315 }
2316 break;
2317 }
2318
2319 rel = (arelent *) xmalloc (sizeof (arelent));
2320 rel->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2321
2322 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM)
2323 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
2324 else
2325 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2326
2327 rel->address = fixp->fx_frag->fr_address + fixp->fx_where;
2328 /* Always pass the addend along! */
2329 rel->addend = fixp->fx_offset;
2330 rel->howto = bfd_reloc_type_lookup (stdoutput, code);
2331
2332 if (rel->howto == NULL)
2333 {
2334 as_bad_where (fixp->fx_file, fixp->fx_line,
2335 _("Cannot represent relocation type %s"),
2336 bfd_get_reloc_code_name (code));
2337
2338 /* Set howto to a garbage value so that we can keep going. */
2339 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32);
2340 gas_assert (rel->howto != NULL);
2341 }
2342 return rel;
2343 }
2344
2345 int
2346 md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
2347 {
2348 switch (c)
2349 {
2350 case OPTION_EB:
2351 target_big_endian = 1;
2352 break;
2353 case OPTION_EL:
2354 target_big_endian = 0;
2355 break;
2356 default:
2357 return 0;
2358 }
2359 return 1;
2360 }
2361
2362 void
2363 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
2364 {
2365 /* fprintf(stream, _("\
2366 MicroBlaze options:\n\
2367 -noSmall Data in the comm and data sections do not go into the small data section\n")); */
2368 }
2369
2370
2371 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze
2372 found a machine specific op in an expression,
2373 then we create relocs accordingly. */
2374
2375 void
2376 cons_fix_new_microblaze (fragS * frag,
2377 int where,
2378 int size,
2379 expressionS *exp)
2380 {
2381
2382 bfd_reloc_code_real_type r;
2383
2384 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) &&
2385 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4)
2386 && (!S_IS_LOCAL (exp->X_op_symbol)))
2387 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM;
2388 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva)
2389 {
2390 exp->X_op = O_symbol;
2391 r = BFD_RELOC_MICROBLAZE_32_GOTOFF;
2392 }
2393 else
2394 {
2395 switch (size)
2396 {
2397 case 1:
2398 r = BFD_RELOC_8;
2399 break;
2400 case 2:
2401 r = BFD_RELOC_16;
2402 break;
2403 case 4:
2404 r = BFD_RELOC_32;
2405 break;
2406 case 8:
2407 r = BFD_RELOC_64;
2408 break;
2409 default:
2410 as_bad (_("unsupported BFD relocation size %u"), size);
2411 r = BFD_RELOC_32;
2412 break;
2413 }
2414 }
2415 fix_new_exp (frag, where, size, exp, 0, r);
2416 }
This page took 0.078415 seconds and 5 git commands to generate.