OpenCores
URL https://opencores.org/ocsvn/openrisc_me/openrisc_me/trunk

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [binutils-2.20.1/] [gas/] [config/] [tc-microblaze.c] - Blame information for rev 219

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.