]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-riscv.c
2.41 Release sources
[thirdparty/binutils-gdb.git] / gas / config / tc-riscv.c
CommitLineData
e23eba97 1/* tc-riscv.c -- RISC-V assembler
d87bef3a 2 Copyright (C) 2011-2023 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"
31
1080bf78 32#include "bfd/elfxx-riscv.h"
e23eba97
NC
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
634001bb
TO
45 /* The encoded instruction bits
46 (first bits enough to extract instruction length on a long opcode). */
e23eba97
NC
47 insn_t insn_opcode;
48
634001bb
TO
49 /* The long encoded instruction bits ([0] is non-zero on a long opcode). */
50 char insn_long_opcode[RISCV_MAX_INSN_LEN];
51
e23eba97
NC
52 /* The frag that contains the instruction. */
53 struct frag *frag;
54
55 /* The offset into FRAG of the first instruction byte. */
56 long where;
57
58 /* The relocs associated with the instruction, if any. */
59 fixS *fixp;
60};
61
3d73d29e
NC
62/* All RISC-V CSR belong to one of these classes. */
63enum riscv_csr_class
64{
65 CSR_CLASS_NONE,
66
67 CSR_CLASS_I,
65e4a99a
NC
68 CSR_CLASS_I_32, /* rv32 only */
69 CSR_CLASS_F, /* f-ext only */
70 CSR_CLASS_ZKR, /* zkr only */
71 CSR_CLASS_V, /* rvv only */
c625f4ed
NC
72 CSR_CLASS_DEBUG, /* debug CSR */
73 CSR_CLASS_H, /* hypervisor */
74 CSR_CLASS_H_32, /* hypervisor, rv32 only */
ac8df5a1
CM
75 CSR_CLASS_SMAIA, /* Smaia */
76 CSR_CLASS_SMAIA_32, /* Smaia, rv32 only */
6af47b08 77 CSR_CLASS_SMSTATEEN, /* Smstateen only */
6af47b08 78 CSR_CLASS_SMSTATEEN_32, /* Smstateen RV32 only */
ac8df5a1
CM
79 CSR_CLASS_SSAIA, /* Ssaia */
80 CSR_CLASS_SSAIA_AND_H, /* Ssaia with H */
81 CSR_CLASS_SSAIA_32, /* Ssaia, rv32 only */
82 CSR_CLASS_SSAIA_AND_H_32, /* Ssaia with H, rv32 only */
15253318
TO
83 CSR_CLASS_SSSTATEEN, /* S[ms]stateen only */
84 CSR_CLASS_SSSTATEEN_AND_H, /* S[ms]stateen only (with H) */
85 CSR_CLASS_SSSTATEEN_AND_H_32, /* S[ms]stateen RV32 only (with H) */
713f3708
TO
86 CSR_CLASS_SSCOFPMF, /* Sscofpmf only */
87 CSR_CLASS_SSCOFPMF_32, /* Sscofpmf RV32 only */
766077c1
TO
88 CSR_CLASS_SSTC, /* Sstc only */
89 CSR_CLASS_SSTC_AND_H, /* Sstc only (with H) */
90 CSR_CLASS_SSTC_32, /* Sstc RV32 only */
91 CSR_CLASS_SSTC_AND_H_32, /* Sstc RV32 only (with H) */
3d73d29e
NC
92};
93
94/* This structure holds all restricted conditions for a CSR. */
95struct riscv_csr_extra
96{
97 /* Class to which this CSR belongs. Used to decide whether or
98 not this CSR is legal in the current -march context. */
99 enum riscv_csr_class csr_class;
100
101 /* CSR may have differnet numbers in the previous priv spec. */
102 unsigned address;
103
104 /* Record the CSR is defined/valid in which versions. */
105 enum riscv_spec_class define_version;
106
107 /* Record the CSR is aborted/invalid from which versions. If it isn't
a63375ac 108 aborted in the current version, then it should be PRIV_SPEC_CLASS_DRAFT. */
3d73d29e
NC
109 enum riscv_spec_class abort_version;
110
111 /* The CSR may have more than one setting. */
112 struct riscv_csr_extra *next;
113};
114
e4028336
PN
115/* This structure contains information about errors that occur within the
116 riscv_ip function */
117struct riscv_ip_error
118{
119 /* General error message */
120 const char* msg;
121
122 /* Statement that caused the error */
123 char* statement;
124
125 /* Missing extension that needs to be enabled */
126 const char* missing_ext;
127};
128
e23eba97
NC
129#ifndef DEFAULT_ARCH
130#define DEFAULT_ARCH "riscv64"
131#endif
132
2dc8dd17
JW
133#ifndef DEFAULT_RISCV_ATTR
134#define DEFAULT_RISCV_ATTR 0
135#endif
136
8f595e9b 137/* Let riscv_after_parse_args set the default value according to xlen. */
8f595e9b
NC
138#ifndef DEFAULT_RISCV_ARCH_WITH_EXT
139#define DEFAULT_RISCV_ARCH_WITH_EXT NULL
140#endif
141
dcd709e0 142/* Need to sync the version with RISC-V compiler. */
8f595e9b 143#ifndef DEFAULT_RISCV_ISA_SPEC
aed44286 144#define DEFAULT_RISCV_ISA_SPEC "20191213"
8f595e9b
NC
145#endif
146
147#ifndef DEFAULT_RISCV_PRIV_SPEC
148#define DEFAULT_RISCV_PRIV_SPEC "1.11"
149#endif
150
e23eba97 151static const char default_arch[] = DEFAULT_ARCH;
8f595e9b 152static const char *default_arch_with_ext = DEFAULT_RISCV_ARCH_WITH_EXT;
3d73d29e
NC
153static enum riscv_spec_class default_isa_spec = ISA_SPEC_CLASS_NONE;
154static enum riscv_spec_class default_priv_spec = PRIV_SPEC_CLASS_NONE;
e23eba97 155
dcd709e0
NC
156static unsigned xlen = 0; /* The width of an x-register. */
157static unsigned abi_xlen = 0; /* The width of a pointer in the ABI. */
5b7c81bd 158static bool rve_abi = false;
1942a048
NC
159enum float_abi
160{
6e1605e4
NC
161 FLOAT_ABI_DEFAULT = -1,
162 FLOAT_ABI_SOFT,
163 FLOAT_ABI_SINGLE,
164 FLOAT_ABI_DOUBLE,
165 FLOAT_ABI_QUAD
166};
167static enum float_abi float_abi = FLOAT_ABI_DEFAULT;
e23eba97 168
2922d21d 169#define LOAD_ADDRESS_INSN (abi_xlen == 64 ? "ld" : "lw")
e23eba97
NC
170#define ADD32_INSN (xlen == 64 ? "addiw" : "addi")
171
172static unsigned elf_flags = 0;
173
7a29ee29
JB
174static bool probing_insn_operands;
175
dcd709e0
NC
176/* Set the default_isa_spec. Return 0 if the spec isn't supported.
177 Otherwise, return 1. */
8f595e9b
NC
178
179static int
180riscv_set_default_isa_spec (const char *s)
181{
3d73d29e
NC
182 enum riscv_spec_class class = ISA_SPEC_CLASS_NONE;
183 RISCV_GET_ISA_SPEC_CLASS (s, class);
184 if (class == ISA_SPEC_CLASS_NONE)
8f595e9b 185 {
b800637e
NC
186 as_bad ("unknown default ISA spec `%s' set by "
187 "-misa-spec or --with-isa-spec", s);
8f595e9b
NC
188 return 0;
189 }
190 else
191 default_isa_spec = class;
192 return 1;
193}
194
dcd709e0
NC
195/* Set the default_priv_spec. Find the privileged elf attributes when
196 the input string is NULL. Return 0 if the spec isn't supported.
197 Otherwise, return 1. */
8f595e9b
NC
198
199static int
200riscv_set_default_priv_spec (const char *s)
201{
3d73d29e 202 enum riscv_spec_class class = PRIV_SPEC_CLASS_NONE;
8f595e9b
NC
203 unsigned major, minor, revision;
204 obj_attribute *attr;
8f595e9b 205
3d73d29e
NC
206 RISCV_GET_PRIV_SPEC_CLASS (s, class);
207 if (class != PRIV_SPEC_CLASS_NONE)
8f595e9b
NC
208 {
209 default_priv_spec = class;
210 return 1;
211 }
212
213 if (s != NULL)
214 {
b800637e
NC
215 as_bad (_("unknown default privileged spec `%s' set by "
216 "-mpriv-spec or --with-priv-spec"), s);
8f595e9b
NC
217 return 0;
218 }
219
dcd709e0 220 /* Set the default_priv_spec by the privileged elf attributes. */
8f595e9b
NC
221 attr = elf_known_obj_attributes_proc (stdoutput);
222 major = (unsigned) attr[Tag_RISCV_priv_spec].i;
223 minor = (unsigned) attr[Tag_RISCV_priv_spec_minor].i;
224 revision = (unsigned) attr[Tag_RISCV_priv_spec_revision].i;
3d73d29e
NC
225 /* Version 0.0.0 is the default value and meningless. */
226 if (major == 0 && minor == 0 && revision == 0)
227 return 1;
8f595e9b 228
3d73d29e
NC
229 riscv_get_priv_spec_class_from_numbers (major, minor, revision, &class);
230 if (class != PRIV_SPEC_CLASS_NONE)
231 {
8f595e9b 232 default_priv_spec = class;
8f595e9b
NC
233 return 1;
234 }
235
dcd709e0 236 /* Still can not find the privileged spec class. */
b800637e
NC
237 as_bad (_("unknown default privileged spec `%d.%d.%d' set by "
238 "privileged elf attributes"), major, minor, revision);
8f595e9b
NC
239 return 0;
240}
241
e23eba97 242/* This is the set of options which the .option pseudo-op may modify. */
e23eba97
NC
243struct riscv_set_options
244{
245 int pic; /* Generate position-independent code. */
246 int rvc; /* Generate RVC code. */
45f76423 247 int relax; /* Emit relocs the linker is allowed to relax. */
dcd709e0 248 int arch_attr; /* Emit architecture and privileged elf attributes. */
2ca89224 249 int csr_check; /* Enable the CSR checking. */
e23eba97
NC
250};
251
252static struct riscv_set_options riscv_opts =
253{
dcd709e0
NC
254 0, /* pic */
255 0, /* rvc */
dcd709e0 256 1, /* relax */
2dc8dd17 257 DEFAULT_RISCV_ATTR, /* arch_attr */
dcd709e0 258 0, /* csr_check */
e23eba97
NC
259};
260
437e2ff1
NC
261/* Enable or disable the rvc flags for riscv_opts. Turn on the rvc flag
262 for elf_flags once we have enabled c extension. */
263
e23eba97 264static void
5b7c81bd 265riscv_set_rvc (bool rvc_value)
e23eba97
NC
266{
267 if (rvc_value)
268 elf_flags |= EF_RISCV_RVC;
269
270 riscv_opts.rvc = rvc_value;
271}
272
96462b01
S
273/* Turn on the tso flag for elf_flags once we have enabled ztso extension. */
274
275static void
0242db99 276riscv_set_tso (void)
96462b01
S
277{
278 elf_flags |= EF_RISCV_TSO;
279}
280
f5cb31a8
JB
281/* The linked list hanging off of .subsets_list records all enabled extensions,
282 which are parsed from the architecture string. The architecture string can
283 be set by the -march option, the elf architecture attributes, and the
284 --with-arch configure option. */
f786c359 285static riscv_parse_subset_t riscv_rps_as =
43135d3b 286{
d3ffd7f7
NC
287 NULL, /* subset_list, we will set it later once
288 riscv_opts_stack is created or updated. */
f786c359
NC
289 as_bad, /* error_handler. */
290 &xlen, /* xlen. */
291 &default_isa_spec, /* isa_spec. */
292 true, /* check_unknown_prefixed_ext. */
293};
43135d3b 294
40f1a1a4
NC
295/* Update the architecture string in the subset_list. */
296
297static void
298riscv_reset_subsets_list_arch_str (void)
299{
300 riscv_subset_list_t *subsets = riscv_rps_as.subset_list;
301 if (subsets->arch_str != NULL)
302 free ((void *) subsets->arch_str);
303 subsets->arch_str = riscv_arch_str (xlen, subsets);
304}
305
d3ffd7f7
NC
306/* This structure is used to hold a stack of .option values. */
307struct riscv_option_stack
308{
309 struct riscv_option_stack *next;
310 struct riscv_set_options options;
311 riscv_subset_list_t *subset_list;
312};
313
314static struct riscv_option_stack *riscv_opts_stack = NULL;
315
2922d21d 316/* Set which ISA and extensions are available. */
e23eba97 317
e23eba97 318static void
2922d21d 319riscv_set_arch (const char *s)
e23eba97 320{
c9f27991
NC
321 if (s != NULL && strcmp (s, "") == 0)
322 {
323 as_bad (_("the architecture string of -march and elf architecture "
324 "attributes cannot be empty"));
325 return;
326 }
7f999549 327
f5cb31a8 328 if (riscv_rps_as.subset_list == NULL)
d3ffd7f7 329 {
f5cb31a8
JB
330 riscv_rps_as.subset_list = XNEW (riscv_subset_list_t);
331 riscv_rps_as.subset_list->head = NULL;
332 riscv_rps_as.subset_list->tail = NULL;
40f1a1a4 333 riscv_rps_as.subset_list->arch_str = NULL;
d3ffd7f7 334 }
f5cb31a8 335 riscv_release_subset_list (riscv_rps_as.subset_list);
f786c359 336 riscv_parse_subset (&riscv_rps_as, s);
40f1a1a4 337 riscv_reset_subsets_list_arch_str ();
28b2963f 338
28b2963f 339 riscv_set_rvc (false);
675b9d61 340 if (riscv_subset_supports (&riscv_rps_as, "c"))
28b2963f 341 riscv_set_rvc (true);
96462b01
S
342
343 if (riscv_subset_supports (&riscv_rps_as, "ztso"))
344 riscv_set_tso ();
e23eba97
NC
345}
346
dcd709e0 347/* Indicate -mabi option is explictly set. */
5b7c81bd 348static bool explicit_mabi = false;
6e1605e4 349
437e2ff1
NC
350/* Set the abi information. */
351
6e1605e4 352static void
5b7c81bd 353riscv_set_abi (unsigned new_xlen, enum float_abi new_float_abi, bool rve)
6e1605e4
NC
354{
355 abi_xlen = new_xlen;
356 float_abi = new_float_abi;
357 rve_abi = rve;
358}
359
dcd709e0
NC
360/* If the -mabi option isn't set, then set the abi according to the
361 ISA string. Otherwise, check if there is any conflict. */
6e1605e4
NC
362
363static void
364riscv_set_abi_by_arch (void)
365{
366 if (!explicit_mabi)
367 {
f786c359 368 if (riscv_subset_supports (&riscv_rps_as, "q"))
5b7c81bd 369 riscv_set_abi (xlen, FLOAT_ABI_QUAD, false);
f786c359 370 else if (riscv_subset_supports (&riscv_rps_as, "d"))
5b7c81bd 371 riscv_set_abi (xlen, FLOAT_ABI_DOUBLE, false);
f786c359 372 else if (riscv_subset_supports (&riscv_rps_as, "e"))
5d0ed830 373 riscv_set_abi (xlen, FLOAT_ABI_SOFT, true);
6e1605e4 374 else
5b7c81bd 375 riscv_set_abi (xlen, FLOAT_ABI_SOFT, false);
6e1605e4
NC
376 }
377 else
378 {
379 gas_assert (abi_xlen != 0 && xlen != 0 && float_abi != FLOAT_ABI_DEFAULT);
380 if (abi_xlen > xlen)
381 as_bad ("can't have %d-bit ABI on %d-bit ISA", abi_xlen, xlen);
382 else if (abi_xlen < xlen)
383 as_bad ("%d-bit ABI not yet supported on %d-bit ISA", abi_xlen, xlen);
5d0ed830 384
f786c359 385 if (riscv_subset_supports (&riscv_rps_as, "e") && !rve_abi)
5d0ed830
NC
386 as_bad ("only the ilp32e ABI is supported for e extension");
387
388 if (float_abi == FLOAT_ABI_SINGLE
f786c359 389 && !riscv_subset_supports (&riscv_rps_as, "f"))
5d0ed830
NC
390 as_bad ("ilp32f/lp64f ABI can't be used when f extension "
391 "isn't supported");
392 else if (float_abi == FLOAT_ABI_DOUBLE
f786c359 393 && !riscv_subset_supports (&riscv_rps_as, "d"))
5d0ed830
NC
394 as_bad ("ilp32d/lp64d ABI can't be used when d extension "
395 "isn't supported");
396 else if (float_abi == FLOAT_ABI_QUAD
f786c359 397 && !riscv_subset_supports (&riscv_rps_as, "q"))
5d0ed830
NC
398 as_bad ("ilp32q/lp64q ABI can't be used when q extension "
399 "isn't supported");
6e1605e4
NC
400 }
401
402 /* Update the EF_RISCV_FLOAT_ABI field of elf_flags. */
403 elf_flags &= ~EF_RISCV_FLOAT_ABI;
404 elf_flags |= float_abi << 1;
405
406 if (rve_abi)
407 elf_flags |= EF_RISCV_RVE;
408}
409
e23eba97 410/* Handle of the OPCODE hash table. */
629310ab 411static htab_t op_hash = NULL;
e23eba97 412
0e35537d 413/* Handle of the type of .insn hash table. */
629310ab 414static htab_t insn_type_hash = NULL;
0e35537d 415
e23eba97 416/* This array holds the chars that always start a comment. If the
dcd709e0 417 pre-processor is disabled, these aren't very useful. */
e23eba97
NC
418const char comment_chars[] = "#";
419
420/* This array holds the chars that only start a comment at the beginning of
421 a line. If the line seems to have the form '# 123 filename'
dcd709e0
NC
422 .line and .file directives will appear in the pre-processed output
423
424 Note that input_file.c hand checks for '#' at the beginning of the
e23eba97 425 first line of the input file. This is because the compiler outputs
dcd709e0
NC
426 #NO_APP at the beginning of its output.
427
428 Also note that C style comments are always supported. */
e23eba97
NC
429const char line_comment_chars[] = "#";
430
431/* This array holds machine specific line separator characters. */
432const char line_separator_chars[] = ";";
433
dcd709e0 434/* Chars that can be used to separate mant from exp in floating point nums. */
e23eba97
NC
435const char EXP_CHARS[] = "eE";
436
dcd709e0
NC
437/* Chars that mean this number is a floating point constant.
438 As in 0f12.456 or 0d1.2345e12. */
035784e3 439const char FLT_CHARS[] = "rRsSfFdDxXpPhH";
e23eba97 440
2dc8dd17 441/* Indicate we are already assemble any instructions or not. */
5b7c81bd 442static bool start_assemble = false;
2dc8dd17 443
f9a6a8f0 444/* Indicate ELF attributes are explicitly set. */
5b7c81bd 445static bool explicit_attr = false;
2dc8dd17 446
f9a6a8f0 447/* Indicate CSR or priv instructions are explicitly used. */
5b7c81bd 448static bool explicit_priv_attr = false;
3fc6c3dc 449
6eb099ae 450static char *expr_parse_end;
437e2ff1 451
e23eba97
NC
452/* Macros for encoding relaxation state for RVC branches and far jumps. */
453#define RELAX_BRANCH_ENCODE(uncond, rvc, length) \
454 ((relax_substateT) \
455 (0xc0000000 \
456 | ((uncond) ? 1 : 0) \
457 | ((rvc) ? 2 : 0) \
458 | ((length) << 2)))
459#define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
460#define RELAX_BRANCH_LENGTH(i) (((i) >> 2) & 0xF)
461#define RELAX_BRANCH_RVC(i) (((i) & 2) != 0)
462#define RELAX_BRANCH_UNCOND(i) (((i) & 1) != 0)
463
464/* Is the given value a sign-extended 32-bit value? */
465#define IS_SEXT_32BIT_NUM(x) \
466 (((x) &~ (offsetT) 0x7fffffff) == 0 \
467 || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
468
469/* Is the given value a zero-extended 32-bit value? Or a negated one? */
470#define IS_ZEXT_32BIT_NUM(x) \
471 (((x) &~ (offsetT) 0xffffffff) == 0 \
472 || (((x) &~ (offsetT) 0xffffffff) == ~ (offsetT) 0xffffffff))
473
474/* Change INSN's opcode so that the operand given by FIELD has value VALUE.
475 INSN is a riscv_cl_insn structure and VALUE is evaluated exactly once. */
476#define INSERT_OPERAND(FIELD, INSN, VALUE) \
477 INSERT_BITS ((INSN).insn_opcode, VALUE, OP_MASK_##FIELD, OP_SH_##FIELD)
478
8b7419c4
CM
479#define INSERT_IMM(n, s, INSN, VALUE) \
480 INSERT_BITS ((INSN).insn_opcode, VALUE, (1ULL<<n) - 1, s)
481
e23eba97
NC
482/* Determine if an instruction matches an opcode. */
483#define OPCODE_MATCHES(OPCODE, OP) \
484 (((OPCODE) & MASK_##OP) == MATCH_##OP)
485
9b9b1092
NC
486/* Create a new mapping symbol for the transition to STATE. */
487
488static void
489make_mapping_symbol (enum riscv_seg_mstate state,
490 valueT value,
40f1a1a4 491 fragS *frag,
d918451a
NC
492 const char *arch_str,
493 bool odd_data_padding)
9b9b1092
NC
494{
495 const char *name;
615d4f41 496 char *buff = NULL;
9b9b1092
NC
497 switch (state)
498 {
499 case MAP_DATA:
500 name = "$d";
501 break;
502 case MAP_INSN:
d918451a 503 if (arch_str != NULL)
40f1a1a4 504 {
d918451a 505 size_t size = strlen (arch_str) + 3; /* "$x" + '\0' */
40f1a1a4 506 buff = xmalloc (size);
d918451a 507 snprintf (buff, size, "$x%s", arch_str);
40f1a1a4
NC
508 name = buff;
509 }
510 else
511 name = "$x";
9b9b1092
NC
512 break;
513 default:
514 abort ();
515 }
516
517 symbolS *symbol = symbol_new (name, now_seg, frag, value);
518 symbol_get_bfdsym (symbol)->flags |= (BSF_NO_FLAGS | BSF_LOCAL);
d918451a 519 if (arch_str != NULL)
40f1a1a4
NC
520 {
521 /* Store current $x+arch into tc_segment_info. */
522 seg_info (now_seg)->tc_segment_info_data.arch_map_symbol = symbol;
523 xfree ((void *) buff);
524 }
9b9b1092
NC
525
526 /* If .fill or other data filling directive generates zero sized data,
40f1a1a4
NC
527 then mapping symbol for the following code will have the same value.
528
529 Please see gas/testsuite/gas/riscv/mapping.s: .text.zero.fill.first
530 and .text.zero.fill.last. */
531 symbolS *first = frag->tc_frag_data.first_map_symbol;
532 symbolS *last = frag->tc_frag_data.last_map_symbol;
d918451a 533 symbolS *removed = NULL;
9b9b1092
NC
534 if (value == 0)
535 {
40f1a1a4 536 if (first != NULL)
9b9b1092 537 {
40f1a1a4
NC
538 know (S_GET_VALUE (first) == S_GET_VALUE (symbol)
539 && first == last);
9b9b1092 540 /* Remove the old one. */
d918451a 541 removed = first;
9b9b1092
NC
542 }
543 frag->tc_frag_data.first_map_symbol = symbol;
544 }
40f1a1a4 545 else if (last != NULL)
9b9b1092
NC
546 {
547 /* The mapping symbols should be added in offset order. */
40f1a1a4 548 know (S_GET_VALUE (last) <= S_GET_VALUE (symbol));
9b9b1092 549 /* Remove the old one. */
40f1a1a4 550 if (S_GET_VALUE (last) == S_GET_VALUE (symbol))
d918451a 551 removed = last;
9b9b1092
NC
552 }
553 frag->tc_frag_data.last_map_symbol = symbol;
d918451a
NC
554
555 if (removed == NULL)
556 return;
557
558 if (odd_data_padding)
559 {
560 /* If the removed mapping symbol is $x+arch, then add it back to
561 the next $x. */
562 const char *str = strncmp (S_GET_NAME (removed), "$xrv", 4) == 0
563 ? S_GET_NAME (removed) + 2 : NULL;
564 make_mapping_symbol (MAP_INSN, frag->fr_fix + 1, frag, str,
565 false/* odd_data_padding */);
566 }
567 symbol_remove (removed, &symbol_rootP, &symbol_lastP);
9b9b1092
NC
568}
569
570/* Set the mapping state for frag_now. */
571
572void
573riscv_mapping_state (enum riscv_seg_mstate to_state,
40f1a1a4 574 int max_chars,
3190ebcb 575 bool fr_align_code)
9b9b1092
NC
576{
577 enum riscv_seg_mstate from_state =
578 seg_info (now_seg)->tc_segment_info_data.map_state;
40f1a1a4 579 bool reset_seg_arch_str = false;
9b9b1092
NC
580
581 if (!SEG_NORMAL (now_seg)
40f1a1a4 582 /* For now we only add the mapping symbols to text sections.
9b9b1092
NC
583 Therefore, the dis-assembler only show the actual contents
584 distribution for text. Other sections will be shown as
585 data without the details. */
586 || !subseg_text_p (now_seg))
587 return;
588
589 /* The mapping symbol should be emitted if not in the right
40f1a1a4
NC
590 mapping state. */
591 symbolS *seg_arch_symbol =
592 seg_info (now_seg)->tc_segment_info_data.arch_map_symbol;
593 if (to_state == MAP_INSN && seg_arch_symbol == 0)
594 {
595 /* Always add $x+arch at the first instruction of section. */
596 reset_seg_arch_str = true;
597 }
598 else if (seg_arch_symbol != 0
599 && to_state == MAP_INSN
3190ebcb 600 && !fr_align_code
40f1a1a4
NC
601 && strcmp (riscv_rps_as.subset_list->arch_str,
602 S_GET_NAME (seg_arch_symbol) + 2) != 0)
603 {
604 reset_seg_arch_str = true;
40f1a1a4
NC
605 }
606 else if (from_state == to_state)
9b9b1092
NC
607 return;
608
609 valueT value = (valueT) (frag_now_fix () - max_chars);
610 seg_info (now_seg)->tc_segment_info_data.map_state = to_state;
d918451a
NC
611 const char *arch_str = reset_seg_arch_str
612 ? riscv_rps_as.subset_list->arch_str : NULL;
613 make_mapping_symbol (to_state, value, frag_now, arch_str,
614 false/* odd_data_padding */);
9b9b1092
NC
615}
616
617/* Add the odd bytes of paddings for riscv_handle_align. */
618
619static void
620riscv_add_odd_padding_symbol (fragS *frag)
621{
622 /* If there was already a mapping symbol, it should be
40f1a1a4
NC
623 removed in the make_mapping_symbol.
624
d918451a
NC
625 Please see gas/testsuite/gas/riscv/mapping.s: .text.odd.align.*. */
626 make_mapping_symbol (MAP_DATA, frag->fr_fix, frag,
627 NULL/* arch_str */, true/* odd_data_padding */);
9b9b1092
NC
628}
629
630/* Remove any excess mapping symbols generated for alignment frags in
631 SEC. We may have created a mapping symbol before a zero byte
632 alignment; remove it if there's a mapping symbol after the
633 alignment. */
634
635static void
636riscv_check_mapping_symbols (bfd *abfd ATTRIBUTE_UNUSED,
637 asection *sec,
638 void *dummy ATTRIBUTE_UNUSED)
639{
640 segment_info_type *seginfo = seg_info (sec);
641 fragS *fragp;
642
643 if (seginfo == NULL || seginfo->frchainP == NULL)
644 return;
645
646 for (fragp = seginfo->frchainP->frch_root;
647 fragp != NULL;
648 fragp = fragp->fr_next)
649 {
650 symbolS *last = fragp->tc_frag_data.last_map_symbol;
651 fragS *next = fragp->fr_next;
652
653 if (last == NULL || next == NULL)
654 continue;
655
656 /* Check the last mapping symbol if it is at the boundary of
657 fragment. */
658 if (S_GET_VALUE (last) < next->fr_address)
659 continue;
660 know (S_GET_VALUE (last) == next->fr_address);
661
662 do
663 {
40f1a1a4
NC
664 symbolS *next_first = next->tc_frag_data.first_map_symbol;
665 if (next_first != NULL)
9b9b1092
NC
666 {
667 /* The last mapping symbol overlaps with another one
40f1a1a4
NC
668 which at the start of the next frag.
669
670 Please see the gas/testsuite/gas/riscv/mapping.s:
671 .text.zero.fill.align.A and .text.zero.fill.align.B. */
d918451a
NC
672 know (S_GET_VALUE (last) == S_GET_VALUE (next_first));
673 symbolS *removed = last;
674 if (strncmp (S_GET_NAME (last), "$xrv", 4) == 0
675 && strcmp (S_GET_NAME (next_first), "$x") == 0)
676 removed = next_first;
677 symbol_remove (removed, &symbol_rootP, &symbol_lastP);
9b9b1092
NC
678 break;
679 }
680
681 if (next->fr_next == NULL)
682 {
40f1a1a4
NC
683 /* The last mapping symbol is at the end of the section.
684
685 Please see the gas/testsuite/gas/riscv/mapping.s:
686 .text.last.section. */
9b9b1092
NC
687 know (next->fr_fix == 0 && next->fr_var == 0);
688 symbol_remove (last, &symbol_rootP, &symbol_lastP);
689 break;
690 }
691
692 /* Since we may have empty frags without any mapping symbols,
693 keep looking until the non-empty frag. */
694 if (next->fr_address != next->fr_next->fr_address)
695 break;
696
697 next = next->fr_next;
698 }
699 while (next != NULL);
700 }
701}
702
e23eba97
NC
703/* The default target format to use. */
704
705const char *
706riscv_target_format (void)
707{
fbc09e7a
MC
708 if (target_big_endian)
709 return xlen == 64 ? "elf64-bigriscv" : "elf32-bigriscv";
710 else
711 return xlen == 64 ? "elf64-littleriscv" : "elf32-littleriscv";
e23eba97
NC
712}
713
714/* Return the length of instruction INSN. */
715
716static inline unsigned int
717insn_length (const struct riscv_cl_insn *insn)
718{
719 return riscv_insn_length (insn->insn_opcode);
720}
721
722/* Initialise INSN from opcode entry MO. Leave its position unspecified. */
723
724static void
725create_insn (struct riscv_cl_insn *insn, const struct riscv_opcode *mo)
726{
727 insn->insn_mo = mo;
728 insn->insn_opcode = mo->match;
634001bb 729 insn->insn_long_opcode[0] = 0;
e23eba97
NC
730 insn->frag = NULL;
731 insn->where = 0;
732 insn->fixp = NULL;
733}
734
735/* Install INSN at the location specified by its "frag" and "where" fields. */
736
737static void
738install_insn (const struct riscv_cl_insn *insn)
739{
740 char *f = insn->frag->fr_literal + insn->where;
634001bb
TO
741 if (insn->insn_long_opcode[0] != 0)
742 memcpy (f, insn->insn_long_opcode, insn_length (insn));
743 else
744 number_to_chars_littleendian (f, insn->insn_opcode, insn_length (insn));
e23eba97
NC
745}
746
747/* Move INSN to offset WHERE in FRAG. Adjust the fixups accordingly
748 and install the opcode in the new location. */
749
750static void
751move_insn (struct riscv_cl_insn *insn, fragS *frag, long where)
752{
753 insn->frag = frag;
754 insn->where = where;
755 if (insn->fixp != NULL)
756 {
757 insn->fixp->fx_frag = frag;
758 insn->fixp->fx_where = where;
759 }
760 install_insn (insn);
761}
762
763/* Add INSN to the end of the output. */
764
765static void
766add_fixed_insn (struct riscv_cl_insn *insn)
767{
768 char *f = frag_more (insn_length (insn));
769 move_insn (insn, frag_now, f - frag_now->fr_literal);
770}
771
772static void
773add_relaxed_insn (struct riscv_cl_insn *insn, int max_chars, int var,
774 relax_substateT subtype, symbolS *symbol, offsetT offset)
775{
776 frag_grow (max_chars);
777 move_insn (insn, frag_now, frag_more (0) - frag_now->fr_literal);
778 frag_var (rs_machine_dependent, max_chars, var,
779 subtype, symbol, offset, NULL);
780}
781
782/* Compute the length of a branch sequence, and adjust the stored length
783 accordingly. If FRAGP is NULL, the worst-case length is returned. */
784
785static unsigned
786relaxed_branch_length (fragS *fragp, asection *sec, int update)
787{
788 int jump, rvc, length = 8;
789
790 if (!fragp)
791 return length;
792
793 jump = RELAX_BRANCH_UNCOND (fragp->fr_subtype);
794 rvc = RELAX_BRANCH_RVC (fragp->fr_subtype);
795 length = RELAX_BRANCH_LENGTH (fragp->fr_subtype);
796
797 /* Assume jumps are in range; the linker will catch any that aren't. */
798 length = jump ? 4 : 8;
799
800 if (fragp->fr_symbol != NULL
801 && S_IS_DEFINED (fragp->fr_symbol)
01156111 802 && !S_IS_WEAK (fragp->fr_symbol)
e23eba97
NC
803 && sec == S_GET_SEGMENT (fragp->fr_symbol))
804 {
805 offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
806 bfd_vma rvc_range = jump ? RVC_JUMP_REACH : RVC_BRANCH_REACH;
807 val -= fragp->fr_address + fragp->fr_fix;
808
809 if (rvc && (bfd_vma)(val + rvc_range/2) < rvc_range)
810 length = 2;
811 else if ((bfd_vma)(val + RISCV_BRANCH_REACH/2) < RISCV_BRANCH_REACH)
812 length = 4;
813 else if (!jump && rvc)
814 length = 6;
815 }
816
817 if (update)
818 fragp->fr_subtype = RELAX_BRANCH_ENCODE (jump, rvc, length);
819
820 return length;
821}
822
0e35537d
JW
823/* Information about an opcode name, mnemonics and its value. */
824struct opcode_name_t
825{
826 const char *name;
827 unsigned int val;
828};
829
830/* List for all supported opcode name. */
831static const struct opcode_name_t opcode_name_list[] =
832{
833 {"C0", 0x0},
834 {"C1", 0x1},
835 {"C2", 0x2},
836
837 {"LOAD", 0x03},
838 {"LOAD_FP", 0x07},
839 {"CUSTOM_0", 0x0b},
840 {"MISC_MEM", 0x0f},
841 {"OP_IMM", 0x13},
842 {"AUIPC", 0x17},
843 {"OP_IMM_32", 0x1b},
844 /* 48b 0x1f. */
845
846 {"STORE", 0x23},
847 {"STORE_FP", 0x27},
848 {"CUSTOM_1", 0x2b},
849 {"AMO", 0x2f},
850 {"OP", 0x33},
851 {"LUI", 0x37},
852 {"OP_32", 0x3b},
853 /* 64b 0x3f. */
854
855 {"MADD", 0x43},
856 {"MSUB", 0x47},
857 {"NMADD", 0x4f},
858 {"NMSUB", 0x4b},
859 {"OP_FP", 0x53},
f8ad70a1 860 {"OP_V", 0x57},
0e35537d
JW
861 {"CUSTOM_2", 0x5b},
862 /* 48b 0x5f. */
863
864 {"BRANCH", 0x63},
865 {"JALR", 0x67},
866 /*reserved 0x5b. */
867 {"JAL", 0x6f},
868 {"SYSTEM", 0x73},
869 /*reserved 0x77. */
870 {"CUSTOM_3", 0x7b},
871 /* >80b 0x7f. */
872
873 {NULL, 0}
874};
875
876/* Hash table for lookup opcode name. */
629310ab 877static htab_t opcode_names_hash = NULL;
0e35537d
JW
878
879/* Initialization for hash table of opcode name. */
dcd709e0 880
0e35537d
JW
881static void
882init_opcode_names_hash (void)
883{
0e35537d
JW
884 const struct opcode_name_t *opcode;
885
886 for (opcode = &opcode_name_list[0]; opcode->name != NULL; ++opcode)
fe0e921f 887 if (str_hash_insert (opcode_names_hash, opcode->name, opcode, 0) != NULL)
b800637e 888 as_fatal (_("internal: duplicate %s"), opcode->name);
0e35537d
JW
889}
890
dcd709e0
NC
891/* Find `s` is a valid opcode name or not, return the opcode name info
892 if found. */
893
0e35537d
JW
894static const struct opcode_name_t *
895opcode_name_lookup (char **s)
896{
897 char *e;
898 char save_c;
899 struct opcode_name_t *o;
900
901 /* Find end of name. */
902 e = *s;
903 if (is_name_beginner (*e))
904 ++e;
905 while (is_part_of_name (*e))
906 ++e;
907
908 /* Terminate name. */
909 save_c = *e;
910 *e = '\0';
911
629310ab 912 o = (struct opcode_name_t *) str_hash_find (opcode_names_hash, *s);
0e35537d
JW
913
914 /* Advance to next token if one was recognized. */
915 if (o)
916 *s = e;
917
918 *e = save_c;
6eb099ae 919 expr_parse_end = e;
0e35537d
JW
920
921 return o;
922}
923
437e2ff1 924/* All RISC-V registers belong to one of these classes. */
e23eba97
NC
925enum reg_class
926{
927 RCLASS_GPR,
928 RCLASS_FPR,
65e4a99a
NC
929 RCLASS_VECR,
930 RCLASS_VECM,
8f595e9b
NC
931 RCLASS_MAX,
932
933 RCLASS_CSR
e23eba97
NC
934};
935
629310ab
ML
936static htab_t reg_names_hash = NULL;
937static htab_t csr_extra_hash = NULL;
e23eba97
NC
938
939#define ENCODE_REG_HASH(cls, n) \
940 ((void *)(uintptr_t)((n) * RCLASS_MAX + (cls) + 1))
941#define DECODE_REG_CLASS(hash) (((uintptr_t)(hash) - 1) % RCLASS_MAX)
942#define DECODE_REG_NUM(hash) (((uintptr_t)(hash) - 1) / RCLASS_MAX)
943
944static void
945hash_reg_name (enum reg_class class, const char *name, unsigned n)
946{
947 void *hash = ENCODE_REG_HASH (class, n);
fe0e921f 948 if (str_hash_insert (reg_names_hash, name, hash, 0) != NULL)
b800637e 949 as_fatal (_("internal: duplicate %s"), name);
e23eba97
NC
950}
951
952static void
953hash_reg_names (enum reg_class class, const char * const names[], unsigned n)
954{
955 unsigned i;
956
957 for (i = 0; i < n; i++)
958 hash_reg_name (class, names[i], i);
959}
960
8f595e9b 961/* Init hash table csr_extra_hash to handle CSR. */
dcd709e0 962
8f595e9b
NC
963static void
964riscv_init_csr_hash (const char *name,
3d73d29e
NC
965 unsigned address,
966 enum riscv_csr_class class,
967 enum riscv_spec_class define_version,
968 enum riscv_spec_class abort_version)
8f595e9b
NC
969{
970 struct riscv_csr_extra *entry, *pre_entry;
5b7c81bd 971 bool need_enrty = true;
8f595e9b
NC
972
973 pre_entry = NULL;
629310ab 974 entry = (struct riscv_csr_extra *) str_hash_find (csr_extra_hash, name);
8f595e9b
NC
975 while (need_enrty && entry != NULL)
976 {
977 if (entry->csr_class == class
1942a048
NC
978 && entry->address == address
979 && entry->define_version == define_version
980 && entry->abort_version == abort_version)
5b7c81bd 981 need_enrty = false;
8f595e9b
NC
982 pre_entry = entry;
983 entry = entry->next;
984 }
1942a048 985
dcd709e0 986 /* Duplicate CSR. */
8f595e9b
NC
987 if (!need_enrty)
988 return;
bd0cf5a6 989
7bfc4db2 990 entry = notes_alloc (sizeof (*entry));
8f595e9b
NC
991 entry->csr_class = class;
992 entry->address = address;
993 entry->define_version = define_version;
994 entry->abort_version = abort_version;
5c505568 995 entry->next = NULL;
8f595e9b 996
8f595e9b 997 if (pre_entry == NULL)
fe0e921f 998 str_hash_insert (csr_extra_hash, name, entry, 0);
8f595e9b
NC
999 else
1000 pre_entry->next = entry;
1001}
bd0cf5a6 1002
dcd709e0
NC
1003/* Return the CSR address after checking the ISA dependency and
1004 the privileged spec version.
1005
1006 There are one warning and two errors for CSR,
1007
1008 Invalid CSR: the CSR was defined, but isn't allowed for the current ISA
1009 or the privileged spec, report warning only if -mcsr-check is set.
1010 Unknown CSR: the CSR has never been defined, report error.
1011 Improper CSR: the CSR number over the range (> 0xfff), report error. */
bd0cf5a6 1012
08ccfccf
NC
1013static unsigned int
1014riscv_csr_address (const char *csr_name,
1015 struct riscv_csr_extra *entry)
bd0cf5a6 1016{
08ccfccf
NC
1017 struct riscv_csr_extra *saved_entry = entry;
1018 enum riscv_csr_class csr_class = entry->csr_class;
df0a549e 1019 bool need_check_version = false;
39590abd
TO
1020 bool is_rv32_only = false;
1021 bool is_h_required = false;
df0a549e 1022 const char* extension = NULL;
8f595e9b 1023
8f595e9b 1024 switch (csr_class)
bd0cf5a6 1025 {
08ccfccf 1026 case CSR_CLASS_I_32:
39590abd 1027 is_rv32_only = true;
df0a549e
PN
1028 /* Fall through. */
1029 case CSR_CLASS_I:
1030 need_check_version = true;
1031 extension = "i";
08ccfccf 1032 break;
c625f4ed 1033 case CSR_CLASS_H_32:
39590abd 1034 is_rv32_only = true;
c625f4ed
NC
1035 /* Fall through. */
1036 case CSR_CLASS_H:
1037 extension = "h";
1038 break;
8f595e9b 1039 case CSR_CLASS_F:
df0a549e 1040 extension = "f";
8f595e9b 1041 break;
3d1cafa0 1042 case CSR_CLASS_ZKR:
df0a549e 1043 extension = "zkr";
3d1cafa0 1044 break;
65e4a99a 1045 case CSR_CLASS_V:
1daabcc7 1046 extension = "zve32x";
65e4a99a 1047 break;
ac8df5a1
CM
1048 case CSR_CLASS_SMAIA_32:
1049 is_rv32_only = true;
1050 /* Fall through. */
1051 case CSR_CLASS_SMAIA:
1052 extension = "smaia";
1053 break;
6af47b08 1054 case CSR_CLASS_SMSTATEEN_32:
c509db05
TO
1055 is_rv32_only = true;
1056 /* Fall through. */
1057 case CSR_CLASS_SMSTATEEN:
6af47b08
TO
1058 extension = "smstateen";
1059 break;
ac8df5a1
CM
1060 case CSR_CLASS_SSAIA:
1061 case CSR_CLASS_SSAIA_AND_H:
1062 case CSR_CLASS_SSAIA_32:
1063 case CSR_CLASS_SSAIA_AND_H_32:
1064 is_rv32_only = (csr_class == CSR_CLASS_SSAIA_32
1065 || csr_class == CSR_CLASS_SSAIA_AND_H_32);
1066 is_h_required = (csr_class == CSR_CLASS_SSAIA_AND_H
1067 || csr_class == CSR_CLASS_SSAIA_AND_H_32);
1068 extension = "ssaia";
1069 break;
15253318 1070 case CSR_CLASS_SSSTATEEN_AND_H_32:
c509db05
TO
1071 is_rv32_only = true;
1072 /* Fall through. */
1073 case CSR_CLASS_SSSTATEEN_AND_H:
1074 is_h_required = true;
1075 /* Fall through. */
1076 case CSR_CLASS_SSSTATEEN:
15253318
TO
1077 extension = "ssstateen";
1078 break;
713f3708
TO
1079 case CSR_CLASS_SSCOFPMF_32:
1080 is_rv32_only = true;
1081 /* Fall through. */
1082 case CSR_CLASS_SSCOFPMF:
1083 extension = "sscofpmf";
1084 break;
766077c1
TO
1085 case CSR_CLASS_SSTC:
1086 case CSR_CLASS_SSTC_AND_H:
1087 case CSR_CLASS_SSTC_32:
1088 case CSR_CLASS_SSTC_AND_H_32:
1089 is_rv32_only = (csr_class == CSR_CLASS_SSTC_32
1090 || csr_class == CSR_CLASS_SSTC_AND_H_32);
1091 is_h_required = (csr_class == CSR_CLASS_SSTC_AND_H
1092 || csr_class == CSR_CLASS_SSTC_AND_H_32);
1093 extension = "sstc";
1094 break;
08ccfccf 1095 case CSR_CLASS_DEBUG:
8f595e9b
NC
1096 break;
1097 default:
1098 as_bad (_("internal: bad RISC-V CSR class (0x%x)"), csr_class);
bd0cf5a6
NC
1099 }
1100
df0a549e
PN
1101 if (riscv_opts.csr_check)
1102 {
39590abd 1103 if (is_rv32_only && xlen != 32)
df0a549e 1104 as_warn (_("invalid CSR `%s', needs rv32i extension"), csr_name);
39590abd
TO
1105 if (is_h_required && !riscv_subset_supports (&riscv_rps_as, "h"))
1106 as_warn (_("invalid CSR `%s', needs `h' extension"), csr_name);
df0a549e
PN
1107
1108 if (extension != NULL
1109 && !riscv_subset_supports (&riscv_rps_as, extension))
1110 as_warn (_("invalid CSR `%s', needs `%s' extension"),
1111 csr_name, extension);
1112 }
8f595e9b
NC
1113
1114 while (entry != NULL)
bd0cf5a6 1115 {
08ccfccf
NC
1116 if (!need_check_version
1117 || (default_priv_spec >= entry->define_version
1118 && default_priv_spec < entry->abort_version))
8f595e9b 1119 {
dcd709e0 1120 /* Find the CSR according to the specific version. */
08ccfccf 1121 return entry->address;
8f595e9b
NC
1122 }
1123 entry = entry->next;
1124 }
bd0cf5a6 1125
dcd709e0
NC
1126 /* Can not find the CSR address from the chosen privileged version,
1127 so use the newly defined value. */
8f595e9b
NC
1128 if (riscv_opts.csr_check)
1129 {
3d73d29e
NC
1130 const char *priv_name = NULL;
1131 RISCV_GET_PRIV_SPEC_NAME (priv_name, default_priv_spec);
8f595e9b 1132 if (priv_name != NULL)
b800637e 1133 as_warn (_("invalid CSR `%s' for the privileged spec `%s'"),
8f595e9b 1134 csr_name, priv_name);
bd0cf5a6 1135 }
08ccfccf
NC
1136
1137 return saved_entry->address;
bd0cf5a6
NC
1138}
1139
dcd709e0
NC
1140/* Return -1 if the CSR has never been defined. Otherwise, return
1141 the address. */
bd0cf5a6 1142
8f595e9b 1143static unsigned int
bd0cf5a6
NC
1144reg_csr_lookup_internal (const char *s)
1145{
1146 struct riscv_csr_extra *r =
629310ab 1147 (struct riscv_csr_extra *) str_hash_find (csr_extra_hash, s);
bd0cf5a6
NC
1148
1149 if (r == NULL)
8f595e9b 1150 return -1U;
bd0cf5a6 1151
08ccfccf 1152 return riscv_csr_address (s, r);
bd0cf5a6
NC
1153}
1154
e23eba97
NC
1155static unsigned int
1156reg_lookup_internal (const char *s, enum reg_class class)
1157{
8f595e9b
NC
1158 void *r;
1159
1160 if (class == RCLASS_CSR)
1161 return reg_csr_lookup_internal (s);
e23eba97 1162
629310ab 1163 r = str_hash_find (reg_names_hash, s);
e23eba97
NC
1164 if (r == NULL || DECODE_REG_CLASS (r) != class)
1165 return -1;
7f999549 1166
f786c359 1167 if (riscv_subset_supports (&riscv_rps_as, "e")
edc77c59
NC
1168 && class == RCLASS_GPR
1169 && DECODE_REG_NUM (r) > 15)
7f999549
JW
1170 return -1;
1171
e23eba97
NC
1172 return DECODE_REG_NUM (r);
1173}
1174
5b7c81bd 1175static bool
e23eba97
NC
1176reg_lookup (char **s, enum reg_class class, unsigned int *regnop)
1177{
1178 char *e;
1179 char save_c;
1180 int reg = -1;
1181
1182 /* Find end of name. */
1183 e = *s;
1184 if (is_name_beginner (*e))
1185 ++e;
1186 while (is_part_of_name (*e))
1187 ++e;
1188
1189 /* Terminate name. */
1190 save_c = *e;
1191 *e = '\0';
1192
1193 /* Look for the register. Advance to next token if one was recognized. */
1194 if ((reg = reg_lookup_internal (*s, class)) >= 0)
1195 *s = e;
1196
1197 *e = save_c;
1198 if (regnop)
1199 *regnop = reg;
1200 return reg >= 0;
1201}
1202
5b7c81bd 1203static bool
e23eba97
NC
1204arg_lookup (char **s, const char *const *array, size_t size, unsigned *regnop)
1205{
1206 const char *p = strchr (*s, ',');
1207 size_t i, len = p ? (size_t)(p - *s) : strlen (*s);
1208
bfb218e3 1209 if (len == 0)
5b7c81bd 1210 return false;
bfb218e3 1211
e23eba97 1212 for (i = 0; i < size; i++)
207cc92d
LX
1213 if (array[i] != NULL && strncmp (array[i], *s, len) == 0
1214 && array[i][len] == '\0')
e23eba97
NC
1215 {
1216 *regnop = i;
1217 *s += len;
5b7c81bd 1218 return true;
e23eba97
NC
1219 }
1220
5b7c81bd 1221 return false;
e23eba97
NC
1222}
1223
1f3fc45b
CM
1224static bool
1225flt_lookup (float f, const float *array, size_t size, unsigned *regnop)
1226{
1227 size_t i;
1228
1229 for (i = 0; i < size; i++)
1230 if (array[i] == f)
1231 {
1232 *regnop = i;
1233 return true;
1234 }
1235
1236 return false;
1237}
1238
437e2ff1 1239#define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift)))
8b7419c4
CM
1240#define USE_IMM(n, s) \
1241 (used_bits |= ((insn_t)((1ull<<n)-1) << (s)))
437e2ff1 1242
e23eba97
NC
1243/* For consistency checking, verify that all bits are specified either
1244 by the match/mask part of the instruction definition, or by the
83029f7f
TO
1245 operand list. The `length` could be the actual instruction length or
1246 0 for auto-detection. */
0e35537d 1247
5b7c81bd 1248static bool
0e35537d 1249validate_riscv_insn (const struct riscv_opcode *opc, int length)
e23eba97 1250{
437e2ff1 1251 const char *oparg, *opargStart;
e23eba97 1252 insn_t used_bits = opc->mask;
0e35537d
JW
1253 int insn_width;
1254 insn_t required_bits;
1255
1256 if (length == 0)
83029f7f
TO
1257 length = riscv_insn_length (opc->match);
1258 /* We don't support instructions longer than 64-bits yet. */
1259 if (length > 8)
1260 length = 8;
1261 insn_width = 8 * length;
0e35537d 1262
83029f7f 1263 required_bits = ((insn_t)~0ULL) >> (64 - insn_width);
e23eba97
NC
1264
1265 if ((used_bits & opc->match) != (opc->match & required_bits))
1266 {
1267 as_bad (_("internal: bad RISC-V opcode (mask error): %s %s"),
1268 opc->name, opc->args);
5b7c81bd 1269 return false;
e23eba97
NC
1270 }
1271
437e2ff1
NC
1272 for (oparg = opc->args; *oparg; ++oparg)
1273 {
1274 opargStart = oparg;
1275 switch (*oparg)
1276 {
1277 case 'C': /* RVC */
1278 switch (*++oparg)
1279 {
1280 case 'U': break; /* CRS1, constrained to equal RD. */
1281 case 'c': break; /* CRS1, constrained to equal sp. */
1282 case 'T': /* CRS2, floating point. */
1283 case 'V': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
1284 case 'S': /* CRS1S, floating point. */
1285 case 's': USE_BITS (OP_MASK_CRS1S, OP_SH_CRS1S); break;
1286 case 'w': break; /* CRS1S, constrained to equal RD. */
1287 case 'D': /* CRS2S, floating point. */
1288 case 't': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
1289 case 'x': break; /* CRS2S, constrained to equal RD. */
1290 case 'z': break; /* CRS2S, constrained to be x0. */
1291 case '>': /* CITYPE immediate, compressed shift. */
1292 case 'u': /* CITYPE immediate, compressed lui. */
1293 case 'v': /* CITYPE immediate, li to compressed lui. */
1294 case 'o': /* CITYPE immediate, allow zero. */
1295 case 'j': used_bits |= ENCODE_CITYPE_IMM (-1U); break;
1296 case 'L': used_bits |= ENCODE_CITYPE_ADDI16SP_IMM (-1U); break;
1297 case 'm': used_bits |= ENCODE_CITYPE_LWSP_IMM (-1U); break;
1298 case 'n': used_bits |= ENCODE_CITYPE_LDSP_IMM (-1U); break;
1299 case '6': used_bits |= ENCODE_CSSTYPE_IMM (-1U); break;
1300 case 'M': used_bits |= ENCODE_CSSTYPE_SWSP_IMM (-1U); break;
1301 case 'N': used_bits |= ENCODE_CSSTYPE_SDSP_IMM (-1U); break;
1302 case '8': used_bits |= ENCODE_CIWTYPE_IMM (-1U); break;
1303 case 'K': used_bits |= ENCODE_CIWTYPE_ADDI4SPN_IMM (-1U); break;
1304 /* CLTYPE and CSTYPE have the same immediate encoding. */
1305 case '5': used_bits |= ENCODE_CLTYPE_IMM (-1U); break;
1306 case 'k': used_bits |= ENCODE_CLTYPE_LW_IMM (-1U); break;
1307 case 'l': used_bits |= ENCODE_CLTYPE_LD_IMM (-1U); break;
1308 case 'p': used_bits |= ENCODE_CBTYPE_IMM (-1U); break;
1309 case 'a': used_bits |= ENCODE_CJTYPE_IMM (-1U); break;
1310 case 'F': /* Compressed funct for .insn directive. */
1311 switch (*++oparg)
1312 {
65e4a99a
NC
1313 case '6': USE_BITS (OP_MASK_CFUNCT6, OP_SH_CFUNCT6); break;
1314 case '4': USE_BITS (OP_MASK_CFUNCT4, OP_SH_CFUNCT4); break;
1315 case '3': USE_BITS (OP_MASK_CFUNCT3, OP_SH_CFUNCT3); break;
1316 case '2': USE_BITS (OP_MASK_CFUNCT2, OP_SH_CFUNCT2); break;
1317 default:
1318 goto unknown_validate_operand;
437e2ff1
NC
1319 }
1320 break;
0e35537d 1321 default:
437e2ff1
NC
1322 goto unknown_validate_operand;
1323 }
a63375ac 1324 break; /* end RVC */
65e4a99a
NC
1325 case 'V': /* RVV */
1326 switch (*++oparg)
1327 {
1328 case 'd':
1329 case 'f': USE_BITS (OP_MASK_VD, OP_SH_VD); break;
1330 case 'e': USE_BITS (OP_MASK_VWD, OP_SH_VWD); break;
1331 case 's': USE_BITS (OP_MASK_VS1, OP_SH_VS1); break;
1332 case 't': USE_BITS (OP_MASK_VS2, OP_SH_VS2); break;
1333 case 'u': USE_BITS (OP_MASK_VS1, OP_SH_VS1);
1334 USE_BITS (OP_MASK_VS2, OP_SH_VS2); break;
1335 case 'v': USE_BITS (OP_MASK_VD, OP_SH_VD);
1336 USE_BITS (OP_MASK_VS1, OP_SH_VS1);
1337 USE_BITS (OP_MASK_VS2, OP_SH_VS2); break;
1338 case '0': break;
1339 case 'b': used_bits |= ENCODE_RVV_VB_IMM (-1U); break;
1340 case 'c': used_bits |= ENCODE_RVV_VC_IMM (-1U); break;
1341 case 'i':
1342 case 'j':
1343 case 'k': USE_BITS (OP_MASK_VIMM, OP_SH_VIMM); break;
c8cb3734 1344 case 'l': used_bits |= ENCODE_RVV_VI_UIMM6 (-1U); break;
65e4a99a 1345 case 'm': USE_BITS (OP_MASK_VMASK, OP_SH_VMASK); break;
c1ecdee7
TO
1346 case 'M': break; /* Macro operand, must be a mask register. */
1347 case 'T': break; /* Macro operand, must be a vector register. */
65e4a99a
NC
1348 default:
1349 goto unknown_validate_operand;
1350 }
a63375ac 1351 break; /* end RVV */
437e2ff1
NC
1352 case ',': break;
1353 case '(': break;
1354 case ')': break;
1355 case '<': USE_BITS (OP_MASK_SHAMTW, OP_SH_SHAMTW); break;
1356 case '>': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
1357 case 'A': break; /* Macro operand, must be symbol. */
1358 case 'B': break; /* Macro operand, must be symbol or constant. */
c1ecdee7 1359 case 'c': break; /* Macro operand, must be symbol or constant. */
437e2ff1
NC
1360 case 'I': break; /* Macro operand, must be constant. */
1361 case 'D': /* RD, floating point. */
1362 case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
3d1cafa0 1363 case 'y': USE_BITS (OP_MASK_BS, OP_SH_BS); break;
1364 case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
437e2ff1
NC
1365 case 'Z': /* RS1, CSR number. */
1366 case 'S': /* RS1, floating point. */
1367 case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
1368 case 'U': /* RS1 and RS2 are the same, floating point. */
1369 USE_BITS (OP_MASK_RS1, OP_SH_RS1);
1370 /* Fall through. */
1371 case 'T': /* RS2, floating point. */
1372 case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break;
1373 case 'R': /* RS3, floating point. */
1374 case 'r': USE_BITS (OP_MASK_RS3, OP_SH_RS3); break;
1375 case 'm': USE_BITS (OP_MASK_RM, OP_SH_RM); break;
1376 case 'E': USE_BITS (OP_MASK_CSR, OP_SH_CSR); break;
1377 case 'P': USE_BITS (OP_MASK_PRED, OP_SH_PRED); break;
1378 case 'Q': USE_BITS (OP_MASK_SUCC, OP_SH_SUCC); break;
1379 case 'o': /* ITYPE immediate, load displacement. */
1380 case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
1381 case 'a': used_bits |= ENCODE_JTYPE_IMM (-1U); break;
1382 case 'p': used_bits |= ENCODE_BTYPE_IMM (-1U); break;
1383 case 'q': used_bits |= ENCODE_STYPE_IMM (-1U); break;
1384 case 'u': used_bits |= ENCODE_UTYPE_IMM (-1U); break;
1385 case 'z': break; /* Zero immediate. */
1386 case '[': break; /* Unused operand. */
1387 case ']': break; /* Unused operand. */
1388 case '0': break; /* AMO displacement, must to zero. */
1389 case '1': break; /* Relaxation operand. */
1390 case 'F': /* Funct for .insn directive. */
1391 switch (*++oparg)
1392 {
1393 case '7': USE_BITS (OP_MASK_FUNCT7, OP_SH_FUNCT7); break;
1394 case '3': USE_BITS (OP_MASK_FUNCT3, OP_SH_FUNCT3); break;
1395 case '2': USE_BITS (OP_MASK_FUNCT2, OP_SH_FUNCT2); break;
1396 default:
1397 goto unknown_validate_operand;
1398 }
1399 break;
1400 case 'O': /* Opcode for .insn directive. */
1401 switch (*++oparg)
1402 {
1403 case '4': USE_BITS (OP_MASK_OP, OP_SH_OP); break;
1404 case '2': USE_BITS (OP_MASK_OP2, OP_SH_OP2); break;
1405 default:
1406 goto unknown_validate_operand;
1407 }
1408 break;
54bca63b
TO
1409 case 'W': /* Various operands. */
1410 switch (*++oparg)
1411 {
1412 case 'i':
1413 switch (*++oparg)
1414 {
1415 case 'f': used_bits |= ENCODE_STYPE_IMM (-1U); break;
1416 default:
1417 goto unknown_validate_operand;
1418 }
1419 break;
1f3fc45b
CM
1420 case 'f':
1421 switch (*++oparg)
1422 {
1423 case 'v': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
1424 default:
1425 goto unknown_validate_operand;
1426 }
1427 break;
54bca63b
TO
1428 default:
1429 goto unknown_validate_operand;
1430 }
1431 break;
8b7419c4
CM
1432 case 'X': /* Integer immediate. */
1433 {
1434 size_t n;
1435 size_t s;
1436
1437 switch (*++oparg)
1438 {
25236d63
CM
1439 case 'l': /* Literal. */
1440 oparg += strcspn(oparg, ",") - 1;
1441 break;
8b7419c4
CM
1442 case 's': /* 'XsN@S' ... N-bit signed immediate at bit S. */
1443 goto use_imm;
1444 case 'u': /* 'XuN@S' ... N-bit unsigned immediate at bit S. */
1445 goto use_imm;
1446 use_imm:
b0423163 1447 n = strtol (oparg + 1, (char **)&oparg, 10);
8b7419c4
CM
1448 if (*oparg != '@')
1449 goto unknown_validate_operand;
b0423163 1450 s = strtol (oparg + 1, (char **)&oparg, 10);
8b7419c4
CM
1451 oparg--;
1452
1453 USE_IMM (n, s);
1454 break;
1455 default:
1456 goto unknown_validate_operand;
1457 }
1458 }
1459 break;
437e2ff1
NC
1460 default:
1461 unknown_validate_operand:
1462 as_bad (_("internal: bad RISC-V opcode "
1463 "(unknown operand type `%s'): %s %s"),
1464 opargStart, opc->name, opc->args);
1465 return false;
1466 }
1467 }
1468
e23eba97
NC
1469 if (used_bits != required_bits)
1470 {
b800637e 1471 as_bad (_("internal: bad RISC-V opcode "
6b84c098
TO
1472 "(bits %#llx undefined or invalid): %s %s"),
1473 (unsigned long long)(used_bits ^ required_bits),
e23eba97 1474 opc->name, opc->args);
5b7c81bd 1475 return false;
e23eba97 1476 }
5b7c81bd 1477 return true;
e23eba97
NC
1478}
1479
437e2ff1
NC
1480#undef USE_BITS
1481
e23eba97
NC
1482struct percent_op_match
1483{
1484 const char *str;
1485 bfd_reloc_code_real_type reloc;
1486};
1487
dcd709e0
NC
1488/* Common hash table initialization function for instruction and .insn
1489 directive. */
1490
629310ab 1491static htab_t
0e35537d 1492init_opcode_hash (const struct riscv_opcode *opcodes,
5b7c81bd 1493 bool insn_directive_p)
e23eba97
NC
1494{
1495 int i = 0;
0e35537d 1496 int length;
629310ab 1497 htab_t hash = str_htab_create ();
0e35537d 1498 while (opcodes[i].name)
e23eba97 1499 {
0e35537d 1500 const char *name = opcodes[i].name;
fe0e921f 1501 if (str_hash_insert (hash, name, &opcodes[i], 0) != NULL)
b800637e 1502 as_fatal (_("internal: duplicate %s"), name);
e23eba97
NC
1503
1504 do
1505 {
0e35537d 1506 if (opcodes[i].pinfo != INSN_MACRO)
e23eba97 1507 {
0e35537d
JW
1508 if (insn_directive_p)
1509 length = ((name[0] == 'c') ? 2 : 4);
1510 else
dcd709e0 1511 length = 0; /* Let assembler determine the length. */
0e35537d 1512 if (!validate_riscv_insn (&opcodes[i], length))
b800637e
NC
1513 as_fatal (_("internal: broken assembler. "
1514 "No assembly attempted"));
e23eba97 1515 }
0e35537d
JW
1516 else
1517 gas_assert (!insn_directive_p);
e23eba97
NC
1518 ++i;
1519 }
0e35537d 1520 while (opcodes[i].name && !strcmp (opcodes[i].name, name));
e23eba97
NC
1521 }
1522
0e35537d
JW
1523 return hash;
1524}
1525
1526/* This function is called once, at assembler startup time. It should set up
1527 all the tables, etc. that the MD part of the assembler will need. */
1528
1529void
1530md_begin (void)
1531{
1532 unsigned long mach = xlen == 64 ? bfd_mach_riscv64 : bfd_mach_riscv32;
1533
1534 if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach))
b800637e 1535 as_warn (_("could not set architecture and machine"));
0e35537d 1536
5b7c81bd
AM
1537 op_hash = init_opcode_hash (riscv_opcodes, false);
1538 insn_type_hash = init_opcode_hash (riscv_insn_types, true);
0e35537d 1539
629310ab 1540 reg_names_hash = str_htab_create ();
e23eba97
NC
1541 hash_reg_names (RCLASS_GPR, riscv_gpr_names_numeric, NGPR);
1542 hash_reg_names (RCLASS_GPR, riscv_gpr_names_abi, NGPR);
1543 hash_reg_names (RCLASS_FPR, riscv_fpr_names_numeric, NFPR);
1544 hash_reg_names (RCLASS_FPR, riscv_fpr_names_abi, NFPR);
65e4a99a
NC
1545 hash_reg_names (RCLASS_VECR, riscv_vecr_names_numeric, NVECR);
1546 hash_reg_names (RCLASS_VECM, riscv_vecm_names_numeric, NVECM);
b9c04e5a
JW
1547 /* Add "fp" as an alias for "s0". */
1548 hash_reg_name (RCLASS_GPR, "fp", 8);
1549
bd0cf5a6 1550 /* Create and insert CSR hash tables. */
629310ab 1551 csr_extra_hash = str_htab_create ();
8f595e9b
NC
1552#define DECLARE_CSR(name, num, class, define_version, abort_version) \
1553 riscv_init_csr_hash (#name, num, class, define_version, abort_version);
1554#define DECLARE_CSR_ALIAS(name, num, class, define_version, abort_version) \
1555 DECLARE_CSR(name, num, class, define_version, abort_version);
e23eba97
NC
1556#include "opcode/riscv-opc.h"
1557#undef DECLARE_CSR
1558
629310ab 1559 opcode_names_hash = str_htab_create ();
bd0cf5a6
NC
1560 init_opcode_names_hash ();
1561
e23eba97
NC
1562 /* Set the default alignment for the text section. */
1563 record_alignment (text_section, riscv_opts.rvc ? 1 : 2);
1564}
1565
45f76423
AW
1566static insn_t
1567riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type, bfd_vma value)
1568{
1569 switch (reloc_type)
1570 {
1571 case BFD_RELOC_32:
1572 return value;
1573
1574 case BFD_RELOC_RISCV_HI20:
1575 return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
1576
1577 case BFD_RELOC_RISCV_LO12_S:
1578 return ENCODE_STYPE_IMM (value);
1579
1580 case BFD_RELOC_RISCV_LO12_I:
1581 return ENCODE_ITYPE_IMM (value);
1582
1583 default:
1584 abort ();
1585 }
1586}
1587
e23eba97
NC
1588/* Output an instruction. IP is the instruction information.
1589 ADDRESS_EXPR is an operand of the instruction to be used with
1590 RELOC_TYPE. */
1591
1592static void
1593append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
1594 bfd_reloc_code_real_type reloc_type)
1595{
1596 dwarf2_emit_insn (0);
1597
1598 if (reloc_type != BFD_RELOC_UNUSED)
1599 {
1600 reloc_howto_type *howto;
1601
1d65abb5 1602 gas_assert (address_expr);
e23eba97
NC
1603 if (reloc_type == BFD_RELOC_12_PCREL
1604 || reloc_type == BFD_RELOC_RISCV_JMP)
1605 {
1606 int j = reloc_type == BFD_RELOC_RISCV_JMP;
8c07e983 1607 int best_case = insn_length (ip);
e23eba97 1608 unsigned worst_case = relaxed_branch_length (NULL, NULL, 0);
743f5cfc
JW
1609
1610 if (now_seg == absolute_section)
1611 {
1612 as_bad (_("relaxable branches not supported in absolute section"));
1613 return;
1614 }
1615
e23eba97
NC
1616 add_relaxed_insn (ip, worst_case, best_case,
1617 RELAX_BRANCH_ENCODE (j, best_case == 2, worst_case),
1618 address_expr->X_add_symbol,
1619 address_expr->X_add_number);
1620 return;
1621 }
45f76423 1622 else
e23eba97 1623 {
45f76423
AW
1624 howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
1625 if (howto == NULL)
579f0281 1626 as_bad (_("internal: unsupported RISC-V relocation number %d"),
b800637e 1627 reloc_type);
e23eba97 1628
45f76423
AW
1629 ip->fixp = fix_new_exp (ip->frag, ip->where,
1630 bfd_get_reloc_size (howto),
5b7c81bd 1631 address_expr, false, reloc_type);
e23eba97 1632
45f76423 1633 ip->fixp->fx_tcbit = riscv_opts.relax;
e23eba97 1634 }
e23eba97
NC
1635 }
1636
e23eba97 1637 add_fixed_insn (ip);
f77bb6c5
JW
1638
1639 /* We need to start a new frag after any instruction that can be
1640 optimized away or compressed by the linker during relaxation, to prevent
1641 the assembler from computing static offsets across such an instruction.
1642 This is necessary to get correct EH info. */
b1b11e92 1643 if (reloc_type == BFD_RELOC_RISCV_HI20
f77bb6c5
JW
1644 || reloc_type == BFD_RELOC_RISCV_PCREL_HI20
1645 || reloc_type == BFD_RELOC_RISCV_TPREL_HI20
1646 || reloc_type == BFD_RELOC_RISCV_TPREL_ADD)
1647 {
1648 frag_wane (frag_now);
1649 frag_new (0);
1650 }
e23eba97
NC
1651}
1652
1653/* Build an instruction created by a macro expansion. This is passed
dcd709e0
NC
1654 a pointer to the count of instructions created so far, an expression,
1655 the name of the instruction to build, an operand format string, and
1656 corresponding arguments. */
e23eba97
NC
1657
1658static void
1659macro_build (expressionS *ep, const char *name, const char *fmt, ...)
1660{
1661 const struct riscv_opcode *mo;
1662 struct riscv_cl_insn insn;
1663 bfd_reloc_code_real_type r;
1664 va_list args;
437e2ff1 1665 const char *fmtStart;
e23eba97
NC
1666
1667 va_start (args, fmt);
1668
1669 r = BFD_RELOC_UNUSED;
629310ab 1670 mo = (struct riscv_opcode *) str_hash_find (op_hash, name);
e23eba97
NC
1671 gas_assert (mo);
1672
1673 /* Find a non-RVC variant of the instruction. append_insn will compress
1674 it if possible. */
1675 while (riscv_insn_length (mo->match) < 4)
1676 mo++;
1677 gas_assert (strcmp (name, mo->name) == 0);
1678
1679 create_insn (&insn, mo);
437e2ff1 1680 for (;; ++fmt)
e23eba97 1681 {
437e2ff1
NC
1682 fmtStart = fmt;
1683 switch (*fmt)
e23eba97 1684 {
65e4a99a
NC
1685 case 'V': /* RVV */
1686 switch (*++fmt)
1687 {
1688 case 'd':
1689 INSERT_OPERAND (VD, insn, va_arg (args, int));
1690 continue;
1691 case 's':
1692 INSERT_OPERAND (VS1, insn, va_arg (args, int));
1693 continue;
1694 case 't':
1695 INSERT_OPERAND (VS2, insn, va_arg (args, int));
1696 continue;
1697 case 'm':
1698 {
1699 int reg = va_arg (args, int);
1700 if (reg == -1)
1701 {
1702 INSERT_OPERAND (VMASK, insn, 1);
1703 continue;
1704 }
1705 else if (reg == 0)
1706 {
1707 INSERT_OPERAND (VMASK, insn, 0);
1708 continue;
1709 }
1710 else
1711 goto unknown_macro_argument;
1712 }
1713 default:
1714 goto unknown_macro_argument;
1715 }
1716 break;
1717
e23eba97
NC
1718 case 'd':
1719 INSERT_OPERAND (RD, insn, va_arg (args, int));
1720 continue;
e23eba97
NC
1721 case 's':
1722 INSERT_OPERAND (RS1, insn, va_arg (args, int));
1723 continue;
e23eba97
NC
1724 case 't':
1725 INSERT_OPERAND (RS2, insn, va_arg (args, int));
1726 continue;
1727
e23eba97
NC
1728 case 'j':
1729 case 'u':
1730 case 'q':
1731 gas_assert (ep != NULL);
1732 r = va_arg (args, int);
1733 continue;
1734
1735 case '\0':
1736 break;
1737 case ',':
1738 continue;
1739 default:
65e4a99a 1740 unknown_macro_argument:
437e2ff1 1741 as_fatal (_("internal: invalid macro argument `%s'"), fmtStart);
e23eba97
NC
1742 }
1743 break;
1744 }
1745 va_end (args);
1746 gas_assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
1747
1748 append_insn (&insn, ep, r);
1749}
1750
db3b6ecc
KC
1751/* Build an instruction created by a macro expansion. Like md_assemble but
1752 accept a printf-style format string and arguments. */
1753
1754static void
1755md_assemblef (const char *format, ...)
1756{
1757 char *buf = NULL;
1758 va_list ap;
1759 int r;
1760
1761 va_start (ap, format);
1762
1763 r = vasprintf (&buf, format, ap);
1764
1765 if (r < 0)
b800637e 1766 as_fatal (_("internal: vasprintf failed"));
db3b6ecc
KC
1767
1768 md_assemble (buf);
1769 free(buf);
1770
1771 va_end (ap);
1772}
1773
e23eba97
NC
1774/* Sign-extend 32-bit mode constants that have bit 31 set and all higher bits
1775 unset. */
dcd709e0 1776
e23eba97
NC
1777static void
1778normalize_constant_expr (expressionS *ex)
1779{
1780 if (xlen > 32)
1781 return;
1782 if ((ex->X_op == O_constant || ex->X_op == O_symbol)
1783 && IS_ZEXT_32BIT_NUM (ex->X_add_number))
1784 ex->X_add_number = (((ex->X_add_number & 0xffffffff) ^ 0x80000000)
1785 - 0x80000000);
1786}
1787
ca2fd32c
JW
1788/* Fail if an expression EX is not a constant. IP is the instruction using EX.
1789 MAYBE_CSR is true if the symbol may be an unrecognized CSR name. */
e23eba97
NC
1790
1791static void
ca2fd32c 1792check_absolute_expr (struct riscv_cl_insn *ip, expressionS *ex,
5b7c81bd 1793 bool maybe_csr)
e23eba97
NC
1794{
1795 if (ex->X_op == O_big)
1796 as_bad (_("unsupported large constant"));
ca2fd32c
JW
1797 else if (maybe_csr && ex->X_op == O_symbol)
1798 as_bad (_("unknown CSR `%s'"),
1799 S_GET_NAME (ex->X_add_symbol));
e23eba97 1800 else if (ex->X_op != O_constant)
b800637e 1801 as_bad (_("instruction %s requires absolute expression"),
e23eba97
NC
1802 ip->insn_mo->name);
1803 normalize_constant_expr (ex);
1804}
1805
1806static symbolS *
1807make_internal_label (void)
1808{
e01e1cee
AM
1809 return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg, frag_now,
1810 frag_now_fix ());
e23eba97
NC
1811}
1812
1813/* Load an entry from the GOT. */
dcd709e0 1814
e23eba97
NC
1815static void
1816pcrel_access (int destreg, int tempreg, expressionS *ep,
1817 const char *lo_insn, const char *lo_pattern,
1818 bfd_reloc_code_real_type hi_reloc,
1819 bfd_reloc_code_real_type lo_reloc)
1820{
1821 expressionS ep2;
1822 ep2.X_op = O_symbol;
1823 ep2.X_add_symbol = make_internal_label ();
1824 ep2.X_add_number = 0;
1825
1826 macro_build (ep, "auipc", "d,u", tempreg, hi_reloc);
1827 macro_build (&ep2, lo_insn, lo_pattern, destreg, tempreg, lo_reloc);
1828}
1829
1830static void
1831pcrel_load (int destreg, int tempreg, expressionS *ep, const char *lo_insn,
1832 bfd_reloc_code_real_type hi_reloc,
1833 bfd_reloc_code_real_type lo_reloc)
1834{
1835 pcrel_access (destreg, tempreg, ep, lo_insn, "d,s,j", hi_reloc, lo_reloc);
1836}
1837
1838static void
1839pcrel_store (int srcreg, int tempreg, expressionS *ep, const char *lo_insn,
1840 bfd_reloc_code_real_type hi_reloc,
1841 bfd_reloc_code_real_type lo_reloc)
1842{
1843 pcrel_access (srcreg, tempreg, ep, lo_insn, "t,s,q", hi_reloc, lo_reloc);
1844}
1845
1846/* PC-relative function call using AUIPC/JALR, relaxed to JAL. */
dcd709e0 1847
e23eba97
NC
1848static void
1849riscv_call (int destreg, int tempreg, expressionS *ep,
1850 bfd_reloc_code_real_type reloc)
1851{
b1b11e92
AM
1852 /* Ensure the jalr is emitted to the same frag as the auipc. */
1853 frag_grow (8);
e23eba97
NC
1854 macro_build (ep, "auipc", "d,u", tempreg, reloc);
1855 macro_build (NULL, "jalr", "d,s", destreg, tempreg);
b1b11e92
AM
1856 /* See comment at end of append_insn. */
1857 frag_wane (frag_now);
1858 frag_new (0);
e23eba97
NC
1859}
1860
1861/* Load an integer constant into a register. */
1862
1863static void
1864load_const (int reg, expressionS *ep)
1865{
1866 int shift = RISCV_IMM_BITS;
4f7cc141 1867 bfd_vma upper_imm, sign = (bfd_vma) 1 << (RISCV_IMM_BITS - 1);
e23eba97 1868 expressionS upper = *ep, lower = *ep;
4f7cc141 1869 lower.X_add_number = ((ep->X_add_number & (sign + sign - 1)) ^ sign) - sign;
e23eba97
NC
1870 upper.X_add_number -= lower.X_add_number;
1871
1872 if (ep->X_op != O_constant)
1873 {
1874 as_bad (_("unsupported large constant"));
1875 return;
1876 }
1877
1d65abb5 1878 if (xlen > 32 && !IS_SEXT_32BIT_NUM (ep->X_add_number))
e23eba97
NC
1879 {
1880 /* Reduce to a signed 32-bit constant using SLLI and ADDI. */
1881 while (((upper.X_add_number >> shift) & 1) == 0)
1882 shift++;
1883
1884 upper.X_add_number = (int64_t) upper.X_add_number >> shift;
1d65abb5 1885 load_const (reg, &upper);
e23eba97 1886
db3b6ecc 1887 md_assemblef ("slli x%d, x%d, 0x%x", reg, reg, shift);
e23eba97 1888 if (lower.X_add_number != 0)
b8281767
AM
1889 md_assemblef ("addi x%d, x%d, %" PRId64, reg, reg,
1890 (int64_t) lower.X_add_number);
e23eba97
NC
1891 }
1892 else
1893 {
1894 /* Simply emit LUI and/or ADDI to build a 32-bit signed constant. */
1895 int hi_reg = 0;
1896
1897 if (upper.X_add_number != 0)
1898 {
db3b6ecc
KC
1899 /* Discard low part and zero-extend upper immediate. */
1900 upper_imm = ((uint32_t)upper.X_add_number >> shift);
1901
b8281767 1902 md_assemblef ("lui x%d, 0x%" PRIx64, reg, (uint64_t) upper_imm);
e23eba97
NC
1903 hi_reg = reg;
1904 }
1905
1906 if (lower.X_add_number != 0 || hi_reg == 0)
b8281767
AM
1907 md_assemblef ("%s x%d, x%d, %" PRId64, ADD32_INSN, reg, hi_reg,
1908 (int64_t) lower.X_add_number);
e23eba97
NC
1909 }
1910}
1911
c2137f55
NC
1912/* Zero extend and sign extend byte/half-word/word. */
1913
1914static void
5b7c81bd 1915riscv_ext (int destreg, int srcreg, unsigned shift, bool sign)
c2137f55
NC
1916{
1917 if (sign)
1918 {
1919 md_assemblef ("slli x%d, x%d, 0x%x", destreg, srcreg, shift);
1920 md_assemblef ("srai x%d, x%d, 0x%x", destreg, destreg, shift);
1921 }
1922 else
1923 {
1924 md_assemblef ("slli x%d, x%d, 0x%x", destreg, srcreg, shift);
1925 md_assemblef ("srli x%d, x%d, 0x%x", destreg, destreg, shift);
1926 }
1927}
1928
65e4a99a
NC
1929/* Expand RISC-V Vector macros into one or more instructions. */
1930
1931static void
1932vector_macro (struct riscv_cl_insn *ip)
1933{
1934 int vd = (ip->insn_opcode >> OP_SH_VD) & OP_MASK_VD;
1935 int vs1 = (ip->insn_opcode >> OP_SH_VS1) & OP_MASK_VS1;
1936 int vs2 = (ip->insn_opcode >> OP_SH_VS2) & OP_MASK_VS2;
1937 int vm = (ip->insn_opcode >> OP_SH_VMASK) & OP_MASK_VMASK;
1938 int vtemp = (ip->insn_opcode >> OP_SH_VFUNCT6) & OP_MASK_VFUNCT6;
1939 int mask = ip->insn_mo->mask;
1940
1941 switch (mask)
1942 {
1943 case M_VMSGE:
1944 if (vm)
1945 {
1946 /* Unmasked. */
1947 macro_build (NULL, "vmslt.vx", "Vd,Vt,sVm", vd, vs2, vs1, -1);
1948 macro_build (NULL, "vmnand.mm", "Vd,Vt,Vs", vd, vd, vd);
1949 break;
1950 }
1951 if (vtemp != 0)
1952 {
1953 /* Masked. Have vtemp to avoid overlap constraints. */
1954 if (vd == vm)
1955 {
1956 macro_build (NULL, "vmslt.vx", "Vd,Vt,s", vtemp, vs2, vs1);
1957 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vm, vtemp);
1958 }
1959 else
1960 {
1961 /* Preserve the value of vd if not updating by vm. */
1962 macro_build (NULL, "vmslt.vx", "Vd,Vt,s", vtemp, vs2, vs1);
1963 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vtemp, vm, vtemp);
1964 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vd, vm);
1965 macro_build (NULL, "vmor.mm", "Vd,Vt,Vs", vd, vtemp, vd);
1966 }
1967 }
1968 else if (vd != vm)
1969 {
1970 /* Masked. This may cause the vd overlaps vs2, when LMUL > 1. */
1971 macro_build (NULL, "vmslt.vx", "Vd,Vt,sVm", vd, vs2, vs1, vm);
1972 macro_build (NULL, "vmxor.mm", "Vd,Vt,Vs", vd, vd, vm);
1973 }
1974 else
1975 as_bad (_("must provide temp if destination overlaps mask"));
1976 break;
1977
1978 case M_VMSGEU:
1979 if (vm)
1980 {
1981 /* Unmasked. */
1982 macro_build (NULL, "vmsltu.vx", "Vd,Vt,sVm", vd, vs2, vs1, -1);
1983 macro_build (NULL, "vmnand.mm", "Vd,Vt,Vs", vd, vd, vd);
1984 break;
1985 }
1986 if (vtemp != 0)
1987 {
1988 /* Masked. Have vtemp to avoid overlap constraints. */
1989 if (vd == vm)
1990 {
1991 macro_build (NULL, "vmsltu.vx", "Vd,Vt,s", vtemp, vs2, vs1);
1992 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vm, vtemp);
1993 }
1994 else
1995 {
1996 /* Preserve the value of vd if not updating by vm. */
1997 macro_build (NULL, "vmsltu.vx", "Vd,Vt,s", vtemp, vs2, vs1);
1998 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vtemp, vm, vtemp);
1999 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vd, vm);
2000 macro_build (NULL, "vmor.mm", "Vd,Vt,Vs", vd, vtemp, vd);
2001 }
2002 }
2003 else if (vd != vm)
2004 {
2005 /* Masked. This may cause the vd overlaps vs2, when LMUL > 1. */
2006 macro_build (NULL, "vmsltu.vx", "Vd,Vt,sVm", vd, vs2, vs1, vm);
2007 macro_build (NULL, "vmxor.mm", "Vd,Vt,Vs", vd, vd, vm);
2008 }
2009 else
2010 as_bad (_("must provide temp if destination overlaps mask"));
2011 break;
2012
2013 default:
2014 break;
2015 }
2016}
2017
e23eba97 2018/* Expand RISC-V assembly macros into one or more instructions. */
2652cfad 2019
e23eba97
NC
2020static void
2021macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
2022 bfd_reloc_code_real_type *imm_reloc)
2023{
2024 int rd = (ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD;
2025 int rs1 = (ip->insn_opcode >> OP_SH_RS1) & OP_MASK_RS1;
2026 int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2;
2027 int mask = ip->insn_mo->mask;
2028
2029 switch (mask)
2030 {
2031 case M_LI:
2032 load_const (rd, imm_expr);
2033 break;
2034
2035 case M_LA:
2036 case M_LLA:
ec2260af 2037 case M_LGA:
e23eba97
NC
2038 /* Load the address of a symbol into a register. */
2039 if (!IS_SEXT_32BIT_NUM (imm_expr->X_add_number))
2040 as_bad (_("offset too large"));
2041
2042 if (imm_expr->X_op == O_constant)
2043 load_const (rd, imm_expr);
ec2260af
JW
2044 /* Global PIC symbol. */
2045 else if ((riscv_opts.pic && mask == M_LA)
2046 || mask == M_LGA)
e23eba97
NC
2047 pcrel_load (rd, rd, imm_expr, LOAD_ADDRESS_INSN,
2048 BFD_RELOC_RISCV_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
ec2260af
JW
2049 /* Local PIC symbol, or any non-PIC symbol. */
2050 else
e23eba97
NC
2051 pcrel_load (rd, rd, imm_expr, "addi",
2052 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2053 break;
2054
2055 case M_LA_TLS_GD:
2056 pcrel_load (rd, rd, imm_expr, "addi",
2057 BFD_RELOC_RISCV_TLS_GD_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2058 break;
2059
2060 case M_LA_TLS_IE:
2061 pcrel_load (rd, rd, imm_expr, LOAD_ADDRESS_INSN,
2062 BFD_RELOC_RISCV_TLS_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2063 break;
2064
2065 case M_LB:
2066 pcrel_load (rd, rd, imm_expr, "lb",
2067 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2068 break;
2069
2070 case M_LBU:
2071 pcrel_load (rd, rd, imm_expr, "lbu",
2072 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2073 break;
2074
2075 case M_LH:
2076 pcrel_load (rd, rd, imm_expr, "lh",
2077 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2078 break;
2079
2080 case M_LHU:
2081 pcrel_load (rd, rd, imm_expr, "lhu",
2082 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2083 break;
2084
2085 case M_LW:
2086 pcrel_load (rd, rd, imm_expr, "lw",
2087 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2088 break;
2089
2090 case M_LWU:
2091 pcrel_load (rd, rd, imm_expr, "lwu",
2092 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2093 break;
2094
2095 case M_LD:
2096 pcrel_load (rd, rd, imm_expr, "ld",
2097 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2098 break;
2099
2100 case M_FLW:
2101 pcrel_load (rd, rs1, imm_expr, "flw",
2102 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2103 break;
2104
2105 case M_FLD:
2106 pcrel_load (rd, rs1, imm_expr, "fld",
2107 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2108 break;
2109
2110 case M_SB:
2111 pcrel_store (rs2, rs1, imm_expr, "sb",
2112 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2113 break;
2114
2115 case M_SH:
2116 pcrel_store (rs2, rs1, imm_expr, "sh",
2117 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2118 break;
2119
2120 case M_SW:
2121 pcrel_store (rs2, rs1, imm_expr, "sw",
2122 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2123 break;
2124
2125 case M_SD:
2126 pcrel_store (rs2, rs1, imm_expr, "sd",
2127 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2128 break;
2129
2130 case M_FSW:
2131 pcrel_store (rs2, rs1, imm_expr, "fsw",
2132 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2133 break;
2134
2135 case M_FSD:
2136 pcrel_store (rs2, rs1, imm_expr, "fsd",
2137 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2138 break;
2139
2140 case M_CALL:
2141 riscv_call (rd, rs1, imm_expr, *imm_reloc);
2142 break;
2143
c2137f55 2144 case M_ZEXTH:
5b7c81bd 2145 riscv_ext (rd, rs1, xlen - 16, false);
c2137f55
NC
2146 break;
2147
2148 case M_ZEXTW:
5b7c81bd 2149 riscv_ext (rd, rs1, xlen - 32, false);
c2137f55
NC
2150 break;
2151
2152 case M_SEXTB:
5b7c81bd 2153 riscv_ext (rd, rs1, xlen - 8, true);
c2137f55
NC
2154 break;
2155
2156 case M_SEXTH:
5b7c81bd 2157 riscv_ext (rd, rs1, xlen - 16, true);
c2137f55
NC
2158 break;
2159
65e4a99a
NC
2160 case M_VMSGE:
2161 case M_VMSGEU:
2162 vector_macro (ip);
2163 break;
2164
035784e3
NC
2165 case M_FLH:
2166 pcrel_load (rd, rs1, imm_expr, "flh",
2167 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2168 break;
2169 case M_FSH:
2170 pcrel_store (rs2, rs1, imm_expr, "fsh",
2171 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2172 break;
2173
e23eba97 2174 default:
b800637e 2175 as_bad (_("internal: macro %s not implemented"), ip->insn_mo->name);
e23eba97
NC
2176 break;
2177 }
2178}
2179
2180static const struct percent_op_match percent_op_utype[] =
2181{
85bd4bfb
JB
2182 {"tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
2183 {"pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
2184 {"got_pcrel_hi", BFD_RELOC_RISCV_GOT_HI20},
2185 {"tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
2186 {"tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
2187 {"hi", BFD_RELOC_RISCV_HI20},
e23eba97
NC
2188 {0, 0}
2189};
2190
2191static const struct percent_op_match percent_op_itype[] =
2192{
85bd4bfb
JB
2193 {"lo", BFD_RELOC_RISCV_LO12_I},
2194 {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
2195 {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
e23eba97
NC
2196 {0, 0}
2197};
2198
2199static const struct percent_op_match percent_op_stype[] =
2200{
85bd4bfb
JB
2201 {"lo", BFD_RELOC_RISCV_LO12_S},
2202 {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_S},
2203 {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_S},
e23eba97
NC
2204 {0, 0}
2205};
2206
2207static const struct percent_op_match percent_op_rtype[] =
2208{
85bd4bfb 2209 {"tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
e23eba97
NC
2210 {0, 0}
2211};
2212
f50fabe4
JW
2213static const struct percent_op_match percent_op_null[] =
2214{
2215 {0, 0}
2216};
2217
e23eba97
NC
2218/* Return true if *STR points to a relocation operator. When returning true,
2219 move *STR over the operator and store its relocation code in *RELOC.
2220 Leave both *STR and *RELOC alone when returning false. */
2221
5b7c81bd 2222static bool
e23eba97
NC
2223parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
2224 const struct percent_op_match *percent_op)
2225{
2226 for ( ; percent_op->str; percent_op++)
85bd4bfb 2227 if (strncasecmp (*str + 1, percent_op->str, strlen (percent_op->str)) == 0)
e23eba97 2228 {
85bd4bfb 2229 size_t len = 1 + strlen (percent_op->str);
e23eba97 2230
654dfab0
JB
2231 while (ISSPACE ((*str)[len]))
2232 ++len;
2233 if ((*str)[len] != '(')
e23eba97
NC
2234 continue;
2235
85bd4bfb 2236 *str += len;
e23eba97
NC
2237 *reloc = percent_op->reloc;
2238
2239 /* Check whether the output BFD supports this relocation.
2240 If not, issue an error and fall back on something safe. */
45f76423
AW
2241 if (*reloc != BFD_RELOC_UNUSED
2242 && !bfd_reloc_type_lookup (stdoutput, *reloc))
e23eba97 2243 {
b800637e
NC
2244 as_bad ("internal: relocation %s isn't supported by the "
2245 "current ABI", percent_op->str);
e23eba97
NC
2246 *reloc = BFD_RELOC_UNUSED;
2247 }
5b7c81bd 2248 return true;
e23eba97 2249 }
5b7c81bd 2250 return false;
e23eba97
NC
2251}
2252
2253static void
2254my_getExpression (expressionS *ep, char *str)
2255{
2256 char *save_in;
2257
2258 save_in = input_line_pointer;
2259 input_line_pointer = str;
2260 expression (ep);
6eb099ae 2261 expr_parse_end = input_line_pointer;
e23eba97
NC
2262 input_line_pointer = save_in;
2263}
2264
2265/* Parse string STR as a 16-bit relocatable operand. Store the
2266 expression in *EP and the relocation, if any, in RELOC.
2267 Return the number of relocation operators used (0 or 1).
2268
6eb099ae
AM
2269 On exit, EXPR_PARSE_END points to the first character after the
2270 expression. */
e23eba97
NC
2271
2272static size_t
2273my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
2274 char *str, const struct percent_op_match *percent_op)
2275{
2276 size_t reloc_index;
7a29ee29
JB
2277 unsigned crux_depth, str_depth;
2278 bool orig_probing = probing_insn_operands;
e23eba97
NC
2279 char *crux;
2280
e23eba97 2281 /* Search for the start of the main expression.
dcd709e0
NC
2282
2283 End the loop with CRUX pointing to the start of the main expression and
2284 with CRUX_DEPTH containing the number of open brackets at that point. */
e23eba97
NC
2285 reloc_index = -1;
2286 str_depth = 0;
2287 do
2288 {
2289 reloc_index++;
2290 crux = str;
2291 crux_depth = str_depth;
2292
2293 /* Skip over whitespace and brackets, keeping count of the number
2294 of brackets. */
2295 while (*str == ' ' || *str == '\t' || *str == '(')
2296 if (*str++ == '(')
2297 str_depth++;
2298 }
2299 while (*str == '%'
2300 && reloc_index < 1
2301 && parse_relocation (&str, reloc, percent_op));
2302
a5e756e6
JB
2303 if (*str == '%')
2304 {
2305 /* expression() will choke on anything looking like an (unrecognized)
2306 relocation specifier. Don't even call it, avoiding multiple (and
2307 perhaps redundant) error messages; our caller will issue one. */
2308 ep->X_op = O_illegal;
2309 return 0;
2310 }
2311
7a29ee29
JB
2312 /* Anything inside parentheses or subject to a relocation operator cannot
2313 be a register and hence can be treated the same as operands to
2314 directives (other than .insn). */
2315 if (str_depth || reloc_index)
2316 probing_insn_operands = false;
2317
e23eba97 2318 my_getExpression (ep, crux);
6eb099ae 2319 str = expr_parse_end;
e23eba97 2320
7a29ee29
JB
2321 probing_insn_operands = orig_probing;
2322
e23eba97
NC
2323 /* Match every open bracket. */
2324 while (crux_depth > 0 && (*str == ')' || *str == ' ' || *str == '\t'))
2325 if (*str++ == ')')
2326 crux_depth--;
2327
2328 if (crux_depth > 0)
2329 as_bad ("unclosed '('");
2330
6eb099ae 2331 expr_parse_end = str;
e23eba97
NC
2332
2333 return reloc_index;
2334}
2335
0e35537d 2336/* Parse opcode name, could be an mnemonics or number. */
dcd709e0 2337
0e35537d
JW
2338static size_t
2339my_getOpcodeExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
408ab016 2340 char *str)
0e35537d
JW
2341{
2342 const struct opcode_name_t *o = opcode_name_lookup (&str);
2343
2344 if (o != NULL)
2345 {
2346 ep->X_op = O_constant;
2347 ep->X_add_number = o->val;
2348 return 0;
2349 }
2350
408ab016 2351 return my_getSmallExpression (ep, reloc, str, percent_op_null);
0e35537d
JW
2352}
2353
65e4a99a 2354/* Parse string STR as a vsetvli operand. Store the expression in *EP.
6eb099ae
AM
2355 On exit, EXPR_PARSE_END points to the first character after the
2356 expression. */
65e4a99a
NC
2357
2358static void
2359my_getVsetvliExpression (expressionS *ep, char *str)
2360{
2361 unsigned int vsew_value = 0, vlmul_value = 0;
2362 unsigned int vta_value = 0, vma_value = 0;
2363 bfd_boolean vsew_found = FALSE, vlmul_found = FALSE;
2364 bfd_boolean vta_found = FALSE, vma_found = FALSE;
2365
2366 if (arg_lookup (&str, riscv_vsew, ARRAY_SIZE (riscv_vsew), &vsew_value))
2367 {
2368 if (*str == ',')
2369 ++str;
2370 if (vsew_found)
2371 as_bad (_("multiple vsew constants"));
2372 vsew_found = TRUE;
2373 }
2374 if (arg_lookup (&str, riscv_vlmul, ARRAY_SIZE (riscv_vlmul), &vlmul_value))
2375 {
2376 if (*str == ',')
2377 ++str;
2378 if (vlmul_found)
2379 as_bad (_("multiple vlmul constants"));
2380 vlmul_found = TRUE;
2381 }
2382 if (arg_lookup (&str, riscv_vta, ARRAY_SIZE (riscv_vta), &vta_value))
2383 {
2384 if (*str == ',')
2385 ++str;
2386 if (vta_found)
2387 as_bad (_("multiple vta constants"));
2388 vta_found = TRUE;
2389 }
2390 if (arg_lookup (&str, riscv_vma, ARRAY_SIZE (riscv_vma), &vma_value))
2391 {
2392 if (*str == ',')
2393 ++str;
2394 if (vma_found)
2395 as_bad (_("multiple vma constants"));
2396 vma_found = TRUE;
2397 }
2398
2399 if (vsew_found || vlmul_found || vta_found || vma_found)
2400 {
2401 ep->X_op = O_constant;
2402 ep->X_add_number = (vlmul_value << OP_SH_VLMUL)
2403 | (vsew_value << OP_SH_VSEW)
2404 | (vta_value << OP_SH_VTA)
2405 | (vma_value << OP_SH_VMA);
6eb099ae 2406 expr_parse_end = str;
65e4a99a
NC
2407 }
2408 else
2409 {
2410 my_getExpression (ep, str);
6eb099ae 2411 str = expr_parse_end;
65e4a99a
NC
2412 }
2413}
2414
f0531ed6 2415/* Detect and handle implicitly zero load-store offsets. For example,
437e2ff1 2416 "lw t0, (t1)" is shorthand for "lw t0, 0(t1)". Return true if such
f0531ed6
JW
2417 an implicit offset was detected. */
2418
5b7c81bd 2419static bool
89424b1d 2420riscv_handle_implicit_zero_offset (expressionS *ep, const char *s)
f0531ed6
JW
2421{
2422 /* Check whether there is only a single bracketed expression left.
2423 If so, it must be the base register and the constant must be zero. */
2424 if (*s == '(' && strchr (s + 1, '(') == 0)
2425 {
89424b1d
MR
2426 ep->X_op = O_constant;
2427 ep->X_add_number = 0;
5b7c81bd 2428 return true;
f0531ed6
JW
2429 }
2430
5b7c81bd 2431 return false;
f0531ed6
JW
2432}
2433
54b2aec1 2434/* All RISC-V CSR instructions belong to one of these classes. */
54b2aec1
NC
2435enum csr_insn_type
2436{
2437 INSN_NOT_CSR,
2438 INSN_CSRRW,
2439 INSN_CSRRS,
2440 INSN_CSRRC
2441};
2442
2443/* Return which CSR instruction is checking. */
2444
2445static enum csr_insn_type
2446riscv_csr_insn_type (insn_t insn)
2447{
2448 if (((insn ^ MATCH_CSRRW) & MASK_CSRRW) == 0
2449 || ((insn ^ MATCH_CSRRWI) & MASK_CSRRWI) == 0)
2450 return INSN_CSRRW;
2451 else if (((insn ^ MATCH_CSRRS) & MASK_CSRRS) == 0
2452 || ((insn ^ MATCH_CSRRSI) & MASK_CSRRSI) == 0)
2453 return INSN_CSRRS;
2454 else if (((insn ^ MATCH_CSRRC) & MASK_CSRRC) == 0
2455 || ((insn ^ MATCH_CSRRCI) & MASK_CSRRCI) == 0)
2456 return INSN_CSRRC;
2457 else
2458 return INSN_NOT_CSR;
2459}
2460
2461/* CSRRW and CSRRWI always write CSR. CSRRS, CSRRC, CSRRSI and CSRRCI write
2462 CSR when RS1 isn't zero. The CSR is read only if the [11:10] bits of
2463 CSR address is 0x3. */
2464
5b7c81bd 2465static bool
54b2aec1
NC
2466riscv_csr_read_only_check (insn_t insn)
2467{
2468 int csr = (insn & (OP_MASK_CSR << OP_SH_CSR)) >> OP_SH_CSR;
2469 int rs1 = (insn & (OP_MASK_RS1 << OP_SH_RS1)) >> OP_SH_RS1;
2470 int readonly = (((csr & (0x3 << 10)) >> 10) == 0x3);
2471 enum csr_insn_type csr_insn = riscv_csr_insn_type (insn);
2472
2473 if (readonly
2474 && (((csr_insn == INSN_CSRRS
2475 || csr_insn == INSN_CSRRC)
2476 && rs1 != 0)
2477 || csr_insn == INSN_CSRRW))
5b7c81bd 2478 return false;
54b2aec1 2479
5b7c81bd 2480 return true;
54b2aec1
NC
2481}
2482
437e2ff1 2483/* Return true if it is a privileged instruction. Otherwise, return false.
1a79004f
NC
2484
2485 uret is actually a N-ext instruction. So it is better to regard it as
2486 an user instruction rather than the priv instruction.
2487
2488 hret is used to return from traps in H-mode. H-mode is removed since
2489 the v1.10 priv spec, but probably be added in the new hypervisor spec.
2490 Therefore, hret should be controlled by the hypervisor spec rather than
2491 priv spec in the future.
2492
2493 dret is defined in the debug spec, so it should be checked in the future,
2494 too. */
2495
5b7c81bd 2496static bool
1a79004f
NC
2497riscv_is_priv_insn (insn_t insn)
2498{
2499 return (((insn ^ MATCH_SRET) & MASK_SRET) == 0
2500 || ((insn ^ MATCH_MRET) & MASK_MRET) == 0
2501 || ((insn ^ MATCH_SFENCE_VMA) & MASK_SFENCE_VMA) == 0
2502 || ((insn ^ MATCH_WFI) & MASK_WFI) == 0
2503 /* The sfence.vm is dropped in the v1.10 priv specs, but we still need to
dcd709e0 2504 check it here to keep the compatible. */
1a79004f
NC
2505 || ((insn ^ MATCH_SFENCE_VM) & MASK_SFENCE_VM) == 0);
2506}
2507
7a29ee29
JB
2508static symbolS *deferred_sym_rootP;
2509static symbolS *deferred_sym_lastP;
2510/* Since symbols can't easily be freed, try to recycle ones which weren't
2511 committed. */
2512static symbolS *orphan_sym_rootP;
2513static symbolS *orphan_sym_lastP;
2514
e23eba97
NC
2515/* This routine assembles an instruction into its binary format. As a
2516 side effect, it sets the global variable imm_reloc to the type of
2517 relocation to do if one of the operands is an address expression. */
2518
e4028336 2519static struct riscv_ip_error
e23eba97 2520riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
629310ab 2521 bfd_reloc_code_real_type *imm_reloc, htab_t hash)
e23eba97 2522{
437e2ff1
NC
2523 /* The operand string defined in the riscv_opcodes. */
2524 const char *oparg, *opargStart;
2525 /* The parsed operands from assembly. */
2526 char *asarg, *asargStart;
2527 char save_c = 0;
e23eba97 2528 struct riscv_opcode *insn;
e23eba97 2529 unsigned int regno;
e23eba97 2530 const struct percent_op_match *p;
e4028336
PN
2531 struct riscv_ip_error error;
2532 error.msg = "unrecognized opcode";
2533 error.statement = str;
2534 error.missing_ext = NULL;
54b2aec1 2535 /* Indicate we are assembling instruction with CSR. */
5b7c81bd 2536 bool insn_with_csr = false;
e23eba97
NC
2537
2538 /* Parse the name of the instruction. Terminate the string if whitespace
629310ab 2539 is found so that str_hash_find only sees the name part of the string. */
437e2ff1
NC
2540 for (asarg = str; *asarg!= '\0'; ++asarg)
2541 if (ISSPACE (*asarg))
e23eba97 2542 {
437e2ff1
NC
2543 save_c = *asarg;
2544 *asarg++ = '\0';
e23eba97
NC
2545 break;
2546 }
2547
629310ab 2548 insn = (struct riscv_opcode *) str_hash_find (hash, str);
e23eba97 2549
7a29ee29
JB
2550 probing_insn_operands = true;
2551
437e2ff1 2552 asargStart = asarg;
e23eba97
NC
2553 for ( ; insn && insn->name && strcmp (insn->name, str) == 0; insn++)
2554 {
1080bf78
JW
2555 if ((insn->xlen_requirement != 0) && (xlen != insn->xlen_requirement))
2556 continue;
2557
f786c359 2558 if (!riscv_multi_subset_supports (&riscv_rps_as, insn->insn_class))
e4028336
PN
2559 {
2560 error.missing_ext = riscv_multi_subset_supports_ext (&riscv_rps_as,
2561 insn->insn_class);
2562 continue;
2563 }
e23eba97 2564
65e4a99a 2565 /* Reset error message of the previous round. */
e4028336
PN
2566 error.msg = _("illegal operands");
2567 error.missing_ext = NULL;
7a29ee29
JB
2568
2569 /* Purge deferred symbols from the previous round, if any. */
2570 while (deferred_sym_rootP)
2571 {
2572 symbolS *sym = deferred_sym_rootP;
2573
2574 symbol_remove (sym, &deferred_sym_rootP, &deferred_sym_lastP);
2575 symbol_append (sym, orphan_sym_lastP, &orphan_sym_rootP,
2576 &orphan_sym_lastP);
2577 }
2578
e23eba97 2579 create_insn (ip, insn);
e23eba97
NC
2580
2581 imm_expr->X_op = O_absent;
2582 *imm_reloc = BFD_RELOC_UNUSED;
b33e94cf 2583 p = percent_op_null;
e23eba97 2584
437e2ff1 2585 for (oparg = insn->args;; ++oparg)
e23eba97 2586 {
437e2ff1
NC
2587 opargStart = oparg;
2588 asarg += strspn (asarg, " \t");
2589 switch (*oparg)
e23eba97 2590 {
dcd709e0 2591 case '\0': /* End of args. */
e23eba97
NC
2592 if (insn->pinfo != INSN_MACRO)
2593 {
2594 if (!insn->match_func (insn, ip->insn_opcode))
2595 break;
0e35537d
JW
2596
2597 /* For .insn, insn->match and insn->mask are 0. */
2598 if (riscv_insn_length ((insn->match == 0 && insn->mask == 0)
2599 ? ip->insn_opcode
2600 : insn->match) == 2
2601 && !riscv_opts.rvc)
e23eba97 2602 break;
54b2aec1 2603
1a79004f 2604 if (riscv_is_priv_insn (ip->insn_opcode))
5b7c81bd 2605 explicit_priv_attr = true;
1a79004f 2606
54b2aec1
NC
2607 /* Check if we write a read-only CSR by the CSR
2608 instruction. */
2609 if (insn_with_csr
2610 && riscv_opts.csr_check
2611 && !riscv_csr_read_only_check (ip->insn_opcode))
2612 {
2613 /* Restore the character in advance, since we want to
2614 report the detailed warning message here. */
2615 if (save_c)
437e2ff1 2616 *(asargStart - 1) = save_c;
b800637e 2617 as_warn (_("read-only CSR is written `%s'"), str);
5b7c81bd 2618 insn_with_csr = false;
54b2aec1 2619 }
65e4a99a
NC
2620
2621 /* The (segmant) load and store with EEW 64 cannot be used
2622 when zve32x is enabled. */
2623 if (ip->insn_mo->pinfo & INSN_V_EEW64
2624 && riscv_subset_supports (&riscv_rps_as, "zve32x")
2625 && !riscv_subset_supports (&riscv_rps_as, "zve64x"))
2626 {
e4028336 2627 error.msg = _("illegal opcode for zve32x");
65e4a99a
NC
2628 break;
2629 }
e23eba97 2630 }
437e2ff1 2631 if (*asarg != '\0')
e23eba97 2632 break;
7a29ee29 2633
e23eba97 2634 /* Successful assembly. */
e4028336 2635 error.msg = NULL;
5b7c81bd 2636 insn_with_csr = false;
7a29ee29
JB
2637
2638 /* Commit deferred symbols, if any. */
2639 while (deferred_sym_rootP)
2640 {
2641 symbolS *sym = deferred_sym_rootP;
2642
2643 symbol_remove (sym, &deferred_sym_rootP,
2644 &deferred_sym_lastP);
2645 symbol_append (sym, symbol_lastP, &symbol_rootP,
2646 &symbol_lastP);
2647 symbol_table_insert (sym);
2648 }
e23eba97
NC
2649 goto out;
2650
2651 case 'C': /* RVC */
437e2ff1 2652 switch (*++oparg)
e23eba97 2653 {
dcd709e0 2654 case 's': /* RS1 x8-x15. */
437e2ff1 2655 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2656 || !(regno >= 8 && regno <= 15))
2657 break;
2658 INSERT_OPERAND (CRS1S, *ip, regno % 8);
2659 continue;
2660 case 'w': /* RS1 x8-x15, constrained to equal RD x8-x15. */
437e2ff1 2661 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2662 || EXTRACT_OPERAND (CRS1S, ip->insn_opcode) + 8 != regno)
2663 break;
2664 continue;
dcd709e0 2665 case 't': /* RS2 x8-x15. */
437e2ff1 2666 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2667 || !(regno >= 8 && regno <= 15))
2668 break;
2669 INSERT_OPERAND (CRS2S, *ip, regno % 8);
2670 continue;
2671 case 'x': /* RS2 x8-x15, constrained to equal RD x8-x15. */
437e2ff1 2672 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2673 || EXTRACT_OPERAND (CRS2S, ip->insn_opcode) + 8 != regno)
2674 break;
2675 continue;
2676 case 'U': /* RS1, constrained to equal RD. */
437e2ff1 2677 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2678 || EXTRACT_OPERAND (RD, ip->insn_opcode) != regno)
2679 break;
2680 continue;
2681 case 'V': /* RS2 */
437e2ff1 2682 if (!reg_lookup (&asarg, RCLASS_GPR, &regno))
e23eba97
NC
2683 break;
2684 INSERT_OPERAND (CRS2, *ip, regno);
2685 continue;
2686 case 'c': /* RS1, constrained to equal sp. */
437e2ff1 2687 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2688 || regno != X_SP)
2689 break;
2690 continue;
dcd709e0 2691 case 'z': /* RS2, constrained to equal x0. */
437e2ff1 2692 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
ca0bc150
JW
2693 || regno != 0)
2694 break;
2695 continue;
768589d1 2696 case '>': /* Shift amount, 0 - (XLEN-1). */
437e2ff1 2697 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2698 || imm_expr->X_op != O_constant
768589d1 2699 || (unsigned long) imm_expr->X_add_number >= xlen)
e23eba97 2700 break;
5a9f5403 2701 ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
dc1e8a47 2702 rvc_imm_done:
6eb099ae 2703 asarg = expr_parse_end;
e23eba97
NC
2704 imm_expr->X_op = O_absent;
2705 continue;
5a9f5403 2706 case '5':
437e2ff1 2707 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2708 || imm_expr->X_op != O_constant
5a9f5403 2709 || imm_expr->X_add_number < 0
169ec512 2710 || imm_expr->X_add_number >= 32
5a9f5403 2711 || !VALID_CLTYPE_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2712 break;
0257c2ff 2713 ip->insn_opcode |= ENCODE_CLTYPE_IMM (imm_expr->X_add_number);
e23eba97 2714 goto rvc_imm_done;
5a9f5403 2715 case '6':
437e2ff1 2716 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d 2717 || imm_expr->X_op != O_constant
0e35537d 2718 || imm_expr->X_add_number < 0
5a9f5403
NC
2719 || imm_expr->X_add_number >= 64
2720 || !VALID_CSSTYPE_IMM ((valueT) imm_expr->X_add_number))
0e35537d 2721 break;
0257c2ff 2722 ip->insn_opcode |= ENCODE_CSSTYPE_IMM (imm_expr->X_add_number);
0e35537d 2723 goto rvc_imm_done;
5a9f5403 2724 case '8':
437e2ff1 2725 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2726 || imm_expr->X_op != O_constant
5a9f5403
NC
2727 || imm_expr->X_add_number < 0
2728 || imm_expr->X_add_number >= 256
2729 || !VALID_CIWTYPE_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2730 break;
0257c2ff 2731 ip->insn_opcode |= ENCODE_CIWTYPE_IMM (imm_expr->X_add_number);
e23eba97
NC
2732 goto rvc_imm_done;
2733 case 'j':
437e2ff1 2734 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97
NC
2735 || imm_expr->X_op != O_constant
2736 || imm_expr->X_add_number == 0
5a9f5403 2737 || !VALID_CITYPE_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2738 break;
5a9f5403 2739 ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
e23eba97
NC
2740 goto rvc_imm_done;
2741 case 'k':
437e2ff1 2742 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2743 continue;
437e2ff1 2744 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2745 || imm_expr->X_op != O_constant
5a9f5403 2746 || !VALID_CLTYPE_LW_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2747 break;
5a9f5403 2748 ip->insn_opcode |= ENCODE_CLTYPE_LW_IMM (imm_expr->X_add_number);
e23eba97
NC
2749 goto rvc_imm_done;
2750 case 'l':
437e2ff1 2751 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2752 continue;
437e2ff1 2753 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2754 || imm_expr->X_op != O_constant
5a9f5403 2755 || !VALID_CLTYPE_LD_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2756 break;
5a9f5403 2757 ip->insn_opcode |= ENCODE_CLTYPE_LD_IMM (imm_expr->X_add_number);
e23eba97
NC
2758 goto rvc_imm_done;
2759 case 'm':
437e2ff1 2760 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2761 continue;
437e2ff1 2762 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2763 || imm_expr->X_op != O_constant
5a9f5403 2764 || !VALID_CITYPE_LWSP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2765 break;
2766 ip->insn_opcode |=
5a9f5403 2767 ENCODE_CITYPE_LWSP_IMM (imm_expr->X_add_number);
e23eba97
NC
2768 goto rvc_imm_done;
2769 case 'n':
437e2ff1 2770 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2771 continue;
437e2ff1 2772 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2773 || imm_expr->X_op != O_constant
5a9f5403 2774 || !VALID_CITYPE_LDSP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2775 break;
2776 ip->insn_opcode |=
5a9f5403 2777 ENCODE_CITYPE_LDSP_IMM (imm_expr->X_add_number);
e23eba97 2778 goto rvc_imm_done;
b416fe87 2779 case 'o':
437e2ff1 2780 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
b416fe87 2781 || imm_expr->X_op != O_constant
21a186f2
JW
2782 /* C.addiw, c.li, and c.andi allow zero immediate.
2783 C.addi allows zero immediate as hint. Otherwise this
2784 is same as 'j'. */
5a9f5403 2785 || !VALID_CITYPE_IMM ((valueT) imm_expr->X_add_number))
b416fe87 2786 break;
5a9f5403 2787 ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
b416fe87 2788 goto rvc_imm_done;
e23eba97 2789 case 'K':
437e2ff1 2790 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2791 || imm_expr->X_op != O_constant
169ec512 2792 || imm_expr->X_add_number == 0
5a9f5403 2793 || !VALID_CIWTYPE_ADDI4SPN_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2794 break;
2795 ip->insn_opcode |=
5a9f5403 2796 ENCODE_CIWTYPE_ADDI4SPN_IMM (imm_expr->X_add_number);
e23eba97
NC
2797 goto rvc_imm_done;
2798 case 'L':
437e2ff1 2799 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2800 || imm_expr->X_op != O_constant
5a9f5403 2801 || !VALID_CITYPE_ADDI16SP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2802 break;
2803 ip->insn_opcode |=
5a9f5403 2804 ENCODE_CITYPE_ADDI16SP_IMM (imm_expr->X_add_number);
e23eba97
NC
2805 goto rvc_imm_done;
2806 case 'M':
437e2ff1 2807 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2808 continue;
437e2ff1 2809 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2810 || imm_expr->X_op != O_constant
5a9f5403 2811 || !VALID_CSSTYPE_SWSP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2812 break;
2813 ip->insn_opcode |=
5a9f5403 2814 ENCODE_CSSTYPE_SWSP_IMM (imm_expr->X_add_number);
e23eba97
NC
2815 goto rvc_imm_done;
2816 case 'N':
437e2ff1 2817 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2818 continue;
437e2ff1 2819 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2820 || imm_expr->X_op != O_constant
5a9f5403 2821 || !VALID_CSSTYPE_SDSP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2822 break;
2823 ip->insn_opcode |=
5a9f5403 2824 ENCODE_CSSTYPE_SDSP_IMM (imm_expr->X_add_number);
e23eba97
NC
2825 goto rvc_imm_done;
2826 case 'u':
2827 p = percent_op_utype;
437e2ff1 2828 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p))
e23eba97 2829 break;
dc1e8a47 2830 rvc_lui:
e23eba97
NC
2831 if (imm_expr->X_op != O_constant
2832 || imm_expr->X_add_number <= 0
2833 || imm_expr->X_add_number >= RISCV_BIGIMM_REACH
2834 || (imm_expr->X_add_number >= RISCV_RVC_IMM_REACH / 2
2835 && (imm_expr->X_add_number <
2836 RISCV_BIGIMM_REACH - RISCV_RVC_IMM_REACH / 2)))
2837 break;
5a9f5403 2838 ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
e23eba97
NC
2839 goto rvc_imm_done;
2840 case 'v':
437e2ff1 2841 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97
NC
2842 || (imm_expr->X_add_number & (RISCV_IMM_REACH - 1))
2843 || ((int32_t)imm_expr->X_add_number
2844 != imm_expr->X_add_number))
2845 break;
2846 imm_expr->X_add_number =
2847 ((uint32_t) imm_expr->X_add_number) >> RISCV_IMM_BITS;
2848 goto rvc_lui;
2849 case 'p':
2850 goto branch;
2851 case 'a':
2852 goto jump;
0e35537d 2853 case 'S': /* Floating-point RS1 x8-x15. */
437e2ff1 2854 if (!reg_lookup (&asarg, RCLASS_FPR, &regno)
0e35537d
JW
2855 || !(regno >= 8 && regno <= 15))
2856 break;
2857 INSERT_OPERAND (CRS1S, *ip, regno % 8);
2858 continue;
e23eba97 2859 case 'D': /* Floating-point RS2 x8-x15. */
437e2ff1 2860 if (!reg_lookup (&asarg, RCLASS_FPR, &regno)
e23eba97
NC
2861 || !(regno >= 8 && regno <= 15))
2862 break;
2863 INSERT_OPERAND (CRS2S, *ip, regno % 8);
2864 continue;
2865 case 'T': /* Floating-point RS2. */
437e2ff1 2866 if (!reg_lookup (&asarg, RCLASS_FPR, &regno))
e23eba97
NC
2867 break;
2868 INSERT_OPERAND (CRS2, *ip, regno);
2869 continue;
0e35537d 2870 case 'F':
437e2ff1 2871 switch (*++oparg)
0e35537d 2872 {
4765cd61 2873 case '6':
437e2ff1 2874 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
4765cd61
JW
2875 || imm_expr->X_op != O_constant
2876 || imm_expr->X_add_number < 0
2877 || imm_expr->X_add_number >= 64)
2878 {
b800637e 2879 as_bad (_("bad value for compressed funct6 "
b215cdf5 2880 "field, value must be 0...63"));
4765cd61
JW
2881 break;
2882 }
4765cd61
JW
2883 INSERT_OPERAND (CFUNCT6, *ip, imm_expr->X_add_number);
2884 imm_expr->X_op = O_absent;
6eb099ae 2885 asarg = expr_parse_end;
4765cd61 2886 continue;
1942a048 2887
0e35537d 2888 case '4':
437e2ff1 2889 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
2890 || imm_expr->X_op != O_constant
2891 || imm_expr->X_add_number < 0
2892 || imm_expr->X_add_number >= 16)
2893 {
b800637e
NC
2894 as_bad (_("bad value for compressed funct4 "
2895 "field, value must be 0...15"));
0e35537d
JW
2896 break;
2897 }
0e35537d
JW
2898 INSERT_OPERAND (CFUNCT4, *ip, imm_expr->X_add_number);
2899 imm_expr->X_op = O_absent;
6eb099ae 2900 asarg = expr_parse_end;
0e35537d 2901 continue;
1942a048 2902
0e35537d 2903 case '3':
437e2ff1 2904 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
2905 || imm_expr->X_op != O_constant
2906 || imm_expr->X_add_number < 0
2907 || imm_expr->X_add_number >= 8)
2908 {
b800637e
NC
2909 as_bad (_("bad value for compressed funct3 "
2910 "field, value must be 0...7"));
0e35537d
JW
2911 break;
2912 }
2913 INSERT_OPERAND (CFUNCT3, *ip, imm_expr->X_add_number);
2914 imm_expr->X_op = O_absent;
6eb099ae 2915 asarg = expr_parse_end;
0e35537d 2916 continue;
1942a048 2917
4765cd61 2918 case '2':
437e2ff1 2919 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
4765cd61
JW
2920 || imm_expr->X_op != O_constant
2921 || imm_expr->X_add_number < 0
2922 || imm_expr->X_add_number >= 4)
2923 {
b800637e
NC
2924 as_bad (_("bad value for compressed funct2 "
2925 "field, value must be 0...3"));
4765cd61
JW
2926 break;
2927 }
2928 INSERT_OPERAND (CFUNCT2, *ip, imm_expr->X_add_number);
2929 imm_expr->X_op = O_absent;
6eb099ae 2930 asarg = expr_parse_end;
4765cd61 2931 continue;
1942a048 2932
0e35537d 2933 default:
437e2ff1 2934 goto unknown_riscv_ip_operand;
0e35537d
JW
2935 }
2936 break;
2937
e23eba97 2938 default:
437e2ff1 2939 goto unknown_riscv_ip_operand;
e23eba97 2940 }
a63375ac 2941 break; /* end RVC */
e23eba97 2942
65e4a99a
NC
2943 case 'V': /* RVV */
2944 switch (*++oparg)
2945 {
2946 case 'd': /* VD */
2947 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2948 break;
2949 INSERT_OPERAND (VD, *ip, regno);
2950 continue;
2951
2952 case 'e': /* AMO VD */
2953 if (reg_lookup (&asarg, RCLASS_GPR, &regno) && regno == 0)
2954 INSERT_OPERAND (VWD, *ip, 0);
2955 else if (reg_lookup (&asarg, RCLASS_VECR, &regno))
2956 {
2957 INSERT_OPERAND (VWD, *ip, 1);
2958 INSERT_OPERAND (VD, *ip, regno);
2959 }
2960 else
2961 break;
2962 continue;
2963
2964 case 'f': /* AMO VS3 */
2965 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2966 break;
2967 if (!EXTRACT_OPERAND (VWD, ip->insn_opcode))
2968 INSERT_OPERAND (VD, *ip, regno);
2969 else
2970 {
2971 /* VS3 must match VD. */
2972 if (EXTRACT_OPERAND (VD, ip->insn_opcode) != regno)
2973 break;
2974 }
2975 continue;
2976
2977 case 's': /* VS1 */
2978 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2979 break;
2980 INSERT_OPERAND (VS1, *ip, regno);
2981 continue;
2982
2983 case 't': /* VS2 */
2984 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2985 break;
2986 INSERT_OPERAND (VS2, *ip, regno);
2987 continue;
2988
2989 case 'u': /* VS1 == VS2 */
2990 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2991 break;
2992 INSERT_OPERAND (VS1, *ip, regno);
2993 INSERT_OPERAND (VS2, *ip, regno);
2994 continue;
2995
2996 case 'v': /* VD == VS1 == VS2 */
2997 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2998 break;
2999 INSERT_OPERAND (VD, *ip, regno);
3000 INSERT_OPERAND (VS1, *ip, regno);
3001 INSERT_OPERAND (VS2, *ip, regno);
3002 continue;
3003
3004 /* The `V0` is carry-in register for v[m]adc and v[m]sbc,
3005 and is used to choose vs1/rs1/frs1/imm or vs2 for
3006 v[f]merge. It use the same encoding as the vector mask
3007 register. */
3008 case '0':
3009 if (reg_lookup (&asarg, RCLASS_VECR, &regno) && regno == 0)
3010 continue;
3011 break;
3012
3013 case 'b': /* vtypei for vsetivli */
3014 my_getVsetvliExpression (imm_expr, asarg);
3015 check_absolute_expr (ip, imm_expr, FALSE);
3016 if (!VALID_RVV_VB_IMM (imm_expr->X_add_number))
3017 as_bad (_("bad value for vsetivli immediate field, "
3018 "value must be 0..1023"));
3019 ip->insn_opcode
3020 |= ENCODE_RVV_VB_IMM (imm_expr->X_add_number);
3021 imm_expr->X_op = O_absent;
6eb099ae 3022 asarg = expr_parse_end;
65e4a99a
NC
3023 continue;
3024
3025 case 'c': /* vtypei for vsetvli */
3026 my_getVsetvliExpression (imm_expr, asarg);
3027 check_absolute_expr (ip, imm_expr, FALSE);
3028 if (!VALID_RVV_VC_IMM (imm_expr->X_add_number))
3029 as_bad (_("bad value for vsetvli immediate field, "
3030 "value must be 0..2047"));
3031 ip->insn_opcode
3032 |= ENCODE_RVV_VC_IMM (imm_expr->X_add_number);
3033 imm_expr->X_op = O_absent;
6eb099ae 3034 asarg = expr_parse_end;
65e4a99a
NC
3035 continue;
3036
3037 case 'i': /* vector arith signed immediate */
3038 my_getExpression (imm_expr, asarg);
3039 check_absolute_expr (ip, imm_expr, FALSE);
3040 if (imm_expr->X_add_number > 15
3041 || imm_expr->X_add_number < -16)
3042 as_bad (_("bad value for vector immediate field, "
3043 "value must be -16...15"));
3044 INSERT_OPERAND (VIMM, *ip, imm_expr->X_add_number);
3045 imm_expr->X_op = O_absent;
6eb099ae 3046 asarg = expr_parse_end;
65e4a99a
NC
3047 continue;
3048
3049 case 'j': /* vector arith unsigned immediate */
3050 my_getExpression (imm_expr, asarg);
3051 check_absolute_expr (ip, imm_expr, FALSE);
3052 if (imm_expr->X_add_number < 0
3053 || imm_expr->X_add_number >= 32)
3054 as_bad (_("bad value for vector immediate field, "
3055 "value must be 0...31"));
3056 INSERT_OPERAND (VIMM, *ip, imm_expr->X_add_number);
3057 imm_expr->X_op = O_absent;
6eb099ae 3058 asarg = expr_parse_end;
65e4a99a
NC
3059 continue;
3060
3061 case 'k': /* vector arith signed immediate, minus 1 */
3062 my_getExpression (imm_expr, asarg);
3063 check_absolute_expr (ip, imm_expr, FALSE);
3064 if (imm_expr->X_add_number > 16
3065 || imm_expr->X_add_number < -15)
3066 as_bad (_("bad value for vector immediate field, "
3067 "value must be -15...16"));
3068 INSERT_OPERAND (VIMM, *ip, imm_expr->X_add_number - 1);
3069 imm_expr->X_op = O_absent;
6eb099ae 3070 asarg = expr_parse_end;
65e4a99a
NC
3071 continue;
3072
c8cb3734
CM
3073 case 'l': /* 6-bit vector arith unsigned immediate */
3074 my_getExpression (imm_expr, asarg);
3075 check_absolute_expr (ip, imm_expr, FALSE);
3076 if (imm_expr->X_add_number < 0
3077 || imm_expr->X_add_number >= 64)
3078 as_bad (_("bad value for vector immediate field, "
3079 "value must be 0...63"));
3080 ip->insn_opcode |= ENCODE_RVV_VI_UIMM6 (imm_expr->X_add_number);
3081 imm_expr->X_op = O_absent;
3082 asarg = expr_parse_end;
3083 continue;
3084
65e4a99a
NC
3085 case 'm': /* optional vector mask */
3086 if (*asarg == '\0')
3087 {
3088 INSERT_OPERAND (VMASK, *ip, 1);
3089 continue;
3090 }
3091 else if (*asarg == ',' && asarg++
3092 && reg_lookup (&asarg, RCLASS_VECM, &regno)
3093 && regno == 0)
3094 {
3095 INSERT_OPERAND (VMASK, *ip, 0);
3096 continue;
3097 }
3098 break;
3099
3100 case 'M': /* required vector mask */
3101 if (reg_lookup (&asarg, RCLASS_VECM, &regno) && regno == 0)
3102 {
3103 INSERT_OPERAND (VMASK, *ip, 0);
3104 continue;
3105 }
3106 break;
3107
3108 case 'T': /* vector macro temporary register */
3109 if (!reg_lookup (&asarg, RCLASS_VECR, &regno) || regno == 0)
3110 break;
3111 /* Store it in the FUNCT6 field as we don't have anyplace
3112 else to store it. */
3113 INSERT_OPERAND (VFUNCT6, *ip, regno);
3114 continue;
3115
3116 default:
3117 goto unknown_riscv_ip_operand;
3118 }
a63375ac 3119 break; /* end RVV */
65e4a99a 3120
e23eba97 3121 case ',':
437e2ff1 3122 if (*asarg++ == *oparg)
e23eba97 3123 continue;
437e2ff1 3124 asarg--;
e23eba97
NC
3125 break;
3126
3127 case '(':
3128 case ')':
3129 case '[':
3130 case ']':
437e2ff1 3131 if (*asarg++ == *oparg)
e23eba97
NC
3132 continue;
3133 break;
3134
dcd709e0 3135 case '<': /* Shift amount, 0 - 31. */
437e2ff1 3136 my_getExpression (imm_expr, asarg);
5b7c81bd 3137 check_absolute_expr (ip, imm_expr, false);
e23eba97 3138 if ((unsigned long) imm_expr->X_add_number > 31)
a6eeb20a
CM
3139 as_bad (_("improper shift amount (%"PRIu64")"),
3140 imm_expr->X_add_number);
e23eba97
NC
3141 INSERT_OPERAND (SHAMTW, *ip, imm_expr->X_add_number);
3142 imm_expr->X_op = O_absent;
6eb099ae 3143 asarg = expr_parse_end;
e23eba97
NC
3144 continue;
3145
dcd709e0 3146 case '>': /* Shift amount, 0 - (XLEN-1). */
437e2ff1 3147 my_getExpression (imm_expr, asarg);
5b7c81bd 3148 check_absolute_expr (ip, imm_expr, false);
e23eba97 3149 if ((unsigned long) imm_expr->X_add_number >= xlen)
a6eeb20a
CM
3150 as_bad (_("improper shift amount (%"PRIu64")"),
3151 imm_expr->X_add_number);
e23eba97
NC
3152 INSERT_OPERAND (SHAMT, *ip, imm_expr->X_add_number);
3153 imm_expr->X_op = O_absent;
6eb099ae 3154 asarg = expr_parse_end;
e23eba97
NC
3155 continue;
3156
dcd709e0 3157 case 'Z': /* CSRRxI immediate. */
437e2ff1 3158 my_getExpression (imm_expr, asarg);
5b7c81bd 3159 check_absolute_expr (ip, imm_expr, false);
e23eba97 3160 if ((unsigned long) imm_expr->X_add_number > 31)
a6eeb20a
CM
3161 as_bad (_("improper CSRxI immediate (%"PRIu64")"),
3162 imm_expr->X_add_number);
e23eba97
NC
3163 INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
3164 imm_expr->X_op = O_absent;
6eb099ae 3165 asarg = expr_parse_end;
e23eba97
NC
3166 continue;
3167
dcd709e0 3168 case 'E': /* Control register. */
5b7c81bd
AM
3169 insn_with_csr = true;
3170 explicit_priv_attr = true;
437e2ff1 3171 if (reg_lookup (&asarg, RCLASS_CSR, &regno))
e23eba97
NC
3172 INSERT_OPERAND (CSR, *ip, regno);
3173 else
3174 {
437e2ff1 3175 my_getExpression (imm_expr, asarg);
5b7c81bd 3176 check_absolute_expr (ip, imm_expr, true);
e23eba97 3177 if ((unsigned long) imm_expr->X_add_number > 0xfff)
a6eeb20a
CM
3178 as_bad (_("improper CSR address (%"PRIu64")"),
3179 imm_expr->X_add_number);
e23eba97
NC
3180 INSERT_OPERAND (CSR, *ip, imm_expr->X_add_number);
3181 imm_expr->X_op = O_absent;
6eb099ae 3182 asarg = expr_parse_end;
e23eba97
NC
3183 }
3184 continue;
3185
dcd709e0 3186 case 'm': /* Rounding mode. */
437e2ff1
NC
3187 if (arg_lookup (&asarg, riscv_rm,
3188 ARRAY_SIZE (riscv_rm), &regno))
e23eba97
NC
3189 {
3190 INSERT_OPERAND (RM, *ip, regno);
3191 continue;
3192 }
3193 break;
3194
3195 case 'P':
dcd709e0 3196 case 'Q': /* Fence predecessor/successor. */
437e2ff1
NC
3197 if (arg_lookup (&asarg, riscv_pred_succ,
3198 ARRAY_SIZE (riscv_pred_succ), &regno))
e23eba97 3199 {
437e2ff1 3200 if (*oparg == 'P')
e23eba97
NC
3201 INSERT_OPERAND (PRED, *ip, regno);
3202 else
3203 INSERT_OPERAND (SUCC, *ip, regno);
3204 continue;
3205 }
3206 break;
3207
dcd709e0
NC
3208 case 'd': /* Destination register. */
3209 case 's': /* Source register. */
3210 case 't': /* Target register. */
3211 case 'r': /* RS3 */
437e2ff1 3212 if (reg_lookup (&asarg, RCLASS_GPR, &regno))
e23eba97 3213 {
437e2ff1
NC
3214 char c = *oparg;
3215 if (*asarg == ' ')
3216 ++asarg;
e23eba97
NC
3217
3218 /* Now that we have assembled one operand, we use the args
3219 string to figure out where it goes in the instruction. */
3220 switch (c)
3221 {
3222 case 's':
3223 INSERT_OPERAND (RS1, *ip, regno);
3224 break;
3225 case 'd':
3226 INSERT_OPERAND (RD, *ip, regno);
3227 break;
3228 case 't':
3229 INSERT_OPERAND (RS2, *ip, regno);
3230 break;
0e35537d
JW
3231 case 'r':
3232 INSERT_OPERAND (RS3, *ip, regno);
3233 break;
e23eba97
NC
3234 }
3235 continue;
3236 }
3237 break;
3238
dcd709e0
NC
3239 case 'D': /* Floating point RD. */
3240 case 'S': /* Floating point RS1. */
3241 case 'T': /* Floating point RS2. */
3242 case 'U': /* Floating point RS1 and RS2. */
3243 case 'R': /* Floating point RS3. */
de83e514 3244 if (reg_lookup (&asarg,
3245 (riscv_subset_supports (&riscv_rps_as, "zfinx")
3246 ? RCLASS_GPR : RCLASS_FPR), &regno))
e23eba97 3247 {
437e2ff1
NC
3248 char c = *oparg;
3249 if (*asarg == ' ')
3250 ++asarg;
e23eba97
NC
3251 switch (c)
3252 {
3253 case 'D':
3254 INSERT_OPERAND (RD, *ip, regno);
3255 break;
3256 case 'S':
3257 INSERT_OPERAND (RS1, *ip, regno);
3258 break;
3259 case 'U':
3260 INSERT_OPERAND (RS1, *ip, regno);
dcd709e0 3261 /* Fall through. */
e23eba97
NC
3262 case 'T':
3263 INSERT_OPERAND (RS2, *ip, regno);
3264 break;
3265 case 'R':
3266 INSERT_OPERAND (RS3, *ip, regno);
3267 break;
3268 }
3269 continue;
3270 }
e23eba97
NC
3271 break;
3272
3273 case 'I':
437e2ff1 3274 my_getExpression (imm_expr, asarg);
e23eba97
NC
3275 if (imm_expr->X_op != O_big
3276 && imm_expr->X_op != O_constant)
3277 break;
3278 normalize_constant_expr (imm_expr);
6eb099ae 3279 asarg = expr_parse_end;
e23eba97
NC
3280 continue;
3281
3282 case 'A':
437e2ff1 3283 my_getExpression (imm_expr, asarg);
e23eba97
NC
3284 normalize_constant_expr (imm_expr);
3285 /* The 'A' format specifier must be a symbol. */
3286 if (imm_expr->X_op != O_symbol)
3287 break;
3288 *imm_reloc = BFD_RELOC_32;
6eb099ae 3289 asarg = expr_parse_end;
e23eba97
NC
3290 continue;
3291
160d1b3d 3292 case 'B':
437e2ff1 3293 my_getExpression (imm_expr, asarg);
160d1b3d
SH
3294 normalize_constant_expr (imm_expr);
3295 /* The 'B' format specifier must be a symbol or a constant. */
3296 if (imm_expr->X_op != O_symbol && imm_expr->X_op != O_constant)
3297 break;
3298 if (imm_expr->X_op == O_symbol)
3299 *imm_reloc = BFD_RELOC_32;
6eb099ae 3300 asarg = expr_parse_end;
160d1b3d
SH
3301 continue;
3302
e23eba97 3303 case 'j': /* Sign-extended immediate. */
e23eba97 3304 p = percent_op_itype;
f50fabe4 3305 *imm_reloc = BFD_RELOC_RISCV_LO12_I;
e23eba97
NC
3306 goto alu_op;
3307 case 'q': /* Store displacement. */
3308 p = percent_op_stype;
3309 *imm_reloc = BFD_RELOC_RISCV_LO12_S;
3310 goto load_store;
3311 case 'o': /* Load displacement. */
3312 p = percent_op_itype;
3313 *imm_reloc = BFD_RELOC_RISCV_LO12_I;
3314 goto load_store;
dcd709e0
NC
3315 case '1':
3316 /* This is used for TLS, where the fourth operand is
3317 %tprel_add, to get a relocation applied to an add
3318 instruction, for relaxation to use. */
e23eba97 3319 p = percent_op_rtype;
f50fabe4 3320 goto alu_op;
dcd709e0 3321 case '0': /* AMO displacement, which must be zero. */
dc1e8a47 3322 load_store:
437e2ff1 3323 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
e23eba97 3324 continue;
dc1e8a47 3325 alu_op:
e23eba97
NC
3326 /* If this value won't fit into a 16 bit offset, then go
3327 find a macro that will generate the 32 bit offset
3328 code pattern. */
437e2ff1 3329 if (!my_getSmallExpression (imm_expr, imm_reloc, asarg, p))
e23eba97
NC
3330 {
3331 normalize_constant_expr (imm_expr);
3332 if (imm_expr->X_op != O_constant
437e2ff1
NC
3333 || (*oparg == '0' && imm_expr->X_add_number != 0)
3334 || (*oparg == '1')
e23eba97
NC
3335 || imm_expr->X_add_number >= (signed)RISCV_IMM_REACH/2
3336 || imm_expr->X_add_number < -(signed)RISCV_IMM_REACH/2)
3337 break;
3338 }
6eb099ae 3339 asarg = expr_parse_end;
e23eba97
NC
3340 continue;
3341
dcd709e0 3342 case 'p': /* PC-relative offset. */
dc1e8a47 3343 branch:
e23eba97 3344 *imm_reloc = BFD_RELOC_12_PCREL;
437e2ff1 3345 my_getExpression (imm_expr, asarg);
6eb099ae 3346 asarg = expr_parse_end;
e23eba97
NC
3347 continue;
3348
dcd709e0 3349 case 'u': /* Upper 20 bits. */
e23eba97 3350 p = percent_op_utype;
437e2ff1 3351 if (!my_getSmallExpression (imm_expr, imm_reloc, asarg, p))
e23eba97 3352 {
4288405d
JW
3353 if (imm_expr->X_op != O_constant)
3354 break;
3355
e23eba97
NC
3356 if (imm_expr->X_add_number < 0
3357 || imm_expr->X_add_number >= (signed)RISCV_BIGIMM_REACH)
3358 as_bad (_("lui expression not in range 0..1048575"));
3359
3360 *imm_reloc = BFD_RELOC_RISCV_HI20;
3361 imm_expr->X_add_number <<= RISCV_IMM_BITS;
3362 }
6eb099ae 3363 asarg = expr_parse_end;
e23eba97
NC
3364 continue;
3365
dcd709e0 3366 case 'a': /* 20-bit PC-relative offset. */
dc1e8a47 3367 jump:
437e2ff1 3368 my_getExpression (imm_expr, asarg);
6eb099ae 3369 asarg = expr_parse_end;
e23eba97
NC
3370 *imm_reloc = BFD_RELOC_RISCV_JMP;
3371 continue;
3372
3373 case 'c':
437e2ff1 3374 my_getExpression (imm_expr, asarg);
6eb099ae 3375 asarg = expr_parse_end;
437e2ff1 3376 if (strcmp (asarg, "@plt") == 0)
70f35d72
NC
3377 asarg += 4;
3378 *imm_reloc = BFD_RELOC_RISCV_CALL_PLT;
e23eba97 3379 continue;
1942a048 3380
0e35537d 3381 case 'O':
437e2ff1 3382 switch (*++oparg)
0e35537d
JW
3383 {
3384 case '4':
408ab016 3385 if (my_getOpcodeExpression (imm_expr, imm_reloc, asarg)
0e35537d
JW
3386 || imm_expr->X_op != O_constant
3387 || imm_expr->X_add_number < 0
3388 || imm_expr->X_add_number >= 128
3389 || (imm_expr->X_add_number & 0x3) != 3)
3390 {
3391 as_bad (_("bad value for opcode field, "
3392 "value must be 0...127 and "
3393 "lower 2 bits must be 0x3"));
3394 break;
3395 }
0e35537d
JW
3396 INSERT_OPERAND (OP, *ip, imm_expr->X_add_number);
3397 imm_expr->X_op = O_absent;
6eb099ae 3398 asarg = expr_parse_end;
0e35537d 3399 continue;
1942a048 3400
0e35537d 3401 case '2':
408ab016 3402 if (my_getOpcodeExpression (imm_expr, imm_reloc, asarg)
0e35537d
JW
3403 || imm_expr->X_op != O_constant
3404 || imm_expr->X_add_number < 0
3405 || imm_expr->X_add_number >= 3)
3406 {
3407 as_bad (_("bad value for opcode field, "
3408 "value must be 0...2"));
3409 break;
3410 }
0e35537d
JW
3411 INSERT_OPERAND (OP2, *ip, imm_expr->X_add_number);
3412 imm_expr->X_op = O_absent;
6eb099ae 3413 asarg = expr_parse_end;
0e35537d 3414 continue;
1942a048 3415
0e35537d 3416 default:
437e2ff1 3417 goto unknown_riscv_ip_operand;
0e35537d
JW
3418 }
3419 break;
3420
3421 case 'F':
437e2ff1 3422 switch (*++oparg)
0e35537d
JW
3423 {
3424 case '7':
437e2ff1 3425 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
3426 || imm_expr->X_op != O_constant
3427 || imm_expr->X_add_number < 0
3428 || imm_expr->X_add_number >= 128)
3429 {
3430 as_bad (_("bad value for funct7 field, "
3431 "value must be 0...127"));
3432 break;
3433 }
0e35537d
JW
3434 INSERT_OPERAND (FUNCT7, *ip, imm_expr->X_add_number);
3435 imm_expr->X_op = O_absent;
6eb099ae 3436 asarg = expr_parse_end;
0e35537d 3437 continue;
1942a048 3438
0e35537d 3439 case '3':
437e2ff1 3440 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
3441 || imm_expr->X_op != O_constant
3442 || imm_expr->X_add_number < 0
3443 || imm_expr->X_add_number >= 8)
3444 {
3445 as_bad (_("bad value for funct3 field, "
3446 "value must be 0...7"));
3447 break;
3448 }
0e35537d
JW
3449 INSERT_OPERAND (FUNCT3, *ip, imm_expr->X_add_number);
3450 imm_expr->X_op = O_absent;
6eb099ae 3451 asarg = expr_parse_end;
0e35537d 3452 continue;
1942a048 3453
0e35537d 3454 case '2':
437e2ff1 3455 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
3456 || imm_expr->X_op != O_constant
3457 || imm_expr->X_add_number < 0
3458 || imm_expr->X_add_number >= 4)
3459 {
3460 as_bad (_("bad value for funct2 field, "
3461 "value must be 0...3"));
3462 break;
3463 }
0e35537d
JW
3464 INSERT_OPERAND (FUNCT2, *ip, imm_expr->X_add_number);
3465 imm_expr->X_op = O_absent;
6eb099ae 3466 asarg = expr_parse_end;
0e35537d
JW
3467 continue;
3468
3469 default:
437e2ff1 3470 goto unknown_riscv_ip_operand;
0e35537d
JW
3471 }
3472 break;
e23eba97 3473
3d1cafa0 3474 case 'y': /* bs immediate */
3475 my_getExpression (imm_expr, asarg);
3476 check_absolute_expr (ip, imm_expr, FALSE);
3477 if ((unsigned long)imm_expr->X_add_number > 3)
3478 as_bad(_("Improper bs immediate (%lu)"),
3479 (unsigned long)imm_expr->X_add_number);
3480 INSERT_OPERAND(BS, *ip, imm_expr->X_add_number);
3481 imm_expr->X_op = O_absent;
6eb099ae 3482 asarg = expr_parse_end;
3d1cafa0 3483 continue;
3484
3485 case 'Y': /* rnum immediate */
3486 my_getExpression (imm_expr, asarg);
3487 check_absolute_expr (ip, imm_expr, FALSE);
3488 if ((unsigned long)imm_expr->X_add_number > 10)
3489 as_bad(_("Improper rnum immediate (%lu)"),
3490 (unsigned long)imm_expr->X_add_number);
3491 INSERT_OPERAND(RNUM, *ip, imm_expr->X_add_number);
3492 imm_expr->X_op = O_absent;
6eb099ae 3493 asarg = expr_parse_end;
3d1cafa0 3494 continue;
3495
e925c834 3496 case 'z':
437e2ff1 3497 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e925c834
JW
3498 || imm_expr->X_op != O_constant
3499 || imm_expr->X_add_number != 0)
3500 break;
6eb099ae 3501 asarg = expr_parse_end;
e925c834
JW
3502 imm_expr->X_op = O_absent;
3503 continue;
3504
54bca63b
TO
3505 case 'W': /* Various operands. */
3506 switch (*++oparg)
3507 {
3508 case 'i':
3509 switch (*++oparg)
3510 {
3511 case 'f':
3512 /* Prefetch offset for 'Zicbop' extension.
3513 pseudo S-type but lower 5-bits zero. */
3514 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
3515 continue;
3516 my_getExpression (imm_expr, asarg);
3517 check_absolute_expr (ip, imm_expr, false);
3518 if (((unsigned) (imm_expr->X_add_number) & 0x1fU)
3519 || imm_expr->X_add_number >= RISCV_IMM_REACH / 2
3520 || imm_expr->X_add_number < -RISCV_IMM_REACH / 2)
3521 as_bad (_ ("improper prefetch offset (%ld)"),
3522 (long) imm_expr->X_add_number);
3523 ip->insn_opcode |= ENCODE_STYPE_IMM (
3524 (unsigned) (imm_expr->X_add_number) & ~0x1fU);
3525 imm_expr->X_op = O_absent;
3526 asarg = expr_parse_end;
3527 continue;
3528 default:
3529 goto unknown_riscv_ip_operand;
3530 }
3531 break;
1f3fc45b
CM
3532 case 'f':
3533 switch (*++oparg)
3534 {
3535 case 'v':
3536 /* FLI.[HSDQ] value field for 'Zfa' extension. */
3537 if (!arg_lookup (&asarg, riscv_fli_symval,
3538 ARRAY_SIZE (riscv_fli_symval), &regno))
3539 {
3540 /* 0.0 is not a valid entry in riscv_fli_numval. */
3541 errno = 0;
3542 float f = strtof (asarg, &asarg);
3543 if (errno != 0 || f == 0.0
3544 || !flt_lookup (f, riscv_fli_numval,
3545 ARRAY_SIZE(riscv_fli_numval),
3546 &regno))
3547 {
3548 as_bad (_("bad fli constant operand, "
3549 "supported constants must be in "
3550 "decimal or hexadecimal floating-point "
3551 "literal form"));
3552 break;
3553 }
3554 }
3555 INSERT_OPERAND (RS1, *ip, regno);
3556 continue;
3557 default:
3558 goto unknown_riscv_ip_operand;
3559 }
3560 break;
54bca63b
TO
3561 default:
3562 goto unknown_riscv_ip_operand;
3563 }
3564 break;
3b374308 3565
8b7419c4
CM
3566 case 'X': /* Integer immediate. */
3567 {
3568 size_t n;
3569 size_t s;
3570 bool sign;
3571
3572 switch (*++oparg)
3573 {
25236d63
CM
3574 case 'l': /* Literal. */
3575 n = strcspn (++oparg, ",");
3576 if (strncmp (oparg, asarg, n))
3577 as_bad (_("unexpected literal (%s)"), asarg);
3578 oparg += n - 1;
3579 asarg += n;
3580 continue;
8b7419c4
CM
3581 case 's': /* 'XsN@S' ... N-bit signed immediate at bit S. */
3582 sign = true;
3583 goto parse_imm;
3584 case 'u': /* 'XuN@S' ... N-bit unsigned immediate at bit S. */
3585 sign = false;
3586 goto parse_imm;
3587 parse_imm:
b0423163 3588 n = strtol (oparg + 1, (char **)&oparg, 10);
8b7419c4
CM
3589 if (*oparg != '@')
3590 goto unknown_riscv_ip_operand;
b0423163 3591 s = strtol (oparg + 1, (char **)&oparg, 10);
8b7419c4
CM
3592 oparg--;
3593
3594 my_getExpression (imm_expr, asarg);
3595 check_absolute_expr (ip, imm_expr, false);
3596 if (!sign)
3597 {
3598 if (!VALIDATE_U_IMM (imm_expr->X_add_number, n))
021205d0
JB
3599 as_bad (_("improper immediate value (%"PRIu64")"),
3600 imm_expr->X_add_number);
8b7419c4
CM
3601 }
3602 else
3603 {
3604 if (!VALIDATE_S_IMM (imm_expr->X_add_number, n))
021205d0
JB
3605 as_bad (_("improper immediate value (%"PRIi64")"),
3606 imm_expr->X_add_number);
8b7419c4
CM
3607 }
3608 INSERT_IMM (n, s, *ip, imm_expr->X_add_number);
3609 imm_expr->X_op = O_absent;
6eb099ae 3610 asarg = expr_parse_end;
8b7419c4
CM
3611 continue;
3612 default:
3613 goto unknown_riscv_ip_operand;
3614 }
3615 }
3616 break;
54bca63b 3617
e23eba97 3618 default:
437e2ff1
NC
3619 unknown_riscv_ip_operand:
3620 as_fatal (_("internal: unknown argument type `%s'"),
3621 opargStart);
e23eba97
NC
3622 }
3623 break;
3624 }
437e2ff1 3625 asarg = asargStart;
5b7c81bd 3626 insn_with_csr = false;
e23eba97
NC
3627 }
3628
dc1e8a47 3629 out:
e23eba97
NC
3630 /* Restore the character we might have clobbered above. */
3631 if (save_c)
437e2ff1 3632 *(asargStart - 1) = save_c;
e23eba97 3633
7a29ee29
JB
3634 probing_insn_operands = false;
3635
e23eba97
NC
3636 return error;
3637}
3638
a262b82f
NC
3639/* Similar to riscv_ip, but assembles an instruction according to the
3640 hardcode values of .insn directive. */
3641
3642static const char *
3643riscv_ip_hardcode (char *str,
3644 struct riscv_cl_insn *ip,
3645 expressionS *imm_expr,
3646 const char *error)
3647{
3648 struct riscv_opcode *insn;
3649 insn_t values[2] = {0, 0};
3650 unsigned int num = 0;
3651
3652 input_line_pointer = str;
3653 do
3654 {
3655 expression (imm_expr);
bb996692 3656 switch (imm_expr->X_op)
a262b82f 3657 {
bb996692
JB
3658 case O_constant:
3659 values[num++] = (insn_t) imm_expr->X_add_number;
3660 break;
3661 case O_big:
634001bb
TO
3662 /* Extract lower 32-bits of a big number.
3663 Assume that generic_bignum_to_int32 work on such number. */
3664 values[num++] = (insn_t) generic_bignum_to_int32 ();
bb996692
JB
3665 break;
3666 default:
a262b82f
NC
3667 /* The first value isn't constant, so it should be
3668 .insn <type> <operands>. We have been parsed it
3669 in the riscv_ip. */
3670 if (num == 0)
3671 return error;
3672 return _("values must be constant");
3673 }
a262b82f 3674 }
bb996692 3675 while (*input_line_pointer++ == ',' && num < 2 && imm_expr->X_op != O_big);
a262b82f
NC
3676
3677 input_line_pointer--;
3678 if (*input_line_pointer != '\0')
3679 return _("unrecognized values");
3680
3681 insn = XNEW (struct riscv_opcode);
3682 insn->match = values[num - 1];
3683 create_insn (ip, insn);
3684 unsigned int bytes = riscv_insn_length (insn->match);
bb996692
JB
3685
3686 if (num == 2 && values[0] != bytes)
3687 return _("value conflicts with instruction length");
3688
3689 if (imm_expr->X_op == O_big)
3690 {
634001bb
TO
3691 unsigned int llen = 0;
3692 for (LITTLENUM_TYPE lval = generic_bignum[imm_expr->X_add_number - 1];
3693 lval != 0; llen++)
3694 lval >>= BITS_PER_CHAR;
3695 unsigned int repr_bytes
3696 = (imm_expr->X_add_number - 1) * CHARS_PER_LITTLENUM + llen;
3697 if (bytes < repr_bytes)
bb996692 3698 return _("value conflicts with instruction length");
634001bb
TO
3699 for (num = 0; num < imm_expr->X_add_number - 1; ++num)
3700 number_to_chars_littleendian (
3701 ip->insn_long_opcode + num * CHARS_PER_LITTLENUM,
3702 generic_bignum[num],
3703 CHARS_PER_LITTLENUM);
3704 if (llen != 0)
3705 number_to_chars_littleendian (
3706 ip->insn_long_opcode + num * CHARS_PER_LITTLENUM,
3707 generic_bignum[num],
3708 llen);
3709 memset(ip->insn_long_opcode + repr_bytes, 0, bytes - repr_bytes);
bb996692
JB
3710 return NULL;
3711 }
3712
3713 if (bytes < sizeof(values[0]) && values[num - 1] >> (8 * bytes) != 0)
a262b82f
NC
3714 return _("value conflicts with instruction length");
3715
3716 return NULL;
3717}
3718
e23eba97
NC
3719void
3720md_assemble (char *str)
3721{
3722 struct riscv_cl_insn insn;
3723 expressionS imm_expr;
3724 bfd_reloc_code_real_type imm_reloc = BFD_RELOC_UNUSED;
3725
dcd709e0
NC
3726 /* The architecture and privileged elf attributes should be set
3727 before assembling. */
8f595e9b
NC
3728 if (!start_assemble)
3729 {
5b7c81bd 3730 start_assemble = true;
e23eba97 3731
dcd709e0 3732 riscv_set_abi_by_arch ();
8f595e9b
NC
3733 if (!riscv_set_default_priv_spec (NULL))
3734 return;
3735 }
3736
3190ebcb 3737 riscv_mapping_state (MAP_INSN, 0, false/* fr_align_code */);
9b9b1092 3738
e4028336
PN
3739 const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
3740 &imm_reloc, op_hash);
2dc8dd17 3741
e4028336 3742 if (error.msg)
e23eba97 3743 {
e4028336
PN
3744 if (error.missing_ext)
3745 as_bad ("%s `%s', extension `%s' required", error.msg,
3746 error.statement, error.missing_ext);
3747 else
3748 as_bad ("%s `%s'", error.msg, error.statement);
e23eba97
NC
3749 return;
3750 }
3751
3752 if (insn.insn_mo->pinfo == INSN_MACRO)
3753 macro (&insn, &imm_expr, &imm_reloc);
3754 else
3755 append_insn (&insn, &imm_expr, imm_reloc);
3756}
3757
3758const char *
3759md_atof (int type, char *litP, int *sizeP)
3760{
71a75b51 3761 return ieee_md_atof (type, litP, sizeP, target_big_endian);
e23eba97
NC
3762}
3763
3764void
3765md_number_to_chars (char *buf, valueT val, int n)
3766{
fbc09e7a
MC
3767 if (target_big_endian)
3768 number_to_chars_bigendian (buf, val, n);
3769 else
3770 number_to_chars_littleendian (buf, val, n);
e23eba97
NC
3771}
3772
3773const char *md_shortopts = "O::g::G:";
3774
3775enum options
3776{
2922d21d 3777 OPTION_MARCH = OPTION_MD_BASE,
e23eba97
NC
3778 OPTION_PIC,
3779 OPTION_NO_PIC,
2922d21d 3780 OPTION_MABI,
71060565
JW
3781 OPTION_RELAX,
3782 OPTION_NO_RELAX,
2dc8dd17
JW
3783 OPTION_ARCH_ATTR,
3784 OPTION_NO_ARCH_ATTR,
2ca89224
NC
3785 OPTION_CSR_CHECK,
3786 OPTION_NO_CSR_CHECK,
8f595e9b
NC
3787 OPTION_MISA_SPEC,
3788 OPTION_MPRIV_SPEC,
fbc09e7a
MC
3789 OPTION_BIG_ENDIAN,
3790 OPTION_LITTLE_ENDIAN,
e23eba97
NC
3791 OPTION_END_OF_ENUM
3792};
3793
3794struct option md_longopts[] =
3795{
e23eba97
NC
3796 {"march", required_argument, NULL, OPTION_MARCH},
3797 {"fPIC", no_argument, NULL, OPTION_PIC},
3798 {"fpic", no_argument, NULL, OPTION_PIC},
3799 {"fno-pic", no_argument, NULL, OPTION_NO_PIC},
2922d21d 3800 {"mabi", required_argument, NULL, OPTION_MABI},
71060565
JW
3801 {"mrelax", no_argument, NULL, OPTION_RELAX},
3802 {"mno-relax", no_argument, NULL, OPTION_NO_RELAX},
2dc8dd17
JW
3803 {"march-attr", no_argument, NULL, OPTION_ARCH_ATTR},
3804 {"mno-arch-attr", no_argument, NULL, OPTION_NO_ARCH_ATTR},
2ca89224
NC
3805 {"mcsr-check", no_argument, NULL, OPTION_CSR_CHECK},
3806 {"mno-csr-check", no_argument, NULL, OPTION_NO_CSR_CHECK},
8f595e9b
NC
3807 {"misa-spec", required_argument, NULL, OPTION_MISA_SPEC},
3808 {"mpriv-spec", required_argument, NULL, OPTION_MPRIV_SPEC},
fbc09e7a
MC
3809 {"mbig-endian", no_argument, NULL, OPTION_BIG_ENDIAN},
3810 {"mlittle-endian", no_argument, NULL, OPTION_LITTLE_ENDIAN},
e23eba97
NC
3811
3812 {NULL, no_argument, NULL, 0}
3813};
3814size_t md_longopts_size = sizeof (md_longopts);
3815
e23eba97
NC
3816int
3817md_parse_option (int c, const char *arg)
3818{
3819 switch (c)
3820 {
e23eba97 3821 case OPTION_MARCH:
8f595e9b 3822 default_arch_with_ext = arg;
e23eba97
NC
3823 break;
3824
3825 case OPTION_NO_PIC:
5b7c81bd 3826 riscv_opts.pic = false;
e23eba97
NC
3827 break;
3828
3829 case OPTION_PIC:
5b7c81bd 3830 riscv_opts.pic = true;
e23eba97
NC
3831 break;
3832
2922d21d
AW
3833 case OPTION_MABI:
3834 if (strcmp (arg, "ilp32") == 0)
5b7c81bd 3835 riscv_set_abi (32, FLOAT_ABI_SOFT, false);
7f999549 3836 else if (strcmp (arg, "ilp32e") == 0)
5b7c81bd 3837 riscv_set_abi (32, FLOAT_ABI_SOFT, true);
2922d21d 3838 else if (strcmp (arg, "ilp32f") == 0)
5b7c81bd 3839 riscv_set_abi (32, FLOAT_ABI_SINGLE, false);
2922d21d 3840 else if (strcmp (arg, "ilp32d") == 0)
5b7c81bd 3841 riscv_set_abi (32, FLOAT_ABI_DOUBLE, false);
2922d21d 3842 else if (strcmp (arg, "ilp32q") == 0)
5b7c81bd 3843 riscv_set_abi (32, FLOAT_ABI_QUAD, false);
2922d21d 3844 else if (strcmp (arg, "lp64") == 0)
5b7c81bd 3845 riscv_set_abi (64, FLOAT_ABI_SOFT, false);
2922d21d 3846 else if (strcmp (arg, "lp64f") == 0)
5b7c81bd 3847 riscv_set_abi (64, FLOAT_ABI_SINGLE, false);
2922d21d 3848 else if (strcmp (arg, "lp64d") == 0)
5b7c81bd 3849 riscv_set_abi (64, FLOAT_ABI_DOUBLE, false);
2922d21d 3850 else if (strcmp (arg, "lp64q") == 0)
5b7c81bd 3851 riscv_set_abi (64, FLOAT_ABI_QUAD, false);
2922d21d
AW
3852 else
3853 return 0;
5b7c81bd 3854 explicit_mabi = true;
2922d21d
AW
3855 break;
3856
71060565 3857 case OPTION_RELAX:
5b7c81bd 3858 riscv_opts.relax = true;
71060565
JW
3859 break;
3860
3861 case OPTION_NO_RELAX:
5b7c81bd 3862 riscv_opts.relax = false;
71060565
JW
3863 break;
3864
2dc8dd17 3865 case OPTION_ARCH_ATTR:
5b7c81bd 3866 riscv_opts.arch_attr = true;
2dc8dd17
JW
3867 break;
3868
3869 case OPTION_NO_ARCH_ATTR:
5b7c81bd 3870 riscv_opts.arch_attr = false;
2dc8dd17
JW
3871 break;
3872
2ca89224 3873 case OPTION_CSR_CHECK:
5b7c81bd 3874 riscv_opts.csr_check = true;
2ca89224
NC
3875 break;
3876
3877 case OPTION_NO_CSR_CHECK:
5b7c81bd 3878 riscv_opts.csr_check = false;
2ca89224
NC
3879 break;
3880
8f595e9b
NC
3881 case OPTION_MISA_SPEC:
3882 return riscv_set_default_isa_spec (arg);
3883
3884 case OPTION_MPRIV_SPEC:
3885 return riscv_set_default_priv_spec (arg);
3886
fbc09e7a
MC
3887 case OPTION_BIG_ENDIAN:
3888 target_big_endian = 1;
3889 break;
3890
3891 case OPTION_LITTLE_ENDIAN:
3892 target_big_endian = 0;
3893 break;
3894
e23eba97
NC
3895 default:
3896 return 0;
3897 }
3898
3899 return 1;
3900}
3901
3902void
3903riscv_after_parse_args (void)
3904{
dcd709e0
NC
3905 /* The --with-arch is optional for now, so we still need to set the xlen
3906 according to the default_arch, which is set by the --target. */
e23eba97
NC
3907 if (xlen == 0)
3908 {
3909 if (strcmp (default_arch, "riscv32") == 0)
3910 xlen = 32;
3911 else if (strcmp (default_arch, "riscv64") == 0)
3912 xlen = 64;
3913 else
3914 as_bad ("unknown default architecture `%s'", default_arch);
3915 }
8f595e9b 3916
dcd709e0 3917 /* Set default specs. */
8f595e9b
NC
3918 if (default_isa_spec == ISA_SPEC_CLASS_NONE)
3919 riscv_set_default_isa_spec (DEFAULT_RISCV_ISA_SPEC);
dcd709e0
NC
3920 if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
3921 riscv_set_default_priv_spec (DEFAULT_RISCV_PRIV_SPEC);
2922d21d 3922
8f595e9b 3923 riscv_set_arch (default_arch_with_ext);
2922d21d 3924
0ac2b354
AB
3925 /* If the CIE to be produced has not been overridden on the command line,
3926 then produce version 3 by default. This allows us to use the full
3927 range of registers in a .cfi_return_column directive. */
3928 if (flag_dwarf_cie_version == -1)
3929 flag_dwarf_cie_version = 3;
e23eba97
NC
3930}
3931
7a29ee29
JB
3932bool riscv_parse_name (const char *name, struct expressionS *ep,
3933 enum expr_mode mode)
3934{
3935 unsigned int regno;
3936 symbolS *sym;
3937
3938 if (!probing_insn_operands)
3939 return false;
3940
3941 gas_assert (mode == expr_normal);
3942
3943 regno = reg_lookup_internal (name, RCLASS_GPR);
3944 if (regno == (unsigned int)-1)
3945 return false;
3946
3947 if (symbol_find (name) != NULL)
3948 return false;
3949
3950 /* Create a symbol without adding it to the symbol table yet.
3951 Insertion will happen only once we commit to using the insn
3952 we're probing operands for. */
3953 for (sym = deferred_sym_rootP; sym; sym = symbol_next (sym))
3954 if (strcmp (name, S_GET_NAME (sym)) == 0)
3955 break;
3956 if (!sym)
3957 {
3958 for (sym = orphan_sym_rootP; sym; sym = symbol_next (sym))
3959 if (strcmp (name, S_GET_NAME (sym)) == 0)
3960 {
3961 symbol_remove (sym, &orphan_sym_rootP, &orphan_sym_lastP);
3962 break;
3963 }
3964 if (!sym)
3965 sym = symbol_create (name, undefined_section,
3966 &zero_address_frag, 0);
3967
3968 symbol_append (sym, deferred_sym_lastP, &deferred_sym_rootP,
3969 &deferred_sym_lastP);
3970 }
3971
3972 ep->X_op = O_symbol;
3973 ep->X_add_symbol = sym;
3974 ep->X_add_number = 0;
3975
3976 return true;
3977}
3978
e23eba97
NC
3979long
3980md_pcrel_from (fixS *fixP)
3981{
3982 return fixP->fx_where + fixP->fx_frag->fr_address;
3983}
3984
3985/* Apply a fixup to the object file. */
3986
3987void
3988md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
3989{
45f76423 3990 unsigned int subtype;
e23eba97 3991 bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
5b7c81bd 3992 bool relaxable = false;
c1b465c9 3993 offsetT loc;
a6cbf936 3994 segT sub_segment;
e23eba97
NC
3995
3996 /* Remember value for tc_gen_reloc. */
3997 fixP->fx_addnumber = *valP;
3998
3999 switch (fixP->fx_r_type)
4000 {
e23eba97
NC
4001 case BFD_RELOC_RISCV_HI20:
4002 case BFD_RELOC_RISCV_LO12_I:
4003 case BFD_RELOC_RISCV_LO12_S:
45f76423
AW
4004 bfd_putl32 (riscv_apply_const_reloc (fixP->fx_r_type, *valP)
4005 | bfd_getl32 (buf), buf);
a5ec5e3f 4006 if (fixP->fx_addsy == NULL)
5b7c81bd
AM
4007 fixP->fx_done = true;
4008 relaxable = true;
45f76423
AW
4009 break;
4010
4011 case BFD_RELOC_RISCV_GOT_HI20:
e23eba97
NC
4012 case BFD_RELOC_RISCV_ADD8:
4013 case BFD_RELOC_RISCV_ADD16:
4014 case BFD_RELOC_RISCV_ADD32:
4015 case BFD_RELOC_RISCV_ADD64:
45f76423 4016 case BFD_RELOC_RISCV_SUB6:
e23eba97
NC
4017 case BFD_RELOC_RISCV_SUB8:
4018 case BFD_RELOC_RISCV_SUB16:
4019 case BFD_RELOC_RISCV_SUB32:
4020 case BFD_RELOC_RISCV_SUB64:
45f76423 4021 case BFD_RELOC_RISCV_RELAX:
f1cd8b94
KLC
4022 /* cvt_frag_to_fill () has called output_leb128 (). */
4023 case BFD_RELOC_RISCV_SET_ULEB128:
4024 case BFD_RELOC_RISCV_SUB_ULEB128:
45f76423
AW
4025 break;
4026
4027 case BFD_RELOC_RISCV_TPREL_HI20:
4028 case BFD_RELOC_RISCV_TPREL_LO12_I:
4029 case BFD_RELOC_RISCV_TPREL_LO12_S:
4030 case BFD_RELOC_RISCV_TPREL_ADD:
5b7c81bd 4031 relaxable = true;
45f76423
AW
4032 /* Fall through. */
4033
4034 case BFD_RELOC_RISCV_TLS_GOT_HI20:
4035 case BFD_RELOC_RISCV_TLS_GD_HI20:
4036 case BFD_RELOC_RISCV_TLS_DTPREL32:
4037 case BFD_RELOC_RISCV_TLS_DTPREL64:
e294484e
AW
4038 if (fixP->fx_addsy != NULL)
4039 S_SET_THREAD_LOCAL (fixP->fx_addsy);
4040 else
4041 as_bad_where (fixP->fx_file, fixP->fx_line,
4042 _("TLS relocation against a constant"));
e23eba97
NC
4043 break;
4044
e23eba97 4045 case BFD_RELOC_32:
a6cbf936
KLC
4046 /* Use pc-relative relocation for FDE initial location.
4047 The symbol address in .eh_frame may be adjusted in
4048 _bfd_elf_discard_section_eh_frame, and the content of
4049 .eh_frame will be adjusted in _bfd_elf_write_section_eh_frame.
4050 Therefore, we cannot insert a relocation whose addend symbol is
dcd709e0 4051 in .eh_frame. Othrewise, the value may be adjusted twice. */
a6cbf936
KLC
4052 if (fixP->fx_addsy && fixP->fx_subsy
4053 && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy))
4054 && strcmp (sub_segment->name, ".eh_frame") == 0
4055 && S_GET_VALUE (fixP->fx_subsy)
4056 == fixP->fx_frag->fr_address + fixP->fx_where)
4057 {
4058 fixP->fx_r_type = BFD_RELOC_RISCV_32_PCREL;
4059 fixP->fx_subsy = NULL;
4060 break;
4061 }
4062 /* Fall through. */
4063 case BFD_RELOC_64:
e23eba97
NC
4064 case BFD_RELOC_16:
4065 case BFD_RELOC_8:
45f76423 4066 case BFD_RELOC_RISCV_CFA:
e23eba97
NC
4067 if (fixP->fx_addsy && fixP->fx_subsy)
4068 {
4069 fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
4070 fixP->fx_next->fx_addsy = fixP->fx_subsy;
4071 fixP->fx_next->fx_subsy = NULL;
4072 fixP->fx_next->fx_offset = 0;
4073 fixP->fx_subsy = NULL;
4074
4075 switch (fixP->fx_r_type)
4076 {
4077 case BFD_RELOC_64:
4078 fixP->fx_r_type = BFD_RELOC_RISCV_ADD64;
4079 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB64;
4080 break;
4081
4082 case BFD_RELOC_32:
4083 fixP->fx_r_type = BFD_RELOC_RISCV_ADD32;
4084 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
4085 break;
4086
4087 case BFD_RELOC_16:
4088 fixP->fx_r_type = BFD_RELOC_RISCV_ADD16;
4089 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
4090 break;
4091
4092 case BFD_RELOC_8:
4093 fixP->fx_r_type = BFD_RELOC_RISCV_ADD8;
4094 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
073808ed 4095 break;
e23eba97 4096
45f76423
AW
4097 case BFD_RELOC_RISCV_CFA:
4098 /* Load the byte to get the subtype. */
c1b465c9
KLC
4099 subtype = bfd_get_8 (NULL, &((fragS *) (fixP->fx_frag->fr_opcode))->fr_literal[fixP->fx_where]);
4100 loc = fixP->fx_frag->fr_fix - (subtype & 7);
45f76423
AW
4101 switch (subtype)
4102 {
4103 case DW_CFA_advance_loc1:
c1b465c9
KLC
4104 fixP->fx_where = loc + 1;
4105 fixP->fx_next->fx_where = loc + 1;
45f76423
AW
4106 fixP->fx_r_type = BFD_RELOC_RISCV_SET8;
4107 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
4108 break;
4109
4110 case DW_CFA_advance_loc2:
4111 fixP->fx_size = 2;
45f76423 4112 fixP->fx_next->fx_size = 2;
c1b465c9
KLC
4113 fixP->fx_where = loc + 1;
4114 fixP->fx_next->fx_where = loc + 1;
45f76423
AW
4115 fixP->fx_r_type = BFD_RELOC_RISCV_SET16;
4116 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
4117 break;
4118
4119 case DW_CFA_advance_loc4:
4120 fixP->fx_size = 4;
45f76423 4121 fixP->fx_next->fx_size = 4;
c1b465c9
KLC
4122 fixP->fx_where = loc;
4123 fixP->fx_next->fx_where = loc;
45f76423
AW
4124 fixP->fx_r_type = BFD_RELOC_RISCV_SET32;
4125 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
4126 break;
4127
4128 default:
4129 if (subtype < 0x80 && (subtype & 0x40))
4130 {
4131 /* DW_CFA_advance_loc */
2aece2ba
KLC
4132 fixP->fx_frag = (fragS *) fixP->fx_frag->fr_opcode;
4133 fixP->fx_next->fx_frag = fixP->fx_frag;
45f76423
AW
4134 fixP->fx_r_type = BFD_RELOC_RISCV_SET6;
4135 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB6;
4136 }
4137 else
b800637e 4138 as_fatal (_("internal: bad CFA value #%d"), subtype);
45f76423
AW
4139 break;
4140 }
4141 break;
4142
e23eba97
NC
4143 default:
4144 /* This case is unreachable. */
4145 abort ();
4146 }
4147 }
4148 /* Fall through. */
4149
4150 case BFD_RELOC_RVA:
4151 /* If we are deleting this reloc entry, we must fill in the
4152 value now. This can happen if we have a .word which is not
4153 resolved when it appears but is later defined. */
4154 if (fixP->fx_addsy == NULL)
4155 {
4156 gas_assert (fixP->fx_size <= sizeof (valueT));
4157 md_number_to_chars ((char *) buf, *valP, fixP->fx_size);
4158 fixP->fx_done = 1;
4159 }
4160 break;
4161
4162 case BFD_RELOC_RISCV_JMP:
4163 if (fixP->fx_addsy)
4164 {
4165 /* Fill in a tentative value to improve objdump readability. */
4166 bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
4167 bfd_vma delta = target - md_pcrel_from (fixP);
5a9f5403 4168 bfd_putl32 (bfd_getl32 (buf) | ENCODE_JTYPE_IMM (delta), buf);
e23eba97
NC
4169 }
4170 break;
4171
4172 case BFD_RELOC_12_PCREL:
4173 if (fixP->fx_addsy)
4174 {
4175 /* Fill in a tentative value to improve objdump readability. */
4176 bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
4177 bfd_vma delta = target - md_pcrel_from (fixP);
5a9f5403 4178 bfd_putl32 (bfd_getl32 (buf) | ENCODE_BTYPE_IMM (delta), buf);
e23eba97
NC
4179 }
4180 break;
4181
4182 case BFD_RELOC_RISCV_RVC_BRANCH:
4183 if (fixP->fx_addsy)
4184 {
4185 /* Fill in a tentative value to improve objdump readability. */
4186 bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
4187 bfd_vma delta = target - md_pcrel_from (fixP);
5a9f5403 4188 bfd_putl16 (bfd_getl16 (buf) | ENCODE_CBTYPE_IMM (delta), buf);
e23eba97
NC
4189 }
4190 break;
4191
4192 case BFD_RELOC_RISCV_RVC_JUMP:
4193 if (fixP->fx_addsy)
4194 {
4195 /* Fill in a tentative value to improve objdump readability. */
4196 bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
4197 bfd_vma delta = target - md_pcrel_from (fixP);
5a9f5403 4198 bfd_putl16 (bfd_getl16 (buf) | ENCODE_CJTYPE_IMM (delta), buf);
e23eba97
NC
4199 }
4200 break;
4201
e23eba97
NC
4202 case BFD_RELOC_RISCV_CALL:
4203 case BFD_RELOC_RISCV_CALL_PLT:
5b7c81bd 4204 relaxable = true;
45f76423
AW
4205 break;
4206
9d06997a 4207 case BFD_RELOC_RISCV_PCREL_HI20:
45f76423
AW
4208 case BFD_RELOC_RISCV_PCREL_LO12_S:
4209 case BFD_RELOC_RISCV_PCREL_LO12_I:
9d06997a
PD
4210 relaxable = riscv_opts.relax;
4211 break;
4212
e23eba97
NC
4213 case BFD_RELOC_RISCV_ALIGN:
4214 break;
4215
4216 default:
4217 /* We ignore generic BFD relocations we don't know about. */
4218 if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
b800637e 4219 as_fatal (_("internal: bad relocation #%d"), fixP->fx_r_type);
e23eba97 4220 }
45f76423 4221
e294484e 4222 if (fixP->fx_subsy != NULL)
4bf09429 4223 as_bad_subtract (fixP);
e294484e 4224
45f76423
AW
4225 /* Add an R_RISCV_RELAX reloc if the reloc is relaxable. */
4226 if (relaxable && fixP->fx_tcbit && fixP->fx_addsy != NULL)
4227 {
4228 fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
4229 fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
4230 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX;
b1b11e92 4231 fixP->fx_next->fx_size = 0;
45f76423
AW
4232 }
4233}
4234
4235/* Because the value of .cfi_remember_state may changed after relaxation,
4236 we insert a fix to relocate it again in link-time. */
4237
4238void
4239riscv_pre_output_hook (void)
4240{
4241 const frchainS *frch;
72393fd1
JW
4242 segT s;
4243
4244 /* Save the current segment info. */
4245 segT seg = now_seg;
4246 subsegT subseg = now_subseg;
45f76423
AW
4247
4248 for (s = stdoutput->sections; s; s = s->next)
4249 for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
4250 {
7cb7b948 4251 fragS *frag;
45f76423
AW
4252
4253 for (frag = frch->frch_root; frag; frag = frag->fr_next)
4254 {
4255 if (frag->fr_type == rs_cfa)
4256 {
45f76423 4257 expressionS exp;
8d1015a8 4258 expressionS *symval;
45f76423 4259
8d1015a8 4260 symval = symbol_get_value_expression (frag->fr_symbol);
45f76423 4261 exp.X_op = O_subtract;
8d1015a8 4262 exp.X_add_symbol = symval->X_add_symbol;
45f76423 4263 exp.X_add_number = 0;
8d1015a8 4264 exp.X_op_symbol = symval->X_op_symbol;
45f76423 4265
72393fd1
JW
4266 /* We must set the segment before creating a frag after all
4267 frag chains have been chained together. */
4268 subseg_set (s, frch->frch_subseg);
4269
c1b465c9 4270 fix_new_exp (frag, (int) frag->fr_offset, 1, &exp, 0,
45f76423
AW
4271 BFD_RELOC_RISCV_CFA);
4272 }
4273 }
4274 }
72393fd1
JW
4275
4276 /* Restore the original segment info. */
4277 subseg_set (seg, subseg);
e23eba97
NC
4278}
4279
e23eba97
NC
4280/* Handle the .option pseudo-op. */
4281
4282static void
4283s_riscv_option (int x ATTRIBUTE_UNUSED)
4284{
4285 char *name = input_line_pointer, ch;
4286
4287 while (!is_end_of_line[(unsigned char) *input_line_pointer])
4288 ++input_line_pointer;
4289 ch = *input_line_pointer;
4290 *input_line_pointer = '\0';
4291
4292 if (strcmp (name, "rvc") == 0)
edc77c59 4293 {
d3ffd7f7 4294 riscv_update_subset (&riscv_rps_as, "+c");
40f1a1a4 4295 riscv_reset_subsets_list_arch_str ();
edc77c59
NC
4296 riscv_set_rvc (true);
4297 }
e23eba97 4298 else if (strcmp (name, "norvc") == 0)
edc77c59 4299 {
d3ffd7f7 4300 riscv_update_subset (&riscv_rps_as, "-c");
40f1a1a4 4301 riscv_reset_subsets_list_arch_str ();
edc77c59
NC
4302 riscv_set_rvc (false);
4303 }
e23eba97 4304 else if (strcmp (name, "pic") == 0)
5b7c81bd 4305 riscv_opts.pic = true;
e23eba97 4306 else if (strcmp (name, "nopic") == 0)
5b7c81bd 4307 riscv_opts.pic = false;
45f76423 4308 else if (strcmp (name, "relax") == 0)
5b7c81bd 4309 riscv_opts.relax = true;
45f76423 4310 else if (strcmp (name, "norelax") == 0)
5b7c81bd 4311 riscv_opts.relax = false;
2ca89224 4312 else if (strcmp (name, "csr-check") == 0)
5b7c81bd 4313 riscv_opts.csr_check = true;
2ca89224 4314 else if (strcmp (name, "no-csr-check") == 0)
5b7c81bd 4315 riscv_opts.csr_check = false;
d3ffd7f7
NC
4316 else if (strncmp (name, "arch,", 5) == 0)
4317 {
4318 name += 5;
4319 if (ISSPACE (*name) && *name != '\0')
4320 name++;
4321 riscv_update_subset (&riscv_rps_as, name);
40f1a1a4 4322 riscv_reset_subsets_list_arch_str ();
e7e599a1
NC
4323
4324 riscv_set_rvc (false);
675b9d61 4325 if (riscv_subset_supports (&riscv_rps_as, "c"))
e7e599a1 4326 riscv_set_rvc (true);
acab2a68
TO
4327
4328 if (riscv_subset_supports (&riscv_rps_as, "ztso"))
4329 riscv_set_tso ();
d3ffd7f7 4330 }
e23eba97
NC
4331 else if (strcmp (name, "push") == 0)
4332 {
4333 struct riscv_option_stack *s;
4334
d3ffd7f7 4335 s = XNEW (struct riscv_option_stack);
e23eba97
NC
4336 s->next = riscv_opts_stack;
4337 s->options = riscv_opts;
f5cb31a8 4338 s->subset_list = riscv_rps_as.subset_list;
e23eba97 4339 riscv_opts_stack = s;
f5cb31a8 4340 riscv_rps_as.subset_list = riscv_copy_subset_list (s->subset_list);
e23eba97
NC
4341 }
4342 else if (strcmp (name, "pop") == 0)
4343 {
4344 struct riscv_option_stack *s;
4345
4346 s = riscv_opts_stack;
4347 if (s == NULL)
4348 as_bad (_(".option pop with no .option push"));
4349 else
4350 {
f5cb31a8 4351 riscv_subset_list_t *release_subsets = riscv_rps_as.subset_list;
e23eba97 4352 riscv_opts_stack = s->next;
d3ffd7f7 4353 riscv_opts = s->options;
f5cb31a8 4354 riscv_rps_as.subset_list = s->subset_list;
d3ffd7f7 4355 riscv_release_subset_list (release_subsets);
e23eba97
NC
4356 free (s);
4357 }
4358 }
4359 else
4360 {
c84b3d7e 4361 as_warn (_("unrecognized .option directive: %s"), name);
e23eba97
NC
4362 }
4363 *input_line_pointer = ch;
4364 demand_empty_rest_of_line ();
4365}
4366
4367/* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
4368 a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
4369 use in DWARF debug information. */
4370
4371static void
4372s_dtprel (int bytes)
4373{
4374 expressionS ex;
4375 char *p;
4376
4377 expression (&ex);
4378
4379 if (ex.X_op != O_symbol)
4380 {
b800637e 4381 as_bad (_("unsupported use of %s"), (bytes == 8
e23eba97
NC
4382 ? ".dtpreldword"
4383 : ".dtprelword"));
4384 ignore_rest_of_line ();
4385 }
4386
4387 p = frag_more (bytes);
4388 md_number_to_chars (p, 0, bytes);
5b7c81bd 4389 fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, false,
e23eba97
NC
4390 (bytes == 8
4391 ? BFD_RELOC_RISCV_TLS_DTPREL64
4392 : BFD_RELOC_RISCV_TLS_DTPREL32));
4393
4394 demand_empty_rest_of_line ();
4395}
4396
4397/* Handle the .bss pseudo-op. */
4398
4399static void
4400s_bss (int ignore ATTRIBUTE_UNUSED)
4401{
4402 subseg_set (bss_section, 0);
4403 demand_empty_rest_of_line ();
4404}
4405
e23eba97 4406static void
d115ab8e 4407riscv_make_nops (char *buf, bfd_vma bytes)
e23eba97 4408{
d115ab8e 4409 bfd_vma i = 0;
e23eba97 4410
e5b737de
AW
4411 /* RISC-V instructions cannot begin or end on odd addresses, so this case
4412 means we are not within a valid instruction sequence. It is thus safe
4413 to use a zero byte, even though that is not a valid instruction. */
4414 if (bytes % 2 == 1)
4415 buf[i++] = 0;
4416
4417 /* Use at most one 2-byte NOP. */
4418 if ((bytes - i) % 4 == 2)
e23eba97 4419 {
fbc09e7a 4420 number_to_chars_littleendian (buf + i, RVC_NOP, 2);
d115ab8e 4421 i += 2;
e23eba97
NC
4422 }
4423
e5b737de 4424 /* Fill the remainder with 4-byte NOPs. */
d115ab8e 4425 for ( ; i < bytes; i += 4)
fbc09e7a 4426 number_to_chars_littleendian (buf + i, RISCV_NOP, 4);
d115ab8e 4427}
e23eba97 4428
d115ab8e
AW
4429/* Called from md_do_align. Used to create an alignment frag in a
4430 code section by emitting a worst-case NOP sequence that the linker
4431 will later relax to the correct number of NOPs. We can't compute
4432 the correct alignment now because of other linker relaxations. */
4433
5b7c81bd 4434bool
d115ab8e
AW
4435riscv_frag_align_code (int n)
4436{
e5b737de 4437 bfd_vma bytes = (bfd_vma) 1 << n;
36877bfb
JW
4438 bfd_vma insn_alignment = riscv_opts.rvc ? 2 : 4;
4439 bfd_vma worst_case_bytes = bytes - insn_alignment;
4440 char *nops;
ed0816bd 4441 expressionS ex;
d115ab8e 4442
36877bfb
JW
4443 /* If we are moving to a smaller alignment than the instruction size, then no
4444 alignment is required. */
4445 if (bytes <= insn_alignment)
5b7c81bd 4446 return true;
36877bfb 4447
d115ab8e
AW
4448 /* When not relaxing, riscv_handle_align handles code alignment. */
4449 if (!riscv_opts.relax)
5b7c81bd 4450 return false;
e23eba97 4451
40f1a1a4
NC
4452 /* Maybe we should use frag_var to create a new rs_align_code fragment,
4453 rather than just use frag_more to handle an alignment here? So that we
4454 don't need to call riscv_mapping_state again later, and then only need
4455 to check frag->fr_type to see if it is frag_align_code. */
e80ae190
JW
4456 nops = frag_more (worst_case_bytes);
4457
ed0816bd
PD
4458 ex.X_op = O_constant;
4459 ex.X_add_number = worst_case_bytes;
d115ab8e 4460
ed0816bd 4461 riscv_make_nops (nops, worst_case_bytes);
e23eba97 4462
ed0816bd 4463 fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
5b7c81bd 4464 &ex, false, BFD_RELOC_RISCV_ALIGN);
e23eba97 4465
3190ebcb 4466 riscv_mapping_state (MAP_INSN, worst_case_bytes, true/* fr_align_code */);
9b9b1092 4467
cb2562f5
LX
4468 /* We need to start a new frag after the alignment which may be removed by
4469 the linker, to prevent the assembler from computing static offsets.
4470 This is necessary to get correct EH info. */
4471 frag_wane (frag_now);
4472 frag_new (0);
4473
5b7c81bd 4474 return true;
d115ab8e 4475}
e23eba97 4476
d115ab8e
AW
4477/* Implement HANDLE_ALIGN. */
4478
4479void
4480riscv_handle_align (fragS *fragP)
4481{
4482 switch (fragP->fr_type)
4483 {
4484 case rs_align_code:
4485 /* When relaxing, riscv_frag_align_code handles code alignment. */
4486 if (!riscv_opts.relax)
4487 {
e80ae190
JW
4488 bfd_signed_vma bytes = (fragP->fr_next->fr_address
4489 - fragP->fr_address - fragP->fr_fix);
4490 /* We have 4 byte uncompressed nops. */
4491 bfd_signed_vma size = 4;
4492 bfd_signed_vma excess = bytes % size;
9b9b1092 4493 bfd_boolean odd_padding = (excess % 2 == 1);
e80ae190
JW
4494 char *p = fragP->fr_literal + fragP->fr_fix;
4495
4496 if (bytes <= 0)
d115ab8e
AW
4497 break;
4498
e80ae190
JW
4499 /* Insert zeros or compressed nops to get 4 byte alignment. */
4500 if (excess)
4501 {
9b9b1092
NC
4502 if (odd_padding)
4503 riscv_add_odd_padding_symbol (fragP);
e80ae190
JW
4504 riscv_make_nops (p, excess);
4505 fragP->fr_fix += excess;
4506 p += excess;
4507 }
4508
9b9b1092
NC
4509 /* The frag will be changed to `rs_fill` later. The function
4510 `write_contents` will try to fill the remaining spaces
4511 according to the patterns we give. In this case, we give
4512 a 4 byte uncompressed nop as the pattern, and set the size
4513 of the pattern into `fr_var`. The nop will be output to the
4514 file `fr_offset` times. However, `fr_offset` could be zero
4515 if we don't need to pad the boundary finally. */
e80ae190
JW
4516 riscv_make_nops (p, size);
4517 fragP->fr_var = size;
d115ab8e
AW
4518 }
4519 break;
4520
4521 default:
4522 break;
4523 }
e23eba97
NC
4524}
4525
9b9b1092
NC
4526/* This usually called from frag_var. */
4527
4528void
4529riscv_init_frag (fragS * fragP, int max_chars)
4530{
4531 /* Do not add mapping symbol to debug sections. */
4532 if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
4533 return;
4534
4535 switch (fragP->fr_type)
4536 {
4537 case rs_fill:
4538 case rs_align:
4539 case rs_align_test:
3190ebcb 4540 riscv_mapping_state (MAP_DATA, max_chars, false/* fr_align_code */);
9b9b1092
NC
4541 break;
4542 case rs_align_code:
3190ebcb 4543 riscv_mapping_state (MAP_INSN, max_chars, true/* fr_align_code */);
9b9b1092
NC
4544 break;
4545 default:
4546 break;
4547 }
4548}
4549
e23eba97
NC
4550int
4551md_estimate_size_before_relax (fragS *fragp, asection *segtype)
4552{
5b7c81bd 4553 return (fragp->fr_var = relaxed_branch_length (fragp, segtype, false));
e23eba97
NC
4554}
4555
4556/* Translate internal representation of relocation info to BFD target
4557 format. */
4558
4559arelent *
4560tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
4561{
4562 arelent *reloc = (arelent *) xmalloc (sizeof (arelent));
4563
4564 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4565 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4566 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
4567 reloc->addend = fixp->fx_addnumber;
4568
4569 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
4570 if (reloc->howto == NULL)
4571 {
4572 if ((fixp->fx_r_type == BFD_RELOC_16 || fixp->fx_r_type == BFD_RELOC_8)
4573 && fixp->fx_addsy != NULL && fixp->fx_subsy != NULL)
4574 {
4575 /* We don't have R_RISCV_8/16, but for this special case,
4576 we can use R_RISCV_ADD8/16 with R_RISCV_SUB8/16. */
4577 return reloc;
4578 }
4579
4580 as_bad_where (fixp->fx_file, fixp->fx_line,
4581 _("cannot represent %s relocation in object file"),
4582 bfd_get_reloc_code_name (fixp->fx_r_type));
4583 return NULL;
4584 }
4585
4586 return reloc;
4587}
4588
4589int
4590riscv_relax_frag (asection *sec, fragS *fragp, long stretch ATTRIBUTE_UNUSED)
4591{
4592 if (RELAX_BRANCH_P (fragp->fr_subtype))
4593 {
4594 offsetT old_var = fragp->fr_var;
5b7c81bd 4595 fragp->fr_var = relaxed_branch_length (fragp, sec, true);
e23eba97
NC
4596 return fragp->fr_var - old_var;
4597 }
4598
4599 return 0;
4600}
4601
4602/* Expand far branches to multi-instruction sequences. */
4603
4604static void
4605md_convert_frag_branch (fragS *fragp)
4606{
4607 bfd_byte *buf;
4608 expressionS exp;
4609 fixS *fixp;
4610 insn_t insn;
4611 int rs1, reloc;
4612
4613 buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
4614
4615 exp.X_op = O_symbol;
4616 exp.X_add_symbol = fragp->fr_symbol;
4617 exp.X_add_number = fragp->fr_offset;
4618
4619 gas_assert (fragp->fr_var == RELAX_BRANCH_LENGTH (fragp->fr_subtype));
4620
4621 if (RELAX_BRANCH_RVC (fragp->fr_subtype))
4622 {
4623 switch (RELAX_BRANCH_LENGTH (fragp->fr_subtype))
4624 {
4625 case 8:
4626 case 4:
4627 /* Expand the RVC branch into a RISC-V one. */
4628 insn = bfd_getl16 (buf);
4629 rs1 = 8 + ((insn >> OP_SH_CRS1S) & OP_MASK_CRS1S);
4630 if ((insn & MASK_C_J) == MATCH_C_J)
4631 insn = MATCH_JAL;
4632 else if ((insn & MASK_C_JAL) == MATCH_C_JAL)
4633 insn = MATCH_JAL | (X_RA << OP_SH_RD);
4634 else if ((insn & MASK_C_BEQZ) == MATCH_C_BEQZ)
4635 insn = MATCH_BEQ | (rs1 << OP_SH_RS1);
4636 else if ((insn & MASK_C_BNEZ) == MATCH_C_BNEZ)
4637 insn = MATCH_BNE | (rs1 << OP_SH_RS1);
4638 else
4639 abort ();
4640 bfd_putl32 (insn, buf);
4641 break;
4642
4643 case 6:
4644 /* Invert the branch condition. Branch over the jump. */
4645 insn = bfd_getl16 (buf);
4646 insn ^= MATCH_C_BEQZ ^ MATCH_C_BNEZ;
5a9f5403 4647 insn |= ENCODE_CBTYPE_IMM (6);
e23eba97
NC
4648 bfd_putl16 (insn, buf);
4649 buf += 2;
4650 goto jump;
4651
4652 case 2:
4653 /* Just keep the RVC branch. */
4654 reloc = RELAX_BRANCH_UNCOND (fragp->fr_subtype)
4655 ? BFD_RELOC_RISCV_RVC_JUMP : BFD_RELOC_RISCV_RVC_BRANCH;
4656 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
5b7c81bd 4657 2, &exp, false, reloc);
e23eba97
NC
4658 buf += 2;
4659 goto done;
4660
4661 default:
1d65abb5 4662 abort ();
e23eba97
NC
4663 }
4664 }
4665
4666 switch (RELAX_BRANCH_LENGTH (fragp->fr_subtype))
4667 {
4668 case 8:
4669 gas_assert (!RELAX_BRANCH_UNCOND (fragp->fr_subtype));
4670
4671 /* Invert the branch condition. Branch over the jump. */
4672 insn = bfd_getl32 (buf);
4673 insn ^= MATCH_BEQ ^ MATCH_BNE;
5a9f5403 4674 insn |= ENCODE_BTYPE_IMM (8);
fbc09e7a 4675 bfd_putl32 (insn, buf);
e23eba97
NC
4676 buf += 4;
4677
dc1e8a47 4678 jump:
e23eba97
NC
4679 /* Jump to the target. */
4680 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
5b7c81bd 4681 4, &exp, false, BFD_RELOC_RISCV_JMP);
fbc09e7a 4682 bfd_putl32 (MATCH_JAL, buf);
e23eba97
NC
4683 buf += 4;
4684 break;
4685
4686 case 4:
4687 reloc = RELAX_BRANCH_UNCOND (fragp->fr_subtype)
4688 ? BFD_RELOC_RISCV_JMP : BFD_RELOC_12_PCREL;
4689 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
5b7c81bd 4690 4, &exp, false, reloc);
e23eba97
NC
4691 buf += 4;
4692 break;
4693
4694 default:
4695 abort ();
4696 }
4697
dc1e8a47 4698 done:
e23eba97
NC
4699 fixp->fx_file = fragp->fr_file;
4700 fixp->fx_line = fragp->fr_line;
4701
4702 gas_assert (buf == (bfd_byte *)fragp->fr_literal
4703 + fragp->fr_fix + fragp->fr_var);
4704
4705 fragp->fr_fix += fragp->fr_var;
4706}
4707
4708/* Relax a machine dependent frag. This returns the amount by which
4709 the current size of the frag should change. */
4710
4711void
4712md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
4713 fragS *fragp)
4714{
4715 gas_assert (RELAX_BRANCH_P (fragp->fr_subtype));
4716 md_convert_frag_branch (fragp);
4717}
4718
4719void
4720md_show_usage (FILE *stream)
4721{
4722 fprintf (stream, _("\
4723RISC-V options:\n\
437e2ff1 4724 -fpic or -fPIC generate position-independent code\n\
8f595e9b
NC
4725 -fno-pic don't generate position-independent code (default)\n\
4726 -march=ISA set the RISC-V architecture\n\
4727 -misa-spec=ISAspec set the RISC-V ISA spec (2.2, 20190608, 20191213)\n\
86d39e66 4728 -mpriv-spec=PRIVspec set the RISC-V privilege spec (1.9.1, 1.10, 1.11, 1.12)\n\
8f595e9b
NC
4729 -mabi=ABI set the RISC-V ABI\n\
4730 -mrelax enable relax (default)\n\
4731 -mno-relax disable relax\n\
4732 -march-attr generate RISC-V arch attribute\n\
4733 -mno-arch-attr don't generate RISC-V arch attribute\n\
437e2ff1
NC
4734 -mcsr-check enable the csr ISA and privilege spec version checks\n\
4735 -mno-csr-check disable the csr ISA and privilege spec version checks (default)\n\
4736 -mbig-endian assemble for big-endian\n\
4737 -mlittle-endian assemble for little-endian\n\
e23eba97
NC
4738"));
4739}
4740
4741/* Standard calling conventions leave the CFA at SP on entry. */
dcd709e0 4742
e23eba97
NC
4743void
4744riscv_cfi_frame_initial_instructions (void)
4745{
4746 cfi_add_CFA_def_cfa_register (X_SP);
4747}
4748
4749int
4750tc_riscv_regname_to_dw2regnum (char *regname)
4751{
4752 int reg;
4753
4754 if ((reg = reg_lookup_internal (regname, RCLASS_GPR)) >= 0)
4755 return reg;
4756
4757 if ((reg = reg_lookup_internal (regname, RCLASS_FPR)) >= 0)
4758 return reg + 32;
4759
7b4f2407
TO
4760 if ((reg = reg_lookup_internal (regname, RCLASS_VECR)) >= 0)
4761 return reg + 96;
4762
4762fe62
AB
4763 /* CSRs are numbered 4096 -> 8191. */
4764 if ((reg = reg_lookup_internal (regname, RCLASS_CSR)) >= 0)
4765 return reg + 4096;
4766
e23eba97
NC
4767 as_bad (_("unknown register `%s'"), regname);
4768 return -1;
4769}
4770
4771void
4772riscv_elf_final_processing (void)
4773{
6e1605e4 4774 riscv_set_abi_by_arch ();
40f1a1a4 4775 riscv_release_subset_list (riscv_rps_as.subset_list);
e23eba97 4776 elf_elfheader (stdoutput)->e_flags |= elf_flags;
e23eba97
NC
4777}
4778
4779/* Parse the .sleb128 and .uleb128 pseudos. Only allow constant expressions,
4780 since these directives break relaxation when used with symbol deltas. */
4781
4782static void
4783s_riscv_leb128 (int sign)
4784{
4785 expressionS exp;
4786 char *save_in = input_line_pointer;
4787
4788 expression (&exp);
f1cd8b94
KLC
4789 if (sign && exp.X_op != O_constant)
4790 as_bad (_("non-constant .sleb128 is not supported"));
4791 else if (!sign && exp.X_op != O_constant && exp.X_op != O_subtract)
4792 as_bad (_(".uleb128 only supports constant or subtract expressions"));
4793
e23eba97
NC
4794 demand_empty_rest_of_line ();
4795
4796 input_line_pointer = save_in;
4797 return s_leb128 (sign);
4798}
4799
a262b82f
NC
4800/* Parse the .insn directive. There are three formats,
4801 Format 1: .insn <type> <operand1>, <operand2>, ...
4802 Format 2: .insn <length>, <value>
4803 Format 3: .insn <value>. */
0e35537d
JW
4804
4805static void
4806s_riscv_insn (int x ATTRIBUTE_UNUSED)
4807{
4808 char *str = input_line_pointer;
4809 struct riscv_cl_insn insn;
4810 expressionS imm_expr;
4811 bfd_reloc_code_real_type imm_reloc = BFD_RELOC_UNUSED;
4812 char save_c;
4813
4814 while (!is_end_of_line[(unsigned char) *input_line_pointer])
4815 ++input_line_pointer;
4816
4817 save_c = *input_line_pointer;
4818 *input_line_pointer = '\0';
4819
3190ebcb 4820 riscv_mapping_state (MAP_INSN, 0, false/* fr_align_code */);
9b9b1092 4821
e4028336 4822 struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
0e35537d 4823 &imm_reloc, insn_type_hash);
e4028336 4824 if (error.msg)
0e35537d 4825 {
a262b82f 4826 char *save_in = input_line_pointer;
e4028336 4827 error.msg = riscv_ip_hardcode (str, &insn, &imm_expr, error.msg);
a262b82f 4828 input_line_pointer = save_in;
0e35537d 4829 }
a262b82f 4830
e4028336
PN
4831 if (error.msg)
4832 {
4833 if (error.missing_ext)
4834 as_bad ("%s `%s', extension `%s' required", error.msg, error.statement,
4835 error.missing_ext);
4836 else
4837 as_bad ("%s `%s'", error.msg, error.statement);
4838 }
634001bb 4839 else
0e35537d
JW
4840 {
4841 gas_assert (insn.insn_mo->pinfo != INSN_MACRO);
4842 append_insn (&insn, &imm_expr, imm_reloc);
4843 }
4844
4845 *input_line_pointer = save_c;
4846 demand_empty_rest_of_line ();
4847}
4848
dcd709e0
NC
4849/* Update architecture and privileged elf attributes. If we don't set
4850 them, then try to output the default ones. */
2dc8dd17
JW
4851
4852static void
8f595e9b 4853riscv_write_out_attrs (void)
2dc8dd17 4854{
8f595e9b 4855 const char *arch_str, *priv_str, *p;
dcd709e0
NC
4856 /* versions[0]: major version.
4857 versions[1]: minor version.
4858 versions[2]: revision version. */
8f595e9b
NC
4859 unsigned versions[3] = {0}, number = 0;
4860 unsigned int i;
2dc8dd17 4861
dcd709e0 4862 /* Re-write architecture elf attribute. */
40f1a1a4 4863 arch_str = riscv_rps_as.subset_list->arch_str;
2dc8dd17 4864 bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
8f595e9b
NC
4865
4866 /* For the file without any instruction, we don't set the default_priv_spec
dcd709e0
NC
4867 according to the privileged elf attributes since the md_assemble isn't
4868 called. */
8f595e9b
NC
4869 if (!start_assemble
4870 && !riscv_set_default_priv_spec (NULL))
4871 return;
4872
dcd709e0
NC
4873 /* If we already have set privileged elf attributes, then no need to do
4874 anything. Otherwise, don't generate or update them when no CSR and
4875 privileged instructions are used. */
1a79004f 4876 if (!explicit_priv_attr)
3fc6c3dc
NC
4877 return;
4878
3d73d29e 4879 RISCV_GET_PRIV_SPEC_NAME (priv_str, default_priv_spec);
8f595e9b
NC
4880 p = priv_str;
4881 for (i = 0; *p; ++p)
4882 {
4883 if (*p == '.' && i < 3)
4884 {
4885 versions[i++] = number;
4886 number = 0;
4887 }
4888 else if (ISDIGIT (*p))
4889 number = (number * 10) + (*p - '0');
4890 else
4891 {
b800637e 4892 as_bad (_("internal: bad RISC-V privileged spec (%s)"), priv_str);
8f595e9b
NC
4893 return;
4894 }
4895 }
4896 versions[i] = number;
4897
dcd709e0 4898 /* Re-write privileged elf attributes. */
8f595e9b
NC
4899 bfd_elf_add_proc_attr_int (stdoutput, Tag_RISCV_priv_spec, versions[0]);
4900 bfd_elf_add_proc_attr_int (stdoutput, Tag_RISCV_priv_spec_minor, versions[1]);
4901 bfd_elf_add_proc_attr_int (stdoutput, Tag_RISCV_priv_spec_revision, versions[2]);
2dc8dd17
JW
4902}
4903
dcd709e0 4904/* Add the default contents for the .riscv.attributes section. */
2dc8dd17
JW
4905
4906static void
4907riscv_set_public_attributes (void)
4908{
8f595e9b
NC
4909 if (riscv_opts.arch_attr || explicit_attr)
4910 riscv_write_out_attrs ();
2dc8dd17
JW
4911}
4912
f1cd8b94
KLC
4913/* Scan uleb128 subtraction expressions and insert fixups for them.
4914 e.g., .uleb128 .L1 - .L0
4915 Because relaxation may change the value of the subtraction, we
4916 must resolve them at link-time. */
4917
4918static void
4919riscv_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
4920 asection *sec, void *xxx ATTRIBUTE_UNUSED)
4921{
4922 segment_info_type *seginfo = seg_info (sec);
4923 struct frag *fragP;
4924
4925 subseg_set (sec, 0);
4926
4927 for (fragP = seginfo->frchainP->frch_root;
4928 fragP; fragP = fragP->fr_next)
4929 {
4930 expressionS *exp, *exp_dup;
4931
4932 if (fragP->fr_type != rs_leb128 || fragP->fr_symbol == NULL)
4933 continue;
4934
4935 exp = symbol_get_value_expression (fragP->fr_symbol);
4936
4937 if (exp->X_op != O_subtract)
4938 continue;
4939
4940 /* Only unsigned leb128 can be handled. */
4941 gas_assert (fragP->fr_subtype == 0);
4942 exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp));
4943 exp_dup->X_op = O_symbol;
4944 exp_dup->X_op_symbol = NULL;
4945
4946 /* Insert relocations to resolve the subtraction at link-time.
4947 Emit the SET relocation first in riscv. */
4948 exp_dup->X_add_symbol = exp->X_add_symbol;
4949 fix_new_exp (fragP, fragP->fr_fix, 0,
4950 exp_dup, 0, BFD_RELOC_RISCV_SET_ULEB128);
4951 exp_dup->X_add_symbol = exp->X_op_symbol;
4952 fix_new_exp (fragP, fragP->fr_fix, 0,
4953 exp_dup, 0, BFD_RELOC_RISCV_SUB_ULEB128);
4954 }
4955}
4956
2dc8dd17
JW
4957/* Called after all assembly has been done. */
4958
4959void
ed2917de 4960riscv_md_finish (void)
2dc8dd17
JW
4961{
4962 riscv_set_public_attributes ();
f1cd8b94
KLC
4963 if (riscv_opts.relax)
4964 bfd_map_over_sections (stdoutput, riscv_insert_uleb128_fixes, NULL);
2dc8dd17
JW
4965}
4966
9b9b1092
NC
4967/* Adjust the symbol table. */
4968
4969void
4970riscv_adjust_symtab (void)
4971{
4972 bfd_map_over_sections (stdoutput, riscv_check_mapping_symbols, (char *) 0);
4973 elf_adjust_symtab ();
4974}
4975
2dc8dd17
JW
4976/* Given a symbolic attribute NAME, return the proper integer value.
4977 Returns -1 if the attribute is not known. */
4978
4979int
4980riscv_convert_symbolic_attribute (const char *name)
4981{
4982 static const struct
4983 {
1942a048
NC
4984 const char *name;
4985 const int tag;
2dc8dd17
JW
4986 }
4987 attribute_table[] =
1942a048
NC
4988 {
4989 /* When you modify this table you should
4990 also modify the list in doc/c-riscv.texi. */
4991#define T(tag) {#tag, Tag_RISCV_##tag}, {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
4992 T(arch),
4993 T(priv_spec),
4994 T(priv_spec_minor),
4995 T(priv_spec_revision),
4996 T(unaligned_access),
4997 T(stack_align),
2dc8dd17 4998#undef T
1942a048 4999 };
2dc8dd17
JW
5000
5001 if (name == NULL)
5002 return -1;
5003
1942a048 5004 unsigned int i;
2dc8dd17
JW
5005 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
5006 if (strcmp (name, attribute_table[i].name) == 0)
5007 return attribute_table[i].tag;
5008
5009 return -1;
5010}
5011
5012/* Parse a .attribute directive. */
5013
5014static void
5015s_riscv_attribute (int ignored ATTRIBUTE_UNUSED)
5016{
5017 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
8f595e9b
NC
5018 unsigned old_xlen;
5019 obj_attribute *attr;
2dc8dd17 5020
5b7c81bd 5021 explicit_attr = true;
8f595e9b 5022 switch (tag)
2dc8dd17 5023 {
8f595e9b
NC
5024 case Tag_RISCV_arch:
5025 old_xlen = xlen;
2dc8dd17
JW
5026 attr = elf_known_obj_attributes_proc (stdoutput);
5027 if (!start_assemble)
5028 riscv_set_arch (attr[Tag_RISCV_arch].s);
5029 else
b800637e
NC
5030 as_fatal (_("architecture elf attributes must set before "
5031 "any instructions"));
2dc8dd17
JW
5032
5033 if (old_xlen != xlen)
5034 {
5035 /* We must re-init bfd again if xlen is changed. */
5036 unsigned long mach = xlen == 64 ? bfd_mach_riscv64 : bfd_mach_riscv32;
5037 bfd_find_target (riscv_target_format (), stdoutput);
5038
5039 if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach))
b800637e 5040 as_warn (_("could not set architecture and machine"));
2dc8dd17 5041 }
8f595e9b
NC
5042 break;
5043
5044 case Tag_RISCV_priv_spec:
5045 case Tag_RISCV_priv_spec_minor:
5046 case Tag_RISCV_priv_spec_revision:
5047 if (start_assemble)
b800637e
NC
5048 as_fatal (_("privileged elf attributes must set before "
5049 "any instructions"));
8f595e9b
NC
5050 break;
5051
5052 default:
5053 break;
2dc8dd17
JW
5054 }
5055}
5056
8155b853
NC
5057/* Mark symbol that it follows a variant CC convention. */
5058
5059static void
5060s_variant_cc (int ignored ATTRIBUTE_UNUSED)
5061{
5062 char *name;
5063 char c;
5064 symbolS *sym;
5065 asymbol *bfdsym;
5066 elf_symbol_type *elfsym;
5067
5068 c = get_symbol_name (&name);
5069 if (!*name)
5070 as_bad (_("missing symbol name for .variant_cc directive"));
5071 sym = symbol_find_or_make (name);
5072 restore_line_pointer (c);
5073 demand_empty_rest_of_line ();
5074
5075 bfdsym = symbol_get_bfdsym (sym);
5076 elfsym = elf_symbol_from (bfdsym);
5077 gas_assert (elfsym);
5078 elfsym->internal_elf_sym.st_other |= STO_RISCV_VARIANT_CC;
5079}
5080
5081/* Same as elf_copy_symbol_attributes, but without copying st_other.
5082 This is needed so RISC-V specific st_other values can be independently
5083 specified for an IFUNC resolver (that is called by the dynamic linker)
5084 and the symbol it resolves (aliased to the resolver). In particular,
5085 if a function symbol has special st_other value set via directives,
5086 then attaching an IFUNC resolver to that symbol should not override
5087 the st_other setting. Requiring the directive on the IFUNC resolver
5088 symbol would be unexpected and problematic in C code, where the two
5089 symbols appear as two independent function declarations. */
5090
5091void
5092riscv_elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
5093{
5094 struct elf_obj_sy *srcelf = symbol_get_obj (src);
5095 struct elf_obj_sy *destelf = symbol_get_obj (dest);
a3a7f5e1
FS
5096 /* If size is unset, copy size from src. Because we don't track whether
5097 .size has been used, we can't differentiate .size dest, 0 from the case
5098 where dest's size is unset. */
5099 if (!destelf->size && S_GET_SIZE (dest) == 0)
8155b853 5100 {
a3a7f5e1
FS
5101 if (srcelf->size)
5102 {
5103 destelf->size = XNEW (expressionS);
5104 *destelf->size = *srcelf->size;
5105 }
5106 S_SET_SIZE (dest, S_GET_SIZE (src));
8155b853 5107 }
8155b853
NC
5108}
5109
dcd709e0 5110/* RISC-V pseudo-ops table. */
e23eba97
NC
5111static const pseudo_typeS riscv_pseudo_table[] =
5112{
e23eba97
NC
5113 {"option", s_riscv_option, 0},
5114 {"half", cons, 2},
5115 {"word", cons, 4},
5116 {"dword", cons, 8},
5117 {"dtprelword", s_dtprel, 4},
5118 {"dtpreldword", s_dtprel, 8},
5119 {"bss", s_bss, 0},
e23eba97
NC
5120 {"uleb128", s_riscv_leb128, 0},
5121 {"sleb128", s_riscv_leb128, 1},
0e35537d 5122 {"insn", s_riscv_insn, 0},
2dc8dd17 5123 {"attribute", s_riscv_attribute, 0},
8155b853 5124 {"variant_cc", s_variant_cc, 0},
035784e3 5125 {"float16", float_cons, 'h'},
e23eba97
NC
5126
5127 { NULL, NULL, 0 },
5128};
5129
5130void
5131riscv_pop_insert (void)
5132{
5133 extern void pop_insert (const pseudo_typeS *);
5134
5135 pop_insert (riscv_pseudo_table);
5136}