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