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