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