OpenCores
URL https://opencores.org/ocsvn/hf-risc/hf-risc/trunk

Subversion Repositories hf-risc

[/] [hf-risc/] [trunk/] [tools/] [riscv-gnu-toolchain-master/] [binutils/] [gas/] [config/] [tc-riscv.c] - Blame information for rev 13

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 13 serginhofr
/* tc-riscv.c -- RISC-V assembler
2
   Copyright 2011-2015 Free Software Foundation, Inc.
3
 
4
   Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
5
   Based on MIPS target.
6
 
7
   This file is part of GAS.
8
 
9
   GAS is free software; you can redistribute it and/or modify
10
   it under the terms of the GNU General Public License as published by
11
   the Free Software Foundation; either version 3, or (at your option)
12
   any later version.
13
 
14
   GAS is distributed in the hope that it will be useful,
15
   but WITHOUT ANY WARRANTY; without even the implied warranty of
16
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
   GNU General Public License for more details.
18
 
19
   You should have received a copy of the GNU General Public License
20
   along with this program; see the file COPYING3. If not,
21
   see <http://www.gnu.org/licenses/>.  */
22
 
23
#include "as.h"
24
#include "config.h"
25
#include "subsegs.h"
26
#include "safe-ctype.h"
27
 
28
#include "itbl-ops.h"
29
#include "dwarf2dbg.h"
30
#include "dw2gencfi.h"
31
 
32
#include "elf/riscv.h"
33
#include "opcode/riscv.h"
34
 
35
#include <execinfo.h>
36
#include <stdint.h>
37
 
38
/* Information about an instruction, including its format, operands
39
   and fixups.  */
40
struct riscv_cl_insn
41
{
42
  /* The opcode's entry in riscv_opcodes.  */
43
  const struct riscv_opcode *insn_mo;
44
 
45
  /* The encoded instruction bits.  */
46
  insn_t insn_opcode;
47
 
48
  /* The frag that contains the instruction.  */
49
  struct frag *frag;
50
 
51
  /* The offset into FRAG of the first instruction byte.  */
52
  long where;
53
 
54
  /* The relocs associated with the instruction, if any.  */
55
  fixS *fixp;
56
};
57
 
58
/* The default architecture.  */
59
#ifndef DEFAULT_ARCH
60
#define DEFAULT_ARCH "riscv64"
61
#endif
62
static const char default_arch[] = DEFAULT_ARCH;
63
 
64
unsigned xlen = 0; /* width of an x-register */
65
#define LOAD_ADDRESS_INSN (xlen == 64 ? "ld" : "lw")
66
#define ADD32_INSN (xlen == 64 ? "addiw" : "addi")
67
 
68
static unsigned elf_flags = 0;
69
 
70
/* This is the set of options which the .option pseudo-op may modify.  */
71
 
72
struct riscv_set_options
73
{
74
  int pic; /* Generate position-independent code.  */
75
  int rvc; /* Generate RVC code.  */
76
};
77
 
78
static struct riscv_set_options riscv_opts =
79
{
80
  0,     /* pic */
81
  0,     /* rvc */
82
};
83
 
84
static void
85
riscv_set_rvc (bfd_boolean rvc_value)
86
{
87
  if (rvc_value)
88
    elf_flags |= EF_RISCV_RVC;
89
 
90
  riscv_opts.rvc = rvc_value;
91
}
92
 
93
struct riscv_subset
94
{
95
  const char *name;
96
  int version_major;
97
  int version_minor;
98
 
99
  struct riscv_subset *next;
100
};
101
 
102
static struct riscv_subset *riscv_subsets;
103
 
104
static bfd_boolean
105
riscv_subset_supports (const char *feature)
106
{
107
  struct riscv_subset *s;
108
  char *p;
109
  unsigned xlen_required = strtoul (feature, &p, 10);
110
 
111
  if (xlen_required && xlen != xlen_required)
112
    return FALSE;
113
 
114
  for (s = riscv_subsets; s != NULL; s = s->next)
115
    if (strcasecmp (s->name, p) == 0)
116
      /* FIXME: once we support version numbers:
117
         return major == s->version_major && minor <= s->version_minor; */
118
      return TRUE;
119
 
120
  return FALSE;
121
}
122
 
123
static void
124
riscv_add_subset (const char *subset)
125
{
126
  struct riscv_subset *s = xmalloc (sizeof *s);
127
  s->name = xstrdup (subset);
128
  s->version_major = 1;
129
  s->version_minor = 0;
130
  s->next = riscv_subsets;
131
  riscv_subsets = s;
132
}
133
 
134
/* Set which ISA and extensions are available.  Formally, ISA strings must
135
   begin with RV32 or RV64, but we allow the prefix to be omitted.
136
 
137
   FIXME: Version numbers are not supported yet.  */
138
static void
139
riscv_set_arch (const char *arg)
140
{
141
  char *uppercase = xstrdup (arg);
142
  char *p = uppercase;
143
  const char *all_subsets = "IMAFDC";
144
  const char *extension = NULL;
145
  int rvc = 0;
146
  int i;
147
 
148
  for (i = 0; uppercase[i]; i++)
149
    uppercase[i] = TOUPPER (uppercase[i]);
150
 
151
  if (strncmp (p, "RV32", 4) == 0)
152
    {
153
      xlen = 32;
154
      p += 4;
155
    }
156
  else if (strncmp (p, "RV64", 4) == 0)
157
    {
158
      xlen = 64;
159
      p += 4;
160
    }
161
  else if (strncmp (p, "RV", 2) == 0)
162
    p += 2;
163
 
164
  switch (*p)
165
    {
166
      case 'I':
167
        break;
168
 
169
      case 'G':
170
        p++;
171
        /* Fall through.  */
172
 
173
      case '\0':
174
        for (i = 0; all_subsets[i] != '\0'; i++)
175
          {
176
            const char subset[] = {all_subsets[i], '\0'};
177
            riscv_add_subset (subset);
178
          }
179
        break;
180
 
181
      default:
182
        as_fatal ("`I' must be the first ISA subset name specified (got %c)",
183
                  *p);
184
    }
185
 
186
  while (*p)
187
    {
188
      if (*p == 'X')
189
        {
190
          char *subset = xstrdup (p), *q = subset;
191
 
192
          while (*++q != '\0' && *q != '_')
193
            ;
194
          *q = '\0';
195
 
196
          if (extension)
197
            as_fatal ("only one eXtension is supported (found %s and %s)",
198
                      extension, subset);
199
          extension = subset;
200
          riscv_add_subset (subset);
201
          p += strlen (subset);
202
          free (subset);
203
        }
204
      else if (*p == '_')
205
        p++;
206
      else if ((all_subsets = strchr (all_subsets, *p)) != NULL)
207
        {
208
          const char subset[] = {*p, 0};
209
          riscv_add_subset (subset);
210
          if (*p == 'C')
211
            rvc = 1;
212
          all_subsets++;
213
          p++;
214
        }
215
      else
216
        as_fatal ("unsupported ISA subset %c", *p);
217
    }
218
 
219
  if (rvc)
220
    /* Override -m[no-]rvc setting if C was explicitly listed.  */
221
    riscv_set_rvc (TRUE);
222
  else
223
    /* Add RVC anyway.  -m[no-]rvc toggles its availability.  */
224
    riscv_add_subset ("C");
225
 
226
  free (uppercase);
227
}
228
 
229
/* handle of the OPCODE hash table */
230
static struct hash_control *op_hash = NULL;
231
 
232
/* This array holds the chars that always start a comment.  If the
233
    pre-processor is disabled, these aren't very useful */
234
const char comment_chars[] = "#";
235
 
236
/* This array holds the chars that only start a comment at the beginning of
237
   a line.  If the line seems to have the form '# 123 filename'
238
   .line and .file directives will appear in the pre-processed output */
239
/* Note that input_file.c hand checks for '#' at the beginning of the
240
   first line of the input file.  This is because the compiler outputs
241
   #NO_APP at the beginning of its output.  */
242
/* Also note that C style comments are always supported.  */
243
const char line_comment_chars[] = "#";
244
 
245
/* This array holds machine specific line separator characters.  */
246
const char line_separator_chars[] = ";";
247
 
248
/* Chars that can be used to separate mant from exp in floating point nums */
249
const char EXP_CHARS[] = "eE";
250
 
251
/* Chars that mean this number is a floating point constant */
252
/* As in 0f12.456 */
253
/* or    0d1.2345e12 */
254
const char FLT_CHARS[] = "rRsSfFdDxXpP";
255
 
256
/* Macros for encoding relaxation state for RVC branches and far jumps.  */
257
#define RELAX_BRANCH_ENCODE(uncond, rvc, length)        \
258
  ((relax_substateT)                                    \
259
   (0xc0000000                                          \
260
    | ((uncond) ? 1 : 0)                         \
261
    | ((rvc) ? 2 : 0)                                    \
262
    | ((length) << 2)))
263
#define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
264
#define RELAX_BRANCH_LENGTH(i) (((i) >> 2) & 0xF)
265
#define RELAX_BRANCH_RVC(i) (((i) & 2) != 0)
266
#define RELAX_BRANCH_UNCOND(i) (((i) & 1) != 0)
267
 
268
/* Is the given value a sign-extended 32-bit value?  */
269
#define IS_SEXT_32BIT_NUM(x)                                            \
270
  (((x) &~ (offsetT) 0x7fffffff) == 0                                    \
271
   || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
272
 
273
/* Is the given value a zero-extended 32-bit value?  Or a negated one?  */
274
#define IS_ZEXT_32BIT_NUM(x)                                            \
275
  (((x) &~ (offsetT) 0xffffffff) == 0                                    \
276
   || (((x) &~ (offsetT) 0xffffffff) == ~ (offsetT) 0xffffffff))
277
 
278
/* Change INSN's opcode so that the operand given by FIELD has value VALUE.
279
   INSN is a riscv_cl_insn structure and VALUE is evaluated exactly once.  */
280
#define INSERT_OPERAND(FIELD, INSN, VALUE) \
281
  INSERT_BITS ((INSN).insn_opcode, VALUE, OP_MASK_##FIELD, OP_SH_##FIELD)
282
 
283
/* Determine if an instruction matches an opcode.  */
284
#define OPCODE_MATCHES(OPCODE, OP) \
285
  (((OPCODE) & MASK_##OP) == MATCH_##OP)
286
 
287
static char *expr_end;
288
 
289
/* The default target format to use.  */
290
 
291
const char *
292
riscv_target_format (void)
293
{
294
  return xlen == 64 ? "elf64-littleriscv" : "elf32-littleriscv";
295
}
296
 
297
/* Return the length of instruction INSN.  */
298
 
299
static inline unsigned int
300
insn_length (const struct riscv_cl_insn *insn)
301
{
302
  return riscv_insn_length (insn->insn_opcode);
303
}
304
 
305
/* Initialise INSN from opcode entry MO.  Leave its position unspecified.  */
306
 
307
static void
308
create_insn (struct riscv_cl_insn *insn, const struct riscv_opcode *mo)
309
{
310
  insn->insn_mo = mo;
311
  insn->insn_opcode = mo->match;
312
  insn->frag = NULL;
313
  insn->where = 0;
314
  insn->fixp = NULL;
315
}
316
 
317
/* Install INSN at the location specified by its "frag" and "where" fields.  */
318
 
319
static void
320
install_insn (const struct riscv_cl_insn *insn)
321
{
322
  char *f = insn->frag->fr_literal + insn->where;
323
  md_number_to_chars (f, insn->insn_opcode, insn_length (insn));
324
}
325
 
326
/* Move INSN to offset WHERE in FRAG.  Adjust the fixups accordingly
327
   and install the opcode in the new location.  */
328
 
329
static void
330
move_insn (struct riscv_cl_insn *insn, fragS *frag, long where)
331
{
332
  insn->frag = frag;
333
  insn->where = where;
334
  if (insn->fixp != NULL)
335
    {
336
      insn->fixp->fx_frag = frag;
337
      insn->fixp->fx_where = where;
338
    }
339
  install_insn (insn);
340
}
341
 
342
/* Add INSN to the end of the output.  */
343
 
344
static void
345
add_fixed_insn (struct riscv_cl_insn *insn)
346
{
347
  char *f = frag_more (insn_length (insn));
348
  move_insn (insn, frag_now, f - frag_now->fr_literal);
349
}
350
 
351
static void
352
add_relaxed_insn (struct riscv_cl_insn *insn, int max_chars, int var,
353
      relax_substateT subtype, symbolS *symbol, offsetT offset)
354
{
355
  frag_grow (max_chars);
356
  move_insn (insn, frag_now, frag_more (0) - frag_now->fr_literal);
357
  frag_var (rs_machine_dependent, max_chars, var,
358
      subtype, symbol, offset, NULL);
359
}
360
 
361
/* Compute the length of a branch sequence, and adjust the stored length
362
   accordingly.  If FRAGP is NULL, the worst-case length is returned.  */
363
 
364
static int
365
relaxed_branch_length (fragS *fragp, asection *sec, int update)
366
{
367
  int jump, rvc, length = 8;
368
 
369
  if (!fragp)
370
    return length;
371
 
372
  jump = RELAX_BRANCH_UNCOND (fragp->fr_subtype);
373
  rvc = RELAX_BRANCH_RVC (fragp->fr_subtype);
374
  length = RELAX_BRANCH_LENGTH (fragp->fr_subtype);
375
 
376
  /* Assume jumps are in range; the linker will catch any that aren't.  */
377
  length = jump ? 4 : 8;
378
 
379
  if (fragp->fr_symbol != NULL
380
      && S_IS_DEFINED (fragp->fr_symbol)
381
      && sec == S_GET_SEGMENT (fragp->fr_symbol))
382
    {
383
      offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
384
      bfd_vma rvc_range = jump ? RVC_JUMP_REACH : RVC_BRANCH_REACH;
385
      val -= fragp->fr_address + fragp->fr_fix;
386
 
387
      if (rvc && (bfd_vma)(val + rvc_range/2) < rvc_range)
388
        length = 2;
389
      else if ((bfd_vma)(val + RISCV_BRANCH_REACH/2) < RISCV_BRANCH_REACH)
390
        length = 4;
391
      else if (!jump && rvc)
392
        length = 6;
393
    }
394
 
395
  if (update)
396
    fragp->fr_subtype = RELAX_BRANCH_ENCODE (jump, rvc, length);
397
 
398
  return length;
399
}
400
 
401
struct regname {
402
  const char *name;
403
  unsigned int num;
404
};
405
 
406
enum reg_class {
407
  RCLASS_GPR,
408
  RCLASS_FPR,
409
  RCLASS_CSR,
410
  RCLASS_MAX
411
};
412
 
413
static struct hash_control *reg_names_hash = NULL;
414
 
415
#define ENCODE_REG_HASH(cls, n) (void *)(uintptr_t)((n) * RCLASS_MAX + (cls) + 1)
416
#define DECODE_REG_CLASS(hash) (((uintptr_t)(hash) - 1) % RCLASS_MAX)
417
#define DECODE_REG_NUM(hash) (((uintptr_t)(hash) - 1) / RCLASS_MAX)
418
 
419
static void
420
hash_reg_name (enum reg_class class, const char *name, unsigned n)
421
{
422
  void *hash = ENCODE_REG_HASH (class, n);
423
  const char *retval = hash_insert (reg_names_hash, name, hash);
424
 
425
  if (retval != NULL)
426
    as_fatal (_("internal error: can't hash `%s': %s"), name, retval);
427
}
428
 
429
static void
430
hash_reg_names (enum reg_class class, const char * const names[], unsigned n)
431
{
432
  unsigned i;
433
 
434
  for (i = 0; i < n; i++)
435
    hash_reg_name (class, names[i], i);
436
}
437
 
438
static unsigned int
439
reg_lookup_internal (const char *s, enum reg_class class)
440
{
441
  struct regname *r = (struct regname *) hash_find (reg_names_hash, s);
442
  if (r == NULL || DECODE_REG_CLASS (r) != class)
443
    return -1;
444
  return DECODE_REG_NUM (r);
445
}
446
 
447
static int
448
reg_lookup (char **s, enum reg_class class, unsigned int *regnop)
449
{
450
  char *e;
451
  char save_c;
452
  int reg = -1;
453
 
454
  /* Find end of name.  */
455
  e = *s;
456
  if (is_name_beginner (*e))
457
    ++e;
458
  while (is_part_of_name (*e))
459
    ++e;
460
 
461
  /* Terminate name.  */
462
  save_c = *e;
463
  *e = '\0';
464
 
465
  /* Look for the register.  Advance to next token if one was recognized.  */
466
  if ((reg = reg_lookup_internal (*s, class)) >= 0)
467
    *s = e;
468
 
469
  *e = save_c;
470
  if (regnop)
471
    *regnop = reg;
472
  return reg >= 0;
473
}
474
 
475
static int
476
arg_lookup (char **s, const char *const *array, size_t size, unsigned *regnop)
477
{
478
  const char *p = strchr (*s, ',');
479
  size_t i, len = p ? (size_t)(p - *s) : strlen (*s);
480
 
481
  for (i = 0; i < size; i++)
482
    if (array[i] != NULL && strncmp (array[i], *s, len) == 0)
483
      {
484
        *regnop = i;
485
        *s += len;
486
        return 1;
487
      }
488
 
489
  return 0;
490
}
491
 
492
/* For consistency checking, verify that all bits are specified either
493
   by the match/mask part of the instruction definition, or by the
494
   operand list.  */
495
static int
496
validate_riscv_insn (const struct riscv_opcode *opc)
497
{
498
  const char *p = opc->args;
499
  char c;
500
  insn_t used_bits = opc->mask;
501
  int insn_width = 8 * riscv_insn_length (opc->match);
502
  insn_t required_bits = ~0ULL >> (64 - insn_width);
503
 
504
  if ((used_bits & opc->match) != (opc->match & required_bits))
505
    {
506
      as_bad (_("internal: bad RISC-V opcode (mask error): %s %s"),
507
              opc->name, opc->args);
508
      return 0;
509
    }
510
 
511
#define USE_BITS(mask,shift)    (used_bits |= ((insn_t)(mask) << (shift)))
512
  while (*p)
513
    switch (c = *p++)
514
      {
515
      /* Xcustom */
516
      case '^':
517
        switch (c = *p++)
518
          {
519
          case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
520
          case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
521
          case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break;
522
          case 'j': USE_BITS (OP_MASK_CUSTOM_IMM, OP_SH_CUSTOM_IMM); break;
523
          }
524
        break;
525
      case 'C': /* RVC */
526
        switch (c = *p++)
527
          {
528
          case 'a': used_bits |= ENCODE_RVC_J_IMM(-1U); break;
529
          case 'c': break; /* RS1, constrained to equal sp */
530
          case 'i': used_bits |= ENCODE_RVC_SIMM3(-1U); break;
531
          case 'j': used_bits |= ENCODE_RVC_IMM(-1U); break;
532
          case 'k': used_bits |= ENCODE_RVC_LW_IMM(-1U); break;
533
          case 'l': used_bits |= ENCODE_RVC_LD_IMM(-1U); break;
534
          case 'm': used_bits |= ENCODE_RVC_LWSP_IMM(-1U); break;
535
          case 'n': used_bits |= ENCODE_RVC_LDSP_IMM(-1U); break;
536
          case 'p': used_bits |= ENCODE_RVC_B_IMM(-1U); break;
537
          case 's': USE_BITS (OP_MASK_CRS1S, OP_SH_CRS1S); break;
538
          case 't': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
539
          case 'u': used_bits |= ENCODE_RVC_IMM(-1U); break;
540
          case 'v': used_bits |= ENCODE_RVC_IMM(-1U); break;
541
          case 'w': break; /* RS1S, constrained to equal RD */
542
          case 'x': break; /* RS2S, constrained to equal RD */
543
          case 'K': used_bits |= ENCODE_RVC_ADDI4SPN_IMM(-1U); break;
544
          case 'L': used_bits |= ENCODE_RVC_ADDI16SP_IMM(-1U); break;
545
          case 'M': used_bits |= ENCODE_RVC_SWSP_IMM(-1U); break;
546
          case 'N': used_bits |= ENCODE_RVC_SDSP_IMM(-1U); break;
547
          case 'U': break; /* RS1, constrained to equal RD */
548
          case 'V': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
549
          case '<': used_bits |= ENCODE_RVC_IMM(-1U); break;
550
          case '>': used_bits |= ENCODE_RVC_IMM(-1U); break;
551
          case 'T': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
552
          case 'D': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
553
          default:
554
            as_bad (_("internal: bad RISC-V opcode (unknown operand type `C%c'): %s %s"),
555
                    c, opc->name, opc->args);
556
            return 0;
557
          }
558
        break;
559
      case ',': break;
560
      case '(': break;
561
      case ')': break;
562
      case '<': USE_BITS (OP_MASK_SHAMTW,       OP_SH_SHAMTW);  break;
563
      case '>': USE_BITS (OP_MASK_SHAMT,        OP_SH_SHAMT);   break;
564
      case 'A': break;
565
      case 'D': USE_BITS (OP_MASK_RD,           OP_SH_RD);      break;
566
      case 'Z': USE_BITS (OP_MASK_RS1,          OP_SH_RS1);     break;
567
      case 'E': USE_BITS (OP_MASK_CSR,          OP_SH_CSR);     break;
568
      case 'I': break;
569
      case 'R': USE_BITS (OP_MASK_RS3,          OP_SH_RS3);     break;
570
      case 'S': USE_BITS (OP_MASK_RS1,          OP_SH_RS1);     break;
571
      case 'U': USE_BITS (OP_MASK_RS1,          OP_SH_RS1);     /* fallthru */
572
      case 'T': USE_BITS (OP_MASK_RS2,          OP_SH_RS2);     break;
573
      case 'd': USE_BITS (OP_MASK_RD,           OP_SH_RD);      break;
574
      case 'm': USE_BITS (OP_MASK_RM,           OP_SH_RM);      break;
575
      case 's': USE_BITS (OP_MASK_RS1,          OP_SH_RS1);     break;
576
      case 't': USE_BITS (OP_MASK_RS2,          OP_SH_RS2);     break;
577
      case 'P': USE_BITS (OP_MASK_PRED,         OP_SH_PRED); break;
578
      case 'Q': USE_BITS (OP_MASK_SUCC,         OP_SH_SUCC); break;
579
      case 'o':
580
      case 'j': used_bits |= ENCODE_ITYPE_IMM(-1U); break;
581
      case 'a': used_bits |= ENCODE_UJTYPE_IMM(-1U); break;
582
      case 'p': used_bits |= ENCODE_SBTYPE_IMM(-1U); break;
583
      case 'q': used_bits |= ENCODE_STYPE_IMM(-1U); break;
584
      case 'u': used_bits |= ENCODE_UTYPE_IMM(-1U); break;
585
      case '[': break;
586
      case ']': break;
587
      case '0': break;
588
      default:
589
        as_bad (_("internal: bad RISC-V opcode (unknown operand type `%c'): %s %s"),
590
                c, opc->name, opc->args);
591
        return 0;
592
      }
593
#undef USE_BITS
594
  if (used_bits != required_bits)
595
    {
596
      as_bad (_("internal: bad RISC-V opcode (bits 0x%lx undefined): %s %s"),
597
              ~(long)(used_bits & required_bits), opc->name, opc->args);
598
      return 0;
599
    }
600
  return 1;
601
}
602
 
603
struct percent_op_match
604
{
605
  const char *str;
606
  bfd_reloc_code_real_type reloc;
607
};
608
 
609
/* This function is called once, at assembler startup time.  It should set up
610
   all the tables, etc. that the MD part of the assembler will need.  */
611
 
612
void
613
md_begin (void)
614
{
615
  const char *retval = NULL;
616
  int i = 0;
617
 
618
  if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, 0))
619
    as_warn (_("Could not set architecture and machine"));
620
 
621
  op_hash = hash_new ();
622
 
623
  for (i = 0; i < NUMOPCODES;)
624
    {
625
      const char *name = riscv_opcodes[i].name;
626
 
627
      retval = hash_insert (op_hash, name, (void *) &riscv_opcodes[i]);
628
 
629
      if (retval != NULL)
630
        {
631
          fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
632
                   riscv_opcodes[i].name, retval);
633
          /* Probably a memory allocation problem?  Give up now.  */
634
          as_fatal (_("Broken assembler.  No assembly attempted."));
635
        }
636
      do
637
        {
638
          if (riscv_opcodes[i].pinfo != INSN_MACRO)
639
            {
640
              if (!validate_riscv_insn (&riscv_opcodes[i]))
641
                as_fatal (_("Broken assembler.  No assembly attempted."));
642
            }
643
          ++i;
644
        }
645
      while ((i < NUMOPCODES) && !strcmp (riscv_opcodes[i].name, name));
646
    }
647
 
648
  reg_names_hash = hash_new ();
649
  hash_reg_names (RCLASS_GPR, riscv_gpr_names_numeric, NGPR);
650
  hash_reg_names (RCLASS_GPR, riscv_gpr_names_abi, NGPR);
651
  hash_reg_names (RCLASS_FPR, riscv_fpr_names_numeric, NFPR);
652
  hash_reg_names (RCLASS_FPR, riscv_fpr_names_abi, NFPR);
653
 
654
#define DECLARE_CSR(name, num) hash_reg_name (RCLASS_CSR, #name, num);
655
#include "opcode/riscv-opc.h"
656
#undef DECLARE_CSR
657
 
658
  /* Set the default alignment for the text section.  */
659
  record_alignment (text_section, riscv_opts.rvc ? 1 : 2);
660
}
661
 
662
/* Output an instruction.  IP is the instruction information.
663
   ADDRESS_EXPR is an operand of the instruction to be used with
664
   RELOC_TYPE.  */
665
 
666
static void
667
append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
668
             bfd_reloc_code_real_type reloc_type)
669
{
670
#ifdef OBJ_ELF
671
  dwarf2_emit_insn (0);
672
#endif
673
 
674
  if (reloc_type != BFD_RELOC_UNUSED)
675
    {
676
      reloc_howto_type *howto;
677
 
678
      gas_assert(address_expr);
679
      if (reloc_type == BFD_RELOC_12_PCREL
680
          || reloc_type == BFD_RELOC_RISCV_JMP)
681
        {
682
          int j = reloc_type == BFD_RELOC_RISCV_JMP;
683
          int best_case = riscv_insn_length (ip->insn_opcode);
684
          int worst_case = relaxed_branch_length (NULL, NULL, 0);
685
          add_relaxed_insn (ip, worst_case, best_case,
686
                            RELAX_BRANCH_ENCODE (j, best_case == 2, worst_case),
687
                            address_expr->X_add_symbol,
688
                            address_expr->X_add_number);
689
          return;
690
        }
691
      else if (address_expr->X_op == O_constant)
692
        {
693
          switch (reloc_type)
694
            {
695
            case BFD_RELOC_32:
696
              ip->insn_opcode |= address_expr->X_add_number;
697
              goto append;
698
 
699
            case BFD_RELOC_RISCV_HI20:
700
              {
701
                insn_t imm = RISCV_CONST_HIGH_PART (address_expr->X_add_number);
702
                ip->insn_opcode |= ENCODE_UTYPE_IMM (imm);
703
                goto append;
704
              }
705
 
706
            case BFD_RELOC_RISCV_LO12_S:
707
              ip->insn_opcode |= ENCODE_STYPE_IMM (address_expr->X_add_number);
708
              goto append;
709
 
710
            case BFD_RELOC_RISCV_LO12_I:
711
              ip->insn_opcode |= ENCODE_ITYPE_IMM (address_expr->X_add_number);
712
              goto append;
713
 
714
            default:
715
              break;
716
            }
717
        }
718
 
719
        howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
720
        if (howto == NULL)
721
          as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
722
 
723
        ip->fixp = fix_new_exp (ip->frag, ip->where,
724
                                bfd_get_reloc_size (howto),
725
                                address_expr, FALSE, reloc_type);
726
    }
727
 
728
append:
729
  add_fixed_insn (ip);
730
  install_insn (ip);
731
}
732
 
733
/* Build an instruction created by a macro expansion.  This is passed
734
   a pointer to the count of instructions created so far, an
735
   expression, the name of the instruction to build, an operand format
736
   string, and corresponding arguments.  */
737
 
738
static void
739
macro_build (expressionS *ep, const char *name, const char *fmt, ...)
740
{
741
  const struct riscv_opcode *mo;
742
  struct riscv_cl_insn insn;
743
  bfd_reloc_code_real_type r;
744
  va_list args;
745
 
746
  va_start (args, fmt);
747
 
748
  r = BFD_RELOC_UNUSED;
749
  mo = (struct riscv_opcode *) hash_find (op_hash, name);
750
  gas_assert (mo);
751
 
752
  /* Find a non-RVC variant of the instruction.  */
753
  while (riscv_insn_length (mo->match) < 4)
754
    mo++;
755
  gas_assert (strcmp (name, mo->name) == 0);
756
 
757
  create_insn (&insn, mo);
758
  for (;;)
759
    {
760
      switch (*fmt++)
761
        {
762
        case 'd':
763
          INSERT_OPERAND (RD, insn, va_arg (args, int));
764
          continue;
765
 
766
        case 's':
767
          INSERT_OPERAND (RS1, insn, va_arg (args, int));
768
          continue;
769
 
770
        case 't':
771
          INSERT_OPERAND (RS2, insn, va_arg (args, int));
772
          continue;
773
 
774
        case '>':
775
          INSERT_OPERAND (SHAMT, insn, va_arg (args, int));
776
          continue;
777
 
778
        case 'j':
779
        case 'u':
780
        case 'q':
781
          gas_assert (ep != NULL);
782
          r = va_arg (args, int);
783
          continue;
784
 
785
        case '\0':
786
          break;
787
        case ',':
788
          continue;
789
        default:
790
          as_fatal (_("internal error: invalid macro"));
791
        }
792
      break;
793
    }
794
  va_end (args);
795
  gas_assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
796
 
797
  append_insn (&insn, ep, r);
798
}
799
 
800
/* Sign-extend 32-bit mode constants that have bit 31 set and all higher bits
801
   unset.  */
802
static void
803
normalize_constant_expr (expressionS *ex)
804
{
805
  if (xlen > 32)
806
    return;
807
  if ((ex->X_op == O_constant || ex->X_op == O_symbol)
808
      && IS_ZEXT_32BIT_NUM (ex->X_add_number))
809
    ex->X_add_number = (((ex->X_add_number & 0xffffffff) ^ 0x80000000)
810
                        - 0x80000000);
811
}
812
 
813
/* Warn if an expression is not a constant.  */
814
 
815
static void
816
check_absolute_expr (struct riscv_cl_insn *ip, expressionS *ex)
817
{
818
  if (ex->X_op == O_big)
819
    as_bad (_("unsupported large constant"));
820
  else if (ex->X_op != O_constant)
821
    as_bad (_("Instruction %s requires absolute expression"),
822
            ip->insn_mo->name);
823
  normalize_constant_expr (ex);
824
}
825
 
826
static symbolS *
827
make_internal_label (void)
828
{
829
  return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg,
830
                                        (valueT) frag_now_fix(), frag_now);
831
}
832
 
833
/* Load an entry from the GOT.  */
834
static void
835
pcrel_access (int destreg, int tempreg, expressionS *ep,
836
              const char *lo_insn, const char *lo_pattern,
837
              bfd_reloc_code_real_type hi_reloc,
838
              bfd_reloc_code_real_type lo_reloc)
839
{
840
  expressionS ep2;
841
  ep2.X_op = O_symbol;
842
  ep2.X_add_symbol = make_internal_label ();
843
  ep2.X_add_number = 0;
844
 
845
  macro_build (ep, "auipc", "d,u", tempreg, hi_reloc);
846
  macro_build (&ep2, lo_insn, lo_pattern, destreg, tempreg, lo_reloc);
847
}
848
 
849
static void
850
pcrel_load (int destreg, int tempreg, expressionS *ep, const char *lo_insn,
851
            bfd_reloc_code_real_type hi_reloc,
852
            bfd_reloc_code_real_type lo_reloc)
853
{
854
  pcrel_access (destreg, tempreg, ep, lo_insn, "d,s,j", hi_reloc, lo_reloc);
855
}
856
 
857
static void
858
pcrel_store (int srcreg, int tempreg, expressionS *ep, const char *lo_insn,
859
             bfd_reloc_code_real_type hi_reloc,
860
             bfd_reloc_code_real_type lo_reloc)
861
{
862
  pcrel_access (srcreg, tempreg, ep, lo_insn, "t,s,q", hi_reloc, lo_reloc);
863
}
864
 
865
/* PC-relative function call using AUIPC/JALR, relaxed to JAL.  */
866
static void
867
riscv_call (int destreg, int tempreg, expressionS *ep,
868
            bfd_reloc_code_real_type reloc)
869
{
870
  macro_build (ep, "auipc", "d,u", tempreg, reloc);
871
  macro_build (NULL, "jalr", "d,s", destreg, tempreg);
872
}
873
 
874
/* Load an integer constant into a register.  */
875
 
876
static void
877
load_const (int reg, expressionS *ep)
878
{
879
  int shift = RISCV_IMM_BITS;
880
  expressionS upper = *ep, lower = *ep;
881
  lower.X_add_number = (int32_t) ep->X_add_number << (32-shift) >> (32-shift);
882
  upper.X_add_number -= lower.X_add_number;
883
 
884
  gas_assert (ep->X_op == O_constant);
885
 
886
  if (xlen > 32 && !IS_SEXT_32BIT_NUM(ep->X_add_number))
887
    {
888
      /* Reduce to a signed 32-bit constant using SLLI and ADDI, which
889
         is not optimal but also not so bad.  */
890
      while (((upper.X_add_number >> shift) & 1) == 0)
891
        shift++;
892
 
893
      upper.X_add_number = (int64_t) upper.X_add_number >> shift;
894
      load_const(reg, &upper);
895
 
896
      macro_build (NULL, "slli", "d,s,>", reg, reg, shift);
897
      if (lower.X_add_number != 0)
898
        macro_build (&lower, "addi", "d,s,j", reg, reg, BFD_RELOC_RISCV_LO12_I);
899
    }
900
  else
901
    {
902
      int hi_reg = 0;
903
 
904
      if (upper.X_add_number != 0)
905
        {
906
          macro_build (ep, "lui", "d,u", reg, BFD_RELOC_RISCV_HI20);
907
          hi_reg = reg;
908
        }
909
 
910
      if (lower.X_add_number != 0 || hi_reg == 0)
911
        macro_build (ep, ADD32_INSN, "d,s,j", reg, hi_reg,
912
                     BFD_RELOC_RISCV_LO12_I);
913
    }
914
}
915
 
916
/* Expand RISC-V assembly macros into one or more instructions.  */
917
static void
918
macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
919
       bfd_reloc_code_real_type *imm_reloc)
920
{
921
  int rd = (ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD;
922
  int rs1 = (ip->insn_opcode >> OP_SH_RS1) & OP_MASK_RS1;
923
  int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2;
924
  int mask = ip->insn_mo->mask;
925
 
926
  switch (mask)
927
    {
928
    case M_LI:
929
      load_const (rd, imm_expr);
930
      break;
931
 
932
    case M_LA:
933
    case M_LLA:
934
      /* Load the address of a symbol into a register.  */
935
      if (!IS_SEXT_32BIT_NUM (imm_expr->X_add_number))
936
        as_bad(_("offset too large"));
937
 
938
      if (imm_expr->X_op == O_constant)
939
        load_const (rd, imm_expr);
940
      else if (riscv_opts.pic && mask == M_LA) /* Global PIC symbol */
941
        pcrel_load (rd, rd, imm_expr, LOAD_ADDRESS_INSN,
942
                    BFD_RELOC_RISCV_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
943
      else /* Local PIC symbol, or any non-PIC symbol */
944
        pcrel_load (rd, rd, imm_expr, "addi",
945
                    BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
946
      break;
947
 
948
    case M_LA_TLS_GD:
949
      pcrel_load (rd, rd, imm_expr, "addi",
950
                  BFD_RELOC_RISCV_TLS_GD_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
951
      break;
952
 
953
    case M_LA_TLS_IE:
954
      pcrel_load (rd, rd, imm_expr, LOAD_ADDRESS_INSN,
955
                  BFD_RELOC_RISCV_TLS_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
956
      break;
957
 
958
    case M_LB:
959
      pcrel_load (rd, rd, imm_expr, "lb",
960
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
961
      break;
962
 
963
    case M_LBU:
964
      pcrel_load (rd, rd, imm_expr, "lbu",
965
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
966
      break;
967
 
968
    case M_LH:
969
      pcrel_load (rd, rd, imm_expr, "lh",
970
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
971
      break;
972
 
973
    case M_LHU:
974
      pcrel_load (rd, rd, imm_expr, "lhu",
975
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
976
      break;
977
 
978
    case M_LW:
979
      pcrel_load (rd, rd, imm_expr, "lw",
980
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
981
      break;
982
 
983
    case M_LWU:
984
      pcrel_load (rd, rd, imm_expr, "lwu",
985
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
986
      break;
987
 
988
    case M_LD:
989
      pcrel_load (rd, rd, imm_expr, "ld",
990
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
991
      break;
992
 
993
    case M_FLW:
994
      pcrel_load (rd, rs1, imm_expr, "flw",
995
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
996
      break;
997
 
998
    case M_FLD:
999
      pcrel_load (rd, rs1, imm_expr, "fld",
1000
                  BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
1001
      break;
1002
 
1003
    case M_SB:
1004
      pcrel_store (rs2, rs1, imm_expr, "sb",
1005
                   BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
1006
      break;
1007
 
1008
    case M_SH:
1009
      pcrel_store (rs2, rs1, imm_expr, "sh",
1010
                   BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
1011
      break;
1012
 
1013
    case M_SW:
1014
      pcrel_store (rs2, rs1, imm_expr, "sw",
1015
                   BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
1016
      break;
1017
 
1018
    case M_SD:
1019
      pcrel_store (rs2, rs1, imm_expr, "sd",
1020
                   BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
1021
      break;
1022
 
1023
    case M_FSW:
1024
      pcrel_store (rs2, rs1, imm_expr, "fsw",
1025
                   BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
1026
      break;
1027
 
1028
    case M_FSD:
1029
      pcrel_store (rs2, rs1, imm_expr, "fsd",
1030
                   BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
1031
      break;
1032
 
1033
    case M_CALL:
1034
      riscv_call (rd, rs1, imm_expr, *imm_reloc);
1035
      break;
1036
 
1037
    default:
1038
      as_bad (_("Macro %s not implemented"), ip->insn_mo->name);
1039
      break;
1040
    }
1041
}
1042
 
1043
static const struct percent_op_match percent_op_utype[] =
1044
{
1045
  {"%tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
1046
  {"%pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
1047
  {"%tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
1048
  {"%tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
1049
  {"%hi", BFD_RELOC_RISCV_HI20},
1050
  {0, 0}
1051
};
1052
 
1053
static const struct percent_op_match percent_op_itype[] =
1054
{
1055
  {"%lo", BFD_RELOC_RISCV_LO12_I},
1056
  {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
1057
  {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
1058
  {0, 0}
1059
};
1060
 
1061
static const struct percent_op_match percent_op_stype[] =
1062
{
1063
  {"%lo", BFD_RELOC_RISCV_LO12_S},
1064
  {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_S},
1065
  {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_S},
1066
  {0, 0}
1067
};
1068
 
1069
static const struct percent_op_match percent_op_rtype[] =
1070
{
1071
  {"%tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
1072
  {0, 0}
1073
};
1074
 
1075
/* Return true if *STR points to a relocation operator.  When returning true,
1076
   move *STR over the operator and store its relocation code in *RELOC.
1077
   Leave both *STR and *RELOC alone when returning false.  */
1078
 
1079
static bfd_boolean
1080
parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
1081
                  const struct percent_op_match *percent_op)
1082
{
1083
  for ( ; percent_op->str; percent_op++)
1084
    if (strncasecmp (*str, percent_op->str, strlen (percent_op->str)) == 0)
1085
      {
1086
        int len = strlen (percent_op->str);
1087
 
1088
        if (!ISSPACE ((*str)[len]) && (*str)[len] != '(')
1089
          continue;
1090
 
1091
        *str += strlen (percent_op->str);
1092
        *reloc = percent_op->reloc;
1093
 
1094
        /* Check whether the output BFD supports this relocation.
1095
           If not, issue an error and fall back on something safe.  */
1096
        if (!bfd_reloc_type_lookup (stdoutput, percent_op->reloc))
1097
          {
1098
            as_bad ("relocation %s isn't supported by the current ABI",
1099
                    percent_op->str);
1100
            *reloc = BFD_RELOC_UNUSED;
1101
          }
1102
        return TRUE;
1103
      }
1104
  return FALSE;
1105
}
1106
 
1107
static void
1108
my_getExpression (expressionS *ep, char *str)
1109
{
1110
  char *save_in;
1111
 
1112
  save_in = input_line_pointer;
1113
  input_line_pointer = str;
1114
  expression (ep);
1115
  expr_end = input_line_pointer;
1116
  input_line_pointer = save_in;
1117
}
1118
 
1119
/* Parse string STR as a 16-bit relocatable operand.  Store the
1120
   expression in *EP and the relocation, if any, in RELOC.
1121
   Return the number of relocation operators used (0 or 1).
1122
 
1123
   On exit, EXPR_END points to the first character after the expression.  */
1124
 
1125
static size_t
1126
my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
1127
                       char *str, const struct percent_op_match *percent_op)
1128
{
1129
  size_t reloc_index;
1130
  unsigned crux_depth, str_depth, regno;
1131
  char *crux;
1132
 
1133
  /* First, check for integer registers.  */
1134
  if (reg_lookup (&str, RCLASS_GPR, &regno))
1135
    {
1136
      ep->X_op = O_register;
1137
      ep->X_add_number = regno;
1138
      return 0;
1139
    }
1140
 
1141
  /* Search for the start of the main expression.
1142
     End the loop with CRUX pointing to the start
1143
     of the main expression and with CRUX_DEPTH containing the number
1144
     of open brackets at that point.  */
1145
  reloc_index = -1;
1146
  str_depth = 0;
1147
  do
1148
    {
1149
      reloc_index++;
1150
      crux = str;
1151
      crux_depth = str_depth;
1152
 
1153
      /* Skip over whitespace and brackets, keeping count of the number
1154
         of brackets.  */
1155
      while (*str == ' ' || *str == '\t' || *str == '(')
1156
        if (*str++ == '(')
1157
          str_depth++;
1158
    }
1159
  while (*str == '%'
1160
         && reloc_index < 1
1161
         && parse_relocation (&str, reloc, percent_op));
1162
 
1163
  my_getExpression (ep, crux);
1164
  str = expr_end;
1165
 
1166
  /* Match every open bracket.  */
1167
  while (crux_depth > 0 && (*str == ')' || *str == ' ' || *str == '\t'))
1168
    if (*str++ == ')')
1169
      crux_depth--;
1170
 
1171
  if (crux_depth > 0)
1172
    as_bad ("unclosed '('");
1173
 
1174
  expr_end = str;
1175
 
1176
  return reloc_index;
1177
}
1178
 
1179
/* This routine assembles an instruction into its binary format.  As a
1180
   side effect, it sets the global variable imm_reloc to the type of
1181
   relocation to do if one of the operands is an address expression.  */
1182
 
1183
static const char *
1184
riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
1185
          bfd_reloc_code_real_type *imm_reloc)
1186
{
1187
  char *s;
1188
  const char *args;
1189
  char c = 0;
1190
  struct riscv_opcode *insn, *end = &riscv_opcodes[NUMOPCODES];
1191
  char *argsStart;
1192
  unsigned int regno;
1193
  char save_c = 0;
1194
  int argnum;
1195
  const struct percent_op_match *p;
1196
  const char *error = "unrecognized opcode";
1197
 
1198
  /* Parse the name of the instruction.  Terminate the string if whitespace
1199
     is found so that hash_find only sees the name part of the string.  */
1200
  for (s = str; *s != '\0'; ++s)
1201
    if (ISSPACE (*s))
1202
      {
1203
        save_c = *s;
1204
        *s++ = '\0';
1205
        break;
1206
      }
1207
 
1208
  insn = (struct riscv_opcode *) hash_find (op_hash, str);
1209
 
1210
  argsStart = s;
1211
  for ( ; insn && insn < end && strcmp (insn->name, str) == 0; insn++)
1212
    {
1213
      if (!riscv_subset_supports (insn->subset))
1214
        continue;
1215
 
1216
      create_insn (ip, insn);
1217
      argnum = 1;
1218
 
1219
      imm_expr->X_op = O_absent;
1220
      *imm_reloc = BFD_RELOC_UNUSED;
1221
      p = percent_op_itype;
1222
 
1223
      for (args = insn->args;; ++args)
1224
        {
1225
          s += strspn (s, " \t");
1226
          switch (*args)
1227
            {
1228
            case '\0':          /* end of args */
1229
              if (insn->pinfo != INSN_MACRO)
1230
                {
1231
                  if (!insn->match_func (insn, ip->insn_opcode))
1232
                    break;
1233
                  if (riscv_insn_length (insn->match) == 2 && !riscv_opts.rvc)
1234
                    break;
1235
                }
1236
              if (*s != '\0')
1237
                break;
1238
              /* Successful assembly.  */
1239
              error = NULL;
1240
              goto out;
1241
            /* Xcustom */
1242
            case '^':
1243
              {
1244
                unsigned long max = OP_MASK_RD;
1245
                my_getExpression (imm_expr, s);
1246
                check_absolute_expr (ip, imm_expr);
1247
                switch (*++args)
1248
                  {
1249
                  case 'j':
1250
                    max = OP_MASK_CUSTOM_IMM;
1251
                    INSERT_OPERAND (CUSTOM_IMM, *ip, imm_expr->X_add_number);
1252
                    break;
1253
                  case 'd':
1254
                    INSERT_OPERAND (RD, *ip, imm_expr->X_add_number);
1255
                    break;
1256
                  case 's':
1257
                    INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
1258
                    break;
1259
                  case 't':
1260
                    INSERT_OPERAND (RS2, *ip, imm_expr->X_add_number);
1261
                    break;
1262
                  }
1263
                imm_expr->X_op = O_absent;
1264
                s = expr_end;
1265
                if ((unsigned long) imm_expr->X_add_number > max)
1266
                  as_warn ("Bad custom immediate (%lu), must be at most %lu",
1267
                           (unsigned long)imm_expr->X_add_number, max);
1268
                continue;
1269
              }
1270
 
1271
            case 'C': /* RVC */
1272
              switch (*++args)
1273
                {
1274
                case 's': /* RS1 x8-x15 */
1275
                  if (!reg_lookup (&s, RCLASS_GPR, &regno)
1276
                      || !(regno >= 8 && regno <= 15))
1277
                    break;
1278
                  INSERT_OPERAND (CRS1S, *ip, regno % 8);
1279
                  continue;
1280
                case 'w': /* RS1 x8-x15, constrained to equal RD x8-x15 */
1281
                  if (!reg_lookup (&s, RCLASS_GPR, &regno)
1282
                      || EXTRACT_OPERAND (CRS1S, ip->insn_opcode) + 8 != regno)
1283
                    break;
1284
                  continue;
1285
                case 't': /* RS2 x8-x15 */
1286
                  if (!reg_lookup (&s, RCLASS_GPR, &regno)
1287
                      || !(regno >= 8 && regno <= 15))
1288
                    break;
1289
                  INSERT_OPERAND (CRS2S, *ip, regno % 8);
1290
                  continue;
1291
                case 'x': /* RS2 x8-x15, constrained to equal RD x8-x15 */
1292
                  if (!reg_lookup (&s, RCLASS_GPR, &regno)
1293
                      || EXTRACT_OPERAND (CRS2S, ip->insn_opcode) + 8 != regno)
1294
                    break;
1295
                  continue;
1296
                case 'U': /* RS1, constrained to equal RD */
1297
                  if (!reg_lookup (&s, RCLASS_GPR, &regno)
1298
                      || EXTRACT_OPERAND (RD, ip->insn_opcode) != regno)
1299
                    break;
1300
                  continue;
1301
                case 'V': /* RS2 */
1302
                  if (!reg_lookup (&s, RCLASS_GPR, &regno))
1303
                    break;
1304
                  INSERT_OPERAND (CRS2, *ip, regno);
1305
                  continue;
1306
                case 'c': /* RS1, constrained to equal sp */
1307
                  if (!reg_lookup (&s, RCLASS_GPR, &regno)
1308
                      || regno != X_SP)
1309
                    break;
1310
                  continue;
1311
                case '>':
1312
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1313
                      || imm_expr->X_op != O_constant
1314
                      || imm_expr->X_add_number <= 0
1315
                      || imm_expr->X_add_number >= 64)
1316
                    break;
1317
                  ip->insn_opcode |= ENCODE_RVC_IMM (imm_expr->X_add_number);
1318
rvc_imm_done:
1319
                  s = expr_end;
1320
                  imm_expr->X_op = O_absent;
1321
                  continue;
1322
                case '<':
1323
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1324
                      || imm_expr->X_op != O_constant
1325
                      || !VALID_RVC_IMM (imm_expr->X_add_number)
1326
                      || imm_expr->X_add_number <= 0
1327
                      || imm_expr->X_add_number >= 32)
1328
                    break;
1329
                  ip->insn_opcode |= ENCODE_RVC_IMM (imm_expr->X_add_number);
1330
                  goto rvc_imm_done;
1331
                case 'i':
1332
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1333
                      || imm_expr->X_op != O_constant
1334
                      || imm_expr->X_add_number == 0
1335
                      || !VALID_RVC_SIMM3 (imm_expr->X_add_number))
1336
                    break;
1337
                  ip->insn_opcode |= ENCODE_RVC_SIMM3 (imm_expr->X_add_number);
1338
                  goto rvc_imm_done;
1339
                case 'j':
1340
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1341
                      || imm_expr->X_op != O_constant
1342
                      || imm_expr->X_add_number == 0
1343
                      || !VALID_RVC_IMM (imm_expr->X_add_number))
1344
                    break;
1345
                  ip->insn_opcode |= ENCODE_RVC_IMM (imm_expr->X_add_number);
1346
                  goto rvc_imm_done;
1347
                case 'k':
1348
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1349
                      || imm_expr->X_op != O_constant
1350
                      || !VALID_RVC_LW_IMM (imm_expr->X_add_number))
1351
                    break;
1352
                  ip->insn_opcode |= ENCODE_RVC_LW_IMM (imm_expr->X_add_number);
1353
                  goto rvc_imm_done;
1354
                case 'l':
1355
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1356
                      || imm_expr->X_op != O_constant
1357
                      || !VALID_RVC_LD_IMM (imm_expr->X_add_number))
1358
                    break;
1359
                  ip->insn_opcode |= ENCODE_RVC_LD_IMM (imm_expr->X_add_number);
1360
                  goto rvc_imm_done;
1361
                case 'm':
1362
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1363
                      || imm_expr->X_op != O_constant
1364
                      || !VALID_RVC_LWSP_IMM (imm_expr->X_add_number))
1365
                    break;
1366
                  ip->insn_opcode |=
1367
                    ENCODE_RVC_LWSP_IMM (imm_expr->X_add_number);
1368
                  goto rvc_imm_done;
1369
                case 'n':
1370
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1371
                      || imm_expr->X_op != O_constant
1372
                      || !VALID_RVC_LDSP_IMM (imm_expr->X_add_number))
1373
                    break;
1374
                  ip->insn_opcode |=
1375
                    ENCODE_RVC_LDSP_IMM (imm_expr->X_add_number);
1376
                  goto rvc_imm_done;
1377
                case 'K':
1378
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1379
                      || imm_expr->X_op != O_constant
1380
                      || !VALID_RVC_ADDI4SPN_IMM (imm_expr->X_add_number)
1381
                      || imm_expr->X_add_number == 0)
1382
                    break;
1383
                  ip->insn_opcode |=
1384
                    ENCODE_RVC_ADDI4SPN_IMM (imm_expr->X_add_number);
1385
                  goto rvc_imm_done;
1386
                case 'L':
1387
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1388
                      || imm_expr->X_op != O_constant
1389
                      || !VALID_RVC_ADDI16SP_IMM (imm_expr->X_add_number))
1390
                    break;
1391
                  ip->insn_opcode |=
1392
                    ENCODE_RVC_ADDI16SP_IMM (imm_expr->X_add_number);
1393
                  goto rvc_imm_done;
1394
                case 'M':
1395
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1396
                      || imm_expr->X_op != O_constant
1397
                      || !VALID_RVC_SWSP_IMM (imm_expr->X_add_number))
1398
                    break;
1399
                  ip->insn_opcode |=
1400
                    ENCODE_RVC_SWSP_IMM (imm_expr->X_add_number);
1401
                  goto rvc_imm_done;
1402
                case 'N':
1403
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1404
                      || imm_expr->X_op != O_constant
1405
                      || !VALID_RVC_SDSP_IMM (imm_expr->X_add_number))
1406
                    break;
1407
                  ip->insn_opcode |=
1408
                    ENCODE_RVC_SDSP_IMM (imm_expr->X_add_number);
1409
                  goto rvc_imm_done;
1410
                case 'u':
1411
                  p = percent_op_utype;
1412
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p))
1413
                    break;
1414
rvc_lui:
1415
                  if (imm_expr->X_op != O_constant
1416
                      || imm_expr->X_add_number <= 0
1417
                      || imm_expr->X_add_number >= RISCV_BIGIMM_REACH
1418
                      || (imm_expr->X_add_number >= RISCV_RVC_IMM_REACH / 2
1419
                          && imm_expr->X_add_number <
1420
                              RISCV_BIGIMM_REACH - RISCV_RVC_IMM_REACH / 2))
1421
                    break;
1422
                  ip->insn_opcode |= ENCODE_RVC_IMM (imm_expr->X_add_number);
1423
                  goto rvc_imm_done;
1424
                case 'v':
1425
                  if (my_getSmallExpression (imm_expr, imm_reloc, s, p)
1426
                      || (imm_expr->X_add_number & (RISCV_IMM_REACH - 1))
1427
                      || (int32_t)imm_expr->X_add_number
1428
                          != imm_expr->X_add_number)
1429
                    break;
1430
                  imm_expr->X_add_number =
1431
                    ((uint32_t) imm_expr->X_add_number) >> RISCV_IMM_BITS;
1432
                  goto rvc_lui;
1433
                case 'p':
1434
                  goto branch;
1435
                case 'a':
1436
                  goto jump;
1437
                case 'D': /* floating-point RS2 x8-x15 */
1438
                  if (!reg_lookup (&s, RCLASS_FPR, &regno)
1439
                      || !(regno >= 8 && regno <= 15))
1440
                    break;
1441
                  INSERT_OPERAND (CRS2S, *ip, regno % 8);
1442
                  continue;
1443
                case 'T': /* floating-point RS2 */
1444
                  if (!reg_lookup (&s, RCLASS_FPR, &regno))
1445
                    break;
1446
                  INSERT_OPERAND (CRS2, *ip, regno);
1447
                  continue;
1448
                default:
1449
                  as_bad (_("bad RVC field specifier 'C%c'\n"), *args);
1450
                }
1451
              break;
1452
 
1453
            case ',':
1454
              ++argnum;
1455
              if (*s++ == *args)
1456
                continue;
1457
              s--;
1458
              break;
1459
 
1460
            case '(':
1461
            case ')':
1462
            case '[':
1463
            case ']':
1464
              if (*s++ == *args)
1465
                continue;
1466
              break;
1467
 
1468
            case '<':           /* shift amount, 0 - 31 */
1469
              my_getExpression (imm_expr, s);
1470
              check_absolute_expr (ip, imm_expr);
1471
              if ((unsigned long) imm_expr->X_add_number > 31)
1472
                as_warn (_("Improper shift amount (%lu)"),
1473
                         (unsigned long) imm_expr->X_add_number);
1474
              INSERT_OPERAND (SHAMTW, *ip, imm_expr->X_add_number);
1475
              imm_expr->X_op = O_absent;
1476
              s = expr_end;
1477
              continue;
1478
 
1479
            case '>':           /* shift amount, 0 - (XLEN-1) */
1480
              my_getExpression (imm_expr, s);
1481
              check_absolute_expr (ip, imm_expr);
1482
              if ((unsigned long) imm_expr->X_add_number >= xlen)
1483
                as_warn (_("Improper shift amount (%lu)"),
1484
                         (unsigned long) imm_expr->X_add_number);
1485
              INSERT_OPERAND (SHAMT, *ip, imm_expr->X_add_number);
1486
              imm_expr->X_op = O_absent;
1487
              s = expr_end;
1488
              continue;
1489
 
1490
            case 'Z':           /* CSRRxI immediate */
1491
              my_getExpression (imm_expr, s);
1492
              check_absolute_expr (ip, imm_expr);
1493
              if ((unsigned long) imm_expr->X_add_number > 31)
1494
                as_warn (_("Improper CSRxI immediate (%lu)"),
1495
                         (unsigned long) imm_expr->X_add_number);
1496
              INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
1497
              imm_expr->X_op = O_absent;
1498
              s = expr_end;
1499
              continue;
1500
 
1501
            case 'E':           /* Control register.  */
1502
              if (reg_lookup (&s, RCLASS_CSR, &regno))
1503
                INSERT_OPERAND (CSR, *ip, regno);
1504
              else
1505
                {
1506
                  my_getExpression (imm_expr, s);
1507
                  check_absolute_expr (ip, imm_expr);
1508
                  if ((unsigned long) imm_expr->X_add_number > 0xfff)
1509
                    as_warn(_("Improper CSR address (%lu)"),
1510
                            (unsigned long) imm_expr->X_add_number);
1511
                  INSERT_OPERAND (CSR, *ip, imm_expr->X_add_number);
1512
                  imm_expr->X_op = O_absent;
1513
                  s = expr_end;
1514
                }
1515
              continue;
1516
 
1517
            case 'm':           /* rounding mode */
1518
              if (arg_lookup (&s, riscv_rm, ARRAY_SIZE (riscv_rm), &regno))
1519
                {
1520
                  INSERT_OPERAND (RM, *ip, regno);
1521
                  continue;
1522
                }
1523
              break;
1524
 
1525
            case 'P':
1526
            case 'Q':           /* fence predecessor/successor */
1527
              if (arg_lookup (&s, riscv_pred_succ, ARRAY_SIZE (riscv_pred_succ),
1528
                              &regno))
1529
                {
1530
                  if (*args == 'P')
1531
                    INSERT_OPERAND (PRED, *ip, regno);
1532
                  else
1533
                    INSERT_OPERAND (SUCC, *ip, regno);
1534
                  continue;
1535
                }
1536
              break;
1537
 
1538
            case 'd':           /* destination register */
1539
            case 's':           /* source register */
1540
            case 't':           /* target register */
1541
              if (reg_lookup (&s, RCLASS_GPR, &regno))
1542
                {
1543
                  c = *args;
1544
                  if (*s == ' ')
1545
                    ++s;
1546
 
1547
                  /* Now that we have assembled one operand, we use the args
1548
                     string to figure out where it goes in the instruction.  */
1549
                  switch (c)
1550
                    {
1551
                    case 's':
1552
                      INSERT_OPERAND (RS1, *ip, regno);
1553
                      break;
1554
                    case 'd':
1555
                      INSERT_OPERAND (RD, *ip, regno);
1556
                      break;
1557
                    case 't':
1558
                      INSERT_OPERAND (RS2, *ip, regno);
1559
                      break;
1560
                    }
1561
                  continue;
1562
                }
1563
              break;
1564
 
1565
            case 'D':           /* floating point rd */
1566
            case 'S':           /* floating point rs1 */
1567
            case 'T':           /* floating point rs2 */
1568
            case 'U':           /* floating point rs1 and rs2 */
1569
            case 'R':           /* floating point rs3 */
1570
              if (reg_lookup (&s, RCLASS_FPR, &regno))
1571
                {
1572
                  c = *args;
1573
                  if (*s == ' ')
1574
                    ++s;
1575
                  switch (c)
1576
                    {
1577
                    case 'D':
1578
                      INSERT_OPERAND (RD, *ip, regno);
1579
                      break;
1580
                    case 'S':
1581
                      INSERT_OPERAND (RS1, *ip, regno);
1582
                      break;
1583
                    case 'U':
1584
                      INSERT_OPERAND (RS1, *ip, regno);
1585
                      /* fallthru */
1586
                    case 'T':
1587
                      INSERT_OPERAND (RS2, *ip, regno);
1588
                      break;
1589
                    case 'R':
1590
                      INSERT_OPERAND (RS3, *ip, regno);
1591
                      break;
1592
                    }
1593
                  continue;
1594
                }
1595
 
1596
              break;
1597
 
1598
            case 'I':
1599
              my_getExpression (imm_expr, s);
1600
              if (imm_expr->X_op != O_big
1601
                  && imm_expr->X_op != O_constant)
1602
                break;
1603
              normalize_constant_expr (imm_expr);
1604
              s = expr_end;
1605
              continue;
1606
 
1607
            case 'A':
1608
              my_getExpression (imm_expr, s);
1609
              normalize_constant_expr (imm_expr);
1610
              *imm_reloc = BFD_RELOC_32;
1611
              s = expr_end;
1612
              continue;
1613
 
1614
            case 'j': /* sign-extended immediate */
1615
              *imm_reloc = BFD_RELOC_RISCV_LO12_I;
1616
              p = percent_op_itype;
1617
              goto alu_op;
1618
            case 'q': /* store displacement */
1619
              p = percent_op_stype;
1620
              *imm_reloc = BFD_RELOC_RISCV_LO12_S;
1621
              goto load_store;
1622
            case 'o': /* load displacement */
1623
              p = percent_op_itype;
1624
              *imm_reloc = BFD_RELOC_RISCV_LO12_I;
1625
              goto load_store;
1626
            case '0': /* AMO "displacement," which must be zero */
1627
              p = percent_op_rtype;
1628
              *imm_reloc = BFD_RELOC_UNUSED;
1629
load_store:
1630
              /* Check whether there is only a single bracketed expression
1631
                 left.  If so, it must be the base register and the
1632
                 constant must be zero.  */
1633
              imm_expr->X_op = O_constant;
1634
              imm_expr->X_add_number = 0;
1635
              if (*s == '(' && strchr (s + 1, '(') == 0)
1636
                continue;
1637
alu_op:
1638
              /* If this value won't fit into a 16 bit offset, then go
1639
                 find a macro that will generate the 32 bit offset
1640
                 code pattern.  */
1641
              if (!my_getSmallExpression (imm_expr, imm_reloc, s, p))
1642
                {
1643
                  normalize_constant_expr (imm_expr);
1644
                  if (imm_expr->X_op != O_constant
1645
                      || (*args == '0' && imm_expr->X_add_number != 0)
1646
                      || imm_expr->X_add_number >= (signed)RISCV_IMM_REACH/2
1647
                      || imm_expr->X_add_number < -(signed)RISCV_IMM_REACH/2)
1648
                    break;
1649
                }
1650
 
1651
              s = expr_end;
1652
              continue;
1653
 
1654
            case 'p':           /* pc relative offset */
1655
branch:
1656
              *imm_reloc = BFD_RELOC_12_PCREL;
1657
              my_getExpression (imm_expr, s);
1658
              s = expr_end;
1659
              continue;
1660
 
1661
            case 'u':           /* upper 20 bits */
1662
              p = percent_op_utype;
1663
              if (!my_getSmallExpression (imm_expr, imm_reloc, s, p)
1664
                  && imm_expr->X_op == O_constant)
1665
                {
1666
                  if (imm_expr->X_add_number < 0
1667
                      || imm_expr->X_add_number >= (signed)RISCV_BIGIMM_REACH)
1668
                    as_bad (_("lui expression not in range 0..1048575"));
1669
 
1670
                  *imm_reloc = BFD_RELOC_RISCV_HI20;
1671
                  imm_expr->X_add_number <<= RISCV_IMM_BITS;
1672
                }
1673
              s = expr_end;
1674
              continue;
1675
 
1676
            case 'a':           /* 26 bit address */
1677
jump:
1678
              my_getExpression (imm_expr, s);
1679
              s = expr_end;
1680
              *imm_reloc = BFD_RELOC_RISCV_JMP;
1681
              continue;
1682
 
1683
            case 'c':
1684
              my_getExpression (imm_expr, s);
1685
              s = expr_end;
1686
              *imm_reloc = BFD_RELOC_RISCV_CALL;
1687
              if (*s == '@')
1688
                *imm_reloc = BFD_RELOC_RISCV_CALL_PLT, s++;
1689
              continue;
1690
 
1691
            default:
1692
              as_fatal (_("internal error: bad argument type %c"), *args);
1693
            }
1694
          break;
1695
        }
1696
      s = argsStart;
1697
      error = _("illegal operands");
1698
    }
1699
 
1700
out:
1701
  /* Restore the character we might have clobbered above.  */
1702
  if (save_c)
1703
    *(argsStart - 1) = save_c;
1704
 
1705
  return error;
1706
}
1707
 
1708
void
1709
md_assemble (char *str)
1710
{
1711
  struct riscv_cl_insn insn;
1712
  expressionS imm_expr;
1713
  bfd_reloc_code_real_type imm_reloc = BFD_RELOC_UNUSED;
1714
 
1715
  const char *error = riscv_ip (str, &insn, &imm_expr, &imm_reloc);
1716
 
1717
  if (error)
1718
    {
1719
      as_bad ("%s `%s'", error, str);
1720
      return;
1721
    }
1722
 
1723
  if (insn.insn_mo->pinfo == INSN_MACRO)
1724
    macro (&insn, &imm_expr, &imm_reloc);
1725
  else
1726
    append_insn (&insn, &imm_expr, imm_reloc);
1727
}
1728
 
1729
char *
1730
md_atof (int type, char *litP, int *sizeP)
1731
{
1732
  return ieee_md_atof (type, litP, sizeP, TARGET_BYTES_BIG_ENDIAN);
1733
}
1734
 
1735
void
1736
md_number_to_chars (char *buf, valueT val, int n)
1737
{
1738
  number_to_chars_littleendian (buf, val, n);
1739
}
1740
 
1741
const char *md_shortopts = "O::g::G:";
1742
 
1743
enum options
1744
  {
1745
    OPTION_M32 = OPTION_MD_BASE,
1746
    OPTION_M64,
1747
    OPTION_MARCH,
1748
    OPTION_PIC,
1749
    OPTION_NO_PIC,
1750
    OPTION_MSOFT_FLOAT,
1751
    OPTION_MHARD_FLOAT,
1752
    OPTION_MRVC,
1753
    OPTION_MNO_RVC,
1754
    OPTION_END_OF_ENUM
1755
  };
1756
 
1757
struct option md_longopts[] =
1758
{
1759
  {"m32", no_argument, NULL, OPTION_M32},
1760
  {"m64", no_argument, NULL, OPTION_M64},
1761
  {"march", required_argument, NULL, OPTION_MARCH},
1762
  {"fPIC", no_argument, NULL, OPTION_PIC},
1763
  {"fpic", no_argument, NULL, OPTION_PIC},
1764
  {"fno-pic", no_argument, NULL, OPTION_NO_PIC},
1765
  {"mrvc", no_argument, NULL, OPTION_MRVC},
1766
  {"mno-rvc", no_argument, NULL, OPTION_MNO_RVC},
1767
  {"msoft-float", no_argument, NULL, OPTION_MSOFT_FLOAT},
1768
  {"mhard-float", no_argument, NULL, OPTION_MHARD_FLOAT},
1769
 
1770
  {NULL, no_argument, NULL, 0}
1771
};
1772
size_t md_longopts_size = sizeof (md_longopts);
1773
 
1774
int
1775
md_parse_option (int c, char *arg)
1776
{
1777
  switch (c)
1778
    {
1779
    case OPTION_MRVC:
1780
      riscv_set_rvc (TRUE);
1781
      break;
1782
 
1783
    case OPTION_MNO_RVC:
1784
      riscv_set_rvc (FALSE);
1785
      break;
1786
 
1787
    case OPTION_MSOFT_FLOAT:
1788
      elf_flags |= EF_RISCV_SOFT_FLOAT;
1789
      break;
1790
 
1791
    case OPTION_MHARD_FLOAT:
1792
      elf_flags &= ~EF_RISCV_SOFT_FLOAT;
1793
      break;
1794
 
1795
    case OPTION_M32:
1796
      xlen = 32;
1797
      break;
1798
 
1799
    case OPTION_M64:
1800
      xlen = 64;
1801
      break;
1802
 
1803
    case OPTION_MARCH:
1804
      riscv_set_arch (arg);
1805
      break;
1806
 
1807
    case OPTION_NO_PIC:
1808
      riscv_opts.pic = FALSE;
1809
      break;
1810
 
1811
    case OPTION_PIC:
1812
      riscv_opts.pic = TRUE;
1813
      break;
1814
 
1815
    default:
1816
      return 0;
1817
    }
1818
 
1819
  return 1;
1820
}
1821
 
1822
void
1823
riscv_after_parse_args (void)
1824
{
1825
  if (riscv_subsets == NULL)
1826
    riscv_set_arch ("RVIMAFDXcustom");
1827
 
1828
  if (xlen == 0)
1829
    {
1830
      if (strcmp (default_arch, "riscv32") == 0)
1831
        xlen = 32;
1832
      else if (strcmp (default_arch, "riscv64") == 0)
1833
        xlen = 64;
1834
      else
1835
        as_bad ("unknown default architecture `%s'", default_arch);
1836
    }
1837
}
1838
 
1839
void
1840
riscv_init_after_args (void)
1841
{
1842
  /* initialize opcodes */
1843
  bfd_riscv_num_opcodes = bfd_riscv_num_builtin_opcodes;
1844
  riscv_opcodes = (struct riscv_opcode *) riscv_builtin_opcodes;
1845
}
1846
 
1847
long
1848
md_pcrel_from (fixS *fixP)
1849
{
1850
  return fixP->fx_where + fixP->fx_frag->fr_address;
1851
}
1852
 
1853
/* Apply a fixup to the object file.  */
1854
 
1855
void
1856
md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
1857
{
1858
  bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
1859
 
1860
  /* Remember value for tc_gen_reloc.  */
1861
  fixP->fx_addnumber = *valP;
1862
 
1863
  switch (fixP->fx_r_type)
1864
    {
1865
    case BFD_RELOC_RISCV_TLS_GOT_HI20:
1866
    case BFD_RELOC_RISCV_TLS_GD_HI20:
1867
    case BFD_RELOC_RISCV_TLS_DTPREL32:
1868
    case BFD_RELOC_RISCV_TLS_DTPREL64:
1869
    case BFD_RELOC_RISCV_TPREL_HI20:
1870
    case BFD_RELOC_RISCV_TPREL_LO12_I:
1871
    case BFD_RELOC_RISCV_TPREL_LO12_S:
1872
    case BFD_RELOC_RISCV_TPREL_ADD:
1873
      S_SET_THREAD_LOCAL (fixP->fx_addsy);
1874
      /* fall through */
1875
 
1876
    case BFD_RELOC_RISCV_GOT_HI20:
1877
    case BFD_RELOC_RISCV_PCREL_HI20:
1878
    case BFD_RELOC_RISCV_HI20:
1879
    case BFD_RELOC_RISCV_LO12_I:
1880
    case BFD_RELOC_RISCV_LO12_S:
1881
    case BFD_RELOC_RISCV_ADD8:
1882
    case BFD_RELOC_RISCV_ADD16:
1883
    case BFD_RELOC_RISCV_ADD32:
1884
    case BFD_RELOC_RISCV_ADD64:
1885
    case BFD_RELOC_RISCV_SUB8:
1886
    case BFD_RELOC_RISCV_SUB16:
1887
    case BFD_RELOC_RISCV_SUB32:
1888
    case BFD_RELOC_RISCV_SUB64:
1889
      gas_assert (fixP->fx_addsy != NULL);
1890
      /* Nothing needed to do.  The value comes from the reloc entry.  */
1891
      break;
1892
 
1893
    case BFD_RELOC_64:
1894
    case BFD_RELOC_32:
1895
    case BFD_RELOC_16:
1896
    case BFD_RELOC_8:
1897
      if (fixP->fx_addsy && fixP->fx_subsy)
1898
        {
1899
          fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
1900
          fixP->fx_next->fx_addsy = fixP->fx_subsy;
1901
          fixP->fx_next->fx_subsy = NULL;
1902
          fixP->fx_next->fx_offset = 0;
1903
          fixP->fx_subsy = NULL;
1904
 
1905
          if (fixP->fx_r_type == BFD_RELOC_64)
1906
            {
1907
              fixP->fx_r_type = BFD_RELOC_RISCV_ADD64;
1908
              fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB64;
1909
            }
1910
          else if (fixP->fx_r_type == BFD_RELOC_32)
1911
            {
1912
              fixP->fx_r_type = BFD_RELOC_RISCV_ADD32;
1913
              fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
1914
            }
1915
          else if (fixP->fx_r_type == BFD_RELOC_16)
1916
            {
1917
              fixP->fx_r_type = BFD_RELOC_RISCV_ADD16;
1918
              fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
1919
            }
1920
          else
1921
            {
1922
              fixP->fx_r_type = BFD_RELOC_RISCV_ADD8;
1923
              fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
1924
            }
1925
        }
1926
      /* fall through */
1927
 
1928
    case BFD_RELOC_RVA:
1929
      /* If we are deleting this reloc entry, we must fill in the
1930
         value now.  This can happen if we have a .word which is not
1931
         resolved when it appears but is later defined.  */
1932
      if (fixP->fx_addsy == NULL)
1933
        {
1934
          gas_assert (fixP->fx_size <= sizeof (valueT));
1935
          md_number_to_chars ((char *) buf, *valP, fixP->fx_size);
1936
          fixP->fx_done = 1;
1937
        }
1938
      break;
1939
 
1940
    case BFD_RELOC_RISCV_JMP:
1941
      if (fixP->fx_addsy)
1942
        {
1943
          /* Fill in a tentative value to improve objdump readability.  */
1944
          bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
1945
          bfd_vma delta = target - md_pcrel_from (fixP);
1946
          bfd_putl32 (bfd_getl32 (buf) | ENCODE_UJTYPE_IMM (delta), buf);
1947
        }
1948
      break;
1949
 
1950
    case BFD_RELOC_12_PCREL:
1951
      if (fixP->fx_addsy)
1952
        {
1953
          /* Fill in a tentative value to improve objdump readability.  */
1954
          bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
1955
          bfd_vma delta = target - md_pcrel_from (fixP);
1956
          bfd_putl32 (bfd_getl32 (buf) | ENCODE_SBTYPE_IMM (delta), buf);
1957
        }
1958
      break;
1959
 
1960
    case BFD_RELOC_RISCV_RVC_BRANCH:
1961
      if (fixP->fx_addsy)
1962
        {
1963
          /* Fill in a tentative value to improve objdump readability.  */
1964
          bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
1965
          bfd_vma delta = target - md_pcrel_from (fixP);
1966
          bfd_putl16 (bfd_getl16 (buf) | ENCODE_RVC_B_IMM (delta), buf);
1967
        }
1968
      break;
1969
 
1970
    case BFD_RELOC_RISCV_RVC_JUMP:
1971
      if (fixP->fx_addsy)
1972
        {
1973
          /* Fill in a tentative value to improve objdump readability.  */
1974
          bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
1975
          bfd_vma delta = target - md_pcrel_from (fixP);
1976
          bfd_putl16 (bfd_getl16 (buf) | ENCODE_RVC_J_IMM (delta), buf);
1977
        }
1978
      break;
1979
 
1980
    case BFD_RELOC_RISCV_PCREL_LO12_S:
1981
    case BFD_RELOC_RISCV_PCREL_LO12_I:
1982
    case BFD_RELOC_RISCV_CALL:
1983
    case BFD_RELOC_RISCV_CALL_PLT:
1984
    case BFD_RELOC_RISCV_ALIGN:
1985
      break;
1986
 
1987
    default:
1988
      /* We ignore generic BFD relocations we don't know about.  */
1989
      if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
1990
        as_fatal (_("internal error: bad relocation #%d"), fixP->fx_r_type);
1991
    }
1992
}
1993
 
1994
/* This structure is used to hold a stack of .option values.  */
1995
 
1996
struct riscv_option_stack
1997
{
1998
  struct riscv_option_stack *next;
1999
  struct riscv_set_options options;
2000
};
2001
 
2002
static struct riscv_option_stack *riscv_opts_stack;
2003
 
2004
/* Handle the .option pseudo-op.  */
2005
 
2006
static void
2007
s_riscv_option (int x ATTRIBUTE_UNUSED)
2008
{
2009
  char *name = input_line_pointer, ch;
2010
 
2011
  while (!is_end_of_line[(unsigned char) *input_line_pointer])
2012
    ++input_line_pointer;
2013
  ch = *input_line_pointer;
2014
  *input_line_pointer = '\0';
2015
 
2016
  if (strcmp (name, "rvc") == 0)
2017
    riscv_set_rvc (TRUE);
2018
  else if (strcmp (name, "norvc") == 0)
2019
    riscv_set_rvc (FALSE);
2020
  else if (strcmp (name, "push") == 0)
2021
    {
2022
      struct riscv_option_stack *s;
2023
 
2024
      s = (struct riscv_option_stack *) xmalloc (sizeof *s);
2025
      s->next = riscv_opts_stack;
2026
      s->options = riscv_opts;
2027
      riscv_opts_stack = s;
2028
    }
2029
  else if (strcmp (name, "pop") == 0)
2030
    {
2031
      struct riscv_option_stack *s;
2032
 
2033
      s = riscv_opts_stack;
2034
      if (s == NULL)
2035
        as_bad (_(".option pop with no .option push"));
2036
      else
2037
        {
2038
          riscv_opts = s->options;
2039
          riscv_opts_stack = s->next;
2040
          free (s);
2041
        }
2042
    }
2043
  else
2044
    {
2045
      as_warn (_("Unrecognized .option directive: %s\n"), name);
2046
    }
2047
  *input_line_pointer = ch;
2048
  demand_empty_rest_of_line ();
2049
}
2050
 
2051
/* Handle the .dtprelword and .dtpreldword pseudo-ops.  They generate
2052
   a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
2053
   use in DWARF debug information.  */
2054
 
2055
static void
2056
s_dtprel (int bytes)
2057
{
2058
  expressionS ex;
2059
  char *p;
2060
 
2061
  expression (&ex);
2062
 
2063
  if (ex.X_op != O_symbol)
2064
    {
2065
      as_bad (_("Unsupported use of %s"), (bytes == 8
2066
                                           ? ".dtpreldword"
2067
                                           : ".dtprelword"));
2068
      ignore_rest_of_line ();
2069
    }
2070
 
2071
  p = frag_more (bytes);
2072
  md_number_to_chars (p, 0, bytes);
2073
  fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
2074
               (bytes == 8
2075
                ? BFD_RELOC_RISCV_TLS_DTPREL64
2076
                : BFD_RELOC_RISCV_TLS_DTPREL32));
2077
 
2078
  demand_empty_rest_of_line ();
2079
}
2080
 
2081
/* Handle the .bss pseudo-op.  */
2082
 
2083
static void
2084
s_bss (int ignore ATTRIBUTE_UNUSED)
2085
{
2086
  subseg_set (bss_section, 0);
2087
  demand_empty_rest_of_line ();
2088
}
2089
 
2090
/* Align to a given power of two.  */
2091
 
2092
static void
2093
s_align (int bytes_p)
2094
{
2095
  int fill_value = 0, fill_value_specified = 0;
2096
  int min_text_alignment = riscv_opts.rvc ? 2 : 4;
2097
  int alignment = get_absolute_expression(), bytes;
2098
 
2099
  if (bytes_p)
2100
    {
2101
      bytes = alignment;
2102
      if (bytes < 1 || (bytes & (bytes-1)) != 0)
2103
        as_bad (_("alignment not a power of 2: %d"), bytes);
2104
      for (alignment = 0; bytes > 1; bytes >>= 1)
2105
        alignment++;
2106
    }
2107
 
2108
  bytes = 1 << alignment;
2109
 
2110
  if (alignment < 0 || alignment > 31)
2111
    as_bad (_("unsatisfiable alignment: %d"), alignment);
2112
 
2113
  if (*input_line_pointer == ',')
2114
    {
2115
      ++input_line_pointer;
2116
      fill_value = get_absolute_expression ();
2117
      fill_value_specified = 1;
2118
    }
2119
 
2120
  if (!fill_value_specified
2121
      && subseg_text_p (now_seg)
2122
      && bytes > min_text_alignment)
2123
    {
2124
      /* Emit the worst-case NOP string.  The linker will delete any
2125
         unnecessary NOPs.  This allows us to support code alignment
2126
         in spite of linker relaxations.  */
2127
      bfd_vma i, worst_case_bytes = bytes - min_text_alignment;
2128
      char *nops = frag_more (worst_case_bytes);
2129
      for (i = 0; i < worst_case_bytes - 2; i += 4)
2130
        md_number_to_chars (nops + i, RISCV_NOP, 4);
2131
      if (i < worst_case_bytes)
2132
        md_number_to_chars (nops + i, RVC_NOP, 2);
2133
 
2134
      expressionS ex;
2135
      ex.X_op = O_constant;
2136
      ex.X_add_number = worst_case_bytes;
2137
 
2138
      fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
2139
                   &ex, FALSE, BFD_RELOC_RISCV_ALIGN);
2140
    }
2141
  else if (alignment)
2142
    frag_align (alignment, fill_value, 0);
2143
 
2144
  record_alignment (now_seg, alignment);
2145
 
2146
  demand_empty_rest_of_line ();
2147
}
2148
 
2149
int
2150
md_estimate_size_before_relax (fragS *fragp, asection *segtype)
2151
{
2152
  return (fragp->fr_var = relaxed_branch_length (fragp, segtype, FALSE));
2153
}
2154
 
2155
/* Translate internal representation of relocation info to BFD target
2156
   format.  */
2157
 
2158
arelent *
2159
tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
2160
{
2161
  arelent *reloc = (arelent *) xmalloc (sizeof (arelent));
2162
 
2163
  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
2164
  *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
2165
  reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
2166
  reloc->addend = fixp->fx_addnumber;
2167
 
2168
  reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
2169
  if (reloc->howto == NULL)
2170
    {
2171
      if ((fixp->fx_r_type == BFD_RELOC_16 || fixp->fx_r_type == BFD_RELOC_8)
2172
          && fixp->fx_addsy != NULL && fixp->fx_subsy != NULL)
2173
        {
2174
          /* We don't have R_RISCV_8/16, but for this special case,
2175
             we can use R_RISCV_ADD8/16 with R_RISCV_SUB8/16.  */
2176
          return reloc;
2177
        }
2178
 
2179
      as_bad_where (fixp->fx_file, fixp->fx_line,
2180
                    _("cannot represent %s relocation in object file"),
2181
                    bfd_get_reloc_code_name (fixp->fx_r_type));
2182
      return NULL;
2183
    }
2184
 
2185
  return reloc;
2186
}
2187
 
2188
int
2189
riscv_relax_frag (asection *sec, fragS *fragp, long stretch ATTRIBUTE_UNUSED)
2190
{
2191
  if (RELAX_BRANCH_P (fragp->fr_subtype))
2192
    {
2193
      offsetT old_var = fragp->fr_var;
2194
      fragp->fr_var = relaxed_branch_length (fragp, sec, TRUE);
2195
      return fragp->fr_var - old_var;
2196
    }
2197
 
2198
  return 0;
2199
}
2200
 
2201
/* Expand far branches to multi-instruction sequences.  */
2202
 
2203
static void
2204
md_convert_frag_branch (fragS *fragp)
2205
{
2206
  bfd_byte *buf;
2207
  expressionS exp;
2208
  fixS *fixp;
2209
  insn_t insn;
2210
  int rs1, reloc;
2211
 
2212
  buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
2213
 
2214
  exp.X_op = O_symbol;
2215
  exp.X_add_symbol = fragp->fr_symbol;
2216
  exp.X_add_number = fragp->fr_offset;
2217
 
2218
  gas_assert (fragp->fr_var == RELAX_BRANCH_LENGTH (fragp->fr_subtype));
2219
 
2220
  if (RELAX_BRANCH_RVC (fragp->fr_subtype))
2221
    {
2222
      switch (RELAX_BRANCH_LENGTH (fragp->fr_subtype))
2223
        {
2224
          case 8:
2225
          case 4:
2226
            /* Expand the RVC branch into a RISC-V one.  */
2227
            insn = bfd_getl16 (buf);
2228
            rs1 = 8 + ((insn >> OP_SH_CRS1S) & OP_MASK_CRS1S);
2229
            if ((insn & MASK_C_J) == MATCH_C_J)
2230
              insn = MATCH_JAL;
2231
            else if ((insn & MASK_C_JAL) == MATCH_C_JAL)
2232
              insn = MATCH_JAL | (X_RA << OP_SH_RD);
2233
            else if ((insn & MASK_C_BEQZ) == MATCH_C_BEQZ)
2234
              insn = MATCH_BEQ | (rs1 << OP_SH_RS1);
2235
            else if ((insn & MASK_C_BNEZ) == MATCH_C_BNEZ)
2236
              insn = MATCH_BNE | (rs1 << OP_SH_RS1);
2237
            else
2238
              abort ();
2239
            bfd_putl32 (insn, buf);
2240
            break;
2241
 
2242
          case 6:
2243
            /* Invert the branch condition.  Branch over the jump.  */
2244
            insn = bfd_getl16 (buf);
2245
            insn ^= MATCH_C_BEQZ ^ MATCH_C_BNEZ;
2246
            insn |= ENCODE_RVC_B_IMM (6);
2247
            bfd_putl16 (insn, buf);
2248
            buf += 2;
2249
            goto jump;
2250
 
2251
          case 2:
2252
            /* Just keep the RVC branch.  */
2253
            reloc = RELAX_BRANCH_UNCOND (fragp->fr_subtype)
2254
                    ? BFD_RELOC_RISCV_RVC_JUMP : BFD_RELOC_RISCV_RVC_BRANCH;
2255
            fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
2256
                                2, &exp, FALSE, reloc);
2257
            buf += 2;
2258
            goto done;
2259
 
2260
          default:
2261
            abort();
2262
        }
2263
    }
2264
 
2265
  switch (RELAX_BRANCH_LENGTH (fragp->fr_subtype))
2266
    {
2267
    case 8:
2268
      gas_assert (!RELAX_BRANCH_UNCOND (fragp->fr_subtype));
2269
 
2270
      /* Invert the branch condition.  Branch over the jump.  */
2271
      insn = bfd_getl32 (buf);
2272
      insn ^= MATCH_BEQ ^ MATCH_BNE;
2273
      insn |= ENCODE_SBTYPE_IMM (8);
2274
      md_number_to_chars ((char *) buf, insn, 4);
2275
      buf += 4;
2276
 
2277
jump:
2278
      /* Jump to the target.  */
2279
      fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
2280
                          4, &exp, FALSE, BFD_RELOC_RISCV_JMP);
2281
      md_number_to_chars ((char *) buf, MATCH_JAL, 4);
2282
      buf += 4;
2283
      break;
2284
 
2285
    case 4:
2286
      reloc = RELAX_BRANCH_UNCOND (fragp->fr_subtype)
2287
              ? BFD_RELOC_RISCV_JMP : BFD_RELOC_12_PCREL;
2288
      fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
2289
                          4, &exp, FALSE, reloc);
2290
      buf += 4;
2291
      break;
2292
 
2293
    default:
2294
      abort ();
2295
    }
2296
 
2297
done:
2298
  fixp->fx_file = fragp->fr_file;
2299
  fixp->fx_line = fragp->fr_line;
2300
 
2301
  gas_assert (buf == (bfd_byte *)fragp->fr_literal
2302
              + fragp->fr_fix + fragp->fr_var);
2303
 
2304
  fragp->fr_fix += fragp->fr_var;
2305
}
2306
 
2307
/* Relax a machine dependent frag.  This returns the amount by which
2308
   the current size of the frag should change.  */
2309
 
2310
void
2311
md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
2312
                 fragS *fragp)
2313
{
2314
  gas_assert (RELAX_BRANCH_P (fragp->fr_subtype));
2315
  md_convert_frag_branch (fragp);
2316
}
2317
 
2318
void
2319
md_show_usage (FILE *stream)
2320
{
2321
  fprintf (stream, _("\
2322
RISC-V options:\n\
2323
  -m32           assemble RV32 code\n\
2324
  -m64           assemble RV64 code (default)\n\
2325
  -fpic          generate position-independent code\n\
2326
  -fno-pic       don't generate position-independent code (default)\n\
2327
"));
2328
}
2329
 
2330
/* Standard calling conventions leave the CFA at SP on entry.  */
2331
void
2332
riscv_cfi_frame_initial_instructions (void)
2333
{
2334
  cfi_add_CFA_def_cfa_register (X_SP);
2335
}
2336
 
2337
int
2338
tc_riscv_regname_to_dw2regnum (char *regname)
2339
{
2340
  int reg;
2341
 
2342
  if ((reg = reg_lookup_internal (regname, RCLASS_GPR)) >= 0)
2343
    return reg;
2344
 
2345
  if ((reg = reg_lookup_internal (regname, RCLASS_FPR)) >= 0)
2346
    return reg + 32;
2347
 
2348
  as_bad (_("unknown register `%s'"), regname);
2349
  return -1;
2350
}
2351
 
2352
void
2353
riscv_elf_final_processing (void)
2354
{
2355
  elf_elfheader (stdoutput)->e_flags |= elf_flags;
2356
}
2357
 
2358
/* Pseudo-op table.  */
2359
 
2360
static const pseudo_typeS riscv_pseudo_table[] =
2361
{
2362
  /* RISC-V-specific pseudo-ops.  */
2363
  {"option", s_riscv_option, 0},
2364
  {"half", cons, 2},
2365
  {"word", cons, 4},
2366
  {"dword", cons, 8},
2367
  {"dtprelword", s_dtprel, 4},
2368
  {"dtpreldword", s_dtprel, 8},
2369
  {"bss", s_bss, 0},
2370
  {"align", s_align, 0},
2371
  {"p2align", s_align, 0},
2372
  {"balign", s_align, 1},
2373
 
2374
  /* leb128 doesn't work with relaxation; disallow it */
2375
  {"uleb128", s_err, 0},
2376
  {"sleb128", s_err, 0},
2377
 
2378
  { NULL, NULL, 0 },
2379
};
2380
 
2381
void
2382
riscv_pop_insert (void)
2383
{
2384
  extern void pop_insert (const pseudo_typeS *);
2385
 
2386
  pop_insert (riscv_pseudo_table);
2387
}

powered by: WebSVN 2.1.0

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