* elf32-m32c.c (ELF_MAXPAGESIZE): Change page size to 256 bytes.
[deliverable/binutils-gdb.git] / gas / config / tc-microblaze.c
1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze
2
3 Copyright 2009, 2010 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 <stdio.h>
23 #include "as.h"
24 #include "bfd.h"
25 #include "subsegs.h"
26 #define DEFINE_TABLE
27 #include "../opcodes/microblaze-opc.h"
28 #include "../opcodes/microblaze-opcm.h"
29 #include "safe-ctype.h"
30 #include <string.h>
31 #include <dwarf2dbg.h>
32 #include "aout/stab_gnu.h"
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 && nlen < 20 && !is_end_of_line [(int)*op_end] && *op_end != ' ';
811 op_end++)
812 {
813 name[nlen] = op_start[nlen];
814 nlen++;
815 }
816
817 name [nlen] = 0;
818
819 if (nlen == 0)
820 {
821 as_bad (_("can't find opcode "));
822 return;
823 }
824
825 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name);
826 if (opcode == NULL)
827 {
828 as_bad (_("unknown opcode \"%s\""), name);
829 return;
830 }
831
832 inst = opcode->bit_sequence;
833 isize = 4;
834
835 switch (opcode->inst_type)
836 {
837 case INST_TYPE_RD_R1_R2:
838 if (strcmp (op_end, ""))
839 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
840 else
841 {
842 as_fatal (_("Error in statement syntax"));
843 reg1 = 0;
844 }
845 if (strcmp (op_end, ""))
846 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
847 else
848 {
849 as_fatal (_("Error in statement syntax"));
850 reg2 = 0;
851 }
852 if (strcmp (op_end, ""))
853 op_end = parse_reg (op_end + 1, &reg3); /* Get r2. */
854 else
855 {
856 as_fatal (_("Error in statement syntax"));
857 reg3 = 0;
858 }
859
860 /* Check for spl registers. */
861 if (check_spl_reg (& reg1))
862 as_fatal (_("Cannot use special register with this instruction"));
863 if (check_spl_reg (& reg2))
864 as_fatal (_("Cannot use special register with this instruction"));
865 if (check_spl_reg (& reg3))
866 as_fatal (_("Cannot use special register with this instruction"));
867
868 if (streq (name, "sub"))
869 {
870 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */
871 inst |= (reg1 << RD_LOW) & RD_MASK;
872 inst |= (reg3 << RA_LOW) & RA_MASK;
873 inst |= (reg2 << RB_LOW) & RB_MASK;
874 }
875 else
876 {
877 inst |= (reg1 << RD_LOW) & RD_MASK;
878 inst |= (reg2 << RA_LOW) & RA_MASK;
879 inst |= (reg3 << RB_LOW) & RB_MASK;
880 }
881 output = frag_more (isize);
882 break;
883
884 case INST_TYPE_RD_R1_IMM:
885 if (strcmp (op_end, ""))
886 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
887 else
888 {
889 as_fatal (_("Error in statement syntax"));
890 reg1 = 0;
891 }
892 if (strcmp (op_end, ""))
893 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
894 else
895 {
896 as_fatal (_("Error in statement syntax"));
897 reg2 = 0;
898 }
899 if (strcmp (op_end, ""))
900 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
901 else
902 as_fatal (_("Error in statement syntax"));
903
904 /* Check for spl registers. */
905 if (check_spl_reg (& reg1))
906 as_fatal (_("Cannot use special register with this instruction"));
907 if (check_spl_reg (& reg2))
908 as_fatal (_("Cannot use special register with this instruction"));
909
910 if (exp.X_op != O_constant)
911 {
912 char *opc;
913 relax_substateT subtype;
914
915 if (streq (name, "lmi"))
916 as_fatal (_("lmi pseudo instruction should not use a label in imm field"));
917 else if (streq (name, "smi"))
918 as_fatal (_("smi pseudo instruction should not use a label in imm field"));
919
920 if (reg2 == REG_ROSDP)
921 opc = str_microblaze_ro_anchor;
922 else if (reg2 == REG_RWSDP)
923 opc = str_microblaze_rw_anchor;
924 else
925 opc = NULL;
926 if (exp.X_md == IMM_GOT)
927 subtype = GOT_OFFSET;
928 else if (exp.X_md == IMM_PLT)
929 subtype = PLT_OFFSET;
930 else if (exp.X_md == IMM_GOTOFF)
931 subtype = GOTOFF_OFFSET;
932 else
933 subtype = opcode->inst_offset_type;
934
935 output = frag_var (rs_machine_dependent,
936 isize * 2, /* maxm of 2 words. */
937 isize, /* minm of 1 word. */
938 subtype, /* PC-relative or not. */
939 exp.X_add_symbol,
940 exp.X_add_number,
941 opc);
942 immed = 0;
943 }
944 else
945 {
946 output = frag_more (isize);
947 immed = exp.X_add_number;
948 }
949
950 if (streq (name, "lmi") || streq (name, "smi"))
951 {
952 /* Load/store 32-d consecutive registers. Used on exit/entry
953 to subroutines to save and restore registers to stack.
954 Generate 32-d insts. */
955 int count;
956
957 count = 32 - reg1;
958 if (streq (name, "lmi"))
959 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi");
960 else
961 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi");
962 if (opcode == NULL)
963 {
964 as_bad (_("unknown opcode \"%s\""), "lwi");
965 return;
966 }
967 inst = opcode->bit_sequence;
968 inst |= (reg1 << RD_LOW) & RD_MASK;
969 inst |= (reg2 << RA_LOW) & RA_MASK;
970 inst |= (immed << IMM_LOW) & IMM_MASK;
971
972 for (i = 0; i < count - 1; i++)
973 {
974 output[0] = INST_BYTE0 (inst);
975 output[1] = INST_BYTE1 (inst);
976 output[2] = INST_BYTE2 (inst);
977 output[3] = INST_BYTE3 (inst);
978 output = frag_more (isize);
979 immed = immed + 4;
980 reg1++;
981 inst = opcode->bit_sequence;
982 inst |= (reg1 << RD_LOW) & RD_MASK;
983 inst |= (reg2 << RA_LOW) & RA_MASK;
984 inst |= (immed << IMM_LOW) & IMM_MASK;
985 }
986 }
987 else
988 {
989 temp = immed & 0xFFFF8000;
990 if ((temp != 0) && (temp != 0xFFFF8000))
991 {
992 /* Needs an immediate inst. */
993 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
994 if (opcode1 == NULL)
995 {
996 as_bad (_("unknown opcode \"%s\""), "imm");
997 return;
998 }
999
1000 inst1 = opcode1->bit_sequence;
1001 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1002 output[0] = INST_BYTE0 (inst1);
1003 output[1] = INST_BYTE1 (inst1);
1004 output[2] = INST_BYTE2 (inst1);
1005 output[3] = INST_BYTE3 (inst1);
1006 output = frag_more (isize);
1007 }
1008 inst |= (reg1 << RD_LOW) & RD_MASK;
1009 inst |= (reg2 << RA_LOW) & RA_MASK;
1010 inst |= (immed << IMM_LOW) & IMM_MASK;
1011 }
1012 break;
1013
1014 case INST_TYPE_RD_R1_IMM5:
1015 if (strcmp (op_end, ""))
1016 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1017 else
1018 {
1019 as_fatal (_("Error in statement syntax"));
1020 reg1 = 0;
1021 }
1022 if (strcmp (op_end, ""))
1023 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1024 else
1025 {
1026 as_fatal (_("Error in statement syntax"));
1027 reg2 = 0;
1028 }
1029 if (strcmp (op_end, ""))
1030 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1031 else
1032 as_fatal (_("Error in statement syntax"));
1033
1034 /* Check for spl registers. */
1035 if (check_spl_reg (&reg1))
1036 as_fatal (_("Cannot use special register with this instruction"));
1037 if (check_spl_reg (&reg2))
1038 as_fatal (_("Cannot use special register with this instruction"));
1039
1040 if (exp.X_op != O_constant)
1041 as_warn (_("Symbol used as immediate for shift instruction"));
1042 else
1043 {
1044 output = frag_more (isize);
1045 immed = exp.X_add_number;
1046 }
1047
1048 if (immed != (immed % 32))
1049 {
1050 as_warn (_("Shift value > 32. using <value %% 32>"));
1051 immed = immed % 32;
1052 }
1053 inst |= (reg1 << RD_LOW) & RD_MASK;
1054 inst |= (reg2 << RA_LOW) & RA_MASK;
1055 inst |= (immed << IMM_LOW) & IMM5_MASK;
1056 break;
1057
1058 case INST_TYPE_R1_R2:
1059 if (strcmp (op_end, ""))
1060 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1061 else
1062 {
1063 as_fatal (_("Error in statement syntax"));
1064 reg1 = 0;
1065 }
1066 if (strcmp (op_end, ""))
1067 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1068 else
1069 {
1070 as_fatal (_("Error in statement syntax"));
1071 reg2 = 0;
1072 }
1073
1074 /* Check for spl registers. */
1075 if (check_spl_reg (& reg1))
1076 as_fatal (_("Cannot use special register with this instruction"));
1077 if (check_spl_reg (& reg2))
1078 as_fatal (_("Cannot use special register with this instruction"));
1079
1080 inst |= (reg1 << RA_LOW) & RA_MASK;
1081 inst |= (reg2 << RB_LOW) & RB_MASK;
1082 output = frag_more (isize);
1083 break;
1084
1085 case INST_TYPE_RD_R1:
1086 if (strcmp (op_end, ""))
1087 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1088 else
1089 {
1090 as_fatal (_("Error in statement syntax"));
1091 reg1 = 0;
1092 }
1093 if (strcmp (op_end, ""))
1094 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1095 else
1096 {
1097 as_fatal (_("Error in statement syntax"));
1098 reg2 =0;
1099 }
1100
1101 /* Check for spl registers. */
1102 if (check_spl_reg (&reg1))
1103 as_fatal (_("Cannot use special register with this instruction"));
1104 if (check_spl_reg (&reg2))
1105 as_fatal (_("Cannot use special register with this instruction"));
1106
1107 inst |= (reg1 << RD_LOW) & RD_MASK;
1108 inst |= (reg2 << RA_LOW) & RA_MASK;
1109 output = frag_more (isize);
1110 break;
1111
1112 case INST_TYPE_RD_RFSL:
1113 if (strcmp (op_end, ""))
1114 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1115 else
1116 {
1117 as_fatal (_("Error in statement syntax"));
1118 reg1 = 0;
1119 }
1120 if (strcmp (op_end, ""))
1121 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1122 else
1123 {
1124 as_fatal (_("Error in statement syntax"));
1125 immed = 0;
1126 }
1127
1128 /* Check for spl registers. */
1129 if (check_spl_reg (&reg1))
1130 as_fatal (_("Cannot use special register with this instruction"));
1131
1132 inst |= (reg1 << RD_LOW) & RD_MASK;
1133 inst |= (immed << IMM_LOW) & RFSL_MASK;
1134 output = frag_more (isize);
1135 break;
1136
1137 case INST_TYPE_RD_IMM15:
1138 if (strcmp (op_end, ""))
1139 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1140 else
1141 {
1142 as_fatal (_("Error in statement syntax"));
1143 reg1 = 0;
1144 }
1145
1146 if (strcmp (op_end, ""))
1147 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15);
1148 else
1149 as_fatal (_("Error in statement syntax"));
1150
1151 /* Check for spl registers. */
1152 if (check_spl_reg (&reg1))
1153 as_fatal (_("Cannot use special register with this instruction"));
1154
1155 if (exp.X_op != O_constant)
1156 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions"));
1157 else
1158 {
1159 output = frag_more (isize);
1160 immed = exp.X_add_number;
1161 }
1162 inst |= (reg1 << RD_LOW) & RD_MASK;
1163 inst |= (immed << IMM_LOW) & IMM15_MASK;
1164 break;
1165
1166 case INST_TYPE_R1_RFSL:
1167 if (strcmp (op_end, ""))
1168 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1169 else
1170 {
1171 as_fatal (_("Error in statement syntax"));
1172 reg1 = 0;
1173 }
1174 if (strcmp (op_end, ""))
1175 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1176 else
1177 {
1178 as_fatal (_("Error in statement syntax"));
1179 immed = 0;
1180 }
1181
1182 /* Check for spl registers. */
1183 if (check_spl_reg (&reg1))
1184 as_fatal (_("Cannot use special register with this instruction"));
1185
1186 inst |= (reg1 << RA_LOW) & RA_MASK;
1187 inst |= (immed << IMM_LOW) & RFSL_MASK;
1188 output = frag_more (isize);
1189 break;
1190
1191 case INST_TYPE_RFSL:
1192 if (strcmp (op_end, ""))
1193 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */
1194 else
1195 {
1196 as_fatal (_("Error in statement syntax"));
1197 immed = 0;
1198 }
1199 /* Check for spl registers. */
1200 if (check_spl_reg (&reg1))
1201 as_fatal (_("Cannot use special register with this instruction"));
1202 inst |= (immed << IMM_LOW) & RFSL_MASK;
1203 output = frag_more (isize);
1204 break;
1205
1206 case INST_TYPE_R1:
1207 if (strcmp (op_end, ""))
1208 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1209 else
1210 {
1211 as_fatal (_("Error in statement syntax"));
1212 reg1 = 0;
1213 }
1214
1215 /* Check for spl registers. */
1216 if (check_spl_reg (&reg1))
1217 as_fatal (_("Cannot use special register with this instruction"));
1218
1219 inst |= (reg1 << RA_LOW) & RA_MASK;
1220 output = frag_more (isize);
1221 break;
1222
1223 /* For tuqula insn...:) */
1224 case INST_TYPE_RD:
1225 if (strcmp (op_end, ""))
1226 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1227 else
1228 {
1229 as_fatal (_("Error in statement syntax"));
1230 reg1 = 0;
1231 }
1232
1233 /* Check for spl registers. */
1234 if (check_spl_reg (&reg1))
1235 as_fatal (_("Cannot use special register with this instruction"));
1236
1237 inst |= (reg1 << RD_LOW) & RD_MASK;
1238 output = frag_more (isize);
1239 break;
1240
1241 case INST_TYPE_RD_SPECIAL:
1242 if (strcmp (op_end, ""))
1243 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1244 else
1245 {
1246 as_fatal (_("Error in statement syntax"));
1247 reg1 = 0;
1248 }
1249 if (strcmp (op_end, ""))
1250 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1251 else
1252 {
1253 as_fatal (_("Error in statement syntax"));
1254 reg2 = 0;
1255 }
1256
1257 if (reg2 == REG_MSR)
1258 immed = opcode->immval_mask | REG_MSR_MASK;
1259 else if (reg2 == REG_PC)
1260 immed = opcode->immval_mask | REG_PC_MASK;
1261 else if (reg2 == REG_EAR)
1262 immed = opcode->immval_mask | REG_EAR_MASK;
1263 else if (reg2 == REG_ESR)
1264 immed = opcode->immval_mask | REG_ESR_MASK;
1265 else if (reg2 == REG_FSR)
1266 immed = opcode->immval_mask | REG_FSR_MASK;
1267 else if (reg2 == REG_BTR)
1268 immed = opcode->immval_mask | REG_BTR_MASK;
1269 else if (reg2 == REG_EDR)
1270 immed = opcode->immval_mask | REG_EDR_MASK;
1271 else if (reg2 == REG_PID)
1272 immed = opcode->immval_mask | REG_PID_MASK;
1273 else if (reg2 == REG_ZPR)
1274 immed = opcode->immval_mask | REG_ZPR_MASK;
1275 else if (reg2 == REG_TLBX)
1276 immed = opcode->immval_mask | REG_TLBX_MASK;
1277 else if (reg2 == REG_TLBLO)
1278 immed = opcode->immval_mask | REG_TLBLO_MASK;
1279 else if (reg2 == REG_TLBHI)
1280 immed = opcode->immval_mask | REG_TLBHI_MASK;
1281 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM))
1282 immed = opcode->immval_mask | REG_PVR_MASK | reg2;
1283 else
1284 as_fatal (_("invalid value for special purpose register"));
1285 inst |= (reg1 << RD_LOW) & RD_MASK;
1286 inst |= (immed << IMM_LOW) & IMM_MASK;
1287 output = frag_more (isize);
1288 break;
1289
1290 case INST_TYPE_SPECIAL_R1:
1291 if (strcmp (op_end, ""))
1292 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1293 else
1294 {
1295 as_fatal (_("Error in statement syntax"));
1296 reg1 = 0;
1297 }
1298 if (strcmp (op_end, ""))
1299 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1300 else
1301 {
1302 as_fatal (_("Error in statement syntax"));
1303 reg2 = 0;
1304 }
1305
1306 if (reg1 == REG_MSR)
1307 immed = opcode->immval_mask | REG_MSR_MASK;
1308 else if (reg1 == REG_PC)
1309 immed = opcode->immval_mask | REG_PC_MASK;
1310 else if (reg1 == REG_EAR)
1311 immed = opcode->immval_mask | REG_EAR_MASK;
1312 else if (reg1 == REG_ESR)
1313 immed = opcode->immval_mask | REG_ESR_MASK;
1314 else if (reg1 == REG_FSR)
1315 immed = opcode->immval_mask | REG_FSR_MASK;
1316 else if (reg1 == REG_BTR)
1317 immed = opcode->immval_mask | REG_BTR_MASK;
1318 else if (reg1 == REG_EDR)
1319 immed = opcode->immval_mask | REG_EDR_MASK;
1320 else if (reg1 == REG_PID)
1321 immed = opcode->immval_mask | REG_PID_MASK;
1322 else if (reg1 == REG_ZPR)
1323 immed = opcode->immval_mask | REG_ZPR_MASK;
1324 else if (reg1 == REG_TLBX)
1325 immed = opcode->immval_mask | REG_TLBX_MASK;
1326 else if (reg1 == REG_TLBLO)
1327 immed = opcode->immval_mask | REG_TLBLO_MASK;
1328 else if (reg1 == REG_TLBHI)
1329 immed = opcode->immval_mask | REG_TLBHI_MASK;
1330 else if (reg1 == REG_TLBSX)
1331 immed = opcode->immval_mask | REG_TLBSX_MASK;
1332 else
1333 as_fatal (_("invalid value for special purpose register"));
1334 inst |= (reg2 << RA_LOW) & RA_MASK;
1335 inst |= (immed << IMM_LOW) & IMM_MASK;
1336 output = frag_more (isize);
1337 break;
1338
1339 case INST_TYPE_RD_R1_SPECIAL:
1340 if (strcmp (op_end, ""))
1341 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1342 else
1343 {
1344 as_fatal (_("Error in statement syntax"));
1345 reg1 = 0;
1346 }
1347 if (strcmp (op_end, ""))
1348 op_end = parse_reg (op_end + 1, &reg2); /* Get r1. */
1349 else
1350 {
1351 as_fatal (_("Error in statement syntax"));
1352 reg2 =0;
1353 }
1354
1355 /* Check for spl registers. */
1356 if (check_spl_reg (&reg1))
1357 as_fatal (_("Cannot use special register with this instruction"));
1358 if (check_spl_reg (&reg2))
1359 as_fatal (_("Cannot use special register with this instruction"));
1360
1361 /* insn wic ra, rb => wic ra, ra, rb. */
1362 inst |= (reg1 << RD_LOW) & RD_MASK;
1363 inst |= (reg1 << RA_LOW) & RA_MASK;
1364 inst |= (reg2 << RB_LOW) & RB_MASK;
1365
1366 output = frag_more (isize);
1367 break;
1368
1369 case INST_TYPE_RD_R2:
1370 if (strcmp (op_end, ""))
1371 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1372 else
1373 {
1374 as_fatal (_("Error in statement syntax"));
1375 reg1 = 0;
1376 }
1377 if (strcmp (op_end, ""))
1378 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1379 else
1380 {
1381 as_fatal (_("Error in statement syntax"));
1382 reg2 = 0;
1383 }
1384
1385 /* Check for spl registers. */
1386 if (check_spl_reg (&reg1))
1387 as_fatal (_("Cannot use special register with this instruction"));
1388 if (check_spl_reg (&reg2))
1389 as_fatal (_("Cannot use special register with this instruction"));
1390
1391 inst |= (reg1 << RD_LOW) & RD_MASK;
1392 inst |= (reg2 << RB_LOW) & RB_MASK;
1393 output = frag_more (isize);
1394 break;
1395
1396 case INST_TYPE_R1_IMM:
1397 if (strcmp (op_end, ""))
1398 op_end = parse_reg (op_end + 1, &reg1); /* Get r1. */
1399 else
1400 {
1401 as_fatal (_("Error in statement syntax"));
1402 reg1 = 0;
1403 }
1404 if (strcmp (op_end, ""))
1405 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1406 else
1407 as_fatal (_("Error in statement syntax"));
1408
1409 /* Check for spl registers. */
1410 if (check_spl_reg (&reg1))
1411 as_fatal (_("Cannot use special register with this instruction"));
1412
1413 if (exp.X_op != O_constant)
1414 {
1415 char *opc = NULL;
1416 relax_substateT subtype;
1417
1418 if (exp.X_md == IMM_GOT)
1419 subtype = GOT_OFFSET;
1420 else if (exp.X_md == IMM_PLT)
1421 subtype = PLT_OFFSET;
1422 else
1423 subtype = opcode->inst_offset_type;
1424 output = frag_var (rs_machine_dependent,
1425 isize * 2, /* maxm of 2 words. */
1426 isize, /* minm of 1 word. */
1427 subtype, /* PC-relative or not. */
1428 exp.X_add_symbol,
1429 exp.X_add_number,
1430 opc);
1431 immed = 0;
1432 }
1433 else
1434 {
1435 output = frag_more (isize);
1436 immed = exp.X_add_number;
1437 }
1438
1439 temp = immed & 0xFFFF8000;
1440 if ((temp != 0) && (temp != 0xFFFF8000))
1441 {
1442 /* Needs an immediate inst. */
1443 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1444 if (opcode1 == NULL)
1445 {
1446 as_bad (_("unknown opcode \"%s\""), "imm");
1447 return;
1448 }
1449
1450 inst1 = opcode1->bit_sequence;
1451 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1452 output[0] = INST_BYTE0 (inst1);
1453 output[1] = INST_BYTE1 (inst1);
1454 output[2] = INST_BYTE2 (inst1);
1455 output[3] = INST_BYTE3 (inst1);
1456 output = frag_more (isize);
1457 }
1458
1459 inst |= (reg1 << RA_LOW) & RA_MASK;
1460 inst |= (immed << IMM_LOW) & IMM_MASK;
1461 break;
1462
1463 case INST_TYPE_RD_IMM:
1464 if (strcmp (op_end, ""))
1465 op_end = parse_reg (op_end + 1, &reg1); /* Get rd. */
1466 else
1467 {
1468 as_fatal (_("Error in statement syntax"));
1469 reg1 = 0;
1470 }
1471 if (strcmp (op_end, ""))
1472 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1473 else
1474 as_fatal (_("Error in statement syntax"));
1475
1476 /* Check for spl registers. */
1477 if (check_spl_reg (&reg1))
1478 as_fatal (_("Cannot use special register with this instruction"));
1479
1480 if (exp.X_op != O_constant)
1481 {
1482 char *opc = NULL;
1483 relax_substateT subtype;
1484
1485 if (exp.X_md == IMM_GOT)
1486 subtype = GOT_OFFSET;
1487 else if (exp.X_md == IMM_PLT)
1488 subtype = PLT_OFFSET;
1489 else
1490 subtype = opcode->inst_offset_type;
1491 output = frag_var (rs_machine_dependent,
1492 isize * 2, /* maxm of 2 words. */
1493 isize, /* minm of 1 word. */
1494 subtype, /* PC-relative or not. */
1495 exp.X_add_symbol,
1496 exp.X_add_number,
1497 opc);
1498 immed = 0;
1499 }
1500 else
1501 {
1502 output = frag_more (isize);
1503 immed = exp.X_add_number;
1504 }
1505
1506 temp = immed & 0xFFFF8000;
1507 if ((temp != 0) && (temp != 0xFFFF8000))
1508 {
1509 /* Needs an immediate inst. */
1510 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1511 if (opcode1 == NULL)
1512 {
1513 as_bad (_("unknown opcode \"%s\""), "imm");
1514 return;
1515 }
1516
1517 inst1 = opcode1->bit_sequence;
1518 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1519 output[0] = INST_BYTE0 (inst1);
1520 output[1] = INST_BYTE1 (inst1);
1521 output[2] = INST_BYTE2 (inst1);
1522 output[3] = INST_BYTE3 (inst1);
1523 output = frag_more (isize);
1524 }
1525
1526 inst |= (reg1 << RD_LOW) & RD_MASK;
1527 inst |= (immed << IMM_LOW) & IMM_MASK;
1528 break;
1529
1530 case INST_TYPE_R2:
1531 if (strcmp (op_end, ""))
1532 op_end = parse_reg (op_end + 1, &reg2); /* Get r2. */
1533 else
1534 {
1535 as_fatal (_("Error in statement syntax"));
1536 reg2 = 0;
1537 }
1538
1539 /* Check for spl registers. */
1540 if (check_spl_reg (&reg2))
1541 as_fatal (_("Cannot use special register with this instruction"));
1542
1543 inst |= (reg2 << RB_LOW) & RB_MASK;
1544 output = frag_more (isize);
1545 break;
1546
1547 case INST_TYPE_IMM:
1548 if (streq (name, "imm"))
1549 as_fatal (_("An IMM instruction should not be present in the .s file"));
1550
1551 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM);
1552
1553 if (exp.X_op != O_constant)
1554 {
1555 char *opc = NULL;
1556 relax_substateT subtype;
1557
1558 if (exp.X_md == IMM_GOT)
1559 subtype = GOT_OFFSET;
1560 else if (exp.X_md == IMM_PLT)
1561 subtype = PLT_OFFSET;
1562 else
1563 subtype = opcode->inst_offset_type;
1564 output = frag_var (rs_machine_dependent,
1565 isize * 2, /* maxm of 2 words. */
1566 isize, /* minm of 1 word. */
1567 subtype, /* PC-relative or not. */
1568 exp.X_add_symbol,
1569 exp.X_add_number,
1570 opc);
1571 immed = 0;
1572 }
1573 else
1574 {
1575 output = frag_more (isize);
1576 immed = exp.X_add_number;
1577 }
1578
1579
1580 temp = immed & 0xFFFF8000;
1581 if ((temp != 0) && (temp != 0xFFFF8000))
1582 {
1583 /* Needs an immediate inst. */
1584 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1585 if (opcode1 == NULL)
1586 {
1587 as_bad (_("unknown opcode \"%s\""), "imm");
1588 return;
1589 }
1590
1591 inst1 = opcode1->bit_sequence;
1592 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK;
1593 output[0] = INST_BYTE0 (inst1);
1594 output[1] = INST_BYTE1 (inst1);
1595 output[2] = INST_BYTE2 (inst1);
1596 output[3] = INST_BYTE3 (inst1);
1597 output = frag_more (isize);
1598 }
1599 inst |= (immed << IMM_LOW) & IMM_MASK;
1600 break;
1601
1602 case INST_TYPE_NONE:
1603 output = frag_more (isize);
1604 break;
1605
1606 default:
1607 as_fatal (_("unimplemented opcode \"%s\""), name);
1608 }
1609
1610 /* Drop whitespace after all the operands have been parsed. */
1611 while (ISSPACE (* op_end))
1612 op_end ++;
1613
1614 /* Give warning message if the insn has more operands than required. */
1615 if (strcmp (op_end, opcode->name) && strcmp (op_end, ""))
1616 as_warn (_("ignoring operands: %s "), op_end);
1617
1618 output[0] = INST_BYTE0 (inst);
1619 output[1] = INST_BYTE1 (inst);
1620 output[2] = INST_BYTE2 (inst);
1621 output[3] = INST_BYTE3 (inst);
1622
1623 #ifdef OBJ_ELF
1624 dwarf2_emit_insn (4);
1625 #endif
1626 }
1627
1628 symbolS *
1629 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1630 {
1631 return NULL;
1632 }
1633
1634 /* Various routines to kill one day. */
1635 /* Equal to MAX_PRECISION in atof-ieee.c */
1636 #define MAX_LITTLENUMS 6
1637
1638 /* Turn a string in input_line_pointer into a floating point constant of type
1639 type, and store the appropriate bytes in *litP. The number of LITTLENUMS
1640 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/
1641 char *
1642 md_atof (int type, char * litP, int * sizeP)
1643 {
1644 int prec;
1645 LITTLENUM_TYPE words[MAX_LITTLENUMS];
1646 int i;
1647 char * t;
1648
1649 switch (type)
1650 {
1651 case 'f':
1652 case 'F':
1653 case 's':
1654 case 'S':
1655 prec = 2;
1656 break;
1657
1658 case 'd':
1659 case 'D':
1660 case 'r':
1661 case 'R':
1662 prec = 4;
1663 break;
1664
1665 case 'x':
1666 case 'X':
1667 prec = 6;
1668 break;
1669
1670 case 'p':
1671 case 'P':
1672 prec = 6;
1673 break;
1674
1675 default:
1676 *sizeP = 0;
1677 return _("Bad call to MD_NTOF()");
1678 }
1679
1680 t = atof_ieee (input_line_pointer, type, words);
1681
1682 if (t)
1683 input_line_pointer = t;
1684
1685 *sizeP = prec * sizeof (LITTLENUM_TYPE);
1686
1687 if (! target_big_endian)
1688 {
1689 for (i = prec - 1; i >= 0; i--)
1690 {
1691 md_number_to_chars (litP, (valueT) words[i],
1692 sizeof (LITTLENUM_TYPE));
1693 litP += sizeof (LITTLENUM_TYPE);
1694 }
1695 }
1696 else
1697 for (i = 0; i < prec; i++)
1698 {
1699 md_number_to_chars (litP, (valueT) words[i],
1700 sizeof (LITTLENUM_TYPE));
1701 litP += sizeof (LITTLENUM_TYPE);
1702 }
1703
1704 return NULL;
1705 }
1706 \f
1707 const char * md_shortopts = "";
1708
1709 struct option md_longopts[] =
1710 {
1711 { NULL, no_argument, NULL, 0}
1712 };
1713
1714 size_t md_longopts_size = sizeof (md_longopts);
1715
1716 int md_short_jump_size;
1717
1718 void
1719 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED,
1720 addressT from_Nddr ATTRIBUTE_UNUSED,
1721 addressT to_Nddr ATTRIBUTE_UNUSED,
1722 fragS * frag ATTRIBUTE_UNUSED,
1723 symbolS * to_symbol ATTRIBUTE_UNUSED)
1724 {
1725 as_fatal (_("failed sanity check: short_jump"));
1726 }
1727
1728 void
1729 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED,
1730 addressT from_Nddr ATTRIBUTE_UNUSED,
1731 addressT to_Nddr ATTRIBUTE_UNUSED,
1732 fragS * frag ATTRIBUTE_UNUSED,
1733 symbolS * to_symbol ATTRIBUTE_UNUSED)
1734 {
1735 as_fatal (_("failed sanity check: long_jump"));
1736 }
1737
1738 /* Called after relaxing, change the frags so they know how big they are. */
1739
1740 void
1741 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
1742 segT sec ATTRIBUTE_UNUSED,
1743 fragS * fragP)
1744 {
1745 fixS *fixP;
1746
1747 switch (fragP->fr_subtype)
1748 {
1749 case UNDEFINED_PC_OFFSET:
1750 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1751 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1752 fragP->fr_fix += INST_WORD_SIZE * 2;
1753 fragP->fr_var = 0;
1754 break;
1755 case DEFINED_ABS_SEGMENT:
1756 if (fragP->fr_symbol == GOT_symbol)
1757 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1758 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC);
1759 else
1760 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1761 fragP->fr_offset, FALSE, BFD_RELOC_64);
1762 fragP->fr_fix += INST_WORD_SIZE * 2;
1763 fragP->fr_var = 0;
1764 break;
1765 case DEFINED_RO_SEGMENT:
1766 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1767 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA);
1768 fragP->fr_fix += INST_WORD_SIZE;
1769 fragP->fr_var = 0;
1770 break;
1771 case DEFINED_RW_SEGMENT:
1772 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1773 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA);
1774 fragP->fr_fix += INST_WORD_SIZE;
1775 fragP->fr_var = 0;
1776 break;
1777 case DEFINED_PC_OFFSET:
1778 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol,
1779 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL);
1780 fragP->fr_fix += INST_WORD_SIZE;
1781 fragP->fr_var = 0;
1782 break;
1783 case LARGE_DEFINED_PC_OFFSET:
1784 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1785 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL);
1786 fragP->fr_fix += INST_WORD_SIZE * 2;
1787 fragP->fr_var = 0;
1788 break;
1789 case GOT_OFFSET:
1790 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1791 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT);
1792 fragP->fr_fix += INST_WORD_SIZE * 2;
1793 fragP->fr_var = 0;
1794 break;
1795 case PLT_OFFSET:
1796 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1797 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT);
1798 /* fixP->fx_plt = 1; */
1799 (void) fixP;
1800 fragP->fr_fix += INST_WORD_SIZE * 2;
1801 fragP->fr_var = 0;
1802 break;
1803 case GOTOFF_OFFSET:
1804 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol,
1805 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF);
1806 fragP->fr_fix += INST_WORD_SIZE * 2;
1807 fragP->fr_var = 0;
1808 break;
1809
1810 default:
1811 abort ();
1812 }
1813 }
1814
1815 /* Applies the desired value to the specified location.
1816 Also sets up addends for 'rela' type relocations. */
1817 void
1818 md_apply_fix (fixS * fixP,
1819 valueT * valp,
1820 segT segment)
1821 {
1822 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal;
1823 char * file = fixP->fx_file ? fixP->fx_file : _("unknown");
1824 const char * symname;
1825 /* Note: use offsetT because it is signed, valueT is unsigned. */
1826 offsetT val = (offsetT) * valp;
1827 int i;
1828 struct op_code_struct * opcode1;
1829 unsigned long inst1;
1830
1831 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>");
1832
1833 /* fixP->fx_offset is supposed to be set up correctly for all
1834 symbol relocations. */
1835 if (fixP->fx_addsy == NULL)
1836 {
1837 if (!fixP->fx_pcrel)
1838 fixP->fx_offset = val; /* Absolute relocation. */
1839 else
1840 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n",
1841 (unsigned int) fixP->fx_offset, (unsigned int) val);
1842 }
1843
1844 /* If we aren't adjusting this fixup to be against the section
1845 symbol, we need to adjust the value. */
1846 if (fixP->fx_addsy != NULL)
1847 {
1848 if (S_IS_WEAK (fixP->fx_addsy)
1849 || (symbol_used_in_reloc_p (fixP->fx_addsy)
1850 && (((bfd_get_section_flags (stdoutput,
1851 S_GET_SEGMENT (fixP->fx_addsy))
1852 & SEC_LINK_ONCE) != 0)
1853 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)),
1854 ".gnu.linkonce",
1855 sizeof (".gnu.linkonce") - 1))))
1856 {
1857 val -= S_GET_VALUE (fixP->fx_addsy);
1858 if (val != 0 && ! fixP->fx_pcrel)
1859 {
1860 /* In this case, the bfd_install_relocation routine will
1861 incorrectly add the symbol value back in. We just want
1862 the addend to appear in the object file.
1863 FIXME: If this makes VALUE zero, we're toast. */
1864 val -= S_GET_VALUE (fixP->fx_addsy);
1865 }
1866 }
1867 }
1868
1869 /* If the fix is relative to a symbol which is not defined, or not
1870 in the same segment as the fix, we cannot resolve it here. */
1871 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */
1872 if (fixP->fx_addsy != NULL
1873 && (!S_IS_DEFINED (fixP->fx_addsy)
1874 || (S_GET_SEGMENT (fixP->fx_addsy) != segment)))
1875 {
1876 fixP->fx_done = 0;
1877 #ifdef OBJ_ELF
1878 /* For ELF we can just return and let the reloc that will be generated
1879 take care of everything. For COFF we still have to insert 'val'
1880 into the insn since the addend field will be ignored. */
1881 /* return; */
1882 #endif
1883 }
1884 /* All fixups in the text section must be handled in the linker. */
1885 else if (segment->flags & SEC_CODE)
1886 fixP->fx_done = 0;
1887 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL)
1888 fixP->fx_done = 0;
1889 else
1890 fixP->fx_done = 1;
1891
1892 switch (fixP->fx_r_type)
1893 {
1894 case BFD_RELOC_MICROBLAZE_32_LO:
1895 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
1896 if (target_big_endian)
1897 {
1898 buf[2] |= ((val >> 8) & 0xff);
1899 buf[3] |= (val & 0xff);
1900 }
1901 else
1902 {
1903 buf[1] |= ((val >> 8) & 0xff);
1904 buf[0] |= (val & 0xff);
1905 }
1906 break;
1907 case BFD_RELOC_MICROBLAZE_32_ROSDA:
1908 case BFD_RELOC_MICROBLAZE_32_RWSDA:
1909 /* Don't do anything if the symbol is not defined. */
1910 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1911 {
1912 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000))
1913 as_bad_where (file, fixP->fx_line,
1914 _("pcrel for branch to %s too far (0x%x)"),
1915 symname, (int) val);
1916 if (target_big_endian)
1917 {
1918 buf[2] |= ((val >> 8) & 0xff);
1919 buf[3] |= (val & 0xff);
1920 }
1921 else
1922 {
1923 buf[1] |= ((val >> 8) & 0xff);
1924 buf[0] |= (val & 0xff);
1925 }
1926 }
1927 break;
1928 case BFD_RELOC_32:
1929 case BFD_RELOC_RVA:
1930 case BFD_RELOC_32_PCREL:
1931 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
1932 /* Don't do anything if the symbol is not defined. */
1933 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1934 {
1935 if (target_big_endian)
1936 {
1937 buf[0] |= ((val >> 24) & 0xff);
1938 buf[1] |= ((val >> 16) & 0xff);
1939 buf[2] |= ((val >> 8) & 0xff);
1940 buf[3] |= (val & 0xff);
1941 }
1942 else
1943 {
1944 buf[3] |= ((val >> 24) & 0xff);
1945 buf[2] |= ((val >> 16) & 0xff);
1946 buf[1] |= ((val >> 8) & 0xff);
1947 buf[0] |= (val & 0xff);
1948 }
1949 }
1950 break;
1951 case BFD_RELOC_64_PCREL:
1952 case BFD_RELOC_64:
1953 /* Add an imm instruction. First save the current instruction. */
1954 for (i = 0; i < INST_WORD_SIZE; i++)
1955 buf[i + INST_WORD_SIZE] = buf[i];
1956
1957 /* Generate the imm instruction. */
1958 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
1959 if (opcode1 == NULL)
1960 {
1961 as_bad (_("unknown opcode \"%s\""), "imm");
1962 return;
1963 }
1964
1965 inst1 = opcode1->bit_sequence;
1966 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1967 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK;
1968
1969 buf[0] = INST_BYTE0 (inst1);
1970 buf[1] = INST_BYTE1 (inst1);
1971 buf[2] = INST_BYTE2 (inst1);
1972 buf[3] = INST_BYTE3 (inst1);
1973
1974 /* Add the value only if the symbol is defined. */
1975 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy))
1976 {
1977 if (target_big_endian)
1978 {
1979 buf[6] |= ((val >> 8) & 0xff);
1980 buf[7] |= (val & 0xff);
1981 }
1982 else
1983 {
1984 buf[5] |= ((val >> 8) & 0xff);
1985 buf[4] |= (val & 0xff);
1986 }
1987 }
1988 break;
1989
1990 case BFD_RELOC_MICROBLAZE_64_GOTPC:
1991 case BFD_RELOC_MICROBLAZE_64_GOT:
1992 case BFD_RELOC_MICROBLAZE_64_PLT:
1993 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
1994 /* Add an imm instruction. First save the current instruction. */
1995 for (i = 0; i < INST_WORD_SIZE; i++)
1996 buf[i + INST_WORD_SIZE] = buf[i];
1997
1998 /* Generate the imm instruction. */
1999 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm");
2000 if (opcode1 == NULL)
2001 {
2002 as_bad (_("unknown opcode \"%s\""), "imm");
2003 return;
2004 }
2005
2006 inst1 = opcode1->bit_sequence;
2007
2008 /* We can fixup call to a defined non-global address
2009 within the same section only. */
2010 buf[0] = INST_BYTE0 (inst1);
2011 buf[1] = INST_BYTE1 (inst1);
2012 buf[2] = INST_BYTE2 (inst1);
2013 buf[3] = INST_BYTE3 (inst1);
2014 return;
2015
2016 default:
2017 break;
2018 }
2019
2020 if (fixP->fx_addsy == NULL)
2021 {
2022 /* This fixup has been resolved. Create a reloc in case the linker
2023 moves code around due to relaxing. */
2024 if (fixP->fx_r_type == BFD_RELOC_64_PCREL)
2025 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE;
2026 else
2027 fixP->fx_r_type = BFD_RELOC_NONE;
2028 fixP->fx_addsy = section_symbol (absolute_section);
2029 }
2030 return;
2031 }
2032
2033 void
2034 md_operand (expressionS * expressionP)
2035 {
2036 /* Ignore leading hash symbol, if present. */
2037 if (*input_line_pointer == '#')
2038 {
2039 input_line_pointer ++;
2040 expression (expressionP);
2041 }
2042 }
2043
2044 /* Called just before address relaxation, return the length
2045 by which a fragment must grow to reach it's destination. */
2046
2047 int
2048 md_estimate_size_before_relax (fragS * fragP,
2049 segT segment_type)
2050 {
2051 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss");
2052 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2");
2053 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata");
2054 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2");
2055
2056 switch (fragP->fr_subtype)
2057 {
2058 case INST_PC_OFFSET:
2059 /* Used to be a PC-relative branch. */
2060 if (!fragP->fr_symbol)
2061 {
2062 /* We know the abs value: Should never happen. */
2063 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error....."));
2064 abort ();
2065 }
2066 else if ((S_GET_SEGMENT (fragP->fr_symbol) == segment_type))
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)
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)
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.109755 seconds and 4 git commands to generate.