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