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