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