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

Subversion Repositories open8_urisc

[/] [open8_urisc/] [trunk/] [gnu/] [binutils/] [gas/] [config/] [tc-microblaze.c] - Blame information for rev 241

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

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

powered by: WebSVN 2.1.0

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