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-v850.c] - Blame information for rev 438

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

Line No. Rev Author Line
1 205 julius
/* tc-v850.c -- Assembler code for the NEC V850
2
   Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
3
   2006, 2007, 2009  Free Software Foundation, Inc.
4
 
5
   This file is part of GAS, the GNU Assembler.
6
 
7
   GAS is free software; you can redistribute it and/or modify
8
   it under the terms of the GNU General Public License as published by
9
   the Free Software Foundation; either version 3, or (at your option)
10
   any later version.
11
 
12
   GAS is distributed in the hope that it will be useful,
13
   but WITHOUT ANY WARRANTY; without even the implied warranty of
14
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
   GNU General Public License for more details.
16
 
17
   You should have received a copy of the GNU General Public License
18
   along with GAS; see the file COPYING.  If not, write to
19
   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20
   Boston, MA 02110-1301, USA.  */
21
 
22
#include "as.h"
23
#include "safe-ctype.h"
24
#include "subsegs.h"
25
#include "opcode/v850.h"
26
#include "dwarf2dbg.h"
27
 
28
/* Sign-extend a 16-bit number.  */
29
#define SEXT16(x)       ((((x) & 0xffff) ^ (~0x7fff)) + 0x8000)
30
 
31
/* Temporarily holds the reloc in a cons expression.  */
32
static bfd_reloc_code_real_type hold_cons_reloc = BFD_RELOC_UNUSED;
33
 
34
/* Set to TRUE if we want to be pedantic about signed overflows.  */
35
static bfd_boolean warn_signed_overflows   = FALSE;
36
static bfd_boolean warn_unsigned_overflows = FALSE;
37
 
38
/* Indicates the target BFD machine number.  */
39
static int machine = -1;
40
 
41
/* Indicates the target processor(s) for the assemble.  */
42
static int processor_mask = -1;
43
 
44
/* Structure to hold information about predefined registers.  */
45
struct reg_name
46
{
47
  const char *name;
48
  int value;
49
};
50
 
51
/* Generic assembler global variables which must be defined by all
52
   targets.  */
53
 
54
/* Characters which always start a comment.  */
55
const char comment_chars[] = "#";
56
 
57
/* Characters which start a comment at the beginning of a line.  */
58
const char line_comment_chars[] = ";#";
59
 
60
/* Characters which may be used to separate multiple commands on a
61
   single line.  */
62
const char line_separator_chars[] = ";";
63
 
64
/* Characters which are used to indicate an exponent in a floating
65
   point number.  */
66
const char EXP_CHARS[] = "eE";
67
 
68
/* Characters which mean that a number is a floating point constant,
69
   as in 0d1.0.  */
70
const char FLT_CHARS[] = "dD";
71
 
72
const relax_typeS md_relax_table[] =
73
{
74
  /* Conditional branches.  */
75
  {0xff,     -0x100,    2, 1},
76
  {0x1fffff, -0x200000, 6, 0},
77
  /* Unconditional branches.  */
78
  {0xff,     -0x100,    2, 3},
79
  {0x1fffff, -0x200000, 4, 0},
80
};
81
 
82
static int  v850_relax = 0;
83
 
84
/* Fixups.  */
85
#define MAX_INSN_FIXUPS   5
86
 
87
struct v850_fixup
88
{
89
  expressionS exp;
90
  int opindex;
91
  bfd_reloc_code_real_type reloc;
92
};
93
 
94
struct v850_fixup fixups[MAX_INSN_FIXUPS];
95
static int fc;
96
 
97
struct v850_seg_entry
98
{
99
  segT s;
100
  const char *name;
101
  flagword flags;
102
};
103
 
104
struct v850_seg_entry v850_seg_table[] =
105
{
106
  { NULL, ".sdata",
107
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
108
    | SEC_SMALL_DATA },
109
  { NULL, ".tdata",
110
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
111
  { NULL, ".zdata",
112
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
113
  { NULL, ".sbss",
114
    SEC_ALLOC | SEC_SMALL_DATA },
115
  { NULL, ".tbss",
116
    SEC_ALLOC },
117
  { NULL, ".zbss",
118
    SEC_ALLOC},
119
  { NULL, ".rosdata",
120
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_DATA
121
    | SEC_HAS_CONTENTS | SEC_SMALL_DATA },
122
  { NULL, ".rozdata",
123
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_DATA
124
    | SEC_HAS_CONTENTS },
125
  { NULL, ".scommon",
126
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
127
    | SEC_SMALL_DATA | SEC_IS_COMMON },
128
  { NULL, ".tcommon",
129
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
130
    | SEC_IS_COMMON },
131
  { NULL, ".zcommon",
132
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS
133
    | SEC_IS_COMMON },
134
  { NULL, ".call_table_data",
135
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_DATA | SEC_HAS_CONTENTS },
136
  { NULL, ".call_table_text",
137
    SEC_ALLOC | SEC_LOAD | SEC_RELOC | SEC_READONLY | SEC_CODE
138
    | SEC_HAS_CONTENTS},
139
  { NULL, ".bss",
140
    SEC_ALLOC }
141
};
142
 
143
#define SDATA_SECTION           0
144
#define TDATA_SECTION           1
145
#define ZDATA_SECTION           2
146
#define SBSS_SECTION            3
147
#define TBSS_SECTION            4
148
#define ZBSS_SECTION            5
149
#define ROSDATA_SECTION         6
150
#define ROZDATA_SECTION         7
151
#define SCOMMON_SECTION         8
152
#define TCOMMON_SECTION         9
153
#define ZCOMMON_SECTION         10
154
#define CALL_TABLE_DATA_SECTION 11
155
#define CALL_TABLE_TEXT_SECTION 12
156
#define BSS_SECTION             13
157
 
158
static void
159
do_v850_seg (int i, subsegT sub)
160
{
161
  struct v850_seg_entry *seg = v850_seg_table + i;
162
 
163
  obj_elf_section_change_hook ();
164
 
165
  if (seg->s != NULL)
166
    subseg_set (seg->s, sub);
167
  else
168
    {
169
      seg->s = subseg_new (seg->name, sub);
170
      bfd_set_section_flags (stdoutput, seg->s, seg->flags);
171
      if ((seg->flags & SEC_LOAD) == 0)
172
        seg_info (seg->s)->bss = 1;
173
    }
174
}
175
 
176
static void
177
v850_seg (int i)
178
{
179
  subsegT sub = get_absolute_expression ();
180
 
181
  do_v850_seg (i, sub);
182
  demand_empty_rest_of_line ();
183
}
184
 
185
static void
186
v850_offset (int ignore ATTRIBUTE_UNUSED)
187
{
188
  char *pfrag;
189
  int temp = get_absolute_expression ();
190
 
191
  pfrag = frag_var (rs_org, 1, 1, (relax_substateT)0, (symbolS *)0,
192
                    (offsetT) temp, (char *) 0);
193
  *pfrag = 0;
194
 
195
  demand_empty_rest_of_line ();
196
}
197
 
198
/* Copied from obj_elf_common() in gas/config/obj-elf.c.  */
199
 
200
static void
201
v850_comm (int area)
202
{
203
  char *name;
204
  char c;
205
  char *p;
206
  int temp;
207
  unsigned int size;
208
  symbolS *symbolP;
209
  int have_align;
210
 
211
  name = input_line_pointer;
212
  c = get_symbol_end ();
213
 
214
  /* Just after name is now '\0'.  */
215
  p = input_line_pointer;
216
  *p = c;
217
 
218
  SKIP_WHITESPACE ();
219
 
220
  if (*input_line_pointer != ',')
221
    {
222
      as_bad (_("Expected comma after symbol-name"));
223
      ignore_rest_of_line ();
224
      return;
225
    }
226
 
227
  /* Skip ','.  */
228
  input_line_pointer++;
229
 
230
  if ((temp = get_absolute_expression ()) < 0)
231
    {
232
      /* xgettext:c-format  */
233
      as_bad (_(".COMMon length (%d.) < 0! Ignored."), temp);
234
      ignore_rest_of_line ();
235
      return;
236
    }
237
 
238
  size = temp;
239
  *p = 0;
240
  symbolP = symbol_find_or_make (name);
241
  *p = c;
242
 
243
  if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP))
244
    {
245
      as_bad (_("Ignoring attempt to re-define symbol"));
246
      ignore_rest_of_line ();
247
      return;
248
    }
249
 
250
  if (S_GET_VALUE (symbolP) != 0)
251
    {
252
      if (S_GET_VALUE (symbolP) != size)
253
        /* xgettext:c-format  */
254
        as_warn (_("Length of .comm \"%s\" is already %ld. Not changed to %d."),
255
                 S_GET_NAME (symbolP), (long) S_GET_VALUE (symbolP), size);
256
    }
257
 
258
  know (symbol_get_frag (symbolP) == &zero_address_frag);
259
 
260
  if (*input_line_pointer != ',')
261
    have_align = 0;
262
  else
263
    {
264
      have_align = 1;
265
      input_line_pointer++;
266
      SKIP_WHITESPACE ();
267
    }
268
 
269
  if (! have_align || *input_line_pointer != '"')
270
    {
271
      if (! have_align)
272
        temp = 0;
273
      else
274
        {
275
          temp = get_absolute_expression ();
276
 
277
          if (temp < 0)
278
            {
279
              temp = 0;
280
              as_warn (_("Common alignment negative; 0 assumed"));
281
            }
282
        }
283
 
284
      if (symbol_get_obj (symbolP)->local)
285
        {
286
          segT old_sec;
287
          int old_subsec;
288
          char *pfrag;
289
          int align;
290
          flagword applicable;
291
 
292
          old_sec = now_seg;
293
          old_subsec = now_subseg;
294
 
295
          applicable = bfd_applicable_section_flags (stdoutput);
296
 
297
          applicable &= SEC_ALLOC;
298
 
299
          switch (area)
300
            {
301
            case SCOMMON_SECTION:
302
              do_v850_seg (SBSS_SECTION, 0);
303
              break;
304
 
305
            case ZCOMMON_SECTION:
306
              do_v850_seg (ZBSS_SECTION, 0);
307
              break;
308
 
309
            case TCOMMON_SECTION:
310
              do_v850_seg (TBSS_SECTION, 0);
311
              break;
312
            }
313
 
314
          if (temp)
315
            {
316
              /* Convert to a power of 2 alignment.  */
317
              for (align = 0; (temp & 1) == 0; temp >>= 1, ++align)
318
                ;
319
 
320
              if (temp != 1)
321
                {
322
                  as_bad (_("Common alignment not a power of 2"));
323
                  ignore_rest_of_line ();
324
                  return;
325
                }
326
            }
327
          else
328
            align = 0;
329
 
330
          record_alignment (now_seg, align);
331
 
332
          if (align)
333
            frag_align (align, 0, 0);
334
 
335
          switch (area)
336
            {
337
            case SCOMMON_SECTION:
338
              if (S_GET_SEGMENT (symbolP) == v850_seg_table[SBSS_SECTION].s)
339
                symbol_get_frag (symbolP)->fr_symbol = 0;
340
              break;
341
 
342
            case ZCOMMON_SECTION:
343
              if (S_GET_SEGMENT (symbolP) == v850_seg_table[ZBSS_SECTION].s)
344
                symbol_get_frag (symbolP)->fr_symbol = 0;
345
              break;
346
 
347
            case TCOMMON_SECTION:
348
              if (S_GET_SEGMENT (symbolP) == v850_seg_table[TBSS_SECTION].s)
349
                symbol_get_frag (symbolP)->fr_symbol = 0;
350
              break;
351
 
352
            default:
353
              abort ();
354
            }
355
 
356
          symbol_set_frag (symbolP, frag_now);
357
          pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP,
358
                            (offsetT) size, (char *) 0);
359
          *pfrag = 0;
360
          S_SET_SIZE (symbolP, size);
361
 
362
          switch (area)
363
            {
364
            case SCOMMON_SECTION:
365
              S_SET_SEGMENT (symbolP, v850_seg_table[SBSS_SECTION].s);
366
              break;
367
 
368
            case ZCOMMON_SECTION:
369
              S_SET_SEGMENT (symbolP, v850_seg_table[ZBSS_SECTION].s);
370
              break;
371
 
372
            case TCOMMON_SECTION:
373
              S_SET_SEGMENT (symbolP, v850_seg_table[TBSS_SECTION].s);
374
              break;
375
 
376
            default:
377
              abort ();
378
            }
379
 
380
          S_CLEAR_EXTERNAL (symbolP);
381
          obj_elf_section_change_hook ();
382
          subseg_set (old_sec, old_subsec);
383
        }
384
      else
385
        {
386
          segT   old_sec;
387
          int    old_subsec;
388
 
389
        allocate_common:
390
          old_sec = now_seg;
391
          old_subsec = now_subseg;
392
 
393
          S_SET_VALUE (symbolP, (valueT) size);
394
          S_SET_ALIGN (symbolP, temp);
395
          S_SET_EXTERNAL (symbolP);
396
 
397
          switch (area)
398
            {
399
            case SCOMMON_SECTION:
400
            case ZCOMMON_SECTION:
401
            case TCOMMON_SECTION:
402
              do_v850_seg (area, 0);
403
              S_SET_SEGMENT (symbolP, v850_seg_table[area].s);
404
              break;
405
 
406
            default:
407
              abort ();
408
            }
409
 
410
          obj_elf_section_change_hook ();
411
          subseg_set (old_sec, old_subsec);
412
        }
413
    }
414
  else
415
    {
416
      input_line_pointer++;
417
 
418
      /* @@ Some use the dot, some don't.  Can we get some consistency??  */
419
      if (*input_line_pointer == '.')
420
        input_line_pointer++;
421
 
422
      /* @@ Some say data, some say bss.  */
423
      if (strncmp (input_line_pointer, "bss\"", 4)
424
          && strncmp (input_line_pointer, "data\"", 5))
425
        {
426
          while (*--input_line_pointer != '"')
427
            ;
428
          input_line_pointer--;
429
          goto bad_common_segment;
430
        }
431
 
432
      while (*input_line_pointer++ != '"')
433
        ;
434
 
435
      goto allocate_common;
436
    }
437
 
438
  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
439
 
440
  demand_empty_rest_of_line ();
441
  return;
442
 
443
  {
444
  bad_common_segment:
445
    p = input_line_pointer;
446
    while (*p && *p != '\n')
447
      p++;
448
    c = *p;
449
    *p = '\0';
450
    as_bad (_("bad .common segment %s"), input_line_pointer + 1);
451
    *p = c;
452
    input_line_pointer = p;
453
    ignore_rest_of_line ();
454
    return;
455
  }
456
}
457
 
458
static void
459
set_machine (int number)
460
{
461
  machine = number;
462
  bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
463
 
464
  switch (machine)
465
    {
466
    case 0:                processor_mask = PROCESSOR_V850;   break;
467
    case bfd_mach_v850e:  processor_mask = PROCESSOR_V850E;  break;
468
    case bfd_mach_v850e1: processor_mask = PROCESSOR_V850E;  break;
469
    }
470
}
471
 
472
static void
473
v850_longcode (int type)
474
{
475
  expressionS ex;
476
 
477
  if (! v850_relax)
478
    {
479
      if (type == 1)
480
        as_warn (_(".longcall pseudo-op seen when not relaxing"));
481
      else
482
        as_warn (_(".longjump pseudo-op seen when not relaxing"));
483
    }
484
 
485
  expression (&ex);
486
 
487
  if (ex.X_op != O_symbol || ex.X_add_number != 0)
488
    {
489
      as_bad (_("bad .longcall format"));
490
      ignore_rest_of_line ();
491
 
492
      return;
493
    }
494
 
495
  if (type == 1)
496
    fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
497
                 BFD_RELOC_V850_LONGCALL);
498
  else
499
    fix_new_exp (frag_now, frag_now_fix (), 4, & ex, 1,
500
                 BFD_RELOC_V850_LONGJUMP);
501
 
502
  demand_empty_rest_of_line ();
503
}
504
 
505
/* The target specific pseudo-ops which we support.  */
506
const pseudo_typeS md_pseudo_table[] =
507
{
508
  { "sdata",            v850_seg,               SDATA_SECTION           },
509
  { "tdata",            v850_seg,               TDATA_SECTION           },
510
  { "zdata",            v850_seg,               ZDATA_SECTION           },
511
  { "sbss",             v850_seg,               SBSS_SECTION            },
512
  { "tbss",             v850_seg,               TBSS_SECTION            },
513
  { "zbss",             v850_seg,               ZBSS_SECTION            },
514
  { "rosdata",          v850_seg,               ROSDATA_SECTION         },
515
  { "rozdata",          v850_seg,               ROZDATA_SECTION         },
516
  { "bss",              v850_seg,               BSS_SECTION             },
517
  { "offset",           v850_offset,            0                        },
518
  { "word",             cons,                   4                       },
519
  { "zcomm",            v850_comm,              ZCOMMON_SECTION         },
520
  { "scomm",            v850_comm,              SCOMMON_SECTION         },
521
  { "tcomm",            v850_comm,              TCOMMON_SECTION         },
522
  { "v850",             set_machine,            0                        },
523
  { "call_table_data",  v850_seg,               CALL_TABLE_DATA_SECTION },
524
  { "call_table_text",  v850_seg,               CALL_TABLE_TEXT_SECTION },
525
  { "v850e",            set_machine,            bfd_mach_v850e          },
526
  { "v850e1",           set_machine,            bfd_mach_v850e1         },
527
  { "longcall",         v850_longcode,          1                       },
528
  { "longjump",         v850_longcode,          2                       },
529
  { NULL,               NULL,                   0                        }
530
};
531
 
532
/* Opcode hash table.  */
533
static struct hash_control *v850_hash;
534
 
535
/* This table is sorted.  Suitable for searching by a binary search.  */
536
static const struct reg_name pre_defined_registers[] =
537
{
538
  { "ep",  30 },                /* ep - element ptr.  */
539
  { "gp",   4 },                /* gp - global ptr.  */
540
  { "hp",   2 },                /* hp - handler stack ptr.  */
541
  { "lp",  31 },                /* lp - link ptr.  */
542
  { "r0",   0 },
543
  { "r1",   1 },
544
  { "r10", 10 },
545
  { "r11", 11 },
546
  { "r12", 12 },
547
  { "r13", 13 },
548
  { "r14", 14 },
549
  { "r15", 15 },
550
  { "r16", 16 },
551
  { "r17", 17 },
552
  { "r18", 18 },
553
  { "r19", 19 },
554
  { "r2",   2 },
555
  { "r20", 20 },
556
  { "r21", 21 },
557
  { "r22", 22 },
558
  { "r23", 23 },
559
  { "r24", 24 },
560
  { "r25", 25 },
561
  { "r26", 26 },
562
  { "r27", 27 },
563
  { "r28", 28 },
564
  { "r29", 29 },
565
  { "r3",   3 },
566
  { "r30", 30 },
567
  { "r31", 31 },
568
  { "r4",   4 },
569
  { "r5",   5 },
570
  { "r6",   6 },
571
  { "r7",   7 },
572
  { "r8",   8 },
573
  { "r9",   9 },
574
  { "sp",   3 },                /* sp - stack ptr.  */
575
  { "tp",   5 },                /* tp - text ptr.  */
576
  { "zero", 0 },
577
};
578
 
579
#define REG_NAME_CNT                                            \
580
  (sizeof (pre_defined_registers) / sizeof (struct reg_name))
581
 
582
static const struct reg_name system_registers[] =
583
{
584
  { "asid",  23 },
585
  { "bpc",   22 },
586
  { "bpav",  24 },
587
  { "bpam",  25 },
588
  { "bpdv",  26 },
589
  { "bpdm",  27 },
590
  { "ctbp",  20 },
591
  { "ctpc",  16 },
592
  { "ctpsw", 17 },
593
  { "dbpc",  18 },
594
  { "dbpsw", 19 },
595
  { "dir",   21 },
596
  { "ecr",    4 },
597
  { "eipc",   0 },
598
  { "eipsw",  1 },
599
  { "fepc",   2 },
600
  { "fepsw",  3 },
601
  { "psw",    5 },
602
};
603
 
604
#define SYSREG_NAME_CNT                                         \
605
  (sizeof (system_registers) / sizeof (struct reg_name))
606
 
607
static const struct reg_name system_list_registers[] =
608
{
609
  {"PS",      5 },
610
  {"SR",      0 + 1}
611
};
612
 
613
#define SYSREGLIST_NAME_CNT                                     \
614
  (sizeof (system_list_registers) / sizeof (struct reg_name))
615
 
616
static const struct reg_name cc_names[] =
617
{
618
  { "c",  0x1 },
619
  { "e",  0x2 },
620
  { "ge", 0xe },
621
  { "gt", 0xf },
622
  { "h",  0xb },
623
  { "l",  0x1 },
624
  { "le", 0x7 },
625
  { "lt", 0x6 },
626
  { "n",  0x4 },
627
  { "nc", 0x9 },
628
  { "ne", 0xa },
629
  { "nh", 0x3 },
630
  { "nl", 0x9 },
631
  { "ns", 0xc },
632
  { "nv", 0x8 },
633
  { "nz", 0xa },
634
  { "p",  0xc },
635
  { "s",  0x4 },
636
  { "sa", 0xd },
637
  { "t",  0x5 },
638
  { "v",  0x0 },
639
  { "z",  0x2 },
640
};
641
 
642
#define CC_NAME_CNT                                     \
643
  (sizeof (cc_names) / sizeof (struct reg_name))
644
 
645
/* Do a binary search of the given register table to see if NAME is a
646
   valid regiter name.  Return the register number from the array on
647
   success, or -1 on failure.  */
648
 
649
static int
650
reg_name_search (const struct reg_name *regs,
651
                 int regcount,
652
                 const char *name,
653
                 bfd_boolean accept_numbers)
654
{
655
  int middle, low, high;
656
  int cmp;
657
  symbolS *symbolP;
658
 
659
  /* If the register name is a symbol, then evaluate it.  */
660
  if ((symbolP = symbol_find (name)) != NULL)
661
    {
662
      /* If the symbol is an alias for another name then use that.
663
         If the symbol is an alias for a number, then return the number.  */
664
      if (symbol_equated_p (symbolP))
665
        name
666
          = S_GET_NAME (symbol_get_value_expression (symbolP)->X_add_symbol);
667
      else if (accept_numbers)
668
        {
669
          int reg = S_GET_VALUE (symbolP);
670
 
671
          if (reg >= 0 && reg <= 31)
672
            return reg;
673
        }
674
 
675
      /* Otherwise drop through and try parsing name normally.  */
676
    }
677
 
678
  low = 0;
679
  high = regcount - 1;
680
 
681
  do
682
    {
683
      middle = (low + high) / 2;
684
      cmp = strcasecmp (name, regs[middle].name);
685
      if (cmp < 0)
686
        high = middle - 1;
687
      else if (cmp > 0)
688
        low = middle + 1;
689
      else
690
        return regs[middle].value;
691
    }
692
  while (low <= high);
693
  return -1;
694
}
695
 
696
/* Summary of register_name().
697
 
698
   in: Input_line_pointer points to 1st char of operand.
699
 
700
   out: An expressionS.
701
        The operand may have been a register: in this case, X_op == O_register,
702
        X_add_number is set to the register number, and truth is returned.
703
        Input_line_pointer->(next non-blank) char after operand, or is in
704
        its original state.  */
705
 
706
static bfd_boolean
707
register_name (expressionS *expressionP)
708
{
709
  int reg_number;
710
  char *name;
711
  char *start;
712
  char c;
713
 
714
  /* Find the spelling of the operand.  */
715
  start = name = input_line_pointer;
716
 
717
  c = get_symbol_end ();
718
 
719
  reg_number = reg_name_search (pre_defined_registers, REG_NAME_CNT,
720
                                name, FALSE);
721
 
722
  /* Put back the delimiting char.  */
723
  *input_line_pointer = c;
724
 
725
  /* Look to see if it's in the register table.  */
726
  if (reg_number >= 0)
727
    {
728
      expressionP->X_op         = O_register;
729
      expressionP->X_add_number = reg_number;
730
 
731
      /* Make the rest nice.  */
732
      expressionP->X_add_symbol = NULL;
733
      expressionP->X_op_symbol  = NULL;
734
 
735
      return TRUE;
736
    }
737
  else
738
    {
739
      /* Reset the line as if we had not done anything.  */
740
      input_line_pointer = start;
741
 
742
      return FALSE;
743
    }
744
}
745
 
746
/* Summary of system_register_name().
747
 
748
   in:  INPUT_LINE_POINTER points to 1st char of operand.
749
        EXPRESSIONP points to an expression structure to be filled in.
750
        ACCEPT_NUMBERS is true iff numerical register names may be used.
751
        ACCEPT_LIST_NAMES is true iff the special names PS and SR may be
752
        accepted.
753
 
754
   out: An expressionS structure in expressionP.
755
        The operand may have been a register: in this case, X_op == O_register,
756
        X_add_number is set to the register number, and truth is returned.
757
        Input_line_pointer->(next non-blank) char after operand, or is in
758
        its original state.  */
759
 
760
static bfd_boolean
761
system_register_name (expressionS *expressionP,
762
                      bfd_boolean accept_numbers,
763
                      bfd_boolean accept_list_names)
764
{
765
  int reg_number;
766
  char *name;
767
  char *start;
768
  char c;
769
 
770
  /* Find the spelling of the operand.  */
771
  start = name = input_line_pointer;
772
 
773
  c = get_symbol_end ();
774
  reg_number = reg_name_search (system_registers, SYSREG_NAME_CNT, name,
775
                                accept_numbers);
776
 
777
  /* Put back the delimiting char.  */
778
  *input_line_pointer = c;
779
 
780
  if (reg_number < 0
781
      && accept_numbers)
782
    {
783
      /* Reset input_line pointer.  */
784
      input_line_pointer = start;
785
 
786
      if (ISDIGIT (*input_line_pointer))
787
        {
788
          reg_number = strtol (input_line_pointer, &input_line_pointer, 10);
789
 
790
          /* Make sure that the register number is allowable.  */
791
          if (reg_number < 0
792
              || (reg_number > 5 && reg_number < 16)
793
              || reg_number > 27)
794
            reg_number = -1;
795
        }
796
      else if (accept_list_names)
797
        {
798
          c = get_symbol_end ();
799
          reg_number = reg_name_search (system_list_registers,
800
                                        SYSREGLIST_NAME_CNT, name, FALSE);
801
 
802
          /* Put back the delimiting char.  */
803
          *input_line_pointer = c;
804
        }
805
    }
806
 
807
  /* Look to see if it's in the register table.  */
808
  if (reg_number >= 0)
809
    {
810
      expressionP->X_op         = O_register;
811
      expressionP->X_add_number = reg_number;
812
 
813
      /* Make the rest nice.  */
814
      expressionP->X_add_symbol = NULL;
815
      expressionP->X_op_symbol  = NULL;
816
 
817
      return TRUE;
818
    }
819
  else
820
    {
821
      /* Reset the line as if we had not done anything.  */
822
      input_line_pointer = start;
823
 
824
      return FALSE;
825
    }
826
}
827
 
828
/* Summary of cc_name().
829
 
830
   in: INPUT_LINE_POINTER points to 1st char of operand.
831
 
832
   out: An expressionS.
833
        The operand may have been a register: in this case, X_op == O_register,
834
        X_add_number is set to the register number, and truth is returned.
835
        Input_line_pointer->(next non-blank) char after operand, or is in
836
        its original state.  */
837
 
838
static bfd_boolean
839
cc_name (expressionS *expressionP)
840
{
841
  int reg_number;
842
  char *name;
843
  char *start;
844
  char c;
845
 
846
  /* Find the spelling of the operand.  */
847
  start = name = input_line_pointer;
848
 
849
  c = get_symbol_end ();
850
  reg_number = reg_name_search (cc_names, CC_NAME_CNT, name, FALSE);
851
 
852
  /* Put back the delimiting char.  */
853
  *input_line_pointer = c;
854
 
855
  /* Look to see if it's in the register table.  */
856
  if (reg_number >= 0)
857
    {
858
      expressionP->X_op         = O_constant;
859
      expressionP->X_add_number = reg_number;
860
 
861
      /* Make the rest nice.  */
862
      expressionP->X_add_symbol = NULL;
863
      expressionP->X_op_symbol  = NULL;
864
 
865
      return TRUE;
866
    }
867
  else
868
    {
869
      /* Reset the line as if we had not done anything.  */
870
      input_line_pointer = start;
871
 
872
      return FALSE;
873
    }
874
}
875
 
876
static void
877
skip_white_space (void)
878
{
879
  while (*input_line_pointer == ' '
880
         || *input_line_pointer == '\t')
881
    ++input_line_pointer;
882
}
883
 
884
/* Summary of parse_register_list ().
885
 
886
   in: INPUT_LINE_POINTER  points to 1st char of a list of registers.
887
       INSN                is the partially constructed instruction.
888
       OPERAND             is the operand being inserted.
889
 
890
   out: NULL if the parse completed successfully, otherwise a
891
        pointer to an error message is returned.  If the parse
892
        completes the correct bit fields in the instruction
893
        will be filled in.
894
 
895
   Parses register lists with the syntax:
896
 
897
     { rX }
898
     { rX, rY }
899
     { rX - rY }
900
     { rX - rY, rZ }
901
     etc
902
 
903
   and also parses constant expressions whoes bits indicate the
904
   registers in the lists.  The LSB in the expression refers to
905
   the lowest numbered permissible register in the register list,
906
   and so on upwards.  System registers are considered to be very
907
   high numbers.  */
908
 
909
static char *
910
parse_register_list (unsigned long *insn,
911
                     const struct v850_operand *operand)
912
{
913
  static int type1_regs[32] =
914
  {
915
    30,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
916
     0,  0,  0,  0,  0, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
917
  };
918
  static int type2_regs[32] =
919
  {
920
    19, 18, 17, 16,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
921
     0,  0,  0,  0, 30, 31, 29, 28, 23, 22, 21, 20, 27, 26, 25, 24
922
  };
923
  static int type3_regs[32] =
924
  {
925
     3,  2,  1,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
926
     0,  0,  0,  0, 14, 15, 13, 12,  7,  6,  5,  4, 11, 10,  9,  8
927
  };
928
  int *regs;
929
  expressionS exp;
930
 
931
  /* Select a register array to parse.  */
932
  switch (operand->shift)
933
    {
934
    case 0xffe00001: regs = type1_regs; break;
935
    case 0xfff8000f: regs = type2_regs; break;
936
    case 0xfff8001f: regs = type3_regs; break;
937
    default:
938
      as_bad (_("unknown operand shift: %x\n"), operand->shift);
939
      return _("internal failure in parse_register_list");
940
    }
941
 
942
  skip_white_space ();
943
 
944
  /* If the expression starts with a curly brace it is a register list.
945
     Otherwise it is a constant expression, whoes bits indicate which
946
     registers are to be included in the list.  */
947
  if (*input_line_pointer != '{')
948
    {
949
      int reg;
950
      int i;
951
 
952
      expression (&exp);
953
 
954
      if (exp.X_op != O_constant)
955
        return _("constant expression or register list expected");
956
 
957
      if (regs == type1_regs)
958
        {
959
          if (exp.X_add_number & 0xFFFFF000)
960
            return _("high bits set in register list expression");
961
 
962
          for (reg = 20; reg < 32; reg++)
963
            if (exp.X_add_number & (1 << (reg - 20)))
964
              {
965
                for (i = 0; i < 32; i++)
966
                  if (regs[i] == reg)
967
                    *insn |= (1 << i);
968
              }
969
        }
970
      else if (regs == type2_regs)
971
        {
972
          if (exp.X_add_number & 0xFFFE0000)
973
            return _("high bits set in register list expression");
974
 
975
          for (reg = 1; reg < 16; reg++)
976
            if (exp.X_add_number & (1 << (reg - 1)))
977
              {
978
                for (i = 0; i < 32; i++)
979
                  if (regs[i] == reg)
980
                    *insn |= (1 << i);
981
              }
982
 
983
          if (exp.X_add_number & (1 << 15))
984
            *insn |= (1 << 3);
985
 
986
          if (exp.X_add_number & (1 << 16))
987
            *insn |= (1 << 19);
988
        }
989
      else /* regs == type3_regs  */
990
        {
991
          if (exp.X_add_number & 0xFFFE0000)
992
            return _("high bits set in register list expression");
993
 
994
          for (reg = 16; reg < 32; reg++)
995
            if (exp.X_add_number & (1 << (reg - 16)))
996
              {
997
                for (i = 0; i < 32; i++)
998
                  if (regs[i] == reg)
999
                    *insn |= (1 << i);
1000
              }
1001
 
1002
          if (exp.X_add_number & (1 << 16))
1003
            *insn |= (1 << 19);
1004
        }
1005
 
1006
      return NULL;
1007
    }
1008
 
1009
  input_line_pointer++;
1010
 
1011
  /* Parse the register list until a terminator (closing curly brace or
1012
     new-line) is found.  */
1013
  for (;;)
1014
    {
1015
      if (register_name (&exp))
1016
        {
1017
          int i;
1018
 
1019
          /* Locate the given register in the list, and if it is there,
1020
             insert the corresponding bit into the instruction.  */
1021
          for (i = 0; i < 32; i++)
1022
            {
1023
              if (regs[i] == exp.X_add_number)
1024
                {
1025
                  *insn |= (1 << i);
1026
                  break;
1027
                }
1028
            }
1029
 
1030
          if (i == 32)
1031
            return _("illegal register included in list");
1032
        }
1033
      else if (system_register_name (&exp, TRUE, TRUE))
1034
        {
1035
          if (regs == type1_regs)
1036
            {
1037
              return _("system registers cannot be included in list");
1038
            }
1039
          else if (exp.X_add_number == 5)
1040
            {
1041
              if (regs == type2_regs)
1042
                return _("PSW cannot be included in list");
1043
              else
1044
                *insn |= 0x8;
1045
            }
1046
          else if (exp.X_add_number < 4)
1047
            *insn |= 0x80000;
1048
          else
1049
            return _("High value system registers cannot be included in list");
1050
        }
1051
      else if (*input_line_pointer == '}')
1052
        {
1053
          input_line_pointer++;
1054
          break;
1055
        }
1056
      else if (*input_line_pointer == ',')
1057
        {
1058
          input_line_pointer++;
1059
          continue;
1060
        }
1061
      else if (*input_line_pointer == '-')
1062
        {
1063
          /* We have encountered a range of registers: rX - rY.  */
1064
          int j;
1065
          expressionS exp2;
1066
 
1067
          /* Skip the dash.  */
1068
          ++input_line_pointer;
1069
 
1070
          /* Get the second register in the range.  */
1071
          if (! register_name (&exp2))
1072
            {
1073
              return _("second register should follow dash in register list");
1074
              exp2.X_add_number = exp.X_add_number;
1075
            }
1076
 
1077
          /* Add the rest of the registers in the range.  */
1078
          for (j = exp.X_add_number + 1; j <= exp2.X_add_number; j++)
1079
            {
1080
              int i;
1081
 
1082
              /* Locate the given register in the list, and if it is there,
1083
                 insert the corresponding bit into the instruction.  */
1084
              for (i = 0; i < 32; i++)
1085
                {
1086
                  if (regs[i] == j)
1087
                    {
1088
                      *insn |= (1 << i);
1089
                      break;
1090
                    }
1091
                }
1092
 
1093
              if (i == 32)
1094
                return _("illegal register included in list");
1095
            }
1096
        }
1097
      else
1098
        break;
1099
 
1100
      skip_white_space ();
1101
    }
1102
 
1103
  return NULL;
1104
}
1105
 
1106
const char *md_shortopts = "m:";
1107
 
1108
struct option md_longopts[] =
1109
{
1110
  {NULL, no_argument, NULL, 0}
1111
};
1112
 
1113
size_t md_longopts_size = sizeof (md_longopts);
1114
 
1115
void
1116
md_show_usage (FILE *stream)
1117
{
1118
  fprintf (stream, _(" V850 options:\n"));
1119
  fprintf (stream, _("  -mwarn-signed-overflow    Warn if signed immediate values overflow\n"));
1120
  fprintf (stream, _("  -mwarn-unsigned-overflow  Warn if unsigned immediate values overflow\n"));
1121
  fprintf (stream, _("  -mv850                    The code is targeted at the v850\n"));
1122
  fprintf (stream, _("  -mv850e                   The code is targeted at the v850e\n"));
1123
  fprintf (stream, _("  -mv850e1                  The code is targeted at the v850e1\n"));
1124
  fprintf (stream, _("  -mv850any                 The code is generic, despite any processor specific instructions\n"));
1125
  fprintf (stream, _("  -mrelax                   Enable relaxation\n"));
1126
}
1127
 
1128
int
1129
md_parse_option (int c, char *arg)
1130
{
1131
  if (c != 'm')
1132
    return 0;
1133
 
1134
  if (strcmp (arg, "warn-signed-overflow") == 0)
1135
    warn_signed_overflows = TRUE;
1136
 
1137
  else if (strcmp (arg, "warn-unsigned-overflow") == 0)
1138
    warn_unsigned_overflows = TRUE;
1139
 
1140
  else if (strcmp (arg, "v850") == 0)
1141
    {
1142
      machine = 0;
1143
      processor_mask = PROCESSOR_V850;
1144
    }
1145
  else if (strcmp (arg, "v850e") == 0)
1146
    {
1147
      machine = bfd_mach_v850e;
1148
      processor_mask = PROCESSOR_V850E;
1149
    }
1150
  else if (strcmp (arg, "v850e1") == 0)
1151
    {
1152
      machine = bfd_mach_v850e1;
1153
      processor_mask = PROCESSOR_V850E1;
1154
    }
1155
  else if (strcmp (arg, "v850any") == 0)
1156
    {
1157
      /* Tell the world that this is for any v850 chip.  */
1158
      machine = 0;
1159
 
1160
      /* But support instructions for the extended versions.  */
1161
      processor_mask = PROCESSOR_V850E;
1162
      processor_mask |= PROCESSOR_V850E1;
1163
    }
1164
  else if (strcmp (arg, "relax") == 0)
1165
    v850_relax = 1;
1166
  else
1167
    return 0;
1168
 
1169
  return 1;
1170
}
1171
 
1172
symbolS *
1173
md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
1174
{
1175
  return 0;
1176
}
1177
 
1178
char *
1179
md_atof (int type, char *litp, int *sizep)
1180
{
1181
  return ieee_md_atof (type, litp, sizep, FALSE);
1182
}
1183
 
1184
/* Very gross.  */
1185
 
1186
void
1187
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
1188
                 asection *sec,
1189
                 fragS *fragP)
1190
{
1191
  /* This code performs some nasty type punning between the
1192
     fr_opcode field of the frag structure (a char *) and the
1193
     fx_r_type field of the fix structure (a bfd_reloc_code_real_type)
1194
     On a 64bit host this causes problems because these two fields
1195
     are not the same size, but since we know that we are only
1196
     ever storing small integers in the fields, it is safe to use
1197
     a union to convert between them.  */
1198
  union u
1199
  {
1200
    bfd_reloc_code_real_type fx_r_type;
1201
    char * fr_opcode;
1202
  }
1203
  opcode_converter;
1204
  subseg_change (sec, 0);
1205
 
1206
  opcode_converter.fr_opcode = fragP->fr_opcode;
1207
 
1208
  /* In range conditional or unconditional branch.  */
1209
  if (fragP->fr_subtype == 0 || fragP->fr_subtype == 2)
1210
    {
1211
      fix_new (fragP, fragP->fr_fix, 2, fragP->fr_symbol,
1212
               fragP->fr_offset, 1,
1213
               BFD_RELOC_UNUSED + opcode_converter.fx_r_type);
1214
      fragP->fr_fix += 2;
1215
    }
1216
  /* Out of range conditional branch.  Emit a branch around a jump.  */
1217
  else if (fragP->fr_subtype == 1)
1218
    {
1219
      unsigned char *buffer =
1220
        (unsigned char *) (fragP->fr_fix + fragP->fr_literal);
1221
 
1222
      /* Reverse the condition of the first branch.  */
1223
      buffer[0] ^= 0x08;
1224
      /* Mask off all the displacement bits.  */
1225
      buffer[0] &= 0x8f;
1226
      buffer[1] &= 0x07;
1227
      /* Now set the displacement bits so that we branch
1228
         around the unconditional branch.  */
1229
      buffer[0] |= 0x30;
1230
 
1231
      /* Now create the unconditional branch + fixup to the final
1232
         target.  */
1233
      md_number_to_chars ((char *) buffer + 2, 0x00000780, 4);
1234
      fix_new (fragP, fragP->fr_fix + 2, 4, fragP->fr_symbol,
1235
               fragP->fr_offset, 1,
1236
               BFD_RELOC_UNUSED + opcode_converter.fx_r_type + 1);
1237
      fragP->fr_fix += 6;
1238
    }
1239
  /* Out of range unconditional branch.  Emit a jump.  */
1240
  else if (fragP->fr_subtype == 3)
1241
    {
1242
      md_number_to_chars (fragP->fr_fix + fragP->fr_literal, 0x00000780, 4);
1243
      fix_new (fragP, fragP->fr_fix, 4, fragP->fr_symbol,
1244
               fragP->fr_offset, 1,
1245
               BFD_RELOC_UNUSED + opcode_converter.fx_r_type + 1);
1246
      fragP->fr_fix += 4;
1247
    }
1248
  else
1249
    abort ();
1250
}
1251
 
1252
valueT
1253
md_section_align (asection *seg, valueT addr)
1254
{
1255
  int align = bfd_get_section_alignment (stdoutput, seg);
1256
  return ((addr + (1 << align) - 1) & (-1 << align));
1257
}
1258
 
1259
void
1260
md_begin (void)
1261
{
1262
  char *prev_name = "";
1263
  const struct v850_opcode *op;
1264
 
1265
  if (strncmp (TARGET_CPU, "v850e1", 6) == 0)
1266
    {
1267
      if (machine == -1)
1268
        machine = bfd_mach_v850e1;
1269
 
1270
      if (processor_mask == -1)
1271
        processor_mask = PROCESSOR_V850E1;
1272
    }
1273
  else if (strncmp (TARGET_CPU, "v850e", 5) == 0)
1274
    {
1275
      if (machine == -1)
1276
        machine = bfd_mach_v850e;
1277
 
1278
      if (processor_mask == -1)
1279
        processor_mask = PROCESSOR_V850E;
1280
    }
1281
  else if (strncmp (TARGET_CPU, "v850", 4) == 0)
1282
    {
1283
      if (machine == -1)
1284
        machine = 0;
1285
 
1286
      if (processor_mask == -1)
1287
        processor_mask = PROCESSOR_V850;
1288
    }
1289
  else
1290
    /* xgettext:c-format  */
1291
    as_bad (_("Unable to determine default target processor from string: %s"),
1292
            TARGET_CPU);
1293
 
1294
  v850_hash = hash_new ();
1295
 
1296
  /* Insert unique names into hash table.  The V850 instruction set
1297
     has many identical opcode names that have different opcodes based
1298
     on the operands.  This hash table then provides a quick index to
1299
     the first opcode with a particular name in the opcode table.  */
1300
  op = v850_opcodes;
1301
  while (op->name)
1302
    {
1303
      if (strcmp (prev_name, op->name))
1304
        {
1305
          prev_name = (char *) op->name;
1306
          hash_insert (v850_hash, op->name, (char *) op);
1307
        }
1308
      op++;
1309
    }
1310
 
1311
  v850_seg_table[BSS_SECTION].s = bss_section;
1312
  bfd_set_arch_mach (stdoutput, TARGET_ARCH, machine);
1313
}
1314
 
1315
static bfd_reloc_code_real_type
1316
handle_lo16 (const struct v850_operand *operand)
1317
{
1318
  if (operand != NULL)
1319
    {
1320
      if (operand->bits == -1)
1321
        return BFD_RELOC_V850_LO16_SPLIT_OFFSET;
1322
 
1323
      if (!(operand->bits == 16 && operand->shift == 16)
1324
          && !(operand->bits == 15 && operand->shift == 17))
1325
        {
1326
          as_bad (_("lo() relocation used on an instruction which does "
1327
                    "not support it"));
1328
          return BFD_RELOC_64;  /* Used to indicate an error condition.  */
1329
        }
1330
    }
1331
  return BFD_RELOC_LO16;
1332
}
1333
 
1334
static bfd_reloc_code_real_type
1335
handle_ctoff (const struct v850_operand *operand)
1336
{
1337
  if (operand == NULL)
1338
    return BFD_RELOC_V850_CALLT_16_16_OFFSET;
1339
 
1340
  if (operand->bits != 6
1341
      || operand->shift != 0)
1342
    {
1343
      as_bad (_("ctoff() relocation used on an instruction which does not support it"));
1344
      return BFD_RELOC_64;  /* Used to indicate an error condition.  */
1345
    }
1346
 
1347
  return BFD_RELOC_V850_CALLT_6_7_OFFSET;
1348
}
1349
 
1350
static bfd_reloc_code_real_type
1351
handle_sdaoff (const struct v850_operand *operand)
1352
{
1353
  if (operand == NULL)
1354
    return BFD_RELOC_V850_SDA_16_16_OFFSET;
1355
 
1356
  if (operand->bits == 15 && operand->shift == 17)
1357
    return BFD_RELOC_V850_SDA_15_16_OFFSET;
1358
 
1359
  if (operand->bits == -1)
1360
    return BFD_RELOC_V850_SDA_16_16_SPLIT_OFFSET;
1361
 
1362
  if (operand->bits != 16
1363
      || operand->shift != 16)
1364
    {
1365
      as_bad (_("sdaoff() relocation used on an instruction which does not support it"));
1366
      return BFD_RELOC_64;  /* Used to indicate an error condition.  */
1367
    }
1368
 
1369
  return BFD_RELOC_V850_SDA_16_16_OFFSET;
1370
}
1371
 
1372
static bfd_reloc_code_real_type
1373
handle_zdaoff (const struct v850_operand *operand)
1374
{
1375
  if (operand == NULL)
1376
    return BFD_RELOC_V850_ZDA_16_16_OFFSET;
1377
 
1378
  if (operand->bits == 15 && operand->shift == 17)
1379
    return BFD_RELOC_V850_ZDA_15_16_OFFSET;
1380
 
1381
  if (operand->bits == -1)
1382
    return BFD_RELOC_V850_ZDA_16_16_SPLIT_OFFSET;
1383
 
1384
  if (operand->bits != 16
1385
      || operand->shift != 16)
1386
    {
1387
      as_bad (_("zdaoff() relocation used on an instruction which does not support it"));
1388
      /* Used to indicate an error condition.  */
1389
      return BFD_RELOC_64;
1390
    }
1391
 
1392
  return BFD_RELOC_V850_ZDA_16_16_OFFSET;
1393
}
1394
 
1395
static bfd_reloc_code_real_type
1396
handle_tdaoff (const struct v850_operand *operand)
1397
{
1398
  if (operand == NULL)
1399
    /* Data item, not an instruction.  */
1400
    return BFD_RELOC_V850_TDA_7_7_OFFSET;
1401
 
1402
  if (operand->bits == 6 && operand->shift == 1)
1403
    /* sld.w/sst.w, operand: D8_6.  */
1404
    return BFD_RELOC_V850_TDA_6_8_OFFSET;
1405
 
1406
  if (operand->bits == 4 && operand->insert != NULL)
1407
    /* sld.hu, operand: D5-4.  */
1408
    return BFD_RELOC_V850_TDA_4_5_OFFSET;
1409
 
1410
  if (operand->bits == 4 && operand->insert == NULL)
1411
    /* sld.bu, operand: D4.   */
1412
    return BFD_RELOC_V850_TDA_4_4_OFFSET;
1413
 
1414
  if (operand->bits == 16 && operand->shift == 16)
1415
    /* set1 & chums, operands: D16.  */
1416
    return BFD_RELOC_V850_TDA_16_16_OFFSET;
1417
 
1418
  if (operand->bits != 7)
1419
    {
1420
      as_bad (_("tdaoff() relocation used on an instruction which does not support it"));
1421
      /* Used to indicate an error condition.  */
1422
      return BFD_RELOC_64;
1423
    }
1424
 
1425
  return  operand->insert != NULL
1426
    ? BFD_RELOC_V850_TDA_7_8_OFFSET     /* sld.h/sst.h, operand: D8_7.  */
1427
    : BFD_RELOC_V850_TDA_7_7_OFFSET;    /* sld.b/sst.b, operand: D7.    */
1428
}
1429
 
1430
/* Warning: The code in this function relies upon the definitions
1431
   in the v850_operands[] array (defined in opcodes/v850-opc.c)
1432
   matching the hard coded values contained herein.  */
1433
 
1434
static bfd_reloc_code_real_type
1435
v850_reloc_prefix (const struct v850_operand *operand)
1436
{
1437
  bfd_boolean paren_skipped = FALSE;
1438
 
1439
  /* Skip leading opening parenthesis.  */
1440
  if (*input_line_pointer == '(')
1441
    {
1442
      ++input_line_pointer;
1443
      paren_skipped = TRUE;
1444
    }
1445
 
1446
#define CHECK_(name, reloc)                                             \
1447
  if (strncmp (input_line_pointer, name "(", strlen (name) + 1) == 0)    \
1448
    {                                                                   \
1449
      input_line_pointer += strlen (name);                              \
1450
      return reloc;                                                     \
1451
    }
1452
 
1453
  CHECK_ ("hi0",    BFD_RELOC_HI16         );
1454
  CHECK_ ("hi",     BFD_RELOC_HI16_S       );
1455
  CHECK_ ("lo",     handle_lo16 (operand)  );
1456
  CHECK_ ("sdaoff", handle_sdaoff (operand));
1457
  CHECK_ ("zdaoff", handle_zdaoff (operand));
1458
  CHECK_ ("tdaoff", handle_tdaoff (operand));
1459
  CHECK_ ("hilo",   BFD_RELOC_32           );
1460
  CHECK_ ("ctoff",  handle_ctoff (operand) );
1461
 
1462
  /* Restore skipped parenthesis.  */
1463
  if (paren_skipped)
1464
    --input_line_pointer;
1465
 
1466
  return BFD_RELOC_UNUSED;
1467
}
1468
 
1469
/* Insert an operand value into an instruction.  */
1470
 
1471
static unsigned long
1472
v850_insert_operand (unsigned long insn,
1473
                     const struct v850_operand *operand,
1474
                     offsetT val,
1475
                     char *file,
1476
                     unsigned int line,
1477
                     char *str)
1478
{
1479
  if (operand->insert)
1480
    {
1481
      const char *message = NULL;
1482
 
1483
      insn = operand->insert (insn, val, &message);
1484
      if (message != NULL)
1485
        {
1486
          if ((operand->flags & V850_OPERAND_SIGNED)
1487
              && ! warn_signed_overflows
1488
              && strstr (message, "out of range") != NULL)
1489
            {
1490
              /* Skip warning...  */
1491
            }
1492
          else if ((operand->flags & V850_OPERAND_SIGNED) == 0
1493
                   && ! warn_unsigned_overflows
1494
                   && strstr (message, "out of range") != NULL)
1495
            {
1496
              /* Skip warning...  */
1497
            }
1498
          else if (str)
1499
            {
1500
              if (file == (char *) NULL)
1501
                as_warn ("%s: %s", str, message);
1502
              else
1503
                as_warn_where (file, line, "%s: %s", str, message);
1504
            }
1505
          else
1506
            {
1507
              if (file == (char *) NULL)
1508
                as_warn ("%s", message);
1509
              else
1510
                as_warn_where (file, line, "%s", message);
1511
            }
1512
        }
1513
    }
1514
  else
1515
    {
1516
      if (operand->bits != 32)
1517
        {
1518
          long min, max;
1519
 
1520
          if ((operand->flags & V850_OPERAND_SIGNED) != 0)
1521
            {
1522
              if (! warn_signed_overflows)
1523
                max = (1 << operand->bits) - 1;
1524
              else
1525
                max = (1 << (operand->bits - 1)) - 1;
1526
 
1527
              min = -(1 << (operand->bits - 1));
1528
            }
1529
          else
1530
            {
1531
              max = (1 << operand->bits) - 1;
1532
 
1533
              if (! warn_unsigned_overflows)
1534
                min = -(1 << (operand->bits - 1));
1535
              else
1536
                min = 0;
1537
            }
1538
 
1539
          if (val < (offsetT) min || val > (offsetT) max)
1540
            {
1541
              char buf [128];
1542
 
1543
              /* Restore min and mix to expected values for decimal ranges.  */
1544
              if ((operand->flags & V850_OPERAND_SIGNED)
1545
                  && ! warn_signed_overflows)
1546
                max = (1 << (operand->bits - 1)) - 1;
1547
 
1548
              if (! (operand->flags & V850_OPERAND_SIGNED)
1549
                  && ! warn_unsigned_overflows)
1550
                min = 0;
1551
 
1552
              if (str)
1553
                sprintf (buf, "%s: ", str);
1554
              else
1555
                buf[0] = 0;
1556
              strcat (buf, _("operand"));
1557
 
1558
              as_bad_value_out_of_range (buf, val, (offsetT) min, (offsetT) max, file, line);
1559
            }
1560
        }
1561
 
1562
      insn |= (((long) val & ((1 << operand->bits) - 1)) << operand->shift);
1563
    }
1564
 
1565
  return insn;
1566
}
1567
 
1568
static char copy_of_instruction[128];
1569
 
1570
void
1571
md_assemble (char *str)
1572
{
1573
  char *s;
1574
  char *start_of_operands;
1575
  struct v850_opcode *opcode;
1576
  struct v850_opcode *next_opcode;
1577
  const unsigned char *opindex_ptr;
1578
  int next_opindex;
1579
  int relaxable = 0;
1580
  unsigned long insn;
1581
  unsigned long insn_size;
1582
  char *f;
1583
  int i;
1584
  int match;
1585
  bfd_boolean extra_data_after_insn = FALSE;
1586
  unsigned extra_data_len = 0;
1587
  unsigned long extra_data = 0;
1588
  char *saved_input_line_pointer;
1589
 
1590
  strncpy (copy_of_instruction, str, sizeof (copy_of_instruction) - 1);
1591
 
1592
  /* Get the opcode.  */
1593
  for (s = str; *s != '\0' && ! ISSPACE (*s); s++)
1594
    continue;
1595
 
1596
  if (*s != '\0')
1597
    *s++ = '\0';
1598
 
1599
  /* Find the first opcode with the proper name.  */
1600
  opcode = (struct v850_opcode *) hash_find (v850_hash, str);
1601
  if (opcode == NULL)
1602
    {
1603
      /* xgettext:c-format  */
1604
      as_bad (_("Unrecognized opcode: `%s'"), str);
1605
      ignore_rest_of_line ();
1606
      return;
1607
    }
1608
 
1609
  str = s;
1610
  while (ISSPACE (*str))
1611
    ++str;
1612
 
1613
  start_of_operands = str;
1614
 
1615
  saved_input_line_pointer = input_line_pointer;
1616
 
1617
  for (;;)
1618
    {
1619
      const char *errmsg = NULL;
1620
 
1621
      match = 0;
1622
 
1623
      if ((opcode->processors & processor_mask) == 0)
1624
        {
1625
          errmsg = _("Target processor does not support this instruction.");
1626
          goto error;
1627
        }
1628
 
1629
      relaxable = 0;
1630
      fc = 0;
1631
      next_opindex = 0;
1632
      insn = opcode->opcode;
1633
      extra_data_after_insn = FALSE;
1634
 
1635
      input_line_pointer = str = start_of_operands;
1636
 
1637
      for (opindex_ptr = opcode->operands; *opindex_ptr != 0; opindex_ptr++)
1638
        {
1639
          const struct v850_operand *operand;
1640
          char *hold;
1641
          expressionS ex;
1642
          bfd_reloc_code_real_type reloc;
1643
 
1644
          if (next_opindex == 0)
1645
            operand = &v850_operands[*opindex_ptr];
1646
          else
1647
            {
1648
              operand = &v850_operands[next_opindex];
1649
              next_opindex = 0;
1650
            }
1651
 
1652
          errmsg = NULL;
1653
 
1654
          while (*str == ' ' || *str == ',' || *str == '[' || *str == ']')
1655
            ++str;
1656
 
1657
          if (operand->flags & V850_OPERAND_RELAX)
1658
            relaxable = 1;
1659
 
1660
          /* Gather the operand.  */
1661
          hold = input_line_pointer;
1662
          input_line_pointer = str;
1663
 
1664
          /* lo(), hi(), hi0(), etc...  */
1665
          if ((reloc = v850_reloc_prefix (operand)) != BFD_RELOC_UNUSED)
1666
            {
1667
              /* This is a fake reloc, used to indicate an error condition.  */
1668
              if (reloc == BFD_RELOC_64)
1669
                {
1670
                  match = 1;
1671
                  goto error;
1672
                }
1673
 
1674
              expression (&ex);
1675
 
1676
              if (ex.X_op == O_constant)
1677
                {
1678
                  switch (reloc)
1679
                    {
1680
                    case BFD_RELOC_V850_ZDA_16_16_OFFSET:
1681
                      /* To cope with "not1 7, zdaoff(0xfffff006)[r0]"
1682
                         and the like.  */
1683
                      /* Fall through.  */
1684
 
1685
                    case BFD_RELOC_LO16:
1686
                    case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
1687
                      {
1688
                        /* Truncate, then sign extend the value.  */
1689
                        ex.X_add_number = SEXT16 (ex.X_add_number);
1690
                        break;
1691
                      }
1692
 
1693
                    case BFD_RELOC_HI16:
1694
                      {
1695
                        /* Truncate, then sign extend the value.  */
1696
                        ex.X_add_number = SEXT16 (ex.X_add_number >> 16);
1697
                        break;
1698
                      }
1699
 
1700
                    case BFD_RELOC_HI16_S:
1701
                      {
1702
                        /* Truncate, then sign extend the value.  */
1703
                        int temp = (ex.X_add_number >> 16) & 0xffff;
1704
 
1705
                        temp += (ex.X_add_number >> 15) & 1;
1706
 
1707
                        ex.X_add_number = SEXT16 (temp);
1708
                        break;
1709
                      }
1710
 
1711
                    case BFD_RELOC_32:
1712
                      if ((operand->flags & V850E_IMMEDIATE32) == 0)
1713
                        {
1714
                          errmsg = _("immediate operand is too large");
1715
                          goto error;
1716
                        }
1717
 
1718
                      extra_data_after_insn = TRUE;
1719
                      extra_data_len        = 4;
1720
                      extra_data            = 0;
1721
                      break;
1722
 
1723
                    default:
1724
                      fprintf (stderr, "reloc: %d\n", reloc);
1725
                      as_bad (_("AAARG -> unhandled constant reloc"));
1726
                      break;
1727
                    }
1728
 
1729
                  if (fc > MAX_INSN_FIXUPS)
1730
                    as_fatal (_("too many fixups"));
1731
 
1732
                  fixups[fc].exp     = ex;
1733
                  fixups[fc].opindex = *opindex_ptr;
1734
                  fixups[fc].reloc   = reloc;
1735
                  fc++;
1736
                }
1737
              else
1738
                {
1739
                  if (reloc == BFD_RELOC_32)
1740
                    {
1741
                      if ((operand->flags & V850E_IMMEDIATE32) == 0)
1742
                        {
1743
                          errmsg = _("immediate operand is too large");
1744
                          goto error;
1745
                        }
1746
 
1747
                      extra_data_after_insn = TRUE;
1748
                      extra_data_len        = 4;
1749
                      extra_data            = ex.X_add_number;
1750
                    }
1751
 
1752
                  if (fc > MAX_INSN_FIXUPS)
1753
                    as_fatal (_("too many fixups"));
1754
 
1755
                  fixups[fc].exp     = ex;
1756
                  fixups[fc].opindex = *opindex_ptr;
1757
                  fixups[fc].reloc   = reloc;
1758
                  fc++;
1759
                }
1760
            }
1761
          else
1762
            {
1763
              errmsg = NULL;
1764
 
1765
              if ((operand->flags & V850_OPERAND_REG) != 0)
1766
                {
1767
                  if (!register_name (&ex))
1768
                    errmsg = _("invalid register name");
1769
                  else if ((operand->flags & V850_NOT_R0)
1770
                           && ex.X_add_number == 0)
1771
                    {
1772
                      errmsg = _("register r0 cannot be used here");
1773
 
1774
                      /* Force an error message to be generated by
1775
                         skipping over any following potential matches
1776
                         for this opcode.  */
1777
                      opcode += 3;
1778
                    }
1779
                }
1780
              else if ((operand->flags & V850_OPERAND_SRG) != 0)
1781
                {
1782
                  if (!system_register_name (&ex, TRUE, FALSE))
1783
                    errmsg = _("invalid system register name");
1784
                }
1785
              else if ((operand->flags & V850_OPERAND_EP) != 0)
1786
                {
1787
                  char *start = input_line_pointer;
1788
                  char c = get_symbol_end ();
1789
 
1790
                  if (strcmp (start, "ep") != 0 && strcmp (start, "r30") != 0)
1791
                    {
1792
                      /* Put things back the way we found them.  */
1793
                      *input_line_pointer = c;
1794
                      input_line_pointer = start;
1795
                      errmsg = _("expected EP register");
1796
                      goto error;
1797
                    }
1798
 
1799
                  *input_line_pointer = c;
1800
                  str = input_line_pointer;
1801
                  input_line_pointer = hold;
1802
 
1803
                  while (*str == ' ' || *str == ','
1804
                         || *str == '[' || *str == ']')
1805
                    ++str;
1806
                  continue;
1807
                }
1808
              else if ((operand->flags & V850_OPERAND_CC) != 0)
1809
                {
1810
                  if (!cc_name (&ex))
1811
                    errmsg = _("invalid condition code name");
1812
                }
1813
              else if (operand->flags & V850E_PUSH_POP)
1814
                {
1815
                  errmsg = parse_register_list (&insn, operand);
1816
 
1817
                  /* The parse_register_list() function has already done
1818
                     everything, so fake a dummy expression.  */
1819
                  ex.X_op         = O_constant;
1820
                  ex.X_add_number = 0;
1821
                }
1822
              else if (operand->flags & V850E_IMMEDIATE16)
1823
                {
1824
                  expression (&ex);
1825
 
1826
                  if (ex.X_op != O_constant)
1827
                    errmsg = _("constant expression expected");
1828
                  else if (ex.X_add_number & 0xffff0000)
1829
                    {
1830
                      if (ex.X_add_number & 0xffff)
1831
                        errmsg = _("constant too big to fit into instruction");
1832
                      else if ((insn & 0x001fffc0) == 0x00130780)
1833
                        ex.X_add_number >>= 16;
1834
                      else
1835
                        errmsg = _("constant too big to fit into instruction");
1836
                    }
1837
 
1838
                  extra_data_after_insn = TRUE;
1839
                  extra_data_len        = 2;
1840
                  extra_data            = ex.X_add_number;
1841
                  ex.X_add_number       = 0;
1842
                }
1843
              else if (operand->flags & V850E_IMMEDIATE32)
1844
                {
1845
                  expression (&ex);
1846
 
1847
                  if (ex.X_op != O_constant)
1848
                    errmsg = _("constant expression expected");
1849
 
1850
                  extra_data_after_insn = TRUE;
1851
                  extra_data_len        = 4;
1852
                  extra_data            = ex.X_add_number;
1853
                  ex.X_add_number       = 0;
1854
                }
1855
              else if (register_name (&ex)
1856
                       && (operand->flags & V850_OPERAND_REG) == 0)
1857
                {
1858
                  char c;
1859
                  int exists = 0;
1860
 
1861
                  /* It is possible that an alias has been defined that
1862
                     matches a register name.  For example the code may
1863
                     include a ".set ZERO, 0" directive, which matches
1864
                     the register name "zero".  Attempt to reparse the
1865
                     field as an expression, and only complain if we
1866
                     cannot generate a constant.  */
1867
 
1868
                  input_line_pointer = str;
1869
 
1870
                  c = get_symbol_end ();
1871
 
1872
                  if (symbol_find (str) != NULL)
1873
                    exists = 1;
1874
 
1875
                  *input_line_pointer = c;
1876
                  input_line_pointer = str;
1877
 
1878
                  expression (&ex);
1879
 
1880
                  if (ex.X_op != O_constant)
1881
                    {
1882
                      /* If this register is actually occurring too early on
1883
                         the parsing of the instruction, (because another
1884
                         field is missing) then report this.  */
1885
                      if (opindex_ptr[1] != 0
1886
                          && (v850_operands[opindex_ptr[1]].flags
1887
                              & V850_OPERAND_REG))
1888
                        errmsg = _("syntax error: value is missing before the register name");
1889
                      else
1890
                        errmsg = _("syntax error: register not expected");
1891
 
1892
                      /* If we created a symbol in the process of this
1893
                         test then delete it now, so that it will not
1894
                         be output with the real symbols...  */
1895
                      if (exists == 0
1896
                          && ex.X_op == O_symbol)
1897
                        symbol_remove (ex.X_add_symbol,
1898
                                       &symbol_rootP, &symbol_lastP);
1899
                    }
1900
                }
1901
              else if (system_register_name (&ex, FALSE, FALSE)
1902
                       && (operand->flags & V850_OPERAND_SRG) == 0)
1903
                errmsg = _("syntax error: system register not expected");
1904
 
1905
              else if (cc_name (&ex)
1906
                       && (operand->flags & V850_OPERAND_CC) == 0)
1907
                errmsg = _("syntax error: condition code not expected");
1908
 
1909
              else
1910
                {
1911
                  expression (&ex);
1912
                  /* Special case:
1913
                     If we are assembling a MOV instruction and the immediate
1914
                     value does not fit into the bits available then create a
1915
                     fake error so that the next MOV instruction will be
1916
                     selected.  This one has a 32 bit immediate field.  */
1917
 
1918
                  if (((insn & 0x07e0) == 0x0200)
1919
                      && operand->bits == 5 /* Do not match the CALLT instruction.  */
1920
                      && ex.X_op == O_constant
1921
                      && (ex.X_add_number < (-(1 << (operand->bits - 1)))
1922
                          || ex.X_add_number > ((1 << (operand->bits - 1)) - 1)))
1923
                    errmsg = _("immediate operand is too large");
1924
                }
1925
 
1926
              if (errmsg)
1927
                goto error;
1928
 
1929
              switch (ex.X_op)
1930
                {
1931
                case O_illegal:
1932
                  errmsg = _("illegal operand");
1933
                  goto error;
1934
                case O_absent:
1935
                  errmsg = _("missing operand");
1936
                  goto error;
1937
                case O_register:
1938
                  if ((operand->flags
1939
                       & (V850_OPERAND_REG | V850_OPERAND_SRG)) == 0)
1940
                    {
1941
                      errmsg = _("invalid operand");
1942
                      goto error;
1943
                    }
1944
                  insn = v850_insert_operand (insn, operand, ex.X_add_number,
1945
                                              NULL, 0, copy_of_instruction);
1946
                  break;
1947
 
1948
                case O_constant:
1949
                  insn = v850_insert_operand (insn, operand, ex.X_add_number,
1950
                                              NULL, 0, copy_of_instruction);
1951
                  break;
1952
 
1953
                default:
1954
                  /* We need to generate a fixup for this expression.  */
1955
                  if (fc >= MAX_INSN_FIXUPS)
1956
                    as_fatal (_("too many fixups"));
1957
 
1958
                  fixups[fc].exp     = ex;
1959
                  fixups[fc].opindex = *opindex_ptr;
1960
                  fixups[fc].reloc   = BFD_RELOC_UNUSED;
1961
                  ++fc;
1962
                  break;
1963
                }
1964
            }
1965
 
1966
          str = input_line_pointer;
1967
          input_line_pointer = hold;
1968
 
1969
          while (*str == ' ' || *str == ',' || *str == '[' || *str == ']'
1970
                 || *str == ')')
1971
            ++str;
1972
        }
1973
      match = 1;
1974
 
1975
    error:
1976
      if (match == 0)
1977
        {
1978
          next_opcode = opcode + 1;
1979
          if (next_opcode->name != NULL
1980
              && strcmp (next_opcode->name, opcode->name) == 0)
1981
            {
1982
              opcode = next_opcode;
1983
 
1984
              /* Skip versions that are not supported by the target
1985
                 processor.  */
1986
              if ((opcode->processors & processor_mask) == 0)
1987
                goto error;
1988
 
1989
              continue;
1990
            }
1991
 
1992
          as_bad ("%s: %s", copy_of_instruction, errmsg);
1993
 
1994
          if (*input_line_pointer == ']')
1995
            ++input_line_pointer;
1996
 
1997
          ignore_rest_of_line ();
1998
          input_line_pointer = saved_input_line_pointer;
1999
          return;
2000
        }
2001
      break;
2002
    }
2003
 
2004
  while (ISSPACE (*str))
2005
    ++str;
2006
 
2007
  if (*str != '\0')
2008
    /* xgettext:c-format  */
2009
    as_bad (_("junk at end of line: `%s'"), str);
2010
 
2011
  input_line_pointer = str;
2012
 
2013
  /* Tie dwarf2 debug info to the address at the start of the insn.
2014
     We can't do this after the insn has been output as the current
2015
     frag may have been closed off.  eg. by frag_var.  */
2016
  dwarf2_emit_insn (0);
2017
 
2018
  /* Write out the instruction.  */
2019
 
2020
  if (relaxable && fc > 0)
2021
    {
2022
      /* On a 64-bit host the size of an 'int' is not the same
2023
         as the size of a pointer, so we need a union to convert
2024
         the opindex field of the fr_cgen structure into a char *
2025
         so that it can be stored in the frag.  We do not have
2026
         to worry about loosing accuracy as we are not going to
2027
         be even close to the 32bit limit of the int.  */
2028
      union
2029
      {
2030
        int opindex;
2031
        char * ptr;
2032
      }
2033
      opindex_converter;
2034
 
2035
      opindex_converter.opindex = fixups[0].opindex;
2036
      insn_size = 2;
2037
      fc = 0;
2038
 
2039
      if (!strcmp (opcode->name, "br"))
2040
        {
2041
          f = frag_var (rs_machine_dependent, 4, 2, 2,
2042
                        fixups[0].exp.X_add_symbol,
2043
                        fixups[0].exp.X_add_number,
2044
                        opindex_converter.ptr);
2045
          md_number_to_chars (f, insn, insn_size);
2046
          md_number_to_chars (f + 2, 0, 2);
2047
        }
2048
      else
2049
        {
2050
          f = frag_var (rs_machine_dependent, 6, 4, 0,
2051
                        fixups[0].exp.X_add_symbol,
2052
                        fixups[0].exp.X_add_number,
2053
                        opindex_converter.ptr);
2054
          md_number_to_chars (f, insn, insn_size);
2055
          md_number_to_chars (f + 2, 0, 4);
2056
        }
2057
    }
2058
  else
2059
    {
2060
      /* Four byte insns have an opcode with the two high bits on.  */
2061
      if ((insn & 0x0600) == 0x0600)
2062
        insn_size = 4;
2063
      else
2064
        insn_size = 2;
2065
 
2066
      /* Special case: 32 bit MOV.  */
2067
      if ((insn & 0xffe0) == 0x0620)
2068
        insn_size = 2;
2069
 
2070
      f = frag_more (insn_size);
2071
      md_number_to_chars (f, insn, insn_size);
2072
 
2073
      if (extra_data_after_insn)
2074
        {
2075
          f = frag_more (extra_data_len);
2076
          md_number_to_chars (f, extra_data, extra_data_len);
2077
 
2078
          extra_data_after_insn = FALSE;
2079
        }
2080
    }
2081
 
2082
  /* Create any fixups.  At this point we do not use a
2083
     bfd_reloc_code_real_type, but instead just use the
2084
     BFD_RELOC_UNUSED plus the operand index.  This lets us easily
2085
     handle fixups for any operand type, although that is admittedly
2086
     not a very exciting feature.  We pick a BFD reloc type in
2087
     md_apply_fix.  */
2088
  for (i = 0; i < fc; i++)
2089
    {
2090
      const struct v850_operand *operand;
2091
      bfd_reloc_code_real_type reloc;
2092
 
2093
      operand = &v850_operands[fixups[i].opindex];
2094
 
2095
      reloc = fixups[i].reloc;
2096
 
2097
      if (reloc != BFD_RELOC_UNUSED)
2098
        {
2099
          reloc_howto_type *reloc_howto =
2100
            bfd_reloc_type_lookup (stdoutput, reloc);
2101
          int size;
2102
          int address;
2103
          fixS *fixP;
2104
 
2105
          if (!reloc_howto)
2106
            abort ();
2107
 
2108
          size = bfd_get_reloc_size (reloc_howto);
2109
 
2110
          /* XXX This will abort on an R_V850_8 reloc -
2111
             is this reloc actually used?  */
2112
          if (size != 2 && size != 4)
2113
            abort ();
2114
 
2115
          address = (f - frag_now->fr_literal) + insn_size - size;
2116
 
2117
          if (reloc == BFD_RELOC_32)
2118
            address += 2;
2119
 
2120
          fixP = fix_new_exp (frag_now, address, size,
2121
                              &fixups[i].exp,
2122
                              reloc_howto->pc_relative,
2123
                              reloc);
2124
 
2125
          fixP->tc_fix_data = (void *) operand;
2126
 
2127
          switch (reloc)
2128
            {
2129
            case BFD_RELOC_LO16:
2130
            case BFD_RELOC_V850_LO16_SPLIT_OFFSET:
2131
            case BFD_RELOC_HI16:
2132
            case BFD_RELOC_HI16_S:
2133
              fixP->fx_no_overflow = 1;
2134
              break;
2135
            default:
2136
              break;
2137
            }
2138
        }
2139
      else
2140
        {
2141
          fix_new_exp (frag_now,
2142
                       f - frag_now->fr_literal, 4,
2143
                       & fixups[i].exp,
2144
                       (operand->flags & V850_OPERAND_DISP) != 0,
2145
                       (bfd_reloc_code_real_type) (fixups[i].opindex
2146
                                                   + (int) BFD_RELOC_UNUSED));
2147
        }
2148
    }
2149
 
2150
  input_line_pointer = saved_input_line_pointer;
2151
}
2152
 
2153
/* If while processing a fixup, a reloc really needs to be created
2154
   then it is done here.  */
2155
 
2156
arelent *
2157
tc_gen_reloc (asection *seg ATTRIBUTE_UNUSED, fixS *fixp)
2158
{
2159
  arelent *reloc;
2160
 
2161
  reloc               = xmalloc (sizeof (arelent));
2162
  reloc->sym_ptr_ptr  = xmalloc (sizeof (asymbol *));
2163
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2164
  reloc->address      = fixp->fx_frag->fr_address + fixp->fx_where;
2165
 
2166
  if (   fixp->fx_r_type == BFD_RELOC_VTABLE_ENTRY
2167
      || fixp->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2168
      || fixp->fx_r_type == BFD_RELOC_V850_LONGCALL
2169
      || fixp->fx_r_type == BFD_RELOC_V850_LONGJUMP
2170
      || fixp->fx_r_type == BFD_RELOC_V850_ALIGN)
2171
    reloc->addend = fixp->fx_offset;
2172
  else
2173
    {
2174
      if (fixp->fx_r_type == BFD_RELOC_32
2175
          && fixp->fx_pcrel)
2176
        fixp->fx_r_type = BFD_RELOC_32_PCREL;
2177
 
2178
      reloc->addend = fixp->fx_addnumber;
2179
    }
2180
 
2181
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2182
 
2183
  if (reloc->howto == NULL)
2184
    {
2185
      as_bad_where (fixp->fx_file, fixp->fx_line,
2186
                    /* xgettext:c-format  */
2187
                    _("reloc %d not supported by object file format"),
2188
                    (int) fixp->fx_r_type);
2189
 
2190
      xfree (reloc);
2191
 
2192
      return NULL;
2193
    }
2194
 
2195
  return reloc;
2196
}
2197
 
2198
void
2199
v850_handle_align (fragS * frag)
2200
{
2201
  if (v850_relax
2202
      && frag->fr_type == rs_align
2203
      && frag->fr_address + frag->fr_fix > 0
2204
      && frag->fr_offset > 1
2205
      && now_seg != bss_section
2206
      && now_seg != v850_seg_table[SBSS_SECTION].s
2207
      && now_seg != v850_seg_table[TBSS_SECTION].s
2208
      && now_seg != v850_seg_table[ZBSS_SECTION].s)
2209
    fix_new (frag, frag->fr_fix, 2, & abs_symbol, frag->fr_offset, 0,
2210
             BFD_RELOC_V850_ALIGN);
2211
}
2212
 
2213
/* Return current size of variable part of frag.  */
2214
 
2215
int
2216
md_estimate_size_before_relax (fragS *fragp, asection *seg ATTRIBUTE_UNUSED)
2217
{
2218
  if (fragp->fr_subtype >= sizeof (md_relax_table) / sizeof (md_relax_table[0]))
2219
    abort ();
2220
 
2221
  return md_relax_table[fragp->fr_subtype].rlx_length;
2222
}
2223
 
2224
long
2225
v850_pcrel_from_section (fixS *fixp, segT section)
2226
{
2227
  /* If the symbol is undefined, or in a section other than our own,
2228
     or it is weak (in which case it may well be in another section,
2229
     then let the linker figure it out.  */
2230
  if (fixp->fx_addsy != (symbolS *) NULL
2231
      && (! S_IS_DEFINED (fixp->fx_addsy)
2232
          || S_IS_WEAK (fixp->fx_addsy)
2233
          || (S_GET_SEGMENT (fixp->fx_addsy) != section)))
2234
    return 0;
2235
 
2236
  return fixp->fx_frag->fr_address + fixp->fx_where;
2237
}
2238
 
2239
void
2240
md_apply_fix (fixS *fixP, valueT *valueP, segT seg ATTRIBUTE_UNUSED)
2241
{
2242
  valueT value = * valueP;
2243
  char *where;
2244
 
2245
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2246
      || fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
2247
      || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP
2248
      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2249
    {
2250
      fixP->fx_done = 0;
2251
      return;
2252
    }
2253
 
2254
  if (fixP->fx_addsy == (symbolS *) NULL)
2255
    fixP->fx_addnumber = value,
2256
    fixP->fx_done = 1;
2257
 
2258
  else if (fixP->fx_pcrel)
2259
    fixP->fx_addnumber = fixP->fx_offset;
2260
 
2261
  else
2262
    {
2263
      value = fixP->fx_offset;
2264
      if (fixP->fx_subsy != (symbolS *) NULL)
2265
        {
2266
          if (S_GET_SEGMENT (fixP->fx_subsy) == absolute_section)
2267
            value -= S_GET_VALUE (fixP->fx_subsy);
2268
          else
2269
            /* We don't actually support subtracting a symbol.  */
2270
            as_bad_where (fixP->fx_file, fixP->fx_line,
2271
                          _("expression too complex"));
2272
        }
2273
      fixP->fx_addnumber = value;
2274
    }
2275
 
2276
  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
2277
    {
2278
      int opindex;
2279
      const struct v850_operand *operand;
2280
      unsigned long insn;
2281
 
2282
      opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
2283
      operand = &v850_operands[opindex];
2284
 
2285
      /* Fetch the instruction, insert the fully resolved operand
2286
         value, and stuff the instruction back again.
2287
 
2288
         Note the instruction has been stored in little endian
2289
         format!  */
2290
      where = fixP->fx_frag->fr_literal + fixP->fx_where;
2291
 
2292
      insn = bfd_getl32 ((unsigned char *) where);
2293
      insn = v850_insert_operand (insn, operand, (offsetT) value,
2294
                                  fixP->fx_file, fixP->fx_line, NULL);
2295
      bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
2296
 
2297
      if (fixP->fx_done)
2298
        /* Nothing else to do here.  */
2299
        return;
2300
 
2301
      /* Determine a BFD reloc value based on the operand information.
2302
         We are only prepared to turn a few of the operands into relocs.  */
2303
 
2304
      if (operand->bits == 22)
2305
        fixP->fx_r_type = BFD_RELOC_V850_22_PCREL;
2306
      else if (operand->bits == 9)
2307
        fixP->fx_r_type = BFD_RELOC_V850_9_PCREL;
2308
      else
2309
        {
2310
          as_bad_where (fixP->fx_file, fixP->fx_line,
2311
                        _("unresolved expression that must be resolved"));
2312
          fixP->fx_done = 1;
2313
          return;
2314
        }
2315
    }
2316
  else if (fixP->fx_done)
2317
    {
2318
      /* We still have to insert the value into memory!  */
2319
      where = fixP->fx_frag->fr_literal + fixP->fx_where;
2320
 
2321
      if (fixP->tc_fix_data != NULL
2322
          && ((struct v850_operand *) fixP->tc_fix_data)->insert != NULL)
2323
        {
2324
          const char * message = NULL;
2325
          struct v850_operand * operand = (struct v850_operand *) fixP->tc_fix_data;
2326
          unsigned long insn;
2327
 
2328
          /* The variable "where" currently points at the exact point inside
2329
             the insn where we need to insert the value.  But we need to
2330
             extract the entire insn so we probably need to move "where"
2331
             back a few bytes.  */
2332
          if (fixP->fx_size == 2)
2333
            where -= 2;
2334
          else if (fixP->fx_size == 1)
2335
            where -= 3;
2336
 
2337
          insn = bfd_getl32 ((unsigned char *) where);
2338
 
2339
          /* Use the operand's insertion procedure, if present, in order to
2340
             make sure that the value is correctly stored in the insn.  */
2341
          insn = operand->insert (insn, (offsetT) value, & message);
2342
          /* Ignore message even if it is set.  */
2343
 
2344
          bfd_putl32 ((bfd_vma) insn, (unsigned char *) where);
2345
        }
2346
      else
2347
        {
2348
          if (fixP->fx_r_type == BFD_RELOC_V850_LO16_SPLIT_OFFSET)
2349
            bfd_putl32 (((value << 16) & 0xfffe0000)
2350
                        | ((value << 5) & 0x20)
2351
                        | (bfd_getl32 (where) & ~0xfffe0020), where);
2352
          else if (fixP->fx_size == 1)
2353
            *where = value & 0xff;
2354
          else if (fixP->fx_size == 2)
2355
            bfd_putl16 (value & 0xffff, (unsigned char *) where);
2356
          else if (fixP->fx_size == 4)
2357
            bfd_putl32 (value, (unsigned char *) where);
2358
        }
2359
    }
2360
}
2361
 
2362
/* Parse a cons expression.  We have to handle hi(), lo(), etc
2363
   on the v850.  */
2364
 
2365
void
2366
parse_cons_expression_v850 (expressionS *exp)
2367
{
2368
  /* See if there's a reloc prefix like hi() we have to handle.  */
2369
  hold_cons_reloc = v850_reloc_prefix (NULL);
2370
 
2371
  /* Do normal expression parsing.  */
2372
  expression (exp);
2373
}
2374
 
2375
/* Create a fixup for a cons expression.  If parse_cons_expression_v850
2376
   found a reloc prefix, then we use that reloc, else we choose an
2377
   appropriate one based on the size of the expression.  */
2378
 
2379
void
2380
cons_fix_new_v850 (fragS *frag,
2381
                   int where,
2382
                   int size,
2383
                   expressionS *exp)
2384
{
2385
  if (hold_cons_reloc == BFD_RELOC_UNUSED)
2386
    {
2387
      if (size == 4)
2388
        hold_cons_reloc = BFD_RELOC_32;
2389
      if (size == 2)
2390
        hold_cons_reloc = BFD_RELOC_16;
2391
      if (size == 1)
2392
        hold_cons_reloc = BFD_RELOC_8;
2393
    }
2394
 
2395
  if (exp != NULL)
2396
    fix_new_exp (frag, where, size, exp, 0, hold_cons_reloc);
2397
  else
2398
    fix_new (frag, where, size, NULL, 0, 0, hold_cons_reloc);
2399
 
2400
  hold_cons_reloc = BFD_RELOC_UNUSED;
2401
}
2402
 
2403
bfd_boolean
2404
v850_fix_adjustable (fixS *fixP)
2405
{
2406
  if (fixP->fx_addsy == NULL)
2407
    return 1;
2408
 
2409
  /* Don't adjust function names.  */
2410
  if (S_IS_FUNCTION (fixP->fx_addsy))
2411
    return 0;
2412
 
2413
  /* We need the symbol name for the VTABLE entries.  */
2414
  if (fixP->fx_r_type == BFD_RELOC_VTABLE_INHERIT
2415
      || fixP->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
2416
    return 0;
2417
 
2418
  return 1;
2419
}
2420
 
2421
int
2422
v850_force_relocation (struct fix *fixP)
2423
{
2424
  if (fixP->fx_r_type == BFD_RELOC_V850_LONGCALL
2425
      || fixP->fx_r_type == BFD_RELOC_V850_LONGJUMP)
2426
    return 1;
2427
 
2428
  if (v850_relax
2429
      && (fixP->fx_pcrel
2430
          || fixP->fx_r_type == BFD_RELOC_V850_ALIGN
2431
          || fixP->fx_r_type == BFD_RELOC_V850_22_PCREL
2432
          || fixP->fx_r_type == BFD_RELOC_V850_9_PCREL
2433
          || fixP->fx_r_type >= BFD_RELOC_UNUSED))
2434
    return 1;
2435
 
2436
  return generic_force_reloc (fixP);
2437
}

powered by: WebSVN 2.1.0

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