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