]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-riscv.c
RISC-V: Support subtraction of .uleb128.
[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);
f786c359 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
437e2ff1 1224#define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift)))
8b7419c4
CM
1225#define USE_IMM(n, s) \
1226 (used_bits |= ((insn_t)((1ull<<n)-1) << (s)))
437e2ff1 1227
e23eba97
NC
1228/* For consistency checking, verify that all bits are specified either
1229 by the match/mask part of the instruction definition, or by the
83029f7f
TO
1230 operand list. The `length` could be the actual instruction length or
1231 0 for auto-detection. */
0e35537d 1232
5b7c81bd 1233static bool
0e35537d 1234validate_riscv_insn (const struct riscv_opcode *opc, int length)
e23eba97 1235{
437e2ff1 1236 const char *oparg, *opargStart;
e23eba97 1237 insn_t used_bits = opc->mask;
0e35537d
JW
1238 int insn_width;
1239 insn_t required_bits;
1240
1241 if (length == 0)
83029f7f
TO
1242 length = riscv_insn_length (opc->match);
1243 /* We don't support instructions longer than 64-bits yet. */
1244 if (length > 8)
1245 length = 8;
1246 insn_width = 8 * length;
0e35537d 1247
83029f7f 1248 required_bits = ((insn_t)~0ULL) >> (64 - insn_width);
e23eba97
NC
1249
1250 if ((used_bits & opc->match) != (opc->match & required_bits))
1251 {
1252 as_bad (_("internal: bad RISC-V opcode (mask error): %s %s"),
1253 opc->name, opc->args);
5b7c81bd 1254 return false;
e23eba97
NC
1255 }
1256
437e2ff1
NC
1257 for (oparg = opc->args; *oparg; ++oparg)
1258 {
1259 opargStart = oparg;
1260 switch (*oparg)
1261 {
1262 case 'C': /* RVC */
1263 switch (*++oparg)
1264 {
1265 case 'U': break; /* CRS1, constrained to equal RD. */
1266 case 'c': break; /* CRS1, constrained to equal sp. */
1267 case 'T': /* CRS2, floating point. */
1268 case 'V': USE_BITS (OP_MASK_CRS2, OP_SH_CRS2); break;
1269 case 'S': /* CRS1S, floating point. */
1270 case 's': USE_BITS (OP_MASK_CRS1S, OP_SH_CRS1S); break;
1271 case 'w': break; /* CRS1S, constrained to equal RD. */
1272 case 'D': /* CRS2S, floating point. */
1273 case 't': USE_BITS (OP_MASK_CRS2S, OP_SH_CRS2S); break;
1274 case 'x': break; /* CRS2S, constrained to equal RD. */
1275 case 'z': break; /* CRS2S, constrained to be x0. */
1276 case '>': /* CITYPE immediate, compressed shift. */
1277 case 'u': /* CITYPE immediate, compressed lui. */
1278 case 'v': /* CITYPE immediate, li to compressed lui. */
1279 case 'o': /* CITYPE immediate, allow zero. */
1280 case 'j': used_bits |= ENCODE_CITYPE_IMM (-1U); break;
1281 case 'L': used_bits |= ENCODE_CITYPE_ADDI16SP_IMM (-1U); break;
1282 case 'm': used_bits |= ENCODE_CITYPE_LWSP_IMM (-1U); break;
1283 case 'n': used_bits |= ENCODE_CITYPE_LDSP_IMM (-1U); break;
1284 case '6': used_bits |= ENCODE_CSSTYPE_IMM (-1U); break;
1285 case 'M': used_bits |= ENCODE_CSSTYPE_SWSP_IMM (-1U); break;
1286 case 'N': used_bits |= ENCODE_CSSTYPE_SDSP_IMM (-1U); break;
1287 case '8': used_bits |= ENCODE_CIWTYPE_IMM (-1U); break;
1288 case 'K': used_bits |= ENCODE_CIWTYPE_ADDI4SPN_IMM (-1U); break;
1289 /* CLTYPE and CSTYPE have the same immediate encoding. */
1290 case '5': used_bits |= ENCODE_CLTYPE_IMM (-1U); break;
1291 case 'k': used_bits |= ENCODE_CLTYPE_LW_IMM (-1U); break;
1292 case 'l': used_bits |= ENCODE_CLTYPE_LD_IMM (-1U); break;
1293 case 'p': used_bits |= ENCODE_CBTYPE_IMM (-1U); break;
1294 case 'a': used_bits |= ENCODE_CJTYPE_IMM (-1U); break;
1295 case 'F': /* Compressed funct for .insn directive. */
1296 switch (*++oparg)
1297 {
65e4a99a
NC
1298 case '6': USE_BITS (OP_MASK_CFUNCT6, OP_SH_CFUNCT6); break;
1299 case '4': USE_BITS (OP_MASK_CFUNCT4, OP_SH_CFUNCT4); break;
1300 case '3': USE_BITS (OP_MASK_CFUNCT3, OP_SH_CFUNCT3); break;
1301 case '2': USE_BITS (OP_MASK_CFUNCT2, OP_SH_CFUNCT2); break;
1302 default:
1303 goto unknown_validate_operand;
437e2ff1
NC
1304 }
1305 break;
0e35537d 1306 default:
437e2ff1
NC
1307 goto unknown_validate_operand;
1308 }
a63375ac 1309 break; /* end RVC */
65e4a99a
NC
1310 case 'V': /* RVV */
1311 switch (*++oparg)
1312 {
1313 case 'd':
1314 case 'f': USE_BITS (OP_MASK_VD, OP_SH_VD); break;
1315 case 'e': USE_BITS (OP_MASK_VWD, OP_SH_VWD); break;
1316 case 's': USE_BITS (OP_MASK_VS1, OP_SH_VS1); break;
1317 case 't': USE_BITS (OP_MASK_VS2, OP_SH_VS2); break;
1318 case 'u': USE_BITS (OP_MASK_VS1, OP_SH_VS1);
1319 USE_BITS (OP_MASK_VS2, OP_SH_VS2); break;
1320 case 'v': USE_BITS (OP_MASK_VD, OP_SH_VD);
1321 USE_BITS (OP_MASK_VS1, OP_SH_VS1);
1322 USE_BITS (OP_MASK_VS2, OP_SH_VS2); break;
1323 case '0': break;
1324 case 'b': used_bits |= ENCODE_RVV_VB_IMM (-1U); break;
1325 case 'c': used_bits |= ENCODE_RVV_VC_IMM (-1U); break;
1326 case 'i':
1327 case 'j':
1328 case 'k': USE_BITS (OP_MASK_VIMM, OP_SH_VIMM); break;
1329 case 'm': USE_BITS (OP_MASK_VMASK, OP_SH_VMASK); break;
c1ecdee7
TO
1330 case 'M': break; /* Macro operand, must be a mask register. */
1331 case 'T': break; /* Macro operand, must be a vector register. */
65e4a99a
NC
1332 default:
1333 goto unknown_validate_operand;
1334 }
a63375ac 1335 break; /* end RVV */
437e2ff1
NC
1336 case ',': break;
1337 case '(': break;
1338 case ')': break;
1339 case '<': USE_BITS (OP_MASK_SHAMTW, OP_SH_SHAMTW); break;
1340 case '>': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
1341 case 'A': break; /* Macro operand, must be symbol. */
1342 case 'B': break; /* Macro operand, must be symbol or constant. */
c1ecdee7 1343 case 'c': break; /* Macro operand, must be symbol or constant. */
437e2ff1
NC
1344 case 'I': break; /* Macro operand, must be constant. */
1345 case 'D': /* RD, floating point. */
1346 case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
3d1cafa0 1347 case 'y': USE_BITS (OP_MASK_BS, OP_SH_BS); break;
1348 case 'Y': USE_BITS (OP_MASK_RNUM, OP_SH_RNUM); break;
437e2ff1
NC
1349 case 'Z': /* RS1, CSR number. */
1350 case 'S': /* RS1, floating point. */
1351 case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
1352 case 'U': /* RS1 and RS2 are the same, floating point. */
1353 USE_BITS (OP_MASK_RS1, OP_SH_RS1);
1354 /* Fall through. */
1355 case 'T': /* RS2, floating point. */
1356 case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break;
1357 case 'R': /* RS3, floating point. */
1358 case 'r': USE_BITS (OP_MASK_RS3, OP_SH_RS3); break;
1359 case 'm': USE_BITS (OP_MASK_RM, OP_SH_RM); break;
1360 case 'E': USE_BITS (OP_MASK_CSR, OP_SH_CSR); break;
1361 case 'P': USE_BITS (OP_MASK_PRED, OP_SH_PRED); break;
1362 case 'Q': USE_BITS (OP_MASK_SUCC, OP_SH_SUCC); break;
1363 case 'o': /* ITYPE immediate, load displacement. */
1364 case 'j': used_bits |= ENCODE_ITYPE_IMM (-1U); break;
1365 case 'a': used_bits |= ENCODE_JTYPE_IMM (-1U); break;
1366 case 'p': used_bits |= ENCODE_BTYPE_IMM (-1U); break;
1367 case 'q': used_bits |= ENCODE_STYPE_IMM (-1U); break;
1368 case 'u': used_bits |= ENCODE_UTYPE_IMM (-1U); break;
1369 case 'z': break; /* Zero immediate. */
1370 case '[': break; /* Unused operand. */
1371 case ']': break; /* Unused operand. */
1372 case '0': break; /* AMO displacement, must to zero. */
1373 case '1': break; /* Relaxation operand. */
1374 case 'F': /* Funct for .insn directive. */
1375 switch (*++oparg)
1376 {
1377 case '7': USE_BITS (OP_MASK_FUNCT7, OP_SH_FUNCT7); break;
1378 case '3': USE_BITS (OP_MASK_FUNCT3, OP_SH_FUNCT3); break;
1379 case '2': USE_BITS (OP_MASK_FUNCT2, OP_SH_FUNCT2); break;
1380 default:
1381 goto unknown_validate_operand;
1382 }
1383 break;
1384 case 'O': /* Opcode for .insn directive. */
1385 switch (*++oparg)
1386 {
1387 case '4': USE_BITS (OP_MASK_OP, OP_SH_OP); break;
1388 case '2': USE_BITS (OP_MASK_OP2, OP_SH_OP2); break;
1389 default:
1390 goto unknown_validate_operand;
1391 }
1392 break;
54bca63b
TO
1393 case 'W': /* Various operands. */
1394 switch (*++oparg)
1395 {
1396 case 'i':
1397 switch (*++oparg)
1398 {
1399 case 'f': used_bits |= ENCODE_STYPE_IMM (-1U); break;
1400 default:
1401 goto unknown_validate_operand;
1402 }
1403 break;
1404 default:
1405 goto unknown_validate_operand;
1406 }
1407 break;
8b7419c4
CM
1408 case 'X': /* Integer immediate. */
1409 {
1410 size_t n;
1411 size_t s;
1412
1413 switch (*++oparg)
1414 {
25236d63
CM
1415 case 'l': /* Literal. */
1416 oparg += strcspn(oparg, ",") - 1;
1417 break;
8b7419c4
CM
1418 case 's': /* 'XsN@S' ... N-bit signed immediate at bit S. */
1419 goto use_imm;
1420 case 'u': /* 'XuN@S' ... N-bit unsigned immediate at bit S. */
1421 goto use_imm;
1422 use_imm:
b0423163 1423 n = strtol (oparg + 1, (char **)&oparg, 10);
8b7419c4
CM
1424 if (*oparg != '@')
1425 goto unknown_validate_operand;
b0423163 1426 s = strtol (oparg + 1, (char **)&oparg, 10);
8b7419c4
CM
1427 oparg--;
1428
1429 USE_IMM (n, s);
1430 break;
1431 default:
1432 goto unknown_validate_operand;
1433 }
1434 }
1435 break;
437e2ff1
NC
1436 default:
1437 unknown_validate_operand:
1438 as_bad (_("internal: bad RISC-V opcode "
1439 "(unknown operand type `%s'): %s %s"),
1440 opargStart, opc->name, opc->args);
1441 return false;
1442 }
1443 }
1444
e23eba97
NC
1445 if (used_bits != required_bits)
1446 {
b800637e 1447 as_bad (_("internal: bad RISC-V opcode "
6b84c098
TO
1448 "(bits %#llx undefined or invalid): %s %s"),
1449 (unsigned long long)(used_bits ^ required_bits),
e23eba97 1450 opc->name, opc->args);
5b7c81bd 1451 return false;
e23eba97 1452 }
5b7c81bd 1453 return true;
e23eba97
NC
1454}
1455
437e2ff1
NC
1456#undef USE_BITS
1457
e23eba97
NC
1458struct percent_op_match
1459{
1460 const char *str;
1461 bfd_reloc_code_real_type reloc;
1462};
1463
dcd709e0
NC
1464/* Common hash table initialization function for instruction and .insn
1465 directive. */
1466
629310ab 1467static htab_t
0e35537d 1468init_opcode_hash (const struct riscv_opcode *opcodes,
5b7c81bd 1469 bool insn_directive_p)
e23eba97
NC
1470{
1471 int i = 0;
0e35537d 1472 int length;
629310ab 1473 htab_t hash = str_htab_create ();
0e35537d 1474 while (opcodes[i].name)
e23eba97 1475 {
0e35537d 1476 const char *name = opcodes[i].name;
fe0e921f 1477 if (str_hash_insert (hash, name, &opcodes[i], 0) != NULL)
b800637e 1478 as_fatal (_("internal: duplicate %s"), name);
e23eba97
NC
1479
1480 do
1481 {
0e35537d 1482 if (opcodes[i].pinfo != INSN_MACRO)
e23eba97 1483 {
0e35537d
JW
1484 if (insn_directive_p)
1485 length = ((name[0] == 'c') ? 2 : 4);
1486 else
dcd709e0 1487 length = 0; /* Let assembler determine the length. */
0e35537d 1488 if (!validate_riscv_insn (&opcodes[i], length))
b800637e
NC
1489 as_fatal (_("internal: broken assembler. "
1490 "No assembly attempted"));
e23eba97 1491 }
0e35537d
JW
1492 else
1493 gas_assert (!insn_directive_p);
e23eba97
NC
1494 ++i;
1495 }
0e35537d 1496 while (opcodes[i].name && !strcmp (opcodes[i].name, name));
e23eba97
NC
1497 }
1498
0e35537d
JW
1499 return hash;
1500}
1501
1502/* This function is called once, at assembler startup time. It should set up
1503 all the tables, etc. that the MD part of the assembler will need. */
1504
1505void
1506md_begin (void)
1507{
1508 unsigned long mach = xlen == 64 ? bfd_mach_riscv64 : bfd_mach_riscv32;
1509
1510 if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach))
b800637e 1511 as_warn (_("could not set architecture and machine"));
0e35537d 1512
5b7c81bd
AM
1513 op_hash = init_opcode_hash (riscv_opcodes, false);
1514 insn_type_hash = init_opcode_hash (riscv_insn_types, true);
0e35537d 1515
629310ab 1516 reg_names_hash = str_htab_create ();
e23eba97
NC
1517 hash_reg_names (RCLASS_GPR, riscv_gpr_names_numeric, NGPR);
1518 hash_reg_names (RCLASS_GPR, riscv_gpr_names_abi, NGPR);
1519 hash_reg_names (RCLASS_FPR, riscv_fpr_names_numeric, NFPR);
1520 hash_reg_names (RCLASS_FPR, riscv_fpr_names_abi, NFPR);
65e4a99a
NC
1521 hash_reg_names (RCLASS_VECR, riscv_vecr_names_numeric, NVECR);
1522 hash_reg_names (RCLASS_VECM, riscv_vecm_names_numeric, NVECM);
b9c04e5a
JW
1523 /* Add "fp" as an alias for "s0". */
1524 hash_reg_name (RCLASS_GPR, "fp", 8);
1525
bd0cf5a6 1526 /* Create and insert CSR hash tables. */
629310ab 1527 csr_extra_hash = str_htab_create ();
8f595e9b
NC
1528#define DECLARE_CSR(name, num, class, define_version, abort_version) \
1529 riscv_init_csr_hash (#name, num, class, define_version, abort_version);
1530#define DECLARE_CSR_ALIAS(name, num, class, define_version, abort_version) \
1531 DECLARE_CSR(name, num, class, define_version, abort_version);
e23eba97
NC
1532#include "opcode/riscv-opc.h"
1533#undef DECLARE_CSR
1534
629310ab 1535 opcode_names_hash = str_htab_create ();
bd0cf5a6
NC
1536 init_opcode_names_hash ();
1537
e23eba97
NC
1538 /* Set the default alignment for the text section. */
1539 record_alignment (text_section, riscv_opts.rvc ? 1 : 2);
1540}
1541
45f76423
AW
1542static insn_t
1543riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type, bfd_vma value)
1544{
1545 switch (reloc_type)
1546 {
1547 case BFD_RELOC_32:
1548 return value;
1549
1550 case BFD_RELOC_RISCV_HI20:
1551 return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
1552
1553 case BFD_RELOC_RISCV_LO12_S:
1554 return ENCODE_STYPE_IMM (value);
1555
1556 case BFD_RELOC_RISCV_LO12_I:
1557 return ENCODE_ITYPE_IMM (value);
1558
1559 default:
1560 abort ();
1561 }
1562}
1563
e23eba97
NC
1564/* Output an instruction. IP is the instruction information.
1565 ADDRESS_EXPR is an operand of the instruction to be used with
1566 RELOC_TYPE. */
1567
1568static void
1569append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
1570 bfd_reloc_code_real_type reloc_type)
1571{
1572 dwarf2_emit_insn (0);
1573
1574 if (reloc_type != BFD_RELOC_UNUSED)
1575 {
1576 reloc_howto_type *howto;
1577
1d65abb5 1578 gas_assert (address_expr);
e23eba97
NC
1579 if (reloc_type == BFD_RELOC_12_PCREL
1580 || reloc_type == BFD_RELOC_RISCV_JMP)
1581 {
1582 int j = reloc_type == BFD_RELOC_RISCV_JMP;
8c07e983 1583 int best_case = insn_length (ip);
e23eba97 1584 unsigned worst_case = relaxed_branch_length (NULL, NULL, 0);
743f5cfc
JW
1585
1586 if (now_seg == absolute_section)
1587 {
1588 as_bad (_("relaxable branches not supported in absolute section"));
1589 return;
1590 }
1591
e23eba97
NC
1592 add_relaxed_insn (ip, worst_case, best_case,
1593 RELAX_BRANCH_ENCODE (j, best_case == 2, worst_case),
1594 address_expr->X_add_symbol,
1595 address_expr->X_add_number);
1596 return;
1597 }
45f76423 1598 else
e23eba97 1599 {
45f76423
AW
1600 howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
1601 if (howto == NULL)
579f0281 1602 as_bad (_("internal: unsupported RISC-V relocation number %d"),
b800637e 1603 reloc_type);
e23eba97 1604
45f76423
AW
1605 ip->fixp = fix_new_exp (ip->frag, ip->where,
1606 bfd_get_reloc_size (howto),
5b7c81bd 1607 address_expr, false, reloc_type);
e23eba97 1608
45f76423 1609 ip->fixp->fx_tcbit = riscv_opts.relax;
e23eba97 1610 }
e23eba97
NC
1611 }
1612
e23eba97 1613 add_fixed_insn (ip);
f77bb6c5
JW
1614
1615 /* We need to start a new frag after any instruction that can be
1616 optimized away or compressed by the linker during relaxation, to prevent
1617 the assembler from computing static offsets across such an instruction.
1618 This is necessary to get correct EH info. */
b1b11e92 1619 if (reloc_type == BFD_RELOC_RISCV_HI20
f77bb6c5
JW
1620 || reloc_type == BFD_RELOC_RISCV_PCREL_HI20
1621 || reloc_type == BFD_RELOC_RISCV_TPREL_HI20
1622 || reloc_type == BFD_RELOC_RISCV_TPREL_ADD)
1623 {
1624 frag_wane (frag_now);
1625 frag_new (0);
1626 }
e23eba97
NC
1627}
1628
1629/* Build an instruction created by a macro expansion. This is passed
dcd709e0
NC
1630 a pointer to the count of instructions created so far, an expression,
1631 the name of the instruction to build, an operand format string, and
1632 corresponding arguments. */
e23eba97
NC
1633
1634static void
1635macro_build (expressionS *ep, const char *name, const char *fmt, ...)
1636{
1637 const struct riscv_opcode *mo;
1638 struct riscv_cl_insn insn;
1639 bfd_reloc_code_real_type r;
1640 va_list args;
437e2ff1 1641 const char *fmtStart;
e23eba97
NC
1642
1643 va_start (args, fmt);
1644
1645 r = BFD_RELOC_UNUSED;
629310ab 1646 mo = (struct riscv_opcode *) str_hash_find (op_hash, name);
e23eba97
NC
1647 gas_assert (mo);
1648
1649 /* Find a non-RVC variant of the instruction. append_insn will compress
1650 it if possible. */
1651 while (riscv_insn_length (mo->match) < 4)
1652 mo++;
1653 gas_assert (strcmp (name, mo->name) == 0);
1654
1655 create_insn (&insn, mo);
437e2ff1 1656 for (;; ++fmt)
e23eba97 1657 {
437e2ff1
NC
1658 fmtStart = fmt;
1659 switch (*fmt)
e23eba97 1660 {
65e4a99a
NC
1661 case 'V': /* RVV */
1662 switch (*++fmt)
1663 {
1664 case 'd':
1665 INSERT_OPERAND (VD, insn, va_arg (args, int));
1666 continue;
1667 case 's':
1668 INSERT_OPERAND (VS1, insn, va_arg (args, int));
1669 continue;
1670 case 't':
1671 INSERT_OPERAND (VS2, insn, va_arg (args, int));
1672 continue;
1673 case 'm':
1674 {
1675 int reg = va_arg (args, int);
1676 if (reg == -1)
1677 {
1678 INSERT_OPERAND (VMASK, insn, 1);
1679 continue;
1680 }
1681 else if (reg == 0)
1682 {
1683 INSERT_OPERAND (VMASK, insn, 0);
1684 continue;
1685 }
1686 else
1687 goto unknown_macro_argument;
1688 }
1689 default:
1690 goto unknown_macro_argument;
1691 }
1692 break;
1693
e23eba97
NC
1694 case 'd':
1695 INSERT_OPERAND (RD, insn, va_arg (args, int));
1696 continue;
e23eba97
NC
1697 case 's':
1698 INSERT_OPERAND (RS1, insn, va_arg (args, int));
1699 continue;
e23eba97
NC
1700 case 't':
1701 INSERT_OPERAND (RS2, insn, va_arg (args, int));
1702 continue;
1703
e23eba97
NC
1704 case 'j':
1705 case 'u':
1706 case 'q':
1707 gas_assert (ep != NULL);
1708 r = va_arg (args, int);
1709 continue;
1710
1711 case '\0':
1712 break;
1713 case ',':
1714 continue;
1715 default:
65e4a99a 1716 unknown_macro_argument:
437e2ff1 1717 as_fatal (_("internal: invalid macro argument `%s'"), fmtStart);
e23eba97
NC
1718 }
1719 break;
1720 }
1721 va_end (args);
1722 gas_assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
1723
1724 append_insn (&insn, ep, r);
1725}
1726
db3b6ecc
KC
1727/* Build an instruction created by a macro expansion. Like md_assemble but
1728 accept a printf-style format string and arguments. */
1729
1730static void
1731md_assemblef (const char *format, ...)
1732{
1733 char *buf = NULL;
1734 va_list ap;
1735 int r;
1736
1737 va_start (ap, format);
1738
1739 r = vasprintf (&buf, format, ap);
1740
1741 if (r < 0)
b800637e 1742 as_fatal (_("internal: vasprintf failed"));
db3b6ecc
KC
1743
1744 md_assemble (buf);
1745 free(buf);
1746
1747 va_end (ap);
1748}
1749
e23eba97
NC
1750/* Sign-extend 32-bit mode constants that have bit 31 set and all higher bits
1751 unset. */
dcd709e0 1752
e23eba97
NC
1753static void
1754normalize_constant_expr (expressionS *ex)
1755{
1756 if (xlen > 32)
1757 return;
1758 if ((ex->X_op == O_constant || ex->X_op == O_symbol)
1759 && IS_ZEXT_32BIT_NUM (ex->X_add_number))
1760 ex->X_add_number = (((ex->X_add_number & 0xffffffff) ^ 0x80000000)
1761 - 0x80000000);
1762}
1763
ca2fd32c
JW
1764/* Fail if an expression EX is not a constant. IP is the instruction using EX.
1765 MAYBE_CSR is true if the symbol may be an unrecognized CSR name. */
e23eba97
NC
1766
1767static void
ca2fd32c 1768check_absolute_expr (struct riscv_cl_insn *ip, expressionS *ex,
5b7c81bd 1769 bool maybe_csr)
e23eba97
NC
1770{
1771 if (ex->X_op == O_big)
1772 as_bad (_("unsupported large constant"));
ca2fd32c
JW
1773 else if (maybe_csr && ex->X_op == O_symbol)
1774 as_bad (_("unknown CSR `%s'"),
1775 S_GET_NAME (ex->X_add_symbol));
e23eba97 1776 else if (ex->X_op != O_constant)
b800637e 1777 as_bad (_("instruction %s requires absolute expression"),
e23eba97
NC
1778 ip->insn_mo->name);
1779 normalize_constant_expr (ex);
1780}
1781
1782static symbolS *
1783make_internal_label (void)
1784{
e01e1cee
AM
1785 return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg, frag_now,
1786 frag_now_fix ());
e23eba97
NC
1787}
1788
1789/* Load an entry from the GOT. */
dcd709e0 1790
e23eba97
NC
1791static void
1792pcrel_access (int destreg, int tempreg, expressionS *ep,
1793 const char *lo_insn, const char *lo_pattern,
1794 bfd_reloc_code_real_type hi_reloc,
1795 bfd_reloc_code_real_type lo_reloc)
1796{
1797 expressionS ep2;
1798 ep2.X_op = O_symbol;
1799 ep2.X_add_symbol = make_internal_label ();
1800 ep2.X_add_number = 0;
1801
1802 macro_build (ep, "auipc", "d,u", tempreg, hi_reloc);
1803 macro_build (&ep2, lo_insn, lo_pattern, destreg, tempreg, lo_reloc);
1804}
1805
1806static void
1807pcrel_load (int destreg, int tempreg, expressionS *ep, const char *lo_insn,
1808 bfd_reloc_code_real_type hi_reloc,
1809 bfd_reloc_code_real_type lo_reloc)
1810{
1811 pcrel_access (destreg, tempreg, ep, lo_insn, "d,s,j", hi_reloc, lo_reloc);
1812}
1813
1814static void
1815pcrel_store (int srcreg, int tempreg, expressionS *ep, const char *lo_insn,
1816 bfd_reloc_code_real_type hi_reloc,
1817 bfd_reloc_code_real_type lo_reloc)
1818{
1819 pcrel_access (srcreg, tempreg, ep, lo_insn, "t,s,q", hi_reloc, lo_reloc);
1820}
1821
1822/* PC-relative function call using AUIPC/JALR, relaxed to JAL. */
dcd709e0 1823
e23eba97
NC
1824static void
1825riscv_call (int destreg, int tempreg, expressionS *ep,
1826 bfd_reloc_code_real_type reloc)
1827{
b1b11e92
AM
1828 /* Ensure the jalr is emitted to the same frag as the auipc. */
1829 frag_grow (8);
e23eba97
NC
1830 macro_build (ep, "auipc", "d,u", tempreg, reloc);
1831 macro_build (NULL, "jalr", "d,s", destreg, tempreg);
b1b11e92
AM
1832 /* See comment at end of append_insn. */
1833 frag_wane (frag_now);
1834 frag_new (0);
e23eba97
NC
1835}
1836
1837/* Load an integer constant into a register. */
1838
1839static void
1840load_const (int reg, expressionS *ep)
1841{
1842 int shift = RISCV_IMM_BITS;
4f7cc141 1843 bfd_vma upper_imm, sign = (bfd_vma) 1 << (RISCV_IMM_BITS - 1);
e23eba97 1844 expressionS upper = *ep, lower = *ep;
4f7cc141 1845 lower.X_add_number = ((ep->X_add_number & (sign + sign - 1)) ^ sign) - sign;
e23eba97
NC
1846 upper.X_add_number -= lower.X_add_number;
1847
1848 if (ep->X_op != O_constant)
1849 {
1850 as_bad (_("unsupported large constant"));
1851 return;
1852 }
1853
1d65abb5 1854 if (xlen > 32 && !IS_SEXT_32BIT_NUM (ep->X_add_number))
e23eba97
NC
1855 {
1856 /* Reduce to a signed 32-bit constant using SLLI and ADDI. */
1857 while (((upper.X_add_number >> shift) & 1) == 0)
1858 shift++;
1859
1860 upper.X_add_number = (int64_t) upper.X_add_number >> shift;
1d65abb5 1861 load_const (reg, &upper);
e23eba97 1862
db3b6ecc 1863 md_assemblef ("slli x%d, x%d, 0x%x", reg, reg, shift);
e23eba97 1864 if (lower.X_add_number != 0)
b8281767
AM
1865 md_assemblef ("addi x%d, x%d, %" PRId64, reg, reg,
1866 (int64_t) lower.X_add_number);
e23eba97
NC
1867 }
1868 else
1869 {
1870 /* Simply emit LUI and/or ADDI to build a 32-bit signed constant. */
1871 int hi_reg = 0;
1872
1873 if (upper.X_add_number != 0)
1874 {
db3b6ecc
KC
1875 /* Discard low part and zero-extend upper immediate. */
1876 upper_imm = ((uint32_t)upper.X_add_number >> shift);
1877
b8281767 1878 md_assemblef ("lui x%d, 0x%" PRIx64, reg, (uint64_t) upper_imm);
e23eba97
NC
1879 hi_reg = reg;
1880 }
1881
1882 if (lower.X_add_number != 0 || hi_reg == 0)
b8281767
AM
1883 md_assemblef ("%s x%d, x%d, %" PRId64, ADD32_INSN, reg, hi_reg,
1884 (int64_t) lower.X_add_number);
e23eba97
NC
1885 }
1886}
1887
c2137f55
NC
1888/* Zero extend and sign extend byte/half-word/word. */
1889
1890static void
5b7c81bd 1891riscv_ext (int destreg, int srcreg, unsigned shift, bool sign)
c2137f55
NC
1892{
1893 if (sign)
1894 {
1895 md_assemblef ("slli x%d, x%d, 0x%x", destreg, srcreg, shift);
1896 md_assemblef ("srai x%d, x%d, 0x%x", destreg, destreg, shift);
1897 }
1898 else
1899 {
1900 md_assemblef ("slli x%d, x%d, 0x%x", destreg, srcreg, shift);
1901 md_assemblef ("srli x%d, x%d, 0x%x", destreg, destreg, shift);
1902 }
1903}
1904
65e4a99a
NC
1905/* Expand RISC-V Vector macros into one or more instructions. */
1906
1907static void
1908vector_macro (struct riscv_cl_insn *ip)
1909{
1910 int vd = (ip->insn_opcode >> OP_SH_VD) & OP_MASK_VD;
1911 int vs1 = (ip->insn_opcode >> OP_SH_VS1) & OP_MASK_VS1;
1912 int vs2 = (ip->insn_opcode >> OP_SH_VS2) & OP_MASK_VS2;
1913 int vm = (ip->insn_opcode >> OP_SH_VMASK) & OP_MASK_VMASK;
1914 int vtemp = (ip->insn_opcode >> OP_SH_VFUNCT6) & OP_MASK_VFUNCT6;
1915 int mask = ip->insn_mo->mask;
1916
1917 switch (mask)
1918 {
1919 case M_VMSGE:
1920 if (vm)
1921 {
1922 /* Unmasked. */
1923 macro_build (NULL, "vmslt.vx", "Vd,Vt,sVm", vd, vs2, vs1, -1);
1924 macro_build (NULL, "vmnand.mm", "Vd,Vt,Vs", vd, vd, vd);
1925 break;
1926 }
1927 if (vtemp != 0)
1928 {
1929 /* Masked. Have vtemp to avoid overlap constraints. */
1930 if (vd == vm)
1931 {
1932 macro_build (NULL, "vmslt.vx", "Vd,Vt,s", vtemp, vs2, vs1);
1933 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vm, vtemp);
1934 }
1935 else
1936 {
1937 /* Preserve the value of vd if not updating by vm. */
1938 macro_build (NULL, "vmslt.vx", "Vd,Vt,s", vtemp, vs2, vs1);
1939 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vtemp, vm, vtemp);
1940 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vd, vm);
1941 macro_build (NULL, "vmor.mm", "Vd,Vt,Vs", vd, vtemp, vd);
1942 }
1943 }
1944 else if (vd != vm)
1945 {
1946 /* Masked. This may cause the vd overlaps vs2, when LMUL > 1. */
1947 macro_build (NULL, "vmslt.vx", "Vd,Vt,sVm", vd, vs2, vs1, vm);
1948 macro_build (NULL, "vmxor.mm", "Vd,Vt,Vs", vd, vd, vm);
1949 }
1950 else
1951 as_bad (_("must provide temp if destination overlaps mask"));
1952 break;
1953
1954 case M_VMSGEU:
1955 if (vm)
1956 {
1957 /* Unmasked. */
1958 macro_build (NULL, "vmsltu.vx", "Vd,Vt,sVm", vd, vs2, vs1, -1);
1959 macro_build (NULL, "vmnand.mm", "Vd,Vt,Vs", vd, vd, vd);
1960 break;
1961 }
1962 if (vtemp != 0)
1963 {
1964 /* Masked. Have vtemp to avoid overlap constraints. */
1965 if (vd == vm)
1966 {
1967 macro_build (NULL, "vmsltu.vx", "Vd,Vt,s", vtemp, vs2, vs1);
1968 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vm, vtemp);
1969 }
1970 else
1971 {
1972 /* Preserve the value of vd if not updating by vm. */
1973 macro_build (NULL, "vmsltu.vx", "Vd,Vt,s", vtemp, vs2, vs1);
1974 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vtemp, vm, vtemp);
1975 macro_build (NULL, "vmandnot.mm", "Vd,Vt,Vs", vd, vd, vm);
1976 macro_build (NULL, "vmor.mm", "Vd,Vt,Vs", vd, vtemp, vd);
1977 }
1978 }
1979 else if (vd != vm)
1980 {
1981 /* Masked. This may cause the vd overlaps vs2, when LMUL > 1. */
1982 macro_build (NULL, "vmsltu.vx", "Vd,Vt,sVm", vd, vs2, vs1, vm);
1983 macro_build (NULL, "vmxor.mm", "Vd,Vt,Vs", vd, vd, vm);
1984 }
1985 else
1986 as_bad (_("must provide temp if destination overlaps mask"));
1987 break;
1988
1989 default:
1990 break;
1991 }
1992}
1993
e23eba97 1994/* Expand RISC-V assembly macros into one or more instructions. */
2652cfad 1995
e23eba97
NC
1996static void
1997macro (struct riscv_cl_insn *ip, expressionS *imm_expr,
1998 bfd_reloc_code_real_type *imm_reloc)
1999{
2000 int rd = (ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD;
2001 int rs1 = (ip->insn_opcode >> OP_SH_RS1) & OP_MASK_RS1;
2002 int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2;
2003 int mask = ip->insn_mo->mask;
2004
2005 switch (mask)
2006 {
2007 case M_LI:
2008 load_const (rd, imm_expr);
2009 break;
2010
2011 case M_LA:
2012 case M_LLA:
2013 /* Load the address of a symbol into a register. */
2014 if (!IS_SEXT_32BIT_NUM (imm_expr->X_add_number))
2015 as_bad (_("offset too large"));
2016
2017 if (imm_expr->X_op == O_constant)
2018 load_const (rd, imm_expr);
dcd709e0 2019 else if (riscv_opts.pic && mask == M_LA) /* Global PIC symbol. */
e23eba97
NC
2020 pcrel_load (rd, rd, imm_expr, LOAD_ADDRESS_INSN,
2021 BFD_RELOC_RISCV_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
dcd709e0 2022 else /* Local PIC symbol, or any non-PIC symbol. */
e23eba97
NC
2023 pcrel_load (rd, rd, imm_expr, "addi",
2024 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2025 break;
2026
2027 case M_LA_TLS_GD:
2028 pcrel_load (rd, rd, imm_expr, "addi",
2029 BFD_RELOC_RISCV_TLS_GD_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2030 break;
2031
2032 case M_LA_TLS_IE:
2033 pcrel_load (rd, rd, imm_expr, LOAD_ADDRESS_INSN,
2034 BFD_RELOC_RISCV_TLS_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2035 break;
2036
2037 case M_LB:
2038 pcrel_load (rd, rd, imm_expr, "lb",
2039 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2040 break;
2041
2042 case M_LBU:
2043 pcrel_load (rd, rd, imm_expr, "lbu",
2044 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2045 break;
2046
2047 case M_LH:
2048 pcrel_load (rd, rd, imm_expr, "lh",
2049 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2050 break;
2051
2052 case M_LHU:
2053 pcrel_load (rd, rd, imm_expr, "lhu",
2054 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2055 break;
2056
2057 case M_LW:
2058 pcrel_load (rd, rd, imm_expr, "lw",
2059 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2060 break;
2061
2062 case M_LWU:
2063 pcrel_load (rd, rd, imm_expr, "lwu",
2064 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2065 break;
2066
2067 case M_LD:
2068 pcrel_load (rd, rd, imm_expr, "ld",
2069 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2070 break;
2071
2072 case M_FLW:
2073 pcrel_load (rd, rs1, imm_expr, "flw",
2074 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2075 break;
2076
2077 case M_FLD:
2078 pcrel_load (rd, rs1, imm_expr, "fld",
2079 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2080 break;
2081
2082 case M_SB:
2083 pcrel_store (rs2, rs1, imm_expr, "sb",
2084 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2085 break;
2086
2087 case M_SH:
2088 pcrel_store (rs2, rs1, imm_expr, "sh",
2089 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2090 break;
2091
2092 case M_SW:
2093 pcrel_store (rs2, rs1, imm_expr, "sw",
2094 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2095 break;
2096
2097 case M_SD:
2098 pcrel_store (rs2, rs1, imm_expr, "sd",
2099 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2100 break;
2101
2102 case M_FSW:
2103 pcrel_store (rs2, rs1, imm_expr, "fsw",
2104 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2105 break;
2106
2107 case M_FSD:
2108 pcrel_store (rs2, rs1, imm_expr, "fsd",
2109 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2110 break;
2111
2112 case M_CALL:
2113 riscv_call (rd, rs1, imm_expr, *imm_reloc);
2114 break;
2115
c2137f55 2116 case M_ZEXTH:
5b7c81bd 2117 riscv_ext (rd, rs1, xlen - 16, false);
c2137f55
NC
2118 break;
2119
2120 case M_ZEXTW:
5b7c81bd 2121 riscv_ext (rd, rs1, xlen - 32, false);
c2137f55
NC
2122 break;
2123
2124 case M_SEXTB:
5b7c81bd 2125 riscv_ext (rd, rs1, xlen - 8, true);
c2137f55
NC
2126 break;
2127
2128 case M_SEXTH:
5b7c81bd 2129 riscv_ext (rd, rs1, xlen - 16, true);
c2137f55
NC
2130 break;
2131
65e4a99a
NC
2132 case M_VMSGE:
2133 case M_VMSGEU:
2134 vector_macro (ip);
2135 break;
2136
035784e3
NC
2137 case M_FLH:
2138 pcrel_load (rd, rs1, imm_expr, "flh",
2139 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
2140 break;
2141 case M_FSH:
2142 pcrel_store (rs2, rs1, imm_expr, "fsh",
2143 BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
2144 break;
2145
e23eba97 2146 default:
b800637e 2147 as_bad (_("internal: macro %s not implemented"), ip->insn_mo->name);
e23eba97
NC
2148 break;
2149 }
2150}
2151
2152static const struct percent_op_match percent_op_utype[] =
2153{
85bd4bfb
JB
2154 {"tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
2155 {"pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
2156 {"got_pcrel_hi", BFD_RELOC_RISCV_GOT_HI20},
2157 {"tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
2158 {"tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
2159 {"hi", BFD_RELOC_RISCV_HI20},
e23eba97
NC
2160 {0, 0}
2161};
2162
2163static const struct percent_op_match percent_op_itype[] =
2164{
85bd4bfb
JB
2165 {"lo", BFD_RELOC_RISCV_LO12_I},
2166 {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
2167 {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
e23eba97
NC
2168 {0, 0}
2169};
2170
2171static const struct percent_op_match percent_op_stype[] =
2172{
85bd4bfb
JB
2173 {"lo", BFD_RELOC_RISCV_LO12_S},
2174 {"tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_S},
2175 {"pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_S},
e23eba97
NC
2176 {0, 0}
2177};
2178
2179static const struct percent_op_match percent_op_rtype[] =
2180{
85bd4bfb 2181 {"tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
e23eba97
NC
2182 {0, 0}
2183};
2184
f50fabe4
JW
2185static const struct percent_op_match percent_op_null[] =
2186{
2187 {0, 0}
2188};
2189
e23eba97
NC
2190/* Return true if *STR points to a relocation operator. When returning true,
2191 move *STR over the operator and store its relocation code in *RELOC.
2192 Leave both *STR and *RELOC alone when returning false. */
2193
5b7c81bd 2194static bool
e23eba97
NC
2195parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
2196 const struct percent_op_match *percent_op)
2197{
2198 for ( ; percent_op->str; percent_op++)
85bd4bfb 2199 if (strncasecmp (*str + 1, percent_op->str, strlen (percent_op->str)) == 0)
e23eba97 2200 {
85bd4bfb 2201 size_t len = 1 + strlen (percent_op->str);
e23eba97 2202
654dfab0
JB
2203 while (ISSPACE ((*str)[len]))
2204 ++len;
2205 if ((*str)[len] != '(')
e23eba97
NC
2206 continue;
2207
85bd4bfb 2208 *str += len;
e23eba97
NC
2209 *reloc = percent_op->reloc;
2210
2211 /* Check whether the output BFD supports this relocation.
2212 If not, issue an error and fall back on something safe. */
45f76423
AW
2213 if (*reloc != BFD_RELOC_UNUSED
2214 && !bfd_reloc_type_lookup (stdoutput, *reloc))
e23eba97 2215 {
b800637e
NC
2216 as_bad ("internal: relocation %s isn't supported by the "
2217 "current ABI", percent_op->str);
e23eba97
NC
2218 *reloc = BFD_RELOC_UNUSED;
2219 }
5b7c81bd 2220 return true;
e23eba97 2221 }
5b7c81bd 2222 return false;
e23eba97
NC
2223}
2224
2225static void
2226my_getExpression (expressionS *ep, char *str)
2227{
2228 char *save_in;
2229
2230 save_in = input_line_pointer;
2231 input_line_pointer = str;
2232 expression (ep);
6eb099ae 2233 expr_parse_end = input_line_pointer;
e23eba97
NC
2234 input_line_pointer = save_in;
2235}
2236
2237/* Parse string STR as a 16-bit relocatable operand. Store the
2238 expression in *EP and the relocation, if any, in RELOC.
2239 Return the number of relocation operators used (0 or 1).
2240
6eb099ae
AM
2241 On exit, EXPR_PARSE_END points to the first character after the
2242 expression. */
e23eba97
NC
2243
2244static size_t
2245my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
2246 char *str, const struct percent_op_match *percent_op)
2247{
2248 size_t reloc_index;
7a29ee29
JB
2249 unsigned crux_depth, str_depth;
2250 bool orig_probing = probing_insn_operands;
e23eba97
NC
2251 char *crux;
2252
e23eba97 2253 /* Search for the start of the main expression.
dcd709e0
NC
2254
2255 End the loop with CRUX pointing to the start of the main expression and
2256 with CRUX_DEPTH containing the number of open brackets at that point. */
e23eba97
NC
2257 reloc_index = -1;
2258 str_depth = 0;
2259 do
2260 {
2261 reloc_index++;
2262 crux = str;
2263 crux_depth = str_depth;
2264
2265 /* Skip over whitespace and brackets, keeping count of the number
2266 of brackets. */
2267 while (*str == ' ' || *str == '\t' || *str == '(')
2268 if (*str++ == '(')
2269 str_depth++;
2270 }
2271 while (*str == '%'
2272 && reloc_index < 1
2273 && parse_relocation (&str, reloc, percent_op));
2274
a5e756e6
JB
2275 if (*str == '%')
2276 {
2277 /* expression() will choke on anything looking like an (unrecognized)
2278 relocation specifier. Don't even call it, avoiding multiple (and
2279 perhaps redundant) error messages; our caller will issue one. */
2280 ep->X_op = O_illegal;
2281 return 0;
2282 }
2283
7a29ee29
JB
2284 /* Anything inside parentheses or subject to a relocation operator cannot
2285 be a register and hence can be treated the same as operands to
2286 directives (other than .insn). */
2287 if (str_depth || reloc_index)
2288 probing_insn_operands = false;
2289
e23eba97 2290 my_getExpression (ep, crux);
6eb099ae 2291 str = expr_parse_end;
e23eba97 2292
7a29ee29
JB
2293 probing_insn_operands = orig_probing;
2294
e23eba97
NC
2295 /* Match every open bracket. */
2296 while (crux_depth > 0 && (*str == ')' || *str == ' ' || *str == '\t'))
2297 if (*str++ == ')')
2298 crux_depth--;
2299
2300 if (crux_depth > 0)
2301 as_bad ("unclosed '('");
2302
6eb099ae 2303 expr_parse_end = str;
e23eba97
NC
2304
2305 return reloc_index;
2306}
2307
0e35537d 2308/* Parse opcode name, could be an mnemonics or number. */
dcd709e0 2309
0e35537d
JW
2310static size_t
2311my_getOpcodeExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
408ab016 2312 char *str)
0e35537d
JW
2313{
2314 const struct opcode_name_t *o = opcode_name_lookup (&str);
2315
2316 if (o != NULL)
2317 {
2318 ep->X_op = O_constant;
2319 ep->X_add_number = o->val;
2320 return 0;
2321 }
2322
408ab016 2323 return my_getSmallExpression (ep, reloc, str, percent_op_null);
0e35537d
JW
2324}
2325
65e4a99a 2326/* Parse string STR as a vsetvli operand. Store the expression in *EP.
6eb099ae
AM
2327 On exit, EXPR_PARSE_END points to the first character after the
2328 expression. */
65e4a99a
NC
2329
2330static void
2331my_getVsetvliExpression (expressionS *ep, char *str)
2332{
2333 unsigned int vsew_value = 0, vlmul_value = 0;
2334 unsigned int vta_value = 0, vma_value = 0;
2335 bfd_boolean vsew_found = FALSE, vlmul_found = FALSE;
2336 bfd_boolean vta_found = FALSE, vma_found = FALSE;
2337
2338 if (arg_lookup (&str, riscv_vsew, ARRAY_SIZE (riscv_vsew), &vsew_value))
2339 {
2340 if (*str == ',')
2341 ++str;
2342 if (vsew_found)
2343 as_bad (_("multiple vsew constants"));
2344 vsew_found = TRUE;
2345 }
2346 if (arg_lookup (&str, riscv_vlmul, ARRAY_SIZE (riscv_vlmul), &vlmul_value))
2347 {
2348 if (*str == ',')
2349 ++str;
2350 if (vlmul_found)
2351 as_bad (_("multiple vlmul constants"));
2352 vlmul_found = TRUE;
2353 }
2354 if (arg_lookup (&str, riscv_vta, ARRAY_SIZE (riscv_vta), &vta_value))
2355 {
2356 if (*str == ',')
2357 ++str;
2358 if (vta_found)
2359 as_bad (_("multiple vta constants"));
2360 vta_found = TRUE;
2361 }
2362 if (arg_lookup (&str, riscv_vma, ARRAY_SIZE (riscv_vma), &vma_value))
2363 {
2364 if (*str == ',')
2365 ++str;
2366 if (vma_found)
2367 as_bad (_("multiple vma constants"));
2368 vma_found = TRUE;
2369 }
2370
2371 if (vsew_found || vlmul_found || vta_found || vma_found)
2372 {
2373 ep->X_op = O_constant;
2374 ep->X_add_number = (vlmul_value << OP_SH_VLMUL)
2375 | (vsew_value << OP_SH_VSEW)
2376 | (vta_value << OP_SH_VTA)
2377 | (vma_value << OP_SH_VMA);
6eb099ae 2378 expr_parse_end = str;
65e4a99a
NC
2379 }
2380 else
2381 {
2382 my_getExpression (ep, str);
6eb099ae 2383 str = expr_parse_end;
65e4a99a
NC
2384 }
2385}
2386
f0531ed6 2387/* Detect and handle implicitly zero load-store offsets. For example,
437e2ff1 2388 "lw t0, (t1)" is shorthand for "lw t0, 0(t1)". Return true if such
f0531ed6
JW
2389 an implicit offset was detected. */
2390
5b7c81bd 2391static bool
89424b1d 2392riscv_handle_implicit_zero_offset (expressionS *ep, const char *s)
f0531ed6
JW
2393{
2394 /* Check whether there is only a single bracketed expression left.
2395 If so, it must be the base register and the constant must be zero. */
2396 if (*s == '(' && strchr (s + 1, '(') == 0)
2397 {
89424b1d
MR
2398 ep->X_op = O_constant;
2399 ep->X_add_number = 0;
5b7c81bd 2400 return true;
f0531ed6
JW
2401 }
2402
5b7c81bd 2403 return false;
f0531ed6
JW
2404}
2405
54b2aec1 2406/* All RISC-V CSR instructions belong to one of these classes. */
54b2aec1
NC
2407enum csr_insn_type
2408{
2409 INSN_NOT_CSR,
2410 INSN_CSRRW,
2411 INSN_CSRRS,
2412 INSN_CSRRC
2413};
2414
2415/* Return which CSR instruction is checking. */
2416
2417static enum csr_insn_type
2418riscv_csr_insn_type (insn_t insn)
2419{
2420 if (((insn ^ MATCH_CSRRW) & MASK_CSRRW) == 0
2421 || ((insn ^ MATCH_CSRRWI) & MASK_CSRRWI) == 0)
2422 return INSN_CSRRW;
2423 else if (((insn ^ MATCH_CSRRS) & MASK_CSRRS) == 0
2424 || ((insn ^ MATCH_CSRRSI) & MASK_CSRRSI) == 0)
2425 return INSN_CSRRS;
2426 else if (((insn ^ MATCH_CSRRC) & MASK_CSRRC) == 0
2427 || ((insn ^ MATCH_CSRRCI) & MASK_CSRRCI) == 0)
2428 return INSN_CSRRC;
2429 else
2430 return INSN_NOT_CSR;
2431}
2432
2433/* CSRRW and CSRRWI always write CSR. CSRRS, CSRRC, CSRRSI and CSRRCI write
2434 CSR when RS1 isn't zero. The CSR is read only if the [11:10] bits of
2435 CSR address is 0x3. */
2436
5b7c81bd 2437static bool
54b2aec1
NC
2438riscv_csr_read_only_check (insn_t insn)
2439{
2440 int csr = (insn & (OP_MASK_CSR << OP_SH_CSR)) >> OP_SH_CSR;
2441 int rs1 = (insn & (OP_MASK_RS1 << OP_SH_RS1)) >> OP_SH_RS1;
2442 int readonly = (((csr & (0x3 << 10)) >> 10) == 0x3);
2443 enum csr_insn_type csr_insn = riscv_csr_insn_type (insn);
2444
2445 if (readonly
2446 && (((csr_insn == INSN_CSRRS
2447 || csr_insn == INSN_CSRRC)
2448 && rs1 != 0)
2449 || csr_insn == INSN_CSRRW))
5b7c81bd 2450 return false;
54b2aec1 2451
5b7c81bd 2452 return true;
54b2aec1
NC
2453}
2454
437e2ff1 2455/* Return true if it is a privileged instruction. Otherwise, return false.
1a79004f
NC
2456
2457 uret is actually a N-ext instruction. So it is better to regard it as
2458 an user instruction rather than the priv instruction.
2459
2460 hret is used to return from traps in H-mode. H-mode is removed since
2461 the v1.10 priv spec, but probably be added in the new hypervisor spec.
2462 Therefore, hret should be controlled by the hypervisor spec rather than
2463 priv spec in the future.
2464
2465 dret is defined in the debug spec, so it should be checked in the future,
2466 too. */
2467
5b7c81bd 2468static bool
1a79004f
NC
2469riscv_is_priv_insn (insn_t insn)
2470{
2471 return (((insn ^ MATCH_SRET) & MASK_SRET) == 0
2472 || ((insn ^ MATCH_MRET) & MASK_MRET) == 0
2473 || ((insn ^ MATCH_SFENCE_VMA) & MASK_SFENCE_VMA) == 0
2474 || ((insn ^ MATCH_WFI) & MASK_WFI) == 0
2475 /* The sfence.vm is dropped in the v1.10 priv specs, but we still need to
dcd709e0 2476 check it here to keep the compatible. */
1a79004f
NC
2477 || ((insn ^ MATCH_SFENCE_VM) & MASK_SFENCE_VM) == 0);
2478}
2479
7a29ee29
JB
2480static symbolS *deferred_sym_rootP;
2481static symbolS *deferred_sym_lastP;
2482/* Since symbols can't easily be freed, try to recycle ones which weren't
2483 committed. */
2484static symbolS *orphan_sym_rootP;
2485static symbolS *orphan_sym_lastP;
2486
e23eba97
NC
2487/* This routine assembles an instruction into its binary format. As a
2488 side effect, it sets the global variable imm_reloc to the type of
2489 relocation to do if one of the operands is an address expression. */
2490
e4028336 2491static struct riscv_ip_error
e23eba97 2492riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
629310ab 2493 bfd_reloc_code_real_type *imm_reloc, htab_t hash)
e23eba97 2494{
437e2ff1
NC
2495 /* The operand string defined in the riscv_opcodes. */
2496 const char *oparg, *opargStart;
2497 /* The parsed operands from assembly. */
2498 char *asarg, *asargStart;
2499 char save_c = 0;
e23eba97 2500 struct riscv_opcode *insn;
e23eba97 2501 unsigned int regno;
e23eba97 2502 const struct percent_op_match *p;
e4028336
PN
2503 struct riscv_ip_error error;
2504 error.msg = "unrecognized opcode";
2505 error.statement = str;
2506 error.missing_ext = NULL;
54b2aec1 2507 /* Indicate we are assembling instruction with CSR. */
5b7c81bd 2508 bool insn_with_csr = false;
e23eba97
NC
2509
2510 /* Parse the name of the instruction. Terminate the string if whitespace
629310ab 2511 is found so that str_hash_find only sees the name part of the string. */
437e2ff1
NC
2512 for (asarg = str; *asarg!= '\0'; ++asarg)
2513 if (ISSPACE (*asarg))
e23eba97 2514 {
437e2ff1
NC
2515 save_c = *asarg;
2516 *asarg++ = '\0';
e23eba97
NC
2517 break;
2518 }
2519
629310ab 2520 insn = (struct riscv_opcode *) str_hash_find (hash, str);
e23eba97 2521
7a29ee29
JB
2522 probing_insn_operands = true;
2523
437e2ff1 2524 asargStart = asarg;
e23eba97
NC
2525 for ( ; insn && insn->name && strcmp (insn->name, str) == 0; insn++)
2526 {
1080bf78
JW
2527 if ((insn->xlen_requirement != 0) && (xlen != insn->xlen_requirement))
2528 continue;
2529
f786c359 2530 if (!riscv_multi_subset_supports (&riscv_rps_as, insn->insn_class))
e4028336
PN
2531 {
2532 error.missing_ext = riscv_multi_subset_supports_ext (&riscv_rps_as,
2533 insn->insn_class);
2534 continue;
2535 }
e23eba97 2536
65e4a99a 2537 /* Reset error message of the previous round. */
e4028336
PN
2538 error.msg = _("illegal operands");
2539 error.missing_ext = NULL;
7a29ee29
JB
2540
2541 /* Purge deferred symbols from the previous round, if any. */
2542 while (deferred_sym_rootP)
2543 {
2544 symbolS *sym = deferred_sym_rootP;
2545
2546 symbol_remove (sym, &deferred_sym_rootP, &deferred_sym_lastP);
2547 symbol_append (sym, orphan_sym_lastP, &orphan_sym_rootP,
2548 &orphan_sym_lastP);
2549 }
2550
e23eba97 2551 create_insn (ip, insn);
e23eba97
NC
2552
2553 imm_expr->X_op = O_absent;
2554 *imm_reloc = BFD_RELOC_UNUSED;
b33e94cf 2555 p = percent_op_null;
e23eba97 2556
437e2ff1 2557 for (oparg = insn->args;; ++oparg)
e23eba97 2558 {
437e2ff1
NC
2559 opargStart = oparg;
2560 asarg += strspn (asarg, " \t");
2561 switch (*oparg)
e23eba97 2562 {
dcd709e0 2563 case '\0': /* End of args. */
e23eba97
NC
2564 if (insn->pinfo != INSN_MACRO)
2565 {
2566 if (!insn->match_func (insn, ip->insn_opcode))
2567 break;
0e35537d
JW
2568
2569 /* For .insn, insn->match and insn->mask are 0. */
2570 if (riscv_insn_length ((insn->match == 0 && insn->mask == 0)
2571 ? ip->insn_opcode
2572 : insn->match) == 2
2573 && !riscv_opts.rvc)
e23eba97 2574 break;
54b2aec1 2575
1a79004f 2576 if (riscv_is_priv_insn (ip->insn_opcode))
5b7c81bd 2577 explicit_priv_attr = true;
1a79004f 2578
54b2aec1
NC
2579 /* Check if we write a read-only CSR by the CSR
2580 instruction. */
2581 if (insn_with_csr
2582 && riscv_opts.csr_check
2583 && !riscv_csr_read_only_check (ip->insn_opcode))
2584 {
2585 /* Restore the character in advance, since we want to
2586 report the detailed warning message here. */
2587 if (save_c)
437e2ff1 2588 *(asargStart - 1) = save_c;
b800637e 2589 as_warn (_("read-only CSR is written `%s'"), str);
5b7c81bd 2590 insn_with_csr = false;
54b2aec1 2591 }
65e4a99a
NC
2592
2593 /* The (segmant) load and store with EEW 64 cannot be used
2594 when zve32x is enabled. */
2595 if (ip->insn_mo->pinfo & INSN_V_EEW64
2596 && riscv_subset_supports (&riscv_rps_as, "zve32x")
2597 && !riscv_subset_supports (&riscv_rps_as, "zve64x"))
2598 {
e4028336 2599 error.msg = _("illegal opcode for zve32x");
65e4a99a
NC
2600 break;
2601 }
e23eba97 2602 }
437e2ff1 2603 if (*asarg != '\0')
e23eba97 2604 break;
7a29ee29 2605
e23eba97 2606 /* Successful assembly. */
e4028336 2607 error.msg = NULL;
5b7c81bd 2608 insn_with_csr = false;
7a29ee29
JB
2609
2610 /* Commit deferred symbols, if any. */
2611 while (deferred_sym_rootP)
2612 {
2613 symbolS *sym = deferred_sym_rootP;
2614
2615 symbol_remove (sym, &deferred_sym_rootP,
2616 &deferred_sym_lastP);
2617 symbol_append (sym, symbol_lastP, &symbol_rootP,
2618 &symbol_lastP);
2619 symbol_table_insert (sym);
2620 }
e23eba97
NC
2621 goto out;
2622
2623 case 'C': /* RVC */
437e2ff1 2624 switch (*++oparg)
e23eba97 2625 {
dcd709e0 2626 case 's': /* RS1 x8-x15. */
437e2ff1 2627 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2628 || !(regno >= 8 && regno <= 15))
2629 break;
2630 INSERT_OPERAND (CRS1S, *ip, regno % 8);
2631 continue;
2632 case 'w': /* RS1 x8-x15, constrained to equal RD x8-x15. */
437e2ff1 2633 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2634 || EXTRACT_OPERAND (CRS1S, ip->insn_opcode) + 8 != regno)
2635 break;
2636 continue;
dcd709e0 2637 case 't': /* RS2 x8-x15. */
437e2ff1 2638 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2639 || !(regno >= 8 && regno <= 15))
2640 break;
2641 INSERT_OPERAND (CRS2S, *ip, regno % 8);
2642 continue;
2643 case 'x': /* RS2 x8-x15, constrained to equal RD x8-x15. */
437e2ff1 2644 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2645 || EXTRACT_OPERAND (CRS2S, ip->insn_opcode) + 8 != regno)
2646 break;
2647 continue;
2648 case 'U': /* RS1, constrained to equal RD. */
437e2ff1 2649 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2650 || EXTRACT_OPERAND (RD, ip->insn_opcode) != regno)
2651 break;
2652 continue;
2653 case 'V': /* RS2 */
437e2ff1 2654 if (!reg_lookup (&asarg, RCLASS_GPR, &regno))
e23eba97
NC
2655 break;
2656 INSERT_OPERAND (CRS2, *ip, regno);
2657 continue;
2658 case 'c': /* RS1, constrained to equal sp. */
437e2ff1 2659 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
e23eba97
NC
2660 || regno != X_SP)
2661 break;
2662 continue;
dcd709e0 2663 case 'z': /* RS2, constrained to equal x0. */
437e2ff1 2664 if (!reg_lookup (&asarg, RCLASS_GPR, &regno)
ca0bc150
JW
2665 || regno != 0)
2666 break;
2667 continue;
768589d1 2668 case '>': /* Shift amount, 0 - (XLEN-1). */
437e2ff1 2669 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2670 || imm_expr->X_op != O_constant
768589d1 2671 || (unsigned long) imm_expr->X_add_number >= xlen)
e23eba97 2672 break;
5a9f5403 2673 ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
dc1e8a47 2674 rvc_imm_done:
6eb099ae 2675 asarg = expr_parse_end;
e23eba97
NC
2676 imm_expr->X_op = O_absent;
2677 continue;
5a9f5403 2678 case '5':
437e2ff1 2679 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2680 || imm_expr->X_op != O_constant
5a9f5403 2681 || imm_expr->X_add_number < 0
169ec512 2682 || imm_expr->X_add_number >= 32
5a9f5403 2683 || !VALID_CLTYPE_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2684 break;
0257c2ff 2685 ip->insn_opcode |= ENCODE_CLTYPE_IMM (imm_expr->X_add_number);
e23eba97 2686 goto rvc_imm_done;
5a9f5403 2687 case '6':
437e2ff1 2688 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d 2689 || imm_expr->X_op != O_constant
0e35537d 2690 || imm_expr->X_add_number < 0
5a9f5403
NC
2691 || imm_expr->X_add_number >= 64
2692 || !VALID_CSSTYPE_IMM ((valueT) imm_expr->X_add_number))
0e35537d 2693 break;
0257c2ff 2694 ip->insn_opcode |= ENCODE_CSSTYPE_IMM (imm_expr->X_add_number);
0e35537d 2695 goto rvc_imm_done;
5a9f5403 2696 case '8':
437e2ff1 2697 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2698 || imm_expr->X_op != O_constant
5a9f5403
NC
2699 || imm_expr->X_add_number < 0
2700 || imm_expr->X_add_number >= 256
2701 || !VALID_CIWTYPE_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2702 break;
0257c2ff 2703 ip->insn_opcode |= ENCODE_CIWTYPE_IMM (imm_expr->X_add_number);
e23eba97
NC
2704 goto rvc_imm_done;
2705 case 'j':
437e2ff1 2706 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97
NC
2707 || imm_expr->X_op != O_constant
2708 || imm_expr->X_add_number == 0
5a9f5403 2709 || !VALID_CITYPE_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2710 break;
5a9f5403 2711 ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
e23eba97
NC
2712 goto rvc_imm_done;
2713 case 'k':
437e2ff1 2714 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2715 continue;
437e2ff1 2716 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2717 || imm_expr->X_op != O_constant
5a9f5403 2718 || !VALID_CLTYPE_LW_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2719 break;
5a9f5403 2720 ip->insn_opcode |= ENCODE_CLTYPE_LW_IMM (imm_expr->X_add_number);
e23eba97
NC
2721 goto rvc_imm_done;
2722 case 'l':
437e2ff1 2723 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2724 continue;
437e2ff1 2725 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2726 || imm_expr->X_op != O_constant
5a9f5403 2727 || !VALID_CLTYPE_LD_IMM ((valueT) imm_expr->X_add_number))
e23eba97 2728 break;
5a9f5403 2729 ip->insn_opcode |= ENCODE_CLTYPE_LD_IMM (imm_expr->X_add_number);
e23eba97
NC
2730 goto rvc_imm_done;
2731 case 'm':
437e2ff1 2732 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2733 continue;
437e2ff1 2734 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2735 || imm_expr->X_op != O_constant
5a9f5403 2736 || !VALID_CITYPE_LWSP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2737 break;
2738 ip->insn_opcode |=
5a9f5403 2739 ENCODE_CITYPE_LWSP_IMM (imm_expr->X_add_number);
e23eba97
NC
2740 goto rvc_imm_done;
2741 case 'n':
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_CITYPE_LDSP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2747 break;
2748 ip->insn_opcode |=
5a9f5403 2749 ENCODE_CITYPE_LDSP_IMM (imm_expr->X_add_number);
e23eba97 2750 goto rvc_imm_done;
b416fe87 2751 case 'o':
437e2ff1 2752 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
b416fe87 2753 || imm_expr->X_op != O_constant
21a186f2
JW
2754 /* C.addiw, c.li, and c.andi allow zero immediate.
2755 C.addi allows zero immediate as hint. Otherwise this
2756 is same as 'j'. */
5a9f5403 2757 || !VALID_CITYPE_IMM ((valueT) imm_expr->X_add_number))
b416fe87 2758 break;
5a9f5403 2759 ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
b416fe87 2760 goto rvc_imm_done;
e23eba97 2761 case 'K':
437e2ff1 2762 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2763 || imm_expr->X_op != O_constant
169ec512 2764 || imm_expr->X_add_number == 0
5a9f5403 2765 || !VALID_CIWTYPE_ADDI4SPN_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2766 break;
2767 ip->insn_opcode |=
5a9f5403 2768 ENCODE_CIWTYPE_ADDI4SPN_IMM (imm_expr->X_add_number);
e23eba97
NC
2769 goto rvc_imm_done;
2770 case 'L':
437e2ff1 2771 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2772 || imm_expr->X_op != O_constant
5a9f5403 2773 || !VALID_CITYPE_ADDI16SP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2774 break;
2775 ip->insn_opcode |=
5a9f5403 2776 ENCODE_CITYPE_ADDI16SP_IMM (imm_expr->X_add_number);
e23eba97
NC
2777 goto rvc_imm_done;
2778 case 'M':
437e2ff1 2779 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2780 continue;
437e2ff1 2781 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2782 || imm_expr->X_op != O_constant
5a9f5403 2783 || !VALID_CSSTYPE_SWSP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2784 break;
2785 ip->insn_opcode |=
5a9f5403 2786 ENCODE_CSSTYPE_SWSP_IMM (imm_expr->X_add_number);
e23eba97
NC
2787 goto rvc_imm_done;
2788 case 'N':
437e2ff1 2789 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
f0531ed6 2790 continue;
437e2ff1 2791 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97 2792 || imm_expr->X_op != O_constant
5a9f5403 2793 || !VALID_CSSTYPE_SDSP_IMM ((valueT) imm_expr->X_add_number))
e23eba97
NC
2794 break;
2795 ip->insn_opcode |=
5a9f5403 2796 ENCODE_CSSTYPE_SDSP_IMM (imm_expr->X_add_number);
e23eba97
NC
2797 goto rvc_imm_done;
2798 case 'u':
2799 p = percent_op_utype;
437e2ff1 2800 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p))
e23eba97 2801 break;
dc1e8a47 2802 rvc_lui:
e23eba97
NC
2803 if (imm_expr->X_op != O_constant
2804 || imm_expr->X_add_number <= 0
2805 || imm_expr->X_add_number >= RISCV_BIGIMM_REACH
2806 || (imm_expr->X_add_number >= RISCV_RVC_IMM_REACH / 2
2807 && (imm_expr->X_add_number <
2808 RISCV_BIGIMM_REACH - RISCV_RVC_IMM_REACH / 2)))
2809 break;
5a9f5403 2810 ip->insn_opcode |= ENCODE_CITYPE_IMM (imm_expr->X_add_number);
e23eba97
NC
2811 goto rvc_imm_done;
2812 case 'v':
437e2ff1 2813 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e23eba97
NC
2814 || (imm_expr->X_add_number & (RISCV_IMM_REACH - 1))
2815 || ((int32_t)imm_expr->X_add_number
2816 != imm_expr->X_add_number))
2817 break;
2818 imm_expr->X_add_number =
2819 ((uint32_t) imm_expr->X_add_number) >> RISCV_IMM_BITS;
2820 goto rvc_lui;
2821 case 'p':
2822 goto branch;
2823 case 'a':
2824 goto jump;
0e35537d 2825 case 'S': /* Floating-point RS1 x8-x15. */
437e2ff1 2826 if (!reg_lookup (&asarg, RCLASS_FPR, &regno)
0e35537d
JW
2827 || !(regno >= 8 && regno <= 15))
2828 break;
2829 INSERT_OPERAND (CRS1S, *ip, regno % 8);
2830 continue;
e23eba97 2831 case 'D': /* Floating-point RS2 x8-x15. */
437e2ff1 2832 if (!reg_lookup (&asarg, RCLASS_FPR, &regno)
e23eba97
NC
2833 || !(regno >= 8 && regno <= 15))
2834 break;
2835 INSERT_OPERAND (CRS2S, *ip, regno % 8);
2836 continue;
2837 case 'T': /* Floating-point RS2. */
437e2ff1 2838 if (!reg_lookup (&asarg, RCLASS_FPR, &regno))
e23eba97
NC
2839 break;
2840 INSERT_OPERAND (CRS2, *ip, regno);
2841 continue;
0e35537d 2842 case 'F':
437e2ff1 2843 switch (*++oparg)
0e35537d 2844 {
4765cd61 2845 case '6':
437e2ff1 2846 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
4765cd61
JW
2847 || imm_expr->X_op != O_constant
2848 || imm_expr->X_add_number < 0
2849 || imm_expr->X_add_number >= 64)
2850 {
b800637e 2851 as_bad (_("bad value for compressed funct6 "
b215cdf5 2852 "field, value must be 0...63"));
4765cd61
JW
2853 break;
2854 }
4765cd61
JW
2855 INSERT_OPERAND (CFUNCT6, *ip, imm_expr->X_add_number);
2856 imm_expr->X_op = O_absent;
6eb099ae 2857 asarg = expr_parse_end;
4765cd61 2858 continue;
1942a048 2859
0e35537d 2860 case '4':
437e2ff1 2861 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
2862 || imm_expr->X_op != O_constant
2863 || imm_expr->X_add_number < 0
2864 || imm_expr->X_add_number >= 16)
2865 {
b800637e
NC
2866 as_bad (_("bad value for compressed funct4 "
2867 "field, value must be 0...15"));
0e35537d
JW
2868 break;
2869 }
0e35537d
JW
2870 INSERT_OPERAND (CFUNCT4, *ip, imm_expr->X_add_number);
2871 imm_expr->X_op = O_absent;
6eb099ae 2872 asarg = expr_parse_end;
0e35537d 2873 continue;
1942a048 2874
0e35537d 2875 case '3':
437e2ff1 2876 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
2877 || imm_expr->X_op != O_constant
2878 || imm_expr->X_add_number < 0
2879 || imm_expr->X_add_number >= 8)
2880 {
b800637e
NC
2881 as_bad (_("bad value for compressed funct3 "
2882 "field, value must be 0...7"));
0e35537d
JW
2883 break;
2884 }
2885 INSERT_OPERAND (CFUNCT3, *ip, imm_expr->X_add_number);
2886 imm_expr->X_op = O_absent;
6eb099ae 2887 asarg = expr_parse_end;
0e35537d 2888 continue;
1942a048 2889
4765cd61 2890 case '2':
437e2ff1 2891 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
4765cd61
JW
2892 || imm_expr->X_op != O_constant
2893 || imm_expr->X_add_number < 0
2894 || imm_expr->X_add_number >= 4)
2895 {
b800637e
NC
2896 as_bad (_("bad value for compressed funct2 "
2897 "field, value must be 0...3"));
4765cd61
JW
2898 break;
2899 }
2900 INSERT_OPERAND (CFUNCT2, *ip, imm_expr->X_add_number);
2901 imm_expr->X_op = O_absent;
6eb099ae 2902 asarg = expr_parse_end;
4765cd61 2903 continue;
1942a048 2904
0e35537d 2905 default:
437e2ff1 2906 goto unknown_riscv_ip_operand;
0e35537d
JW
2907 }
2908 break;
2909
e23eba97 2910 default:
437e2ff1 2911 goto unknown_riscv_ip_operand;
e23eba97 2912 }
a63375ac 2913 break; /* end RVC */
e23eba97 2914
65e4a99a
NC
2915 case 'V': /* RVV */
2916 switch (*++oparg)
2917 {
2918 case 'd': /* VD */
2919 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2920 break;
2921 INSERT_OPERAND (VD, *ip, regno);
2922 continue;
2923
2924 case 'e': /* AMO VD */
2925 if (reg_lookup (&asarg, RCLASS_GPR, &regno) && regno == 0)
2926 INSERT_OPERAND (VWD, *ip, 0);
2927 else if (reg_lookup (&asarg, RCLASS_VECR, &regno))
2928 {
2929 INSERT_OPERAND (VWD, *ip, 1);
2930 INSERT_OPERAND (VD, *ip, regno);
2931 }
2932 else
2933 break;
2934 continue;
2935
2936 case 'f': /* AMO VS3 */
2937 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2938 break;
2939 if (!EXTRACT_OPERAND (VWD, ip->insn_opcode))
2940 INSERT_OPERAND (VD, *ip, regno);
2941 else
2942 {
2943 /* VS3 must match VD. */
2944 if (EXTRACT_OPERAND (VD, ip->insn_opcode) != regno)
2945 break;
2946 }
2947 continue;
2948
2949 case 's': /* VS1 */
2950 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2951 break;
2952 INSERT_OPERAND (VS1, *ip, regno);
2953 continue;
2954
2955 case 't': /* VS2 */
2956 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2957 break;
2958 INSERT_OPERAND (VS2, *ip, regno);
2959 continue;
2960
2961 case 'u': /* VS1 == VS2 */
2962 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2963 break;
2964 INSERT_OPERAND (VS1, *ip, regno);
2965 INSERT_OPERAND (VS2, *ip, regno);
2966 continue;
2967
2968 case 'v': /* VD == VS1 == VS2 */
2969 if (!reg_lookup (&asarg, RCLASS_VECR, &regno))
2970 break;
2971 INSERT_OPERAND (VD, *ip, regno);
2972 INSERT_OPERAND (VS1, *ip, regno);
2973 INSERT_OPERAND (VS2, *ip, regno);
2974 continue;
2975
2976 /* The `V0` is carry-in register for v[m]adc and v[m]sbc,
2977 and is used to choose vs1/rs1/frs1/imm or vs2 for
2978 v[f]merge. It use the same encoding as the vector mask
2979 register. */
2980 case '0':
2981 if (reg_lookup (&asarg, RCLASS_VECR, &regno) && regno == 0)
2982 continue;
2983 break;
2984
2985 case 'b': /* vtypei for vsetivli */
2986 my_getVsetvliExpression (imm_expr, asarg);
2987 check_absolute_expr (ip, imm_expr, FALSE);
2988 if (!VALID_RVV_VB_IMM (imm_expr->X_add_number))
2989 as_bad (_("bad value for vsetivli immediate field, "
2990 "value must be 0..1023"));
2991 ip->insn_opcode
2992 |= ENCODE_RVV_VB_IMM (imm_expr->X_add_number);
2993 imm_expr->X_op = O_absent;
6eb099ae 2994 asarg = expr_parse_end;
65e4a99a
NC
2995 continue;
2996
2997 case 'c': /* vtypei for vsetvli */
2998 my_getVsetvliExpression (imm_expr, asarg);
2999 check_absolute_expr (ip, imm_expr, FALSE);
3000 if (!VALID_RVV_VC_IMM (imm_expr->X_add_number))
3001 as_bad (_("bad value for vsetvli immediate field, "
3002 "value must be 0..2047"));
3003 ip->insn_opcode
3004 |= ENCODE_RVV_VC_IMM (imm_expr->X_add_number);
3005 imm_expr->X_op = O_absent;
6eb099ae 3006 asarg = expr_parse_end;
65e4a99a
NC
3007 continue;
3008
3009 case 'i': /* vector arith signed immediate */
3010 my_getExpression (imm_expr, asarg);
3011 check_absolute_expr (ip, imm_expr, FALSE);
3012 if (imm_expr->X_add_number > 15
3013 || imm_expr->X_add_number < -16)
3014 as_bad (_("bad value for vector immediate field, "
3015 "value must be -16...15"));
3016 INSERT_OPERAND (VIMM, *ip, imm_expr->X_add_number);
3017 imm_expr->X_op = O_absent;
6eb099ae 3018 asarg = expr_parse_end;
65e4a99a
NC
3019 continue;
3020
3021 case 'j': /* vector arith unsigned immediate */
3022 my_getExpression (imm_expr, asarg);
3023 check_absolute_expr (ip, imm_expr, FALSE);
3024 if (imm_expr->X_add_number < 0
3025 || imm_expr->X_add_number >= 32)
3026 as_bad (_("bad value for vector immediate field, "
3027 "value must be 0...31"));
3028 INSERT_OPERAND (VIMM, *ip, imm_expr->X_add_number);
3029 imm_expr->X_op = O_absent;
6eb099ae 3030 asarg = expr_parse_end;
65e4a99a
NC
3031 continue;
3032
3033 case 'k': /* vector arith signed immediate, minus 1 */
3034 my_getExpression (imm_expr, asarg);
3035 check_absolute_expr (ip, imm_expr, FALSE);
3036 if (imm_expr->X_add_number > 16
3037 || imm_expr->X_add_number < -15)
3038 as_bad (_("bad value for vector immediate field, "
3039 "value must be -15...16"));
3040 INSERT_OPERAND (VIMM, *ip, imm_expr->X_add_number - 1);
3041 imm_expr->X_op = O_absent;
6eb099ae 3042 asarg = expr_parse_end;
65e4a99a
NC
3043 continue;
3044
3045 case 'm': /* optional vector mask */
3046 if (*asarg == '\0')
3047 {
3048 INSERT_OPERAND (VMASK, *ip, 1);
3049 continue;
3050 }
3051 else if (*asarg == ',' && asarg++
3052 && reg_lookup (&asarg, RCLASS_VECM, &regno)
3053 && regno == 0)
3054 {
3055 INSERT_OPERAND (VMASK, *ip, 0);
3056 continue;
3057 }
3058 break;
3059
3060 case 'M': /* required vector mask */
3061 if (reg_lookup (&asarg, RCLASS_VECM, &regno) && regno == 0)
3062 {
3063 INSERT_OPERAND (VMASK, *ip, 0);
3064 continue;
3065 }
3066 break;
3067
3068 case 'T': /* vector macro temporary register */
3069 if (!reg_lookup (&asarg, RCLASS_VECR, &regno) || regno == 0)
3070 break;
3071 /* Store it in the FUNCT6 field as we don't have anyplace
3072 else to store it. */
3073 INSERT_OPERAND (VFUNCT6, *ip, regno);
3074 continue;
3075
3076 default:
3077 goto unknown_riscv_ip_operand;
3078 }
a63375ac 3079 break; /* end RVV */
65e4a99a 3080
e23eba97 3081 case ',':
437e2ff1 3082 if (*asarg++ == *oparg)
e23eba97 3083 continue;
437e2ff1 3084 asarg--;
e23eba97
NC
3085 break;
3086
3087 case '(':
3088 case ')':
3089 case '[':
3090 case ']':
437e2ff1 3091 if (*asarg++ == *oparg)
e23eba97
NC
3092 continue;
3093 break;
3094
dcd709e0 3095 case '<': /* Shift amount, 0 - 31. */
437e2ff1 3096 my_getExpression (imm_expr, asarg);
5b7c81bd 3097 check_absolute_expr (ip, imm_expr, false);
e23eba97 3098 if ((unsigned long) imm_expr->X_add_number > 31)
a6eeb20a
CM
3099 as_bad (_("improper shift amount (%"PRIu64")"),
3100 imm_expr->X_add_number);
e23eba97
NC
3101 INSERT_OPERAND (SHAMTW, *ip, imm_expr->X_add_number);
3102 imm_expr->X_op = O_absent;
6eb099ae 3103 asarg = expr_parse_end;
e23eba97
NC
3104 continue;
3105
dcd709e0 3106 case '>': /* Shift amount, 0 - (XLEN-1). */
437e2ff1 3107 my_getExpression (imm_expr, asarg);
5b7c81bd 3108 check_absolute_expr (ip, imm_expr, false);
e23eba97 3109 if ((unsigned long) imm_expr->X_add_number >= xlen)
a6eeb20a
CM
3110 as_bad (_("improper shift amount (%"PRIu64")"),
3111 imm_expr->X_add_number);
e23eba97
NC
3112 INSERT_OPERAND (SHAMT, *ip, imm_expr->X_add_number);
3113 imm_expr->X_op = O_absent;
6eb099ae 3114 asarg = expr_parse_end;
e23eba97
NC
3115 continue;
3116
dcd709e0 3117 case 'Z': /* CSRRxI immediate. */
437e2ff1 3118 my_getExpression (imm_expr, asarg);
5b7c81bd 3119 check_absolute_expr (ip, imm_expr, false);
e23eba97 3120 if ((unsigned long) imm_expr->X_add_number > 31)
a6eeb20a
CM
3121 as_bad (_("improper CSRxI immediate (%"PRIu64")"),
3122 imm_expr->X_add_number);
e23eba97
NC
3123 INSERT_OPERAND (RS1, *ip, imm_expr->X_add_number);
3124 imm_expr->X_op = O_absent;
6eb099ae 3125 asarg = expr_parse_end;
e23eba97
NC
3126 continue;
3127
dcd709e0 3128 case 'E': /* Control register. */
5b7c81bd
AM
3129 insn_with_csr = true;
3130 explicit_priv_attr = true;
437e2ff1 3131 if (reg_lookup (&asarg, RCLASS_CSR, &regno))
e23eba97
NC
3132 INSERT_OPERAND (CSR, *ip, regno);
3133 else
3134 {
437e2ff1 3135 my_getExpression (imm_expr, asarg);
5b7c81bd 3136 check_absolute_expr (ip, imm_expr, true);
e23eba97 3137 if ((unsigned long) imm_expr->X_add_number > 0xfff)
a6eeb20a
CM
3138 as_bad (_("improper CSR address (%"PRIu64")"),
3139 imm_expr->X_add_number);
e23eba97
NC
3140 INSERT_OPERAND (CSR, *ip, imm_expr->X_add_number);
3141 imm_expr->X_op = O_absent;
6eb099ae 3142 asarg = expr_parse_end;
e23eba97
NC
3143 }
3144 continue;
3145
dcd709e0 3146 case 'm': /* Rounding mode. */
437e2ff1
NC
3147 if (arg_lookup (&asarg, riscv_rm,
3148 ARRAY_SIZE (riscv_rm), &regno))
e23eba97
NC
3149 {
3150 INSERT_OPERAND (RM, *ip, regno);
3151 continue;
3152 }
3153 break;
3154
3155 case 'P':
dcd709e0 3156 case 'Q': /* Fence predecessor/successor. */
437e2ff1
NC
3157 if (arg_lookup (&asarg, riscv_pred_succ,
3158 ARRAY_SIZE (riscv_pred_succ), &regno))
e23eba97 3159 {
437e2ff1 3160 if (*oparg == 'P')
e23eba97
NC
3161 INSERT_OPERAND (PRED, *ip, regno);
3162 else
3163 INSERT_OPERAND (SUCC, *ip, regno);
3164 continue;
3165 }
3166 break;
3167
dcd709e0
NC
3168 case 'd': /* Destination register. */
3169 case 's': /* Source register. */
3170 case 't': /* Target register. */
3171 case 'r': /* RS3 */
437e2ff1 3172 if (reg_lookup (&asarg, RCLASS_GPR, &regno))
e23eba97 3173 {
437e2ff1
NC
3174 char c = *oparg;
3175 if (*asarg == ' ')
3176 ++asarg;
e23eba97
NC
3177
3178 /* Now that we have assembled one operand, we use the args
3179 string to figure out where it goes in the instruction. */
3180 switch (c)
3181 {
3182 case 's':
3183 INSERT_OPERAND (RS1, *ip, regno);
3184 break;
3185 case 'd':
3186 INSERT_OPERAND (RD, *ip, regno);
3187 break;
3188 case 't':
3189 INSERT_OPERAND (RS2, *ip, regno);
3190 break;
0e35537d
JW
3191 case 'r':
3192 INSERT_OPERAND (RS3, *ip, regno);
3193 break;
e23eba97
NC
3194 }
3195 continue;
3196 }
3197 break;
3198
dcd709e0
NC
3199 case 'D': /* Floating point RD. */
3200 case 'S': /* Floating point RS1. */
3201 case 'T': /* Floating point RS2. */
3202 case 'U': /* Floating point RS1 and RS2. */
3203 case 'R': /* Floating point RS3. */
de83e514 3204 if (reg_lookup (&asarg,
3205 (riscv_subset_supports (&riscv_rps_as, "zfinx")
3206 ? RCLASS_GPR : RCLASS_FPR), &regno))
e23eba97 3207 {
437e2ff1
NC
3208 char c = *oparg;
3209 if (*asarg == ' ')
3210 ++asarg;
e23eba97
NC
3211 switch (c)
3212 {
3213 case 'D':
3214 INSERT_OPERAND (RD, *ip, regno);
3215 break;
3216 case 'S':
3217 INSERT_OPERAND (RS1, *ip, regno);
3218 break;
3219 case 'U':
3220 INSERT_OPERAND (RS1, *ip, regno);
dcd709e0 3221 /* Fall through. */
e23eba97
NC
3222 case 'T':
3223 INSERT_OPERAND (RS2, *ip, regno);
3224 break;
3225 case 'R':
3226 INSERT_OPERAND (RS3, *ip, regno);
3227 break;
3228 }
3229 continue;
3230 }
e23eba97
NC
3231 break;
3232
3233 case 'I':
437e2ff1 3234 my_getExpression (imm_expr, asarg);
e23eba97
NC
3235 if (imm_expr->X_op != O_big
3236 && imm_expr->X_op != O_constant)
3237 break;
3238 normalize_constant_expr (imm_expr);
6eb099ae 3239 asarg = expr_parse_end;
e23eba97
NC
3240 continue;
3241
3242 case 'A':
437e2ff1 3243 my_getExpression (imm_expr, asarg);
e23eba97
NC
3244 normalize_constant_expr (imm_expr);
3245 /* The 'A' format specifier must be a symbol. */
3246 if (imm_expr->X_op != O_symbol)
3247 break;
3248 *imm_reloc = BFD_RELOC_32;
6eb099ae 3249 asarg = expr_parse_end;
e23eba97
NC
3250 continue;
3251
160d1b3d 3252 case 'B':
437e2ff1 3253 my_getExpression (imm_expr, asarg);
160d1b3d
SH
3254 normalize_constant_expr (imm_expr);
3255 /* The 'B' format specifier must be a symbol or a constant. */
3256 if (imm_expr->X_op != O_symbol && imm_expr->X_op != O_constant)
3257 break;
3258 if (imm_expr->X_op == O_symbol)
3259 *imm_reloc = BFD_RELOC_32;
6eb099ae 3260 asarg = expr_parse_end;
160d1b3d
SH
3261 continue;
3262
e23eba97 3263 case 'j': /* Sign-extended immediate. */
e23eba97 3264 p = percent_op_itype;
f50fabe4 3265 *imm_reloc = BFD_RELOC_RISCV_LO12_I;
e23eba97
NC
3266 goto alu_op;
3267 case 'q': /* Store displacement. */
3268 p = percent_op_stype;
3269 *imm_reloc = BFD_RELOC_RISCV_LO12_S;
3270 goto load_store;
3271 case 'o': /* Load displacement. */
3272 p = percent_op_itype;
3273 *imm_reloc = BFD_RELOC_RISCV_LO12_I;
3274 goto load_store;
dcd709e0
NC
3275 case '1':
3276 /* This is used for TLS, where the fourth operand is
3277 %tprel_add, to get a relocation applied to an add
3278 instruction, for relaxation to use. */
e23eba97 3279 p = percent_op_rtype;
f50fabe4 3280 goto alu_op;
dcd709e0 3281 case '0': /* AMO displacement, which must be zero. */
dc1e8a47 3282 load_store:
437e2ff1 3283 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
e23eba97 3284 continue;
dc1e8a47 3285 alu_op:
e23eba97
NC
3286 /* If this value won't fit into a 16 bit offset, then go
3287 find a macro that will generate the 32 bit offset
3288 code pattern. */
437e2ff1 3289 if (!my_getSmallExpression (imm_expr, imm_reloc, asarg, p))
e23eba97
NC
3290 {
3291 normalize_constant_expr (imm_expr);
3292 if (imm_expr->X_op != O_constant
437e2ff1
NC
3293 || (*oparg == '0' && imm_expr->X_add_number != 0)
3294 || (*oparg == '1')
e23eba97
NC
3295 || imm_expr->X_add_number >= (signed)RISCV_IMM_REACH/2
3296 || imm_expr->X_add_number < -(signed)RISCV_IMM_REACH/2)
3297 break;
3298 }
6eb099ae 3299 asarg = expr_parse_end;
e23eba97
NC
3300 continue;
3301
dcd709e0 3302 case 'p': /* PC-relative offset. */
dc1e8a47 3303 branch:
e23eba97 3304 *imm_reloc = BFD_RELOC_12_PCREL;
437e2ff1 3305 my_getExpression (imm_expr, asarg);
6eb099ae 3306 asarg = expr_parse_end;
e23eba97
NC
3307 continue;
3308
dcd709e0 3309 case 'u': /* Upper 20 bits. */
e23eba97 3310 p = percent_op_utype;
437e2ff1 3311 if (!my_getSmallExpression (imm_expr, imm_reloc, asarg, p))
e23eba97 3312 {
4288405d
JW
3313 if (imm_expr->X_op != O_constant)
3314 break;
3315
e23eba97
NC
3316 if (imm_expr->X_add_number < 0
3317 || imm_expr->X_add_number >= (signed)RISCV_BIGIMM_REACH)
3318 as_bad (_("lui expression not in range 0..1048575"));
3319
3320 *imm_reloc = BFD_RELOC_RISCV_HI20;
3321 imm_expr->X_add_number <<= RISCV_IMM_BITS;
3322 }
6eb099ae 3323 asarg = expr_parse_end;
e23eba97
NC
3324 continue;
3325
dcd709e0 3326 case 'a': /* 20-bit PC-relative offset. */
dc1e8a47 3327 jump:
437e2ff1 3328 my_getExpression (imm_expr, asarg);
6eb099ae 3329 asarg = expr_parse_end;
e23eba97
NC
3330 *imm_reloc = BFD_RELOC_RISCV_JMP;
3331 continue;
3332
3333 case 'c':
437e2ff1 3334 my_getExpression (imm_expr, asarg);
6eb099ae 3335 asarg = expr_parse_end;
437e2ff1 3336 if (strcmp (asarg, "@plt") == 0)
70f35d72
NC
3337 asarg += 4;
3338 *imm_reloc = BFD_RELOC_RISCV_CALL_PLT;
e23eba97 3339 continue;
1942a048 3340
0e35537d 3341 case 'O':
437e2ff1 3342 switch (*++oparg)
0e35537d
JW
3343 {
3344 case '4':
408ab016 3345 if (my_getOpcodeExpression (imm_expr, imm_reloc, asarg)
0e35537d
JW
3346 || imm_expr->X_op != O_constant
3347 || imm_expr->X_add_number < 0
3348 || imm_expr->X_add_number >= 128
3349 || (imm_expr->X_add_number & 0x3) != 3)
3350 {
3351 as_bad (_("bad value for opcode field, "
3352 "value must be 0...127 and "
3353 "lower 2 bits must be 0x3"));
3354 break;
3355 }
0e35537d
JW
3356 INSERT_OPERAND (OP, *ip, imm_expr->X_add_number);
3357 imm_expr->X_op = O_absent;
6eb099ae 3358 asarg = expr_parse_end;
0e35537d 3359 continue;
1942a048 3360
0e35537d 3361 case '2':
408ab016 3362 if (my_getOpcodeExpression (imm_expr, imm_reloc, asarg)
0e35537d
JW
3363 || imm_expr->X_op != O_constant
3364 || imm_expr->X_add_number < 0
3365 || imm_expr->X_add_number >= 3)
3366 {
3367 as_bad (_("bad value for opcode field, "
3368 "value must be 0...2"));
3369 break;
3370 }
0e35537d
JW
3371 INSERT_OPERAND (OP2, *ip, imm_expr->X_add_number);
3372 imm_expr->X_op = O_absent;
6eb099ae 3373 asarg = expr_parse_end;
0e35537d 3374 continue;
1942a048 3375
0e35537d 3376 default:
437e2ff1 3377 goto unknown_riscv_ip_operand;
0e35537d
JW
3378 }
3379 break;
3380
3381 case 'F':
437e2ff1 3382 switch (*++oparg)
0e35537d
JW
3383 {
3384 case '7':
437e2ff1 3385 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
3386 || imm_expr->X_op != O_constant
3387 || imm_expr->X_add_number < 0
3388 || imm_expr->X_add_number >= 128)
3389 {
3390 as_bad (_("bad value for funct7 field, "
3391 "value must be 0...127"));
3392 break;
3393 }
0e35537d
JW
3394 INSERT_OPERAND (FUNCT7, *ip, imm_expr->X_add_number);
3395 imm_expr->X_op = O_absent;
6eb099ae 3396 asarg = expr_parse_end;
0e35537d 3397 continue;
1942a048 3398
0e35537d 3399 case '3':
437e2ff1 3400 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
3401 || imm_expr->X_op != O_constant
3402 || imm_expr->X_add_number < 0
3403 || imm_expr->X_add_number >= 8)
3404 {
3405 as_bad (_("bad value for funct3 field, "
3406 "value must be 0...7"));
3407 break;
3408 }
0e35537d
JW
3409 INSERT_OPERAND (FUNCT3, *ip, imm_expr->X_add_number);
3410 imm_expr->X_op = O_absent;
6eb099ae 3411 asarg = expr_parse_end;
0e35537d 3412 continue;
1942a048 3413
0e35537d 3414 case '2':
437e2ff1 3415 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
0e35537d
JW
3416 || imm_expr->X_op != O_constant
3417 || imm_expr->X_add_number < 0
3418 || imm_expr->X_add_number >= 4)
3419 {
3420 as_bad (_("bad value for funct2 field, "
3421 "value must be 0...3"));
3422 break;
3423 }
0e35537d
JW
3424 INSERT_OPERAND (FUNCT2, *ip, imm_expr->X_add_number);
3425 imm_expr->X_op = O_absent;
6eb099ae 3426 asarg = expr_parse_end;
0e35537d
JW
3427 continue;
3428
3429 default:
437e2ff1 3430 goto unknown_riscv_ip_operand;
0e35537d
JW
3431 }
3432 break;
e23eba97 3433
3d1cafa0 3434 case 'y': /* bs immediate */
3435 my_getExpression (imm_expr, asarg);
3436 check_absolute_expr (ip, imm_expr, FALSE);
3437 if ((unsigned long)imm_expr->X_add_number > 3)
3438 as_bad(_("Improper bs immediate (%lu)"),
3439 (unsigned long)imm_expr->X_add_number);
3440 INSERT_OPERAND(BS, *ip, imm_expr->X_add_number);
3441 imm_expr->X_op = O_absent;
6eb099ae 3442 asarg = expr_parse_end;
3d1cafa0 3443 continue;
3444
3445 case 'Y': /* rnum immediate */
3446 my_getExpression (imm_expr, asarg);
3447 check_absolute_expr (ip, imm_expr, FALSE);
3448 if ((unsigned long)imm_expr->X_add_number > 10)
3449 as_bad(_("Improper rnum immediate (%lu)"),
3450 (unsigned long)imm_expr->X_add_number);
3451 INSERT_OPERAND(RNUM, *ip, imm_expr->X_add_number);
3452 imm_expr->X_op = O_absent;
6eb099ae 3453 asarg = expr_parse_end;
3d1cafa0 3454 continue;
3455
e925c834 3456 case 'z':
437e2ff1 3457 if (my_getSmallExpression (imm_expr, imm_reloc, asarg, p)
e925c834
JW
3458 || imm_expr->X_op != O_constant
3459 || imm_expr->X_add_number != 0)
3460 break;
6eb099ae 3461 asarg = expr_parse_end;
e925c834
JW
3462 imm_expr->X_op = O_absent;
3463 continue;
3464
54bca63b
TO
3465 case 'W': /* Various operands. */
3466 switch (*++oparg)
3467 {
3468 case 'i':
3469 switch (*++oparg)
3470 {
3471 case 'f':
3472 /* Prefetch offset for 'Zicbop' extension.
3473 pseudo S-type but lower 5-bits zero. */
3474 if (riscv_handle_implicit_zero_offset (imm_expr, asarg))
3475 continue;
3476 my_getExpression (imm_expr, asarg);
3477 check_absolute_expr (ip, imm_expr, false);
3478 if (((unsigned) (imm_expr->X_add_number) & 0x1fU)
3479 || imm_expr->X_add_number >= RISCV_IMM_REACH / 2
3480 || imm_expr->X_add_number < -RISCV_IMM_REACH / 2)
3481 as_bad (_ ("improper prefetch offset (%ld)"),
3482 (long) imm_expr->X_add_number);
3483 ip->insn_opcode |= ENCODE_STYPE_IMM (
3484 (unsigned) (imm_expr->X_add_number) & ~0x1fU);
3485 imm_expr->X_op = O_absent;
3486 asarg = expr_parse_end;
3487 continue;
3488 default:
3489 goto unknown_riscv_ip_operand;
3490 }
3491 break;
3492 default:
3493 goto unknown_riscv_ip_operand;
3494 }
3495 break;
3b374308 3496
8b7419c4
CM
3497 case 'X': /* Integer immediate. */
3498 {
3499 size_t n;
3500 size_t s;
3501 bool sign;
3502
3503 switch (*++oparg)
3504 {
25236d63
CM
3505 case 'l': /* Literal. */
3506 n = strcspn (++oparg, ",");
3507 if (strncmp (oparg, asarg, n))
3508 as_bad (_("unexpected literal (%s)"), asarg);
3509 oparg += n - 1;
3510 asarg += n;
3511 continue;
8b7419c4
CM
3512 case 's': /* 'XsN@S' ... N-bit signed immediate at bit S. */
3513 sign = true;
3514 goto parse_imm;
3515 case 'u': /* 'XuN@S' ... N-bit unsigned immediate at bit S. */
3516 sign = false;
3517 goto parse_imm;
3518 parse_imm:
b0423163 3519 n = strtol (oparg + 1, (char **)&oparg, 10);
8b7419c4
CM
3520 if (*oparg != '@')
3521 goto unknown_riscv_ip_operand;
b0423163 3522 s = strtol (oparg + 1, (char **)&oparg, 10);
8b7419c4
CM
3523 oparg--;
3524
3525 my_getExpression (imm_expr, asarg);
3526 check_absolute_expr (ip, imm_expr, false);
3527 if (!sign)
3528 {
3529 if (!VALIDATE_U_IMM (imm_expr->X_add_number, n))
021205d0
JB
3530 as_bad (_("improper immediate value (%"PRIu64")"),
3531 imm_expr->X_add_number);
8b7419c4
CM
3532 }
3533 else
3534 {
3535 if (!VALIDATE_S_IMM (imm_expr->X_add_number, n))
021205d0
JB
3536 as_bad (_("improper immediate value (%"PRIi64")"),
3537 imm_expr->X_add_number);
8b7419c4
CM
3538 }
3539 INSERT_IMM (n, s, *ip, imm_expr->X_add_number);
3540 imm_expr->X_op = O_absent;
6eb099ae 3541 asarg = expr_parse_end;
8b7419c4
CM
3542 continue;
3543 default:
3544 goto unknown_riscv_ip_operand;
3545 }
3546 }
3547 break;
54bca63b 3548
e23eba97 3549 default:
437e2ff1
NC
3550 unknown_riscv_ip_operand:
3551 as_fatal (_("internal: unknown argument type `%s'"),
3552 opargStart);
e23eba97
NC
3553 }
3554 break;
3555 }
437e2ff1 3556 asarg = asargStart;
5b7c81bd 3557 insn_with_csr = false;
e23eba97
NC
3558 }
3559
dc1e8a47 3560 out:
e23eba97
NC
3561 /* Restore the character we might have clobbered above. */
3562 if (save_c)
437e2ff1 3563 *(asargStart - 1) = save_c;
e23eba97 3564
7a29ee29
JB
3565 probing_insn_operands = false;
3566
e23eba97
NC
3567 return error;
3568}
3569
a262b82f
NC
3570/* Similar to riscv_ip, but assembles an instruction according to the
3571 hardcode values of .insn directive. */
3572
3573static const char *
3574riscv_ip_hardcode (char *str,
3575 struct riscv_cl_insn *ip,
3576 expressionS *imm_expr,
3577 const char *error)
3578{
3579 struct riscv_opcode *insn;
3580 insn_t values[2] = {0, 0};
3581 unsigned int num = 0;
3582
3583 input_line_pointer = str;
3584 do
3585 {
3586 expression (imm_expr);
bb996692 3587 switch (imm_expr->X_op)
a262b82f 3588 {
bb996692
JB
3589 case O_constant:
3590 values[num++] = (insn_t) imm_expr->X_add_number;
3591 break;
3592 case O_big:
634001bb
TO
3593 /* Extract lower 32-bits of a big number.
3594 Assume that generic_bignum_to_int32 work on such number. */
3595 values[num++] = (insn_t) generic_bignum_to_int32 ();
bb996692
JB
3596 break;
3597 default:
a262b82f
NC
3598 /* The first value isn't constant, so it should be
3599 .insn <type> <operands>. We have been parsed it
3600 in the riscv_ip. */
3601 if (num == 0)
3602 return error;
3603 return _("values must be constant");
3604 }
a262b82f 3605 }
bb996692 3606 while (*input_line_pointer++ == ',' && num < 2 && imm_expr->X_op != O_big);
a262b82f
NC
3607
3608 input_line_pointer--;
3609 if (*input_line_pointer != '\0')
3610 return _("unrecognized values");
3611
3612 insn = XNEW (struct riscv_opcode);
3613 insn->match = values[num - 1];
3614 create_insn (ip, insn);
3615 unsigned int bytes = riscv_insn_length (insn->match);
bb996692
JB
3616
3617 if (num == 2 && values[0] != bytes)
3618 return _("value conflicts with instruction length");
3619
3620 if (imm_expr->X_op == O_big)
3621 {
634001bb
TO
3622 unsigned int llen = 0;
3623 for (LITTLENUM_TYPE lval = generic_bignum[imm_expr->X_add_number - 1];
3624 lval != 0; llen++)
3625 lval >>= BITS_PER_CHAR;
3626 unsigned int repr_bytes
3627 = (imm_expr->X_add_number - 1) * CHARS_PER_LITTLENUM + llen;
3628 if (bytes < repr_bytes)
bb996692 3629 return _("value conflicts with instruction length");
634001bb
TO
3630 for (num = 0; num < imm_expr->X_add_number - 1; ++num)
3631 number_to_chars_littleendian (
3632 ip->insn_long_opcode + num * CHARS_PER_LITTLENUM,
3633 generic_bignum[num],
3634 CHARS_PER_LITTLENUM);
3635 if (llen != 0)
3636 number_to_chars_littleendian (
3637 ip->insn_long_opcode + num * CHARS_PER_LITTLENUM,
3638 generic_bignum[num],
3639 llen);
3640 memset(ip->insn_long_opcode + repr_bytes, 0, bytes - repr_bytes);
bb996692
JB
3641 return NULL;
3642 }
3643
3644 if (bytes < sizeof(values[0]) && values[num - 1] >> (8 * bytes) != 0)
a262b82f
NC
3645 return _("value conflicts with instruction length");
3646
3647 return NULL;
3648}
3649
e23eba97
NC
3650void
3651md_assemble (char *str)
3652{
3653 struct riscv_cl_insn insn;
3654 expressionS imm_expr;
3655 bfd_reloc_code_real_type imm_reloc = BFD_RELOC_UNUSED;
3656
dcd709e0
NC
3657 /* The architecture and privileged elf attributes should be set
3658 before assembling. */
8f595e9b
NC
3659 if (!start_assemble)
3660 {
5b7c81bd 3661 start_assemble = true;
e23eba97 3662
dcd709e0 3663 riscv_set_abi_by_arch ();
8f595e9b
NC
3664 if (!riscv_set_default_priv_spec (NULL))
3665 return;
3666 }
3667
3190ebcb 3668 riscv_mapping_state (MAP_INSN, 0, false/* fr_align_code */);
9b9b1092 3669
e4028336
PN
3670 const struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
3671 &imm_reloc, op_hash);
2dc8dd17 3672
e4028336 3673 if (error.msg)
e23eba97 3674 {
e4028336
PN
3675 if (error.missing_ext)
3676 as_bad ("%s `%s', extension `%s' required", error.msg,
3677 error.statement, error.missing_ext);
3678 else
3679 as_bad ("%s `%s'", error.msg, error.statement);
e23eba97
NC
3680 return;
3681 }
3682
3683 if (insn.insn_mo->pinfo == INSN_MACRO)
3684 macro (&insn, &imm_expr, &imm_reloc);
3685 else
3686 append_insn (&insn, &imm_expr, imm_reloc);
3687}
3688
3689const char *
3690md_atof (int type, char *litP, int *sizeP)
3691{
3692 return ieee_md_atof (type, litP, sizeP, TARGET_BYTES_BIG_ENDIAN);
3693}
3694
3695void
3696md_number_to_chars (char *buf, valueT val, int n)
3697{
fbc09e7a
MC
3698 if (target_big_endian)
3699 number_to_chars_bigendian (buf, val, n);
3700 else
3701 number_to_chars_littleendian (buf, val, n);
e23eba97
NC
3702}
3703
3704const char *md_shortopts = "O::g::G:";
3705
3706enum options
3707{
2922d21d 3708 OPTION_MARCH = OPTION_MD_BASE,
e23eba97
NC
3709 OPTION_PIC,
3710 OPTION_NO_PIC,
2922d21d 3711 OPTION_MABI,
71060565
JW
3712 OPTION_RELAX,
3713 OPTION_NO_RELAX,
2dc8dd17
JW
3714 OPTION_ARCH_ATTR,
3715 OPTION_NO_ARCH_ATTR,
2ca89224
NC
3716 OPTION_CSR_CHECK,
3717 OPTION_NO_CSR_CHECK,
8f595e9b
NC
3718 OPTION_MISA_SPEC,
3719 OPTION_MPRIV_SPEC,
fbc09e7a
MC
3720 OPTION_BIG_ENDIAN,
3721 OPTION_LITTLE_ENDIAN,
e23eba97
NC
3722 OPTION_END_OF_ENUM
3723};
3724
3725struct option md_longopts[] =
3726{
e23eba97
NC
3727 {"march", required_argument, NULL, OPTION_MARCH},
3728 {"fPIC", no_argument, NULL, OPTION_PIC},
3729 {"fpic", no_argument, NULL, OPTION_PIC},
3730 {"fno-pic", no_argument, NULL, OPTION_NO_PIC},
2922d21d 3731 {"mabi", required_argument, NULL, OPTION_MABI},
71060565
JW
3732 {"mrelax", no_argument, NULL, OPTION_RELAX},
3733 {"mno-relax", no_argument, NULL, OPTION_NO_RELAX},
2dc8dd17
JW
3734 {"march-attr", no_argument, NULL, OPTION_ARCH_ATTR},
3735 {"mno-arch-attr", no_argument, NULL, OPTION_NO_ARCH_ATTR},
2ca89224
NC
3736 {"mcsr-check", no_argument, NULL, OPTION_CSR_CHECK},
3737 {"mno-csr-check", no_argument, NULL, OPTION_NO_CSR_CHECK},
8f595e9b
NC
3738 {"misa-spec", required_argument, NULL, OPTION_MISA_SPEC},
3739 {"mpriv-spec", required_argument, NULL, OPTION_MPRIV_SPEC},
fbc09e7a
MC
3740 {"mbig-endian", no_argument, NULL, OPTION_BIG_ENDIAN},
3741 {"mlittle-endian", no_argument, NULL, OPTION_LITTLE_ENDIAN},
e23eba97
NC
3742
3743 {NULL, no_argument, NULL, 0}
3744};
3745size_t md_longopts_size = sizeof (md_longopts);
3746
e23eba97
NC
3747int
3748md_parse_option (int c, const char *arg)
3749{
3750 switch (c)
3751 {
e23eba97 3752 case OPTION_MARCH:
8f595e9b 3753 default_arch_with_ext = arg;
e23eba97
NC
3754 break;
3755
3756 case OPTION_NO_PIC:
5b7c81bd 3757 riscv_opts.pic = false;
e23eba97
NC
3758 break;
3759
3760 case OPTION_PIC:
5b7c81bd 3761 riscv_opts.pic = true;
e23eba97
NC
3762 break;
3763
2922d21d
AW
3764 case OPTION_MABI:
3765 if (strcmp (arg, "ilp32") == 0)
5b7c81bd 3766 riscv_set_abi (32, FLOAT_ABI_SOFT, false);
7f999549 3767 else if (strcmp (arg, "ilp32e") == 0)
5b7c81bd 3768 riscv_set_abi (32, FLOAT_ABI_SOFT, true);
2922d21d 3769 else if (strcmp (arg, "ilp32f") == 0)
5b7c81bd 3770 riscv_set_abi (32, FLOAT_ABI_SINGLE, false);
2922d21d 3771 else if (strcmp (arg, "ilp32d") == 0)
5b7c81bd 3772 riscv_set_abi (32, FLOAT_ABI_DOUBLE, false);
2922d21d 3773 else if (strcmp (arg, "ilp32q") == 0)
5b7c81bd 3774 riscv_set_abi (32, FLOAT_ABI_QUAD, false);
2922d21d 3775 else if (strcmp (arg, "lp64") == 0)
5b7c81bd 3776 riscv_set_abi (64, FLOAT_ABI_SOFT, false);
2922d21d 3777 else if (strcmp (arg, "lp64f") == 0)
5b7c81bd 3778 riscv_set_abi (64, FLOAT_ABI_SINGLE, false);
2922d21d 3779 else if (strcmp (arg, "lp64d") == 0)
5b7c81bd 3780 riscv_set_abi (64, FLOAT_ABI_DOUBLE, false);
2922d21d 3781 else if (strcmp (arg, "lp64q") == 0)
5b7c81bd 3782 riscv_set_abi (64, FLOAT_ABI_QUAD, false);
2922d21d
AW
3783 else
3784 return 0;
5b7c81bd 3785 explicit_mabi = true;
2922d21d
AW
3786 break;
3787
71060565 3788 case OPTION_RELAX:
5b7c81bd 3789 riscv_opts.relax = true;
71060565
JW
3790 break;
3791
3792 case OPTION_NO_RELAX:
5b7c81bd 3793 riscv_opts.relax = false;
71060565
JW
3794 break;
3795
2dc8dd17 3796 case OPTION_ARCH_ATTR:
5b7c81bd 3797 riscv_opts.arch_attr = true;
2dc8dd17
JW
3798 break;
3799
3800 case OPTION_NO_ARCH_ATTR:
5b7c81bd 3801 riscv_opts.arch_attr = false;
2dc8dd17
JW
3802 break;
3803
2ca89224 3804 case OPTION_CSR_CHECK:
5b7c81bd 3805 riscv_opts.csr_check = true;
2ca89224
NC
3806 break;
3807
3808 case OPTION_NO_CSR_CHECK:
5b7c81bd 3809 riscv_opts.csr_check = false;
2ca89224
NC
3810 break;
3811
8f595e9b
NC
3812 case OPTION_MISA_SPEC:
3813 return riscv_set_default_isa_spec (arg);
3814
3815 case OPTION_MPRIV_SPEC:
3816 return riscv_set_default_priv_spec (arg);
3817
fbc09e7a
MC
3818 case OPTION_BIG_ENDIAN:
3819 target_big_endian = 1;
3820 break;
3821
3822 case OPTION_LITTLE_ENDIAN:
3823 target_big_endian = 0;
3824 break;
3825
e23eba97
NC
3826 default:
3827 return 0;
3828 }
3829
3830 return 1;
3831}
3832
3833void
3834riscv_after_parse_args (void)
3835{
dcd709e0
NC
3836 /* The --with-arch is optional for now, so we still need to set the xlen
3837 according to the default_arch, which is set by the --target. */
e23eba97
NC
3838 if (xlen == 0)
3839 {
3840 if (strcmp (default_arch, "riscv32") == 0)
3841 xlen = 32;
3842 else if (strcmp (default_arch, "riscv64") == 0)
3843 xlen = 64;
3844 else
3845 as_bad ("unknown default architecture `%s'", default_arch);
3846 }
8f595e9b 3847
dcd709e0 3848 /* Set default specs. */
8f595e9b
NC
3849 if (default_isa_spec == ISA_SPEC_CLASS_NONE)
3850 riscv_set_default_isa_spec (DEFAULT_RISCV_ISA_SPEC);
dcd709e0
NC
3851 if (default_priv_spec == PRIV_SPEC_CLASS_NONE)
3852 riscv_set_default_priv_spec (DEFAULT_RISCV_PRIV_SPEC);
2922d21d 3853
8f595e9b 3854 riscv_set_arch (default_arch_with_ext);
2922d21d 3855
0ac2b354
AB
3856 /* If the CIE to be produced has not been overridden on the command line,
3857 then produce version 3 by default. This allows us to use the full
3858 range of registers in a .cfi_return_column directive. */
3859 if (flag_dwarf_cie_version == -1)
3860 flag_dwarf_cie_version = 3;
e23eba97
NC
3861}
3862
7a29ee29
JB
3863bool riscv_parse_name (const char *name, struct expressionS *ep,
3864 enum expr_mode mode)
3865{
3866 unsigned int regno;
3867 symbolS *sym;
3868
3869 if (!probing_insn_operands)
3870 return false;
3871
3872 gas_assert (mode == expr_normal);
3873
3874 regno = reg_lookup_internal (name, RCLASS_GPR);
3875 if (regno == (unsigned int)-1)
3876 return false;
3877
3878 if (symbol_find (name) != NULL)
3879 return false;
3880
3881 /* Create a symbol without adding it to the symbol table yet.
3882 Insertion will happen only once we commit to using the insn
3883 we're probing operands for. */
3884 for (sym = deferred_sym_rootP; sym; sym = symbol_next (sym))
3885 if (strcmp (name, S_GET_NAME (sym)) == 0)
3886 break;
3887 if (!sym)
3888 {
3889 for (sym = orphan_sym_rootP; sym; sym = symbol_next (sym))
3890 if (strcmp (name, S_GET_NAME (sym)) == 0)
3891 {
3892 symbol_remove (sym, &orphan_sym_rootP, &orphan_sym_lastP);
3893 break;
3894 }
3895 if (!sym)
3896 sym = symbol_create (name, undefined_section,
3897 &zero_address_frag, 0);
3898
3899 symbol_append (sym, deferred_sym_lastP, &deferred_sym_rootP,
3900 &deferred_sym_lastP);
3901 }
3902
3903 ep->X_op = O_symbol;
3904 ep->X_add_symbol = sym;
3905 ep->X_add_number = 0;
3906
3907 return true;
3908}
3909
e23eba97
NC
3910long
3911md_pcrel_from (fixS *fixP)
3912{
3913 return fixP->fx_where + fixP->fx_frag->fr_address;
3914}
3915
3916/* Apply a fixup to the object file. */
3917
3918void
3919md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
3920{
45f76423 3921 unsigned int subtype;
e23eba97 3922 bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
5b7c81bd 3923 bool relaxable = false;
c1b465c9 3924 offsetT loc;
a6cbf936 3925 segT sub_segment;
e23eba97
NC
3926
3927 /* Remember value for tc_gen_reloc. */
3928 fixP->fx_addnumber = *valP;
3929
3930 switch (fixP->fx_r_type)
3931 {
e23eba97
NC
3932 case BFD_RELOC_RISCV_HI20:
3933 case BFD_RELOC_RISCV_LO12_I:
3934 case BFD_RELOC_RISCV_LO12_S:
45f76423
AW
3935 bfd_putl32 (riscv_apply_const_reloc (fixP->fx_r_type, *valP)
3936 | bfd_getl32 (buf), buf);
a5ec5e3f 3937 if (fixP->fx_addsy == NULL)
5b7c81bd
AM
3938 fixP->fx_done = true;
3939 relaxable = true;
45f76423
AW
3940 break;
3941
3942 case BFD_RELOC_RISCV_GOT_HI20:
e23eba97
NC
3943 case BFD_RELOC_RISCV_ADD8:
3944 case BFD_RELOC_RISCV_ADD16:
3945 case BFD_RELOC_RISCV_ADD32:
3946 case BFD_RELOC_RISCV_ADD64:
45f76423 3947 case BFD_RELOC_RISCV_SUB6:
e23eba97
NC
3948 case BFD_RELOC_RISCV_SUB8:
3949 case BFD_RELOC_RISCV_SUB16:
3950 case BFD_RELOC_RISCV_SUB32:
3951 case BFD_RELOC_RISCV_SUB64:
45f76423 3952 case BFD_RELOC_RISCV_RELAX:
f1cd8b94
KLC
3953 /* cvt_frag_to_fill () has called output_leb128 (). */
3954 case BFD_RELOC_RISCV_SET_ULEB128:
3955 case BFD_RELOC_RISCV_SUB_ULEB128:
45f76423
AW
3956 break;
3957
3958 case BFD_RELOC_RISCV_TPREL_HI20:
3959 case BFD_RELOC_RISCV_TPREL_LO12_I:
3960 case BFD_RELOC_RISCV_TPREL_LO12_S:
3961 case BFD_RELOC_RISCV_TPREL_ADD:
5b7c81bd 3962 relaxable = true;
45f76423
AW
3963 /* Fall through. */
3964
3965 case BFD_RELOC_RISCV_TLS_GOT_HI20:
3966 case BFD_RELOC_RISCV_TLS_GD_HI20:
3967 case BFD_RELOC_RISCV_TLS_DTPREL32:
3968 case BFD_RELOC_RISCV_TLS_DTPREL64:
e294484e
AW
3969 if (fixP->fx_addsy != NULL)
3970 S_SET_THREAD_LOCAL (fixP->fx_addsy);
3971 else
3972 as_bad_where (fixP->fx_file, fixP->fx_line,
3973 _("TLS relocation against a constant"));
e23eba97
NC
3974 break;
3975
e23eba97 3976 case BFD_RELOC_32:
a6cbf936
KLC
3977 /* Use pc-relative relocation for FDE initial location.
3978 The symbol address in .eh_frame may be adjusted in
3979 _bfd_elf_discard_section_eh_frame, and the content of
3980 .eh_frame will be adjusted in _bfd_elf_write_section_eh_frame.
3981 Therefore, we cannot insert a relocation whose addend symbol is
dcd709e0 3982 in .eh_frame. Othrewise, the value may be adjusted twice. */
a6cbf936
KLC
3983 if (fixP->fx_addsy && fixP->fx_subsy
3984 && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy))
3985 && strcmp (sub_segment->name, ".eh_frame") == 0
3986 && S_GET_VALUE (fixP->fx_subsy)
3987 == fixP->fx_frag->fr_address + fixP->fx_where)
3988 {
3989 fixP->fx_r_type = BFD_RELOC_RISCV_32_PCREL;
3990 fixP->fx_subsy = NULL;
3991 break;
3992 }
3993 /* Fall through. */
3994 case BFD_RELOC_64:
e23eba97
NC
3995 case BFD_RELOC_16:
3996 case BFD_RELOC_8:
45f76423 3997 case BFD_RELOC_RISCV_CFA:
e23eba97
NC
3998 if (fixP->fx_addsy && fixP->fx_subsy)
3999 {
4000 fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
4001 fixP->fx_next->fx_addsy = fixP->fx_subsy;
4002 fixP->fx_next->fx_subsy = NULL;
4003 fixP->fx_next->fx_offset = 0;
4004 fixP->fx_subsy = NULL;
4005
4006 switch (fixP->fx_r_type)
4007 {
4008 case BFD_RELOC_64:
4009 fixP->fx_r_type = BFD_RELOC_RISCV_ADD64;
4010 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB64;
4011 break;
4012
4013 case BFD_RELOC_32:
4014 fixP->fx_r_type = BFD_RELOC_RISCV_ADD32;
4015 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
4016 break;
4017
4018 case BFD_RELOC_16:
4019 fixP->fx_r_type = BFD_RELOC_RISCV_ADD16;
4020 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
4021 break;
4022
4023 case BFD_RELOC_8:
4024 fixP->fx_r_type = BFD_RELOC_RISCV_ADD8;
4025 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
073808ed 4026 break;
e23eba97 4027
45f76423
AW
4028 case BFD_RELOC_RISCV_CFA:
4029 /* Load the byte to get the subtype. */
c1b465c9
KLC
4030 subtype = bfd_get_8 (NULL, &((fragS *) (fixP->fx_frag->fr_opcode))->fr_literal[fixP->fx_where]);
4031 loc = fixP->fx_frag->fr_fix - (subtype & 7);
45f76423
AW
4032 switch (subtype)
4033 {
4034 case DW_CFA_advance_loc1:
c1b465c9
KLC
4035 fixP->fx_where = loc + 1;
4036 fixP->fx_next->fx_where = loc + 1;
45f76423
AW
4037 fixP->fx_r_type = BFD_RELOC_RISCV_SET8;
4038 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
4039 break;
4040
4041 case DW_CFA_advance_loc2:
4042 fixP->fx_size = 2;
45f76423 4043 fixP->fx_next->fx_size = 2;
c1b465c9
KLC
4044 fixP->fx_where = loc + 1;
4045 fixP->fx_next->fx_where = loc + 1;
45f76423
AW
4046 fixP->fx_r_type = BFD_RELOC_RISCV_SET16;
4047 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
4048 break;
4049
4050 case DW_CFA_advance_loc4:
4051 fixP->fx_size = 4;
45f76423 4052 fixP->fx_next->fx_size = 4;
c1b465c9
KLC
4053 fixP->fx_where = loc;
4054 fixP->fx_next->fx_where = loc;
45f76423
AW
4055 fixP->fx_r_type = BFD_RELOC_RISCV_SET32;
4056 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
4057 break;
4058
4059 default:
4060 if (subtype < 0x80 && (subtype & 0x40))
4061 {
4062 /* DW_CFA_advance_loc */
2aece2ba
KLC
4063 fixP->fx_frag = (fragS *) fixP->fx_frag->fr_opcode;
4064 fixP->fx_next->fx_frag = fixP->fx_frag;
45f76423
AW
4065 fixP->fx_r_type = BFD_RELOC_RISCV_SET6;
4066 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB6;
4067 }
4068 else
b800637e 4069 as_fatal (_("internal: bad CFA value #%d"), subtype);
45f76423
AW
4070 break;
4071 }
4072 break;
4073
e23eba97
NC
4074 default:
4075 /* This case is unreachable. */
4076 abort ();
4077 }
4078 }
4079 /* Fall through. */
4080
4081 case BFD_RELOC_RVA:
4082 /* If we are deleting this reloc entry, we must fill in the
4083 value now. This can happen if we have a .word which is not
4084 resolved when it appears but is later defined. */
4085 if (fixP->fx_addsy == NULL)
4086 {
4087 gas_assert (fixP->fx_size <= sizeof (valueT));
4088 md_number_to_chars ((char *) buf, *valP, fixP->fx_size);
4089 fixP->fx_done = 1;
4090 }
4091 break;
4092
4093 case BFD_RELOC_RISCV_JMP:
4094 if (fixP->fx_addsy)
4095 {
4096 /* Fill in a tentative value to improve objdump readability. */
4097 bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
4098 bfd_vma delta = target - md_pcrel_from (fixP);
5a9f5403 4099 bfd_putl32 (bfd_getl32 (buf) | ENCODE_JTYPE_IMM (delta), buf);
e23eba97
NC
4100 }
4101 break;
4102
4103 case BFD_RELOC_12_PCREL:
4104 if (fixP->fx_addsy)
4105 {
4106 /* Fill in a tentative value to improve objdump readability. */
4107 bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
4108 bfd_vma delta = target - md_pcrel_from (fixP);
5a9f5403 4109 bfd_putl32 (bfd_getl32 (buf) | ENCODE_BTYPE_IMM (delta), buf);
e23eba97
NC
4110 }
4111 break;
4112
4113 case BFD_RELOC_RISCV_RVC_BRANCH:
4114 if (fixP->fx_addsy)
4115 {
4116 /* Fill in a tentative value to improve objdump readability. */
4117 bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
4118 bfd_vma delta = target - md_pcrel_from (fixP);
5a9f5403 4119 bfd_putl16 (bfd_getl16 (buf) | ENCODE_CBTYPE_IMM (delta), buf);
e23eba97
NC
4120 }
4121 break;
4122
4123 case BFD_RELOC_RISCV_RVC_JUMP:
4124 if (fixP->fx_addsy)
4125 {
4126 /* Fill in a tentative value to improve objdump readability. */
4127 bfd_vma target = S_GET_VALUE (fixP->fx_addsy) + *valP;
4128 bfd_vma delta = target - md_pcrel_from (fixP);
5a9f5403 4129 bfd_putl16 (bfd_getl16 (buf) | ENCODE_CJTYPE_IMM (delta), buf);
e23eba97
NC
4130 }
4131 break;
4132
e23eba97
NC
4133 case BFD_RELOC_RISCV_CALL:
4134 case BFD_RELOC_RISCV_CALL_PLT:
5b7c81bd 4135 relaxable = true;
45f76423
AW
4136 break;
4137
9d06997a 4138 case BFD_RELOC_RISCV_PCREL_HI20:
45f76423
AW
4139 case BFD_RELOC_RISCV_PCREL_LO12_S:
4140 case BFD_RELOC_RISCV_PCREL_LO12_I:
9d06997a
PD
4141 relaxable = riscv_opts.relax;
4142 break;
4143
e23eba97
NC
4144 case BFD_RELOC_RISCV_ALIGN:
4145 break;
4146
4147 default:
4148 /* We ignore generic BFD relocations we don't know about. */
4149 if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
b800637e 4150 as_fatal (_("internal: bad relocation #%d"), fixP->fx_r_type);
e23eba97 4151 }
45f76423 4152
e294484e 4153 if (fixP->fx_subsy != NULL)
4bf09429 4154 as_bad_subtract (fixP);
e294484e 4155
45f76423
AW
4156 /* Add an R_RISCV_RELAX reloc if the reloc is relaxable. */
4157 if (relaxable && fixP->fx_tcbit && fixP->fx_addsy != NULL)
4158 {
4159 fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
4160 fixP->fx_next->fx_addsy = fixP->fx_next->fx_subsy = NULL;
4161 fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_RELAX;
b1b11e92 4162 fixP->fx_next->fx_size = 0;
45f76423
AW
4163 }
4164}
4165
4166/* Because the value of .cfi_remember_state may changed after relaxation,
4167 we insert a fix to relocate it again in link-time. */
4168
4169void
4170riscv_pre_output_hook (void)
4171{
4172 const frchainS *frch;
72393fd1
JW
4173 segT s;
4174
4175 /* Save the current segment info. */
4176 segT seg = now_seg;
4177 subsegT subseg = now_subseg;
45f76423
AW
4178
4179 for (s = stdoutput->sections; s; s = s->next)
4180 for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
4181 {
7cb7b948 4182 fragS *frag;
45f76423
AW
4183
4184 for (frag = frch->frch_root; frag; frag = frag->fr_next)
4185 {
4186 if (frag->fr_type == rs_cfa)
4187 {
45f76423 4188 expressionS exp;
8d1015a8 4189 expressionS *symval;
45f76423 4190
8d1015a8 4191 symval = symbol_get_value_expression (frag->fr_symbol);
45f76423 4192 exp.X_op = O_subtract;
8d1015a8 4193 exp.X_add_symbol = symval->X_add_symbol;
45f76423 4194 exp.X_add_number = 0;
8d1015a8 4195 exp.X_op_symbol = symval->X_op_symbol;
45f76423 4196
72393fd1
JW
4197 /* We must set the segment before creating a frag after all
4198 frag chains have been chained together. */
4199 subseg_set (s, frch->frch_subseg);
4200
c1b465c9 4201 fix_new_exp (frag, (int) frag->fr_offset, 1, &exp, 0,
45f76423
AW
4202 BFD_RELOC_RISCV_CFA);
4203 }
4204 }
4205 }
72393fd1
JW
4206
4207 /* Restore the original segment info. */
4208 subseg_set (seg, subseg);
e23eba97
NC
4209}
4210
e23eba97
NC
4211/* Handle the .option pseudo-op. */
4212
4213static void
4214s_riscv_option (int x ATTRIBUTE_UNUSED)
4215{
4216 char *name = input_line_pointer, ch;
4217
4218 while (!is_end_of_line[(unsigned char) *input_line_pointer])
4219 ++input_line_pointer;
4220 ch = *input_line_pointer;
4221 *input_line_pointer = '\0';
4222
4223 if (strcmp (name, "rvc") == 0)
edc77c59 4224 {
d3ffd7f7 4225 riscv_update_subset (&riscv_rps_as, "+c");
40f1a1a4 4226 riscv_reset_subsets_list_arch_str ();
edc77c59
NC
4227 riscv_set_rvc (true);
4228 }
e23eba97 4229 else if (strcmp (name, "norvc") == 0)
edc77c59 4230 {
d3ffd7f7 4231 riscv_update_subset (&riscv_rps_as, "-c");
40f1a1a4 4232 riscv_reset_subsets_list_arch_str ();
edc77c59
NC
4233 riscv_set_rvc (false);
4234 }
e23eba97 4235 else if (strcmp (name, "pic") == 0)
5b7c81bd 4236 riscv_opts.pic = true;
e23eba97 4237 else if (strcmp (name, "nopic") == 0)
5b7c81bd 4238 riscv_opts.pic = false;
45f76423 4239 else if (strcmp (name, "relax") == 0)
5b7c81bd 4240 riscv_opts.relax = true;
45f76423 4241 else if (strcmp (name, "norelax") == 0)
5b7c81bd 4242 riscv_opts.relax = false;
2ca89224 4243 else if (strcmp (name, "csr-check") == 0)
5b7c81bd 4244 riscv_opts.csr_check = true;
2ca89224 4245 else if (strcmp (name, "no-csr-check") == 0)
5b7c81bd 4246 riscv_opts.csr_check = false;
d3ffd7f7
NC
4247 else if (strncmp (name, "arch,", 5) == 0)
4248 {
4249 name += 5;
4250 if (ISSPACE (*name) && *name != '\0')
4251 name++;
4252 riscv_update_subset (&riscv_rps_as, name);
40f1a1a4 4253 riscv_reset_subsets_list_arch_str ();
e7e599a1
NC
4254
4255 riscv_set_rvc (false);
4256 if (riscv_subset_supports (&riscv_rps_as, "c"))
4257 riscv_set_rvc (true);
acab2a68
TO
4258
4259 if (riscv_subset_supports (&riscv_rps_as, "ztso"))
4260 riscv_set_tso ();
d3ffd7f7 4261 }
e23eba97
NC
4262 else if (strcmp (name, "push") == 0)
4263 {
4264 struct riscv_option_stack *s;
4265
d3ffd7f7 4266 s = XNEW (struct riscv_option_stack);
e23eba97
NC
4267 s->next = riscv_opts_stack;
4268 s->options = riscv_opts;
f5cb31a8 4269 s->subset_list = riscv_rps_as.subset_list;
e23eba97 4270 riscv_opts_stack = s;
f5cb31a8 4271 riscv_rps_as.subset_list = riscv_copy_subset_list (s->subset_list);
e23eba97
NC
4272 }
4273 else if (strcmp (name, "pop") == 0)
4274 {
4275 struct riscv_option_stack *s;
4276
4277 s = riscv_opts_stack;
4278 if (s == NULL)
4279 as_bad (_(".option pop with no .option push"));
4280 else
4281 {
f5cb31a8 4282 riscv_subset_list_t *release_subsets = riscv_rps_as.subset_list;
e23eba97 4283 riscv_opts_stack = s->next;
d3ffd7f7 4284 riscv_opts = s->options;
f5cb31a8 4285 riscv_rps_as.subset_list = s->subset_list;
d3ffd7f7 4286 riscv_release_subset_list (release_subsets);
e23eba97
NC
4287 free (s);
4288 }
4289 }
4290 else
4291 {
c84b3d7e 4292 as_warn (_("unrecognized .option directive: %s"), name);
e23eba97
NC
4293 }
4294 *input_line_pointer = ch;
4295 demand_empty_rest_of_line ();
4296}
4297
4298/* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
4299 a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
4300 use in DWARF debug information. */
4301
4302static void
4303s_dtprel (int bytes)
4304{
4305 expressionS ex;
4306 char *p;
4307
4308 expression (&ex);
4309
4310 if (ex.X_op != O_symbol)
4311 {
b800637e 4312 as_bad (_("unsupported use of %s"), (bytes == 8
e23eba97
NC
4313 ? ".dtpreldword"
4314 : ".dtprelword"));
4315 ignore_rest_of_line ();
4316 }
4317
4318 p = frag_more (bytes);
4319 md_number_to_chars (p, 0, bytes);
5b7c81bd 4320 fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, false,
e23eba97
NC
4321 (bytes == 8
4322 ? BFD_RELOC_RISCV_TLS_DTPREL64
4323 : BFD_RELOC_RISCV_TLS_DTPREL32));
4324
4325 demand_empty_rest_of_line ();
4326}
4327
4328/* Handle the .bss pseudo-op. */
4329
4330static void
4331s_bss (int ignore ATTRIBUTE_UNUSED)
4332{
4333 subseg_set (bss_section, 0);
4334 demand_empty_rest_of_line ();
4335}
4336
e23eba97 4337static void
d115ab8e 4338riscv_make_nops (char *buf, bfd_vma bytes)
e23eba97 4339{
d115ab8e 4340 bfd_vma i = 0;
e23eba97 4341
e5b737de
AW
4342 /* RISC-V instructions cannot begin or end on odd addresses, so this case
4343 means we are not within a valid instruction sequence. It is thus safe
4344 to use a zero byte, even though that is not a valid instruction. */
4345 if (bytes % 2 == 1)
4346 buf[i++] = 0;
4347
4348 /* Use at most one 2-byte NOP. */
4349 if ((bytes - i) % 4 == 2)
e23eba97 4350 {
fbc09e7a 4351 number_to_chars_littleendian (buf + i, RVC_NOP, 2);
d115ab8e 4352 i += 2;
e23eba97
NC
4353 }
4354
e5b737de 4355 /* Fill the remainder with 4-byte NOPs. */
d115ab8e 4356 for ( ; i < bytes; i += 4)
fbc09e7a 4357 number_to_chars_littleendian (buf + i, RISCV_NOP, 4);
d115ab8e 4358}
e23eba97 4359
d115ab8e
AW
4360/* Called from md_do_align. Used to create an alignment frag in a
4361 code section by emitting a worst-case NOP sequence that the linker
4362 will later relax to the correct number of NOPs. We can't compute
4363 the correct alignment now because of other linker relaxations. */
4364
5b7c81bd 4365bool
d115ab8e
AW
4366riscv_frag_align_code (int n)
4367{
e5b737de 4368 bfd_vma bytes = (bfd_vma) 1 << n;
36877bfb
JW
4369 bfd_vma insn_alignment = riscv_opts.rvc ? 2 : 4;
4370 bfd_vma worst_case_bytes = bytes - insn_alignment;
4371 char *nops;
ed0816bd 4372 expressionS ex;
d115ab8e 4373
36877bfb
JW
4374 /* If we are moving to a smaller alignment than the instruction size, then no
4375 alignment is required. */
4376 if (bytes <= insn_alignment)
5b7c81bd 4377 return true;
36877bfb 4378
d115ab8e
AW
4379 /* When not relaxing, riscv_handle_align handles code alignment. */
4380 if (!riscv_opts.relax)
5b7c81bd 4381 return false;
e23eba97 4382
40f1a1a4
NC
4383 /* Maybe we should use frag_var to create a new rs_align_code fragment,
4384 rather than just use frag_more to handle an alignment here? So that we
4385 don't need to call riscv_mapping_state again later, and then only need
4386 to check frag->fr_type to see if it is frag_align_code. */
e80ae190
JW
4387 nops = frag_more (worst_case_bytes);
4388
ed0816bd
PD
4389 ex.X_op = O_constant;
4390 ex.X_add_number = worst_case_bytes;
d115ab8e 4391
ed0816bd 4392 riscv_make_nops (nops, worst_case_bytes);
e23eba97 4393
ed0816bd 4394 fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
5b7c81bd 4395 &ex, false, BFD_RELOC_RISCV_ALIGN);
e23eba97 4396
3190ebcb 4397 riscv_mapping_state (MAP_INSN, worst_case_bytes, true/* fr_align_code */);
9b9b1092 4398
cb2562f5
LX
4399 /* We need to start a new frag after the alignment which may be removed by
4400 the linker, to prevent the assembler from computing static offsets.
4401 This is necessary to get correct EH info. */
4402 frag_wane (frag_now);
4403 frag_new (0);
4404
5b7c81bd 4405 return true;
d115ab8e 4406}
e23eba97 4407
d115ab8e
AW
4408/* Implement HANDLE_ALIGN. */
4409
4410void
4411riscv_handle_align (fragS *fragP)
4412{
4413 switch (fragP->fr_type)
4414 {
4415 case rs_align_code:
4416 /* When relaxing, riscv_frag_align_code handles code alignment. */
4417 if (!riscv_opts.relax)
4418 {
e80ae190
JW
4419 bfd_signed_vma bytes = (fragP->fr_next->fr_address
4420 - fragP->fr_address - fragP->fr_fix);
4421 /* We have 4 byte uncompressed nops. */
4422 bfd_signed_vma size = 4;
4423 bfd_signed_vma excess = bytes % size;
9b9b1092 4424 bfd_boolean odd_padding = (excess % 2 == 1);
e80ae190
JW
4425 char *p = fragP->fr_literal + fragP->fr_fix;
4426
4427 if (bytes <= 0)
d115ab8e
AW
4428 break;
4429
e80ae190
JW
4430 /* Insert zeros or compressed nops to get 4 byte alignment. */
4431 if (excess)
4432 {
9b9b1092
NC
4433 if (odd_padding)
4434 riscv_add_odd_padding_symbol (fragP);
e80ae190
JW
4435 riscv_make_nops (p, excess);
4436 fragP->fr_fix += excess;
4437 p += excess;
4438 }
4439
9b9b1092
NC
4440 /* The frag will be changed to `rs_fill` later. The function
4441 `write_contents` will try to fill the remaining spaces
4442 according to the patterns we give. In this case, we give
4443 a 4 byte uncompressed nop as the pattern, and set the size
4444 of the pattern into `fr_var`. The nop will be output to the
4445 file `fr_offset` times. However, `fr_offset` could be zero
4446 if we don't need to pad the boundary finally. */
e80ae190
JW
4447 riscv_make_nops (p, size);
4448 fragP->fr_var = size;
d115ab8e
AW
4449 }
4450 break;
4451
4452 default:
4453 break;
4454 }
e23eba97
NC
4455}
4456
9b9b1092
NC
4457/* This usually called from frag_var. */
4458
4459void
4460riscv_init_frag (fragS * fragP, int max_chars)
4461{
4462 /* Do not add mapping symbol to debug sections. */
4463 if (bfd_section_flags (now_seg) & SEC_DEBUGGING)
4464 return;
4465
4466 switch (fragP->fr_type)
4467 {
4468 case rs_fill:
4469 case rs_align:
4470 case rs_align_test:
3190ebcb 4471 riscv_mapping_state (MAP_DATA, max_chars, false/* fr_align_code */);
9b9b1092
NC
4472 break;
4473 case rs_align_code:
3190ebcb 4474 riscv_mapping_state (MAP_INSN, max_chars, true/* fr_align_code */);
9b9b1092
NC
4475 break;
4476 default:
4477 break;
4478 }
4479}
4480
e23eba97
NC
4481int
4482md_estimate_size_before_relax (fragS *fragp, asection *segtype)
4483{
5b7c81bd 4484 return (fragp->fr_var = relaxed_branch_length (fragp, segtype, false));
e23eba97
NC
4485}
4486
4487/* Translate internal representation of relocation info to BFD target
4488 format. */
4489
4490arelent *
4491tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
4492{
4493 arelent *reloc = (arelent *) xmalloc (sizeof (arelent));
4494
4495 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
4496 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
4497 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
4498 reloc->addend = fixp->fx_addnumber;
4499
4500 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
4501 if (reloc->howto == NULL)
4502 {
4503 if ((fixp->fx_r_type == BFD_RELOC_16 || fixp->fx_r_type == BFD_RELOC_8)
4504 && fixp->fx_addsy != NULL && fixp->fx_subsy != NULL)
4505 {
4506 /* We don't have R_RISCV_8/16, but for this special case,
4507 we can use R_RISCV_ADD8/16 with R_RISCV_SUB8/16. */
4508 return reloc;
4509 }
4510
4511 as_bad_where (fixp->fx_file, fixp->fx_line,
4512 _("cannot represent %s relocation in object file"),
4513 bfd_get_reloc_code_name (fixp->fx_r_type));
4514 return NULL;
4515 }
4516
4517 return reloc;
4518}
4519
4520int
4521riscv_relax_frag (asection *sec, fragS *fragp, long stretch ATTRIBUTE_UNUSED)
4522{
4523 if (RELAX_BRANCH_P (fragp->fr_subtype))
4524 {
4525 offsetT old_var = fragp->fr_var;
5b7c81bd 4526 fragp->fr_var = relaxed_branch_length (fragp, sec, true);
e23eba97
NC
4527 return fragp->fr_var - old_var;
4528 }
4529
4530 return 0;
4531}
4532
4533/* Expand far branches to multi-instruction sequences. */
4534
4535static void
4536md_convert_frag_branch (fragS *fragp)
4537{
4538 bfd_byte *buf;
4539 expressionS exp;
4540 fixS *fixp;
4541 insn_t insn;
4542 int rs1, reloc;
4543
4544 buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
4545
4546 exp.X_op = O_symbol;
4547 exp.X_add_symbol = fragp->fr_symbol;
4548 exp.X_add_number = fragp->fr_offset;
4549
4550 gas_assert (fragp->fr_var == RELAX_BRANCH_LENGTH (fragp->fr_subtype));
4551
4552 if (RELAX_BRANCH_RVC (fragp->fr_subtype))
4553 {
4554 switch (RELAX_BRANCH_LENGTH (fragp->fr_subtype))
4555 {
4556 case 8:
4557 case 4:
4558 /* Expand the RVC branch into a RISC-V one. */
4559 insn = bfd_getl16 (buf);
4560 rs1 = 8 + ((insn >> OP_SH_CRS1S) & OP_MASK_CRS1S);
4561 if ((insn & MASK_C_J) == MATCH_C_J)
4562 insn = MATCH_JAL;
4563 else if ((insn & MASK_C_JAL) == MATCH_C_JAL)
4564 insn = MATCH_JAL | (X_RA << OP_SH_RD);
4565 else if ((insn & MASK_C_BEQZ) == MATCH_C_BEQZ)
4566 insn = MATCH_BEQ | (rs1 << OP_SH_RS1);
4567 else if ((insn & MASK_C_BNEZ) == MATCH_C_BNEZ)
4568 insn = MATCH_BNE | (rs1 << OP_SH_RS1);
4569 else
4570 abort ();
4571 bfd_putl32 (insn, buf);
4572 break;
4573
4574 case 6:
4575 /* Invert the branch condition. Branch over the jump. */
4576 insn = bfd_getl16 (buf);
4577 insn ^= MATCH_C_BEQZ ^ MATCH_C_BNEZ;
5a9f5403 4578 insn |= ENCODE_CBTYPE_IMM (6);
e23eba97
NC
4579 bfd_putl16 (insn, buf);
4580 buf += 2;
4581 goto jump;
4582
4583 case 2:
4584 /* Just keep the RVC branch. */
4585 reloc = RELAX_BRANCH_UNCOND (fragp->fr_subtype)
4586 ? BFD_RELOC_RISCV_RVC_JUMP : BFD_RELOC_RISCV_RVC_BRANCH;
4587 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
5b7c81bd 4588 2, &exp, false, reloc);
e23eba97
NC
4589 buf += 2;
4590 goto done;
4591
4592 default:
1d65abb5 4593 abort ();
e23eba97
NC
4594 }
4595 }
4596
4597 switch (RELAX_BRANCH_LENGTH (fragp->fr_subtype))
4598 {
4599 case 8:
4600 gas_assert (!RELAX_BRANCH_UNCOND (fragp->fr_subtype));
4601
4602 /* Invert the branch condition. Branch over the jump. */
4603 insn = bfd_getl32 (buf);
4604 insn ^= MATCH_BEQ ^ MATCH_BNE;
5a9f5403 4605 insn |= ENCODE_BTYPE_IMM (8);
fbc09e7a 4606 bfd_putl32 (insn, buf);
e23eba97
NC
4607 buf += 4;
4608
dc1e8a47 4609 jump:
e23eba97
NC
4610 /* Jump to the target. */
4611 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
5b7c81bd 4612 4, &exp, false, BFD_RELOC_RISCV_JMP);
fbc09e7a 4613 bfd_putl32 (MATCH_JAL, buf);
e23eba97
NC
4614 buf += 4;
4615 break;
4616
4617 case 4:
4618 reloc = RELAX_BRANCH_UNCOND (fragp->fr_subtype)
4619 ? BFD_RELOC_RISCV_JMP : BFD_RELOC_12_PCREL;
4620 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
5b7c81bd 4621 4, &exp, false, reloc);
e23eba97
NC
4622 buf += 4;
4623 break;
4624
4625 default:
4626 abort ();
4627 }
4628
dc1e8a47 4629 done:
e23eba97
NC
4630 fixp->fx_file = fragp->fr_file;
4631 fixp->fx_line = fragp->fr_line;
4632
4633 gas_assert (buf == (bfd_byte *)fragp->fr_literal
4634 + fragp->fr_fix + fragp->fr_var);
4635
4636 fragp->fr_fix += fragp->fr_var;
4637}
4638
4639/* Relax a machine dependent frag. This returns the amount by which
4640 the current size of the frag should change. */
4641
4642void
4643md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
4644 fragS *fragp)
4645{
4646 gas_assert (RELAX_BRANCH_P (fragp->fr_subtype));
4647 md_convert_frag_branch (fragp);
4648}
4649
4650void
4651md_show_usage (FILE *stream)
4652{
4653 fprintf (stream, _("\
4654RISC-V options:\n\
437e2ff1 4655 -fpic or -fPIC generate position-independent code\n\
8f595e9b
NC
4656 -fno-pic don't generate position-independent code (default)\n\
4657 -march=ISA set the RISC-V architecture\n\
4658 -misa-spec=ISAspec set the RISC-V ISA spec (2.2, 20190608, 20191213)\n\
86d39e66 4659 -mpriv-spec=PRIVspec set the RISC-V privilege spec (1.9.1, 1.10, 1.11, 1.12)\n\
8f595e9b
NC
4660 -mabi=ABI set the RISC-V ABI\n\
4661 -mrelax enable relax (default)\n\
4662 -mno-relax disable relax\n\
4663 -march-attr generate RISC-V arch attribute\n\
4664 -mno-arch-attr don't generate RISC-V arch attribute\n\
437e2ff1
NC
4665 -mcsr-check enable the csr ISA and privilege spec version checks\n\
4666 -mno-csr-check disable the csr ISA and privilege spec version checks (default)\n\
4667 -mbig-endian assemble for big-endian\n\
4668 -mlittle-endian assemble for little-endian\n\
e23eba97
NC
4669"));
4670}
4671
4672/* Standard calling conventions leave the CFA at SP on entry. */
dcd709e0 4673
e23eba97
NC
4674void
4675riscv_cfi_frame_initial_instructions (void)
4676{
4677 cfi_add_CFA_def_cfa_register (X_SP);
4678}
4679
4680int
4681tc_riscv_regname_to_dw2regnum (char *regname)
4682{
4683 int reg;
4684
4685 if ((reg = reg_lookup_internal (regname, RCLASS_GPR)) >= 0)
4686 return reg;
4687
4688 if ((reg = reg_lookup_internal (regname, RCLASS_FPR)) >= 0)
4689 return reg + 32;
4690
7b4f2407
TO
4691 if ((reg = reg_lookup_internal (regname, RCLASS_VECR)) >= 0)
4692 return reg + 96;
4693
4762fe62
AB
4694 /* CSRs are numbered 4096 -> 8191. */
4695 if ((reg = reg_lookup_internal (regname, RCLASS_CSR)) >= 0)
4696 return reg + 4096;
4697
e23eba97
NC
4698 as_bad (_("unknown register `%s'"), regname);
4699 return -1;
4700}
4701
4702void
4703riscv_elf_final_processing (void)
4704{
6e1605e4 4705 riscv_set_abi_by_arch ();
40f1a1a4 4706 riscv_release_subset_list (riscv_rps_as.subset_list);
e23eba97 4707 elf_elfheader (stdoutput)->e_flags |= elf_flags;
e23eba97
NC
4708}
4709
4710/* Parse the .sleb128 and .uleb128 pseudos. Only allow constant expressions,
4711 since these directives break relaxation when used with symbol deltas. */
4712
4713static void
4714s_riscv_leb128 (int sign)
4715{
4716 expressionS exp;
4717 char *save_in = input_line_pointer;
4718
4719 expression (&exp);
f1cd8b94
KLC
4720 if (sign && exp.X_op != O_constant)
4721 as_bad (_("non-constant .sleb128 is not supported"));
4722 else if (!sign && exp.X_op != O_constant && exp.X_op != O_subtract)
4723 as_bad (_(".uleb128 only supports constant or subtract expressions"));
4724
e23eba97
NC
4725 demand_empty_rest_of_line ();
4726
4727 input_line_pointer = save_in;
4728 return s_leb128 (sign);
4729}
4730
a262b82f
NC
4731/* Parse the .insn directive. There are three formats,
4732 Format 1: .insn <type> <operand1>, <operand2>, ...
4733 Format 2: .insn <length>, <value>
4734 Format 3: .insn <value>. */
0e35537d
JW
4735
4736static void
4737s_riscv_insn (int x ATTRIBUTE_UNUSED)
4738{
4739 char *str = input_line_pointer;
4740 struct riscv_cl_insn insn;
4741 expressionS imm_expr;
4742 bfd_reloc_code_real_type imm_reloc = BFD_RELOC_UNUSED;
4743 char save_c;
4744
4745 while (!is_end_of_line[(unsigned char) *input_line_pointer])
4746 ++input_line_pointer;
4747
4748 save_c = *input_line_pointer;
4749 *input_line_pointer = '\0';
4750
3190ebcb 4751 riscv_mapping_state (MAP_INSN, 0, false/* fr_align_code */);
9b9b1092 4752
e4028336 4753 struct riscv_ip_error error = riscv_ip (str, &insn, &imm_expr,
0e35537d 4754 &imm_reloc, insn_type_hash);
e4028336 4755 if (error.msg)
0e35537d 4756 {
a262b82f 4757 char *save_in = input_line_pointer;
e4028336 4758 error.msg = riscv_ip_hardcode (str, &insn, &imm_expr, error.msg);
a262b82f 4759 input_line_pointer = save_in;
0e35537d 4760 }
a262b82f 4761
e4028336
PN
4762 if (error.msg)
4763 {
4764 if (error.missing_ext)
4765 as_bad ("%s `%s', extension `%s' required", error.msg, error.statement,
4766 error.missing_ext);
4767 else
4768 as_bad ("%s `%s'", error.msg, error.statement);
4769 }
634001bb 4770 else
0e35537d
JW
4771 {
4772 gas_assert (insn.insn_mo->pinfo != INSN_MACRO);
4773 append_insn (&insn, &imm_expr, imm_reloc);
4774 }
4775
4776 *input_line_pointer = save_c;
4777 demand_empty_rest_of_line ();
4778}
4779
dcd709e0
NC
4780/* Update architecture and privileged elf attributes. If we don't set
4781 them, then try to output the default ones. */
2dc8dd17
JW
4782
4783static void
8f595e9b 4784riscv_write_out_attrs (void)
2dc8dd17 4785{
8f595e9b 4786 const char *arch_str, *priv_str, *p;
dcd709e0
NC
4787 /* versions[0]: major version.
4788 versions[1]: minor version.
4789 versions[2]: revision version. */
8f595e9b
NC
4790 unsigned versions[3] = {0}, number = 0;
4791 unsigned int i;
2dc8dd17 4792
dcd709e0 4793 /* Re-write architecture elf attribute. */
40f1a1a4 4794 arch_str = riscv_rps_as.subset_list->arch_str;
2dc8dd17 4795 bfd_elf_add_proc_attr_string (stdoutput, Tag_RISCV_arch, arch_str);
8f595e9b
NC
4796
4797 /* For the file without any instruction, we don't set the default_priv_spec
dcd709e0
NC
4798 according to the privileged elf attributes since the md_assemble isn't
4799 called. */
8f595e9b
NC
4800 if (!start_assemble
4801 && !riscv_set_default_priv_spec (NULL))
4802 return;
4803
dcd709e0
NC
4804 /* If we already have set privileged elf attributes, then no need to do
4805 anything. Otherwise, don't generate or update them when no CSR and
4806 privileged instructions are used. */
1a79004f 4807 if (!explicit_priv_attr)
3fc6c3dc
NC
4808 return;
4809
3d73d29e 4810 RISCV_GET_PRIV_SPEC_NAME (priv_str, default_priv_spec);
8f595e9b
NC
4811 p = priv_str;
4812 for (i = 0; *p; ++p)
4813 {
4814 if (*p == '.' && i < 3)
4815 {
4816 versions[i++] = number;
4817 number = 0;
4818 }
4819 else if (ISDIGIT (*p))
4820 number = (number * 10) + (*p - '0');
4821 else
4822 {
b800637e 4823 as_bad (_("internal: bad RISC-V privileged spec (%s)"), priv_str);
8f595e9b
NC
4824 return;
4825 }
4826 }
4827 versions[i] = number;
4828
dcd709e0 4829 /* Re-write privileged elf attributes. */
8f595e9b
NC
4830 bfd_elf_add_proc_attr_int (stdoutput, Tag_RISCV_priv_spec, versions[0]);
4831 bfd_elf_add_proc_attr_int (stdoutput, Tag_RISCV_priv_spec_minor, versions[1]);
4832 bfd_elf_add_proc_attr_int (stdoutput, Tag_RISCV_priv_spec_revision, versions[2]);
2dc8dd17
JW
4833}
4834
dcd709e0 4835/* Add the default contents for the .riscv.attributes section. */
2dc8dd17
JW
4836
4837static void
4838riscv_set_public_attributes (void)
4839{
8f595e9b
NC
4840 if (riscv_opts.arch_attr || explicit_attr)
4841 riscv_write_out_attrs ();
2dc8dd17
JW
4842}
4843
f1cd8b94
KLC
4844/* Scan uleb128 subtraction expressions and insert fixups for them.
4845 e.g., .uleb128 .L1 - .L0
4846 Because relaxation may change the value of the subtraction, we
4847 must resolve them at link-time. */
4848
4849static void
4850riscv_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
4851 asection *sec, void *xxx ATTRIBUTE_UNUSED)
4852{
4853 segment_info_type *seginfo = seg_info (sec);
4854 struct frag *fragP;
4855
4856 subseg_set (sec, 0);
4857
4858 for (fragP = seginfo->frchainP->frch_root;
4859 fragP; fragP = fragP->fr_next)
4860 {
4861 expressionS *exp, *exp_dup;
4862
4863 if (fragP->fr_type != rs_leb128 || fragP->fr_symbol == NULL)
4864 continue;
4865
4866 exp = symbol_get_value_expression (fragP->fr_symbol);
4867
4868 if (exp->X_op != O_subtract)
4869 continue;
4870
4871 /* Only unsigned leb128 can be handled. */
4872 gas_assert (fragP->fr_subtype == 0);
4873 exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp));
4874 exp_dup->X_op = O_symbol;
4875 exp_dup->X_op_symbol = NULL;
4876
4877 /* Insert relocations to resolve the subtraction at link-time.
4878 Emit the SET relocation first in riscv. */
4879 exp_dup->X_add_symbol = exp->X_add_symbol;
4880 fix_new_exp (fragP, fragP->fr_fix, 0,
4881 exp_dup, 0, BFD_RELOC_RISCV_SET_ULEB128);
4882 exp_dup->X_add_symbol = exp->X_op_symbol;
4883 fix_new_exp (fragP, fragP->fr_fix, 0,
4884 exp_dup, 0, BFD_RELOC_RISCV_SUB_ULEB128);
4885 }
4886}
4887
2dc8dd17
JW
4888/* Called after all assembly has been done. */
4889
4890void
ed2917de 4891riscv_md_finish (void)
2dc8dd17
JW
4892{
4893 riscv_set_public_attributes ();
f1cd8b94
KLC
4894 if (riscv_opts.relax)
4895 bfd_map_over_sections (stdoutput, riscv_insert_uleb128_fixes, NULL);
2dc8dd17
JW
4896}
4897
9b9b1092
NC
4898/* Adjust the symbol table. */
4899
4900void
4901riscv_adjust_symtab (void)
4902{
4903 bfd_map_over_sections (stdoutput, riscv_check_mapping_symbols, (char *) 0);
4904 elf_adjust_symtab ();
4905}
4906
2dc8dd17
JW
4907/* Given a symbolic attribute NAME, return the proper integer value.
4908 Returns -1 if the attribute is not known. */
4909
4910int
4911riscv_convert_symbolic_attribute (const char *name)
4912{
4913 static const struct
4914 {
1942a048
NC
4915 const char *name;
4916 const int tag;
2dc8dd17
JW
4917 }
4918 attribute_table[] =
1942a048
NC
4919 {
4920 /* When you modify this table you should
4921 also modify the list in doc/c-riscv.texi. */
4922#define T(tag) {#tag, Tag_RISCV_##tag}, {"Tag_RISCV_" #tag, Tag_RISCV_##tag}
4923 T(arch),
4924 T(priv_spec),
4925 T(priv_spec_minor),
4926 T(priv_spec_revision),
4927 T(unaligned_access),
4928 T(stack_align),
2dc8dd17 4929#undef T
1942a048 4930 };
2dc8dd17
JW
4931
4932 if (name == NULL)
4933 return -1;
4934
1942a048 4935 unsigned int i;
2dc8dd17
JW
4936 for (i = 0; i < ARRAY_SIZE (attribute_table); i++)
4937 if (strcmp (name, attribute_table[i].name) == 0)
4938 return attribute_table[i].tag;
4939
4940 return -1;
4941}
4942
4943/* Parse a .attribute directive. */
4944
4945static void
4946s_riscv_attribute (int ignored ATTRIBUTE_UNUSED)
4947{
4948 int tag = obj_elf_vendor_attribute (OBJ_ATTR_PROC);
8f595e9b
NC
4949 unsigned old_xlen;
4950 obj_attribute *attr;
2dc8dd17 4951
5b7c81bd 4952 explicit_attr = true;
8f595e9b 4953 switch (tag)
2dc8dd17 4954 {
8f595e9b
NC
4955 case Tag_RISCV_arch:
4956 old_xlen = xlen;
2dc8dd17
JW
4957 attr = elf_known_obj_attributes_proc (stdoutput);
4958 if (!start_assemble)
4959 riscv_set_arch (attr[Tag_RISCV_arch].s);
4960 else
b800637e
NC
4961 as_fatal (_("architecture elf attributes must set before "
4962 "any instructions"));
2dc8dd17
JW
4963
4964 if (old_xlen != xlen)
4965 {
4966 /* We must re-init bfd again if xlen is changed. */
4967 unsigned long mach = xlen == 64 ? bfd_mach_riscv64 : bfd_mach_riscv32;
4968 bfd_find_target (riscv_target_format (), stdoutput);
4969
4970 if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, mach))
b800637e 4971 as_warn (_("could not set architecture and machine"));
2dc8dd17 4972 }
8f595e9b
NC
4973 break;
4974
4975 case Tag_RISCV_priv_spec:
4976 case Tag_RISCV_priv_spec_minor:
4977 case Tag_RISCV_priv_spec_revision:
4978 if (start_assemble)
b800637e
NC
4979 as_fatal (_("privileged elf attributes must set before "
4980 "any instructions"));
8f595e9b
NC
4981 break;
4982
4983 default:
4984 break;
2dc8dd17
JW
4985 }
4986}
4987
8155b853
NC
4988/* Mark symbol that it follows a variant CC convention. */
4989
4990static void
4991s_variant_cc (int ignored ATTRIBUTE_UNUSED)
4992{
4993 char *name;
4994 char c;
4995 symbolS *sym;
4996 asymbol *bfdsym;
4997 elf_symbol_type *elfsym;
4998
4999 c = get_symbol_name (&name);
5000 if (!*name)
5001 as_bad (_("missing symbol name for .variant_cc directive"));
5002 sym = symbol_find_or_make (name);
5003 restore_line_pointer (c);
5004 demand_empty_rest_of_line ();
5005
5006 bfdsym = symbol_get_bfdsym (sym);
5007 elfsym = elf_symbol_from (bfdsym);
5008 gas_assert (elfsym);
5009 elfsym->internal_elf_sym.st_other |= STO_RISCV_VARIANT_CC;
5010}
5011
5012/* Same as elf_copy_symbol_attributes, but without copying st_other.
5013 This is needed so RISC-V specific st_other values can be independently
5014 specified for an IFUNC resolver (that is called by the dynamic linker)
5015 and the symbol it resolves (aliased to the resolver). In particular,
5016 if a function symbol has special st_other value set via directives,
5017 then attaching an IFUNC resolver to that symbol should not override
5018 the st_other setting. Requiring the directive on the IFUNC resolver
5019 symbol would be unexpected and problematic in C code, where the two
5020 symbols appear as two independent function declarations. */
5021
5022void
5023riscv_elf_copy_symbol_attributes (symbolS *dest, symbolS *src)
5024{
5025 struct elf_obj_sy *srcelf = symbol_get_obj (src);
5026 struct elf_obj_sy *destelf = symbol_get_obj (dest);
a3a7f5e1
FS
5027 /* If size is unset, copy size from src. Because we don't track whether
5028 .size has been used, we can't differentiate .size dest, 0 from the case
5029 where dest's size is unset. */
5030 if (!destelf->size && S_GET_SIZE (dest) == 0)
8155b853 5031 {
a3a7f5e1
FS
5032 if (srcelf->size)
5033 {
5034 destelf->size = XNEW (expressionS);
5035 *destelf->size = *srcelf->size;
5036 }
5037 S_SET_SIZE (dest, S_GET_SIZE (src));
8155b853 5038 }
8155b853
NC
5039}
5040
dcd709e0 5041/* RISC-V pseudo-ops table. */
e23eba97
NC
5042static const pseudo_typeS riscv_pseudo_table[] =
5043{
e23eba97
NC
5044 {"option", s_riscv_option, 0},
5045 {"half", cons, 2},
5046 {"word", cons, 4},
5047 {"dword", cons, 8},
5048 {"dtprelword", s_dtprel, 4},
5049 {"dtpreldword", s_dtprel, 8},
5050 {"bss", s_bss, 0},
e23eba97
NC
5051 {"uleb128", s_riscv_leb128, 0},
5052 {"sleb128", s_riscv_leb128, 1},
0e35537d 5053 {"insn", s_riscv_insn, 0},
2dc8dd17 5054 {"attribute", s_riscv_attribute, 0},
8155b853 5055 {"variant_cc", s_variant_cc, 0},
035784e3 5056 {"float16", float_cons, 'h'},
e23eba97
NC
5057
5058 { NULL, NULL, 0 },
5059};
5060
5061void
5062riscv_pop_insert (void)
5063{
5064 extern void pop_insert (const pseudo_typeS *);
5065
5066 pop_insert (riscv_pseudo_table);
5067}