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