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