1 /* tc-riscv.c -- RISC-V assembler
2 Copyright (C) 2011-2018 Free Software Foundation, Inc.
4 Contributed by Andrew Waterman (andrew@sifive.com).
7 This file is part of GAS.
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)
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.
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/>. */
26 #include "safe-ctype.h"
29 #include "dwarf2dbg.h"
30 #include "dw2gencfi.h"
31 #include "struc-symbol.h"
33 #include "elf/riscv.h"
34 #include "opcode/riscv.h"
38 /* Information about an instruction, including its format, operands
42 /* The opcode's entry in riscv_opcodes. */
43 const struct riscv_opcode
*insn_mo
;
45 /* The encoded instruction bits. */
48 /* The frag that contains the instruction. */
51 /* The offset into FRAG of the first instruction byte. */
54 /* The relocs associated with the instruction, if any. */
59 #define DEFAULT_ARCH "riscv64"
62 static const char default_arch
[] = DEFAULT_ARCH
;
64 static unsigned xlen
= 0; /* width of an x-register */
65 static unsigned abi_xlen
= 0; /* width of a pointer in the ABI */
66 static bfd_boolean rve_abi
= FALSE
;
68 #define LOAD_ADDRESS_INSN (abi_xlen == 64 ? "ld" : "lw")
69 #define ADD32_INSN (xlen == 64 ? "addiw" : "addi")
71 static unsigned elf_flags
= 0;
73 /* This is the set of options which the .option pseudo-op may modify. */
75 struct riscv_set_options
77 int pic
; /* Generate position-independent code. */
78 int rvc
; /* Generate RVC code. */
79 int rve
; /* Generate RVE code. */
80 int relax
; /* Emit relocs the linker is allowed to relax. */
83 static struct riscv_set_options riscv_opts
=
92 riscv_set_rvc (bfd_boolean rvc_value
)
95 elf_flags
|= EF_RISCV_RVC
;
97 riscv_opts
.rvc
= rvc_value
;
101 riscv_set_rve (bfd_boolean rve_value
)
103 riscv_opts
.rve
= rve_value
;
110 struct riscv_subset
*next
;
113 static struct riscv_subset
*riscv_subsets
;
116 riscv_subset_supports (unsigned xlen_required
, const char *feature
)
118 struct riscv_subset
*s
;
120 if (xlen_required
&& xlen
!= xlen_required
)
123 for (s
= riscv_subsets
; s
!= NULL
; s
= s
->next
)
124 if (strcasecmp (s
->name
, feature
) == 0)
131 riscv_multi_subset_supports (unsigned xlen_required
, const char *features
[])
134 bfd_boolean supported
= TRUE
;
136 for (;features
[i
]; ++i
)
137 supported
= supported
&& riscv_subset_supports (xlen_required
, features
[i
]);
143 riscv_clear_subsets (void)
145 while (riscv_subsets
!= NULL
)
147 struct riscv_subset
*next
= riscv_subsets
->next
;
148 free ((void *) riscv_subsets
->name
);
149 free (riscv_subsets
);
150 riscv_subsets
= next
;
155 riscv_add_subset (const char *subset
)
157 struct riscv_subset
*s
= xmalloc (sizeof *s
);
159 s
->name
= xstrdup (subset
);
160 s
->next
= riscv_subsets
;
164 /* Set which ISA and extensions are available. */
167 riscv_set_arch (const char *s
)
169 const char *all_subsets
= "imafdqc";
170 char *extension
= NULL
;
173 riscv_clear_subsets();
175 if (strncmp (p
, "rv32", 4) == 0)
180 else if (strncmp (p
, "rv64", 4) == 0)
186 as_fatal ("-march=%s: ISA string must begin with rv32 or rv64", s
);
195 riscv_add_subset ("e");
196 riscv_add_subset ("i");
199 as_fatal ("-march=%s: rv%de is not a valid base ISA", s
, xlen
);
205 for ( ; *all_subsets
!= 'q'; all_subsets
++)
207 const char subset
[] = {*all_subsets
, '\0'};
208 riscv_add_subset (subset
);
213 as_fatal ("-march=%s: first ISA subset must be `e', `i' or `g'", s
);
220 char *subset
= xstrdup (p
);
223 while (*++q
!= '\0' && *q
!= '_')
228 as_fatal ("-march=%s: only one non-standard extension is supported"
229 " (found `%s' and `%s')", s
, extension
, subset
);
231 riscv_add_subset (subset
);
232 p
+= strlen (subset
);
236 else if ((all_subsets
= strchr (all_subsets
, *p
)) != NULL
)
238 const char subset
[] = {*p
, 0};
239 riscv_add_subset (subset
);
244 as_fatal ("-march=%s: unsupported ISA subset `%c'", s
, *p
);
247 if (riscv_subset_supports (0, "e") && riscv_subset_supports (0, "f"))
248 as_fatal ("-march=%s: rv32e does not support the `f' extension", s
);
250 if (riscv_subset_supports (0, "d") && !riscv_subset_supports (0, "f"))
251 as_fatal ("-march=%s: `d' extension requires `f' extension", s
);
253 if (riscv_subset_supports (0, "q") && !riscv_subset_supports (0, "d"))
254 as_fatal ("-march=%s: `q' extension requires `d' extension", s
);
256 if (riscv_subset_supports (0, "q") && xlen
< 64)
257 as_fatal ("-march=%s: rv32 does not support the `q' extension", s
);
262 /* Handle of the OPCODE hash table. */
263 static struct hash_control
*op_hash
= NULL
;
265 /* Handle of the type of .insn hash table. */
266 static struct hash_control
*insn_type_hash
= NULL
;
268 /* This array holds the chars that always start a comment. If the
269 pre-processor is disabled, these aren't very useful */
270 const char comment_chars
[] = "#";
272 /* This array holds the chars that only start a comment at the beginning of
273 a line. If the line seems to have the form '# 123 filename'
274 .line and .file directives will appear in the pre-processed output */
275 /* Note that input_file.c hand checks for '#' at the beginning of the
276 first line of the input file. This is because the compiler outputs
277 #NO_APP at the beginning of its output. */
278 /* Also note that C style comments are always supported. */
279 const char line_comment_chars
[] = "#";
281 /* This array holds machine specific line separator characters. */
282 const char line_separator_chars
[] = ";";
284 /* Chars that can be used to separate mant from exp in floating point nums */
285 const char EXP_CHARS
[] = "eE";
287 /* Chars that mean this number is a floating point constant */
290 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
292 /* Macros for encoding relaxation state for RVC branches and far jumps. */
293 #define RELAX_BRANCH_ENCODE(uncond, rvc, length) \
296 | ((uncond) ? 1 : 0) \
299 #define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
300 #define RELAX_BRANCH_LENGTH(i) (((i) >> 2) & 0xF)
301 #define RELAX_BRANCH_RVC(i) (((i) & 2) != 0)
302 #define RELAX_BRANCH_UNCOND(i) (((i) & 1) != 0)
304 /* Is the given value a sign-extended 32-bit value? */
305 #define IS_SEXT_32BIT_NUM(x) \
306 (((x) &~ (offsetT) 0x7fffffff) == 0 \
307 || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
309 /* Is the given value a zero-extended 32-bit value? Or a negated one? */
310 #define IS_ZEXT_32BIT_NUM(x) \
311 (((x) &~ (offsetT) 0xffffffff) == 0 \
312 || (((x) &~ (offsetT) 0xffffffff) == ~ (offsetT) 0xffffffff))
314 /* Change INSN's opcode so that the operand given by FIELD has value VALUE.
315 INSN is a riscv_cl_insn structure and VALUE is evaluated exactly once. */
316 #define INSERT_OPERAND(FIELD, INSN, VALUE) \
317 INSERT_BITS ((INSN).insn_opcode, VALUE, OP_MASK_##FIELD, OP_SH_##FIELD)
319 /* Determine if an instruction matches an opcode. */
320 #define OPCODE_MATCHES(OPCODE, OP) \
321 (((OPCODE) & MASK_##OP) == MATCH_##OP)
323 static char *expr_end
;
325 /* The default target format to use. */
328 riscv_target_format (void)
330 return xlen
== 64 ? "elf64-littleriscv" : "elf32-littleriscv";
333 /* Return the length of instruction INSN. */
335 static inline unsigned int
336 insn_length (const struct riscv_cl_insn
*insn
)
338 return riscv_insn_length (insn
->insn_opcode
);
341 /* Initialise INSN from opcode entry MO. Leave its position unspecified. */
344 create_insn (struct riscv_cl_insn
*insn
, const struct riscv_opcode
*mo
)
347 insn
->insn_opcode
= mo
->match
;
353 /* Install INSN at the location specified by its "frag" and "where" fields. */
356 install_insn (const struct riscv_cl_insn
*insn
)
358 char *f
= insn
->frag
->fr_literal
+ insn
->where
;
359 md_number_to_chars (f
, insn
->insn_opcode
, insn_length (insn
));
362 /* Move INSN to offset WHERE in FRAG. Adjust the fixups accordingly
363 and install the opcode in the new location. */
366 move_insn (struct riscv_cl_insn
*insn
, fragS
*frag
, long where
)
370 if (insn
->fixp
!= NULL
)
372 insn
->fixp
->fx_frag
= frag
;
373 insn
->fixp
->fx_where
= where
;
378 /* Add INSN to the end of the output. */
381 add_fixed_insn (struct riscv_cl_insn
*insn
)
383 char *f
= frag_more (insn_length (insn
));
384 move_insn (insn
, frag_now
, f
- frag_now
->fr_literal
);
388 add_relaxed_insn (struct riscv_cl_insn
*insn
, int max_chars
, int var
,
389 relax_substateT subtype
, symbolS
*symbol
, offsetT offset
)
391 frag_grow (max_chars
);
392 move_insn (insn
, frag_now
, frag_more (0) - frag_now
->fr_literal
);
393 frag_var (rs_machine_dependent
, max_chars
, var
,
394 subtype
, symbol
, offset
, NULL
);
397 /* Compute the length of a branch sequence, and adjust the stored length
398 accordingly. If FRAGP is NULL, the worst-case length is returned. */
401 relaxed_branch_length (fragS
*fragp
, asection
*sec
, int update
)
403 int jump
, rvc
, length
= 8;
408 jump
= RELAX_BRANCH_UNCOND (fragp
->fr_subtype
);
409 rvc
= RELAX_BRANCH_RVC (fragp
->fr_subtype
);
410 length
= RELAX_BRANCH_LENGTH (fragp
->fr_subtype
);
412 /* Assume jumps are in range; the linker will catch any that aren't. */
413 length
= jump
? 4 : 8;
415 if (fragp
->fr_symbol
!= NULL
416 && S_IS_DEFINED (fragp
->fr_symbol
)
417 && !S_IS_WEAK (fragp
->fr_symbol
)
418 && sec
== S_GET_SEGMENT (fragp
->fr_symbol
))
420 offsetT val
= S_GET_VALUE (fragp
->fr_symbol
) + fragp
->fr_offset
;
421 bfd_vma rvc_range
= jump
? RVC_JUMP_REACH
: RVC_BRANCH_REACH
;
422 val
-= fragp
->fr_address
+ fragp
->fr_fix
;
424 if (rvc
&& (bfd_vma
)(val
+ rvc_range
/2) < rvc_range
)
426 else if ((bfd_vma
)(val
+ RISCV_BRANCH_REACH
/2) < RISCV_BRANCH_REACH
)
428 else if (!jump
&& rvc
)
433 fragp
->fr_subtype
= RELAX_BRANCH_ENCODE (jump
, rvc
, length
);
438 /* Information about an opcode name, mnemonics and its value. */
445 /* List for all supported opcode name. */
446 static const struct opcode_name_t opcode_name_list
[] =
491 /* Hash table for lookup opcode name. */
492 static struct hash_control
*opcode_names_hash
= NULL
;
494 /* Initialization for hash table of opcode name. */
496 init_opcode_names_hash (void)
499 const struct opcode_name_t
*opcode
;
501 for (opcode
= &opcode_name_list
[0]; opcode
->name
!= NULL
; ++opcode
)
503 retval
= hash_insert (opcode_names_hash
, opcode
->name
, (void *)opcode
);
506 as_fatal (_("internal error: can't hash `%s': %s"),
507 opcode
->name
, retval
);
511 /* Find `s` is a valid opcode name or not,
512 return the opcode name info if found. */
513 static const struct opcode_name_t
*
514 opcode_name_lookup (char **s
)
518 struct opcode_name_t
*o
;
520 /* Find end of name. */
522 if (is_name_beginner (*e
))
524 while (is_part_of_name (*e
))
527 /* Terminate name. */
531 o
= (struct opcode_name_t
*) hash_find (opcode_names_hash
, *s
);
533 /* Advance to next token if one was recognized. */
557 static struct hash_control
*reg_names_hash
= NULL
;
559 #define ENCODE_REG_HASH(cls, n) \
560 ((void *)(uintptr_t)((n) * RCLASS_MAX + (cls) + 1))
561 #define DECODE_REG_CLASS(hash) (((uintptr_t)(hash) - 1) % RCLASS_MAX)
562 #define DECODE_REG_NUM(hash) (((uintptr_t)(hash) - 1) / RCLASS_MAX)
565 hash_reg_name (enum reg_class
class, const char *name
, unsigned n
)
567 void *hash
= ENCODE_REG_HASH (class, n
);
568 const char *retval
= hash_insert (reg_names_hash
, name
, hash
);
571 as_fatal (_("internal error: can't hash `%s': %s"), name
, retval
);
575 hash_reg_names (enum reg_class
class, const char * const names
[], unsigned n
)
579 for (i
= 0; i
< n
; i
++)
580 hash_reg_name (class, names
[i
], i
);
584 reg_lookup_internal (const char *s
, enum reg_class
class)
586 struct regname
*r
= (struct regname
*) hash_find (reg_names_hash
, s
);
588 if (r
== NULL
|| DECODE_REG_CLASS (r
) != class)
591 if (riscv_opts
.rve
&& class == RCLASS_GPR
&& DECODE_REG_NUM (r
) > 15)
594 return DECODE_REG_NUM (r
);
598 reg_lookup (char **s
, enum reg_class
class, unsigned int *regnop
)
604 /* Find end of name. */
606 if (is_name_beginner (*e
))
608 while (is_part_of_name (*e
))
611 /* Terminate name. */
615 /* Look for the register. Advance to next token if one was recognized. */
616 if ((reg
= reg_lookup_internal (*s
, class)) >= 0)
626 arg_lookup (char **s
, const char *const *array
, size_t size
, unsigned *regnop
)
628 const char *p
= strchr (*s
, ',');
629 size_t i
, len
= p
? (size_t)(p
- *s
) : strlen (*s
);
634 for (i
= 0; i
< size
; i
++)
635 if (array
[i
] != NULL
&& strncmp (array
[i
], *s
, len
) == 0)
645 /* For consistency checking, verify that all bits are specified either
646 by the match/mask part of the instruction definition, or by the
649 `length` could be 0, 4 or 8, 0 for auto detection. */
651 validate_riscv_insn (const struct riscv_opcode
*opc
, int length
)
653 const char *p
= opc
->args
;
655 insn_t used_bits
= opc
->mask
;
657 insn_t required_bits
;
660 insn_width
= 8 * riscv_insn_length (opc
->match
);
662 insn_width
= 8 * length
;
664 required_bits
= ~0ULL >> (64 - insn_width
);
666 if ((used_bits
& opc
->match
) != (opc
->match
& required_bits
))
668 as_bad (_("internal: bad RISC-V opcode (mask error): %s %s"),
669 opc
->name
, opc
->args
);
673 #define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift)))
680 case 'a': used_bits
|= ENCODE_RVC_J_IMM (-1U); break;
681 case 'c': break; /* RS1, constrained to equal sp */
682 case 'i': used_bits
|= ENCODE_RVC_SIMM3(-1U); break;
683 case 'j': used_bits
|= ENCODE_RVC_IMM (-1U); break;
684 case 'o': used_bits
|= ENCODE_RVC_IMM (-1U); break;
685 case 'k': used_bits
|= ENCODE_RVC_LW_IMM (-1U); break;
686 case 'l': used_bits
|= ENCODE_RVC_LD_IMM (-1U); break;
687 case 'm': used_bits
|= ENCODE_RVC_LWSP_IMM (-1U); break;
688 case 'n': used_bits
|= ENCODE_RVC_LDSP_IMM (-1U); break;
689 case 'p': used_bits
|= ENCODE_RVC_B_IMM (-1U); break;
690 case 's': USE_BITS (OP_MASK_CRS1S
, OP_SH_CRS1S
); break;
691 case 't': USE_BITS (OP_MASK_CRS2S
, OP_SH_CRS2S
); break;
692 case 'u': used_bits
|= ENCODE_RVC_IMM (-1U); break;
693 case 'v': used_bits
|= ENCODE_RVC_IMM (-1U); break;
694 case 'w': break; /* RS1S, constrained to equal RD */
695 case 'x': break; /* RS2S, constrained to equal RD */
696 case 'K': used_bits
|= ENCODE_RVC_ADDI4SPN_IMM (-1U); break;
697 case 'L': used_bits
|= ENCODE_RVC_ADDI16SP_IMM (-1U); break;
698 case 'M': used_bits
|= ENCODE_RVC_SWSP_IMM (-1U); break;
699 case 'N': used_bits
|= ENCODE_RVC_SDSP_IMM (-1U); break;
700 case 'U': break; /* RS1, constrained to equal RD */
701 case 'V': USE_BITS (OP_MASK_CRS2
, OP_SH_CRS2
); break;
702 case '<': used_bits
|= ENCODE_RVC_IMM (-1U); break;
703 case '>': used_bits
|= ENCODE_RVC_IMM (-1U); break;
704 case '8': used_bits
|= ENCODE_RVC_UIMM8 (-1U); break;
705 case 'S': USE_BITS (OP_MASK_CRS1S
, OP_SH_CRS1S
); break;
706 case 'T': USE_BITS (OP_MASK_CRS2
, OP_SH_CRS2
); break;
707 case 'D': USE_BITS (OP_MASK_CRS2S
, OP_SH_CRS2S
); break;
708 case 'F': /* funct */
711 case '4': USE_BITS (OP_MASK_CFUNCT4
, OP_SH_CFUNCT4
); break;
712 case '3': USE_BITS (OP_MASK_CFUNCT3
, OP_SH_CFUNCT3
); break;
714 as_bad (_("internal: bad RISC-V opcode"
715 " (unknown operand type `CF%c'): %s %s"),
716 c
, opc
->name
, opc
->args
);
721 as_bad (_("internal: bad RISC-V opcode (unknown operand type `C%c'): %s %s"),
722 c
, opc
->name
, opc
->args
);
729 case '<': USE_BITS (OP_MASK_SHAMTW
, OP_SH_SHAMTW
); break;
730 case '>': USE_BITS (OP_MASK_SHAMT
, OP_SH_SHAMT
); break;
732 case 'D': USE_BITS (OP_MASK_RD
, OP_SH_RD
); break;
733 case 'Z': USE_BITS (OP_MASK_RS1
, OP_SH_RS1
); break;
734 case 'E': USE_BITS (OP_MASK_CSR
, OP_SH_CSR
); break;
736 case 'R': USE_BITS (OP_MASK_RS3
, OP_SH_RS3
); break;
737 case 'S': USE_BITS (OP_MASK_RS1
, OP_SH_RS1
); break;
738 case 'U': USE_BITS (OP_MASK_RS1
, OP_SH_RS1
); /* fallthru */
739 case 'T': USE_BITS (OP_MASK_RS2
, OP_SH_RS2
); break;
740 case 'd': USE_BITS (OP_MASK_RD
, OP_SH_RD
); break;
741 case 'm': USE_BITS (OP_MASK_RM
, OP_SH_RM
); break;
742 case 's': USE_BITS (OP_MASK_RS1
, OP_SH_RS1
); break;
743 case 't': USE_BITS (OP_MASK_RS2
, OP_SH_RS2
); break;
744 case 'r': USE_BITS (OP_MASK_RS3
, OP_SH_RS3
); break;
745 case 'P': USE_BITS (OP_MASK_PRED
, OP_SH_PRED
); break;
746 case 'Q': USE_BITS (OP_MASK_SUCC
, OP_SH_SUCC
); break;
748 case 'j': used_bits
|= ENCODE_ITYPE_IMM (-1U); break;
749 case 'a': used_bits
|= ENCODE_UJTYPE_IMM (-1U); break;
750 case 'p': used_bits
|= ENCODE_SBTYPE_IMM (-1U); break;
751 case 'q': used_bits
|= ENCODE_STYPE_IMM (-1U); break;
752 case 'u': used_bits
|= ENCODE_UTYPE_IMM (-1U); break;
757 case 'F': /* funct */
760 case '7': USE_BITS (OP_MASK_FUNCT7
, OP_SH_FUNCT7
); break;
761 case '3': USE_BITS (OP_MASK_FUNCT3
, OP_SH_FUNCT3
); break;
762 case '2': USE_BITS (OP_MASK_FUNCT2
, OP_SH_FUNCT2
); break;
764 as_bad (_("internal: bad RISC-V opcode"
765 " (unknown operand type `F%c'): %s %s"),
766 c
, opc
->name
, opc
->args
);
770 case 'O': /* opcode */
773 case '4': USE_BITS (OP_MASK_OP
, OP_SH_OP
); break;
774 case '2': USE_BITS (OP_MASK_OP2
, OP_SH_OP2
); break;
776 as_bad (_("internal: bad RISC-V opcode"
777 " (unknown operand type `F%c'): %s %s"),
778 c
, opc
->name
, opc
->args
);
783 as_bad (_("internal: bad RISC-V opcode "
784 "(unknown operand type `%c'): %s %s"),
785 c
, opc
->name
, opc
->args
);
789 if (used_bits
!= required_bits
)
791 as_bad (_("internal: bad RISC-V opcode (bits 0x%lx undefined): %s %s"),
792 ~(unsigned long)(used_bits
& required_bits
),
793 opc
->name
, opc
->args
);
799 struct percent_op_match
802 bfd_reloc_code_real_type reloc
;
805 /* Common hash table initialization function for
806 instruction and .insn directive. */
807 static struct hash_control
*
808 init_opcode_hash (const struct riscv_opcode
*opcodes
,
809 bfd_boolean insn_directive_p
)
813 struct hash_control
*hash
= hash_new ();
814 while (opcodes
[i
].name
)
816 const char *name
= opcodes
[i
].name
;
817 const char *hash_error
=
818 hash_insert (hash
, name
, (void *) &opcodes
[i
]);
822 fprintf (stderr
, _("internal error: can't hash `%s': %s\n"),
823 opcodes
[i
].name
, hash_error
);
824 /* Probably a memory allocation problem? Give up now. */
825 as_fatal (_("Broken assembler. No assembly attempted."));
830 if (opcodes
[i
].pinfo
!= INSN_MACRO
)
832 if (insn_directive_p
)
833 length
= ((name
[0] == 'c') ? 2 : 4);
835 length
= 0; /* Let assembler determine the length. */
836 if (!validate_riscv_insn (&opcodes
[i
], length
))
837 as_fatal (_("Broken assembler. No assembly attempted."));
840 gas_assert (!insn_directive_p
);
843 while (opcodes
[i
].name
&& !strcmp (opcodes
[i
].name
, name
));
849 /* This function is called once, at assembler startup time. It should set up
850 all the tables, etc. that the MD part of the assembler will need. */
855 unsigned long mach
= xlen
== 64 ? bfd_mach_riscv64
: bfd_mach_riscv32
;
857 if (! bfd_set_arch_mach (stdoutput
, bfd_arch_riscv
, mach
))
858 as_warn (_("Could not set architecture and machine"));
860 op_hash
= init_opcode_hash (riscv_opcodes
, FALSE
);
861 insn_type_hash
= init_opcode_hash (riscv_insn_types
, TRUE
);
863 reg_names_hash
= hash_new ();
864 hash_reg_names (RCLASS_GPR
, riscv_gpr_names_numeric
, NGPR
);
865 hash_reg_names (RCLASS_GPR
, riscv_gpr_names_abi
, NGPR
);
866 hash_reg_names (RCLASS_FPR
, riscv_fpr_names_numeric
, NFPR
);
867 hash_reg_names (RCLASS_FPR
, riscv_fpr_names_abi
, NFPR
);
869 /* Add "fp" as an alias for "s0". */
870 hash_reg_name (RCLASS_GPR
, "fp", 8);
872 opcode_names_hash
= hash_new ();
873 init_opcode_names_hash ();
875 #define DECLARE_CSR(name, num) hash_reg_name (RCLASS_CSR, #name, num);
876 #define DECLARE_CSR_ALIAS(name, num) DECLARE_CSR(name, num);
877 #include "opcode/riscv-opc.h"
880 /* Set the default alignment for the text section. */
881 record_alignment (text_section
, riscv_opts
.rvc
? 1 : 2);
885 riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type
, bfd_vma value
)
892 case BFD_RELOC_RISCV_HI20
:
893 return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value
));
895 case BFD_RELOC_RISCV_LO12_S
:
896 return ENCODE_STYPE_IMM (value
);
898 case BFD_RELOC_RISCV_LO12_I
:
899 return ENCODE_ITYPE_IMM (value
);
906 /* Output an instruction. IP is the instruction information.
907 ADDRESS_EXPR is an operand of the instruction to be used with
911 append_insn (struct riscv_cl_insn
*ip
, expressionS
*address_expr
,
912 bfd_reloc_code_real_type reloc_type
)
914 dwarf2_emit_insn (0);
916 if (reloc_type
!= BFD_RELOC_UNUSED
)
918 reloc_howto_type
*howto
;
920 gas_assert (address_expr
);
921 if (reloc_type
== BFD_RELOC_12_PCREL
922 || reloc_type
== BFD_RELOC_RISCV_JMP
)
924 int j
= reloc_type
== BFD_RELOC_RISCV_JMP
;
925 int best_case
= riscv_insn_length (ip
->insn_opcode
);
926 unsigned worst_case
= relaxed_branch_length (NULL
, NULL
, 0);
927 add_relaxed_insn (ip
, worst_case
, best_case
,
928 RELAX_BRANCH_ENCODE (j
, best_case
== 2, worst_case
),
929 address_expr
->X_add_symbol
,
930 address_expr
->X_add_number
);
935 howto
= bfd_reloc_type_lookup (stdoutput
, reloc_type
);
937 as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type
);
939 ip
->fixp
= fix_new_exp (ip
->frag
, ip
->where
,
940 bfd_get_reloc_size (howto
),
941 address_expr
, FALSE
, reloc_type
);
943 ip
->fixp
->fx_tcbit
= riscv_opts
.relax
;
950 /* We need to start a new frag after any instruction that can be
951 optimized away or compressed by the linker during relaxation, to prevent
952 the assembler from computing static offsets across such an instruction.
953 This is necessary to get correct EH info. */
954 if (reloc_type
== BFD_RELOC_RISCV_CALL
955 || reloc_type
== BFD_RELOC_RISCV_CALL_PLT
956 || reloc_type
== BFD_RELOC_RISCV_HI20
957 || reloc_type
== BFD_RELOC_RISCV_PCREL_HI20
958 || reloc_type
== BFD_RELOC_RISCV_TPREL_HI20
959 || reloc_type
== BFD_RELOC_RISCV_TPREL_ADD
)
961 frag_wane (frag_now
);
966 /* Build an instruction created by a macro expansion. This is passed
967 a pointer to the count of instructions created so far, an
968 expression, the name of the instruction to build, an operand format
969 string, and corresponding arguments. */
972 macro_build (expressionS
*ep
, const char *name
, const char *fmt
, ...)
974 const struct riscv_opcode
*mo
;
975 struct riscv_cl_insn insn
;
976 bfd_reloc_code_real_type r
;
979 va_start (args
, fmt
);
981 r
= BFD_RELOC_UNUSED
;
982 mo
= (struct riscv_opcode
*) hash_find (op_hash
, name
);
985 /* Find a non-RVC variant of the instruction. append_insn will compress
987 while (riscv_insn_length (mo
->match
) < 4)
989 gas_assert (strcmp (name
, mo
->name
) == 0);
991 create_insn (&insn
, mo
);
997 INSERT_OPERAND (RD
, insn
, va_arg (args
, int));
1001 INSERT_OPERAND (RS1
, insn
, va_arg (args
, int));
1005 INSERT_OPERAND (RS2
, insn
, va_arg (args
, int));
1009 INSERT_OPERAND (SHAMT
, insn
, va_arg (args
, int));
1015 gas_assert (ep
!= NULL
);
1016 r
= va_arg (args
, int);
1024 as_fatal (_("internal error: invalid macro"));
1029 gas_assert (r
== BFD_RELOC_UNUSED
? ep
== NULL
: ep
!= NULL
);
1031 append_insn (&insn
, ep
, r
);
1034 /* Sign-extend 32-bit mode constants that have bit 31 set and all higher bits
1037 normalize_constant_expr (expressionS
*ex
)
1041 if ((ex
->X_op
== O_constant
|| ex
->X_op
== O_symbol
)
1042 && IS_ZEXT_32BIT_NUM (ex
->X_add_number
))
1043 ex
->X_add_number
= (((ex
->X_add_number
& 0xffffffff) ^ 0x80000000)
1047 /* Fail if an expression EX is not a constant. IP is the instruction using EX.
1048 MAYBE_CSR is true if the symbol may be an unrecognized CSR name. */
1051 check_absolute_expr (struct riscv_cl_insn
*ip
, expressionS
*ex
,
1052 bfd_boolean maybe_csr
)
1054 if (ex
->X_op
== O_big
)
1055 as_bad (_("unsupported large constant"));
1056 else if (maybe_csr
&& ex
->X_op
== O_symbol
)
1057 as_bad (_("unknown CSR `%s'"),
1058 S_GET_NAME (ex
->X_add_symbol
));
1059 else if (ex
->X_op
!= O_constant
)
1060 as_bad (_("Instruction %s requires absolute expression"),
1062 normalize_constant_expr (ex
);
1066 make_internal_label (void)
1068 return (symbolS
*) local_symbol_make (FAKE_LABEL_NAME
, now_seg
,
1069 (valueT
) frag_now_fix (), frag_now
);
1072 /* Load an entry from the GOT. */
1074 pcrel_access (int destreg
, int tempreg
, expressionS
*ep
,
1075 const char *lo_insn
, const char *lo_pattern
,
1076 bfd_reloc_code_real_type hi_reloc
,
1077 bfd_reloc_code_real_type lo_reloc
)
1080 ep2
.X_op
= O_symbol
;
1081 ep2
.X_add_symbol
= make_internal_label ();
1082 ep2
.X_add_number
= 0;
1084 macro_build (ep
, "auipc", "d,u", tempreg
, hi_reloc
);
1085 macro_build (&ep2
, lo_insn
, lo_pattern
, destreg
, tempreg
, lo_reloc
);
1089 pcrel_load (int destreg
, int tempreg
, expressionS
*ep
, const char *lo_insn
,
1090 bfd_reloc_code_real_type hi_reloc
,
1091 bfd_reloc_code_real_type lo_reloc
)
1093 pcrel_access (destreg
, tempreg
, ep
, lo_insn
, "d,s,j", hi_reloc
, lo_reloc
);
1097 pcrel_store (int srcreg
, int tempreg
, expressionS
*ep
, const char *lo_insn
,
1098 bfd_reloc_code_real_type hi_reloc
,
1099 bfd_reloc_code_real_type lo_reloc
)
1101 pcrel_access (srcreg
, tempreg
, ep
, lo_insn
, "t,s,q", hi_reloc
, lo_reloc
);
1104 /* PC-relative function call using AUIPC/JALR, relaxed to JAL. */
1106 riscv_call (int destreg
, int tempreg
, expressionS
*ep
,
1107 bfd_reloc_code_real_type reloc
)
1109 macro_build (ep
, "auipc", "d,u", tempreg
, reloc
);
1110 macro_build (NULL
, "jalr", "d,s", destreg
, tempreg
);
1113 /* Load an integer constant into a register. */
1116 load_const (int reg
, expressionS
*ep
)
1118 int shift
= RISCV_IMM_BITS
;
1119 expressionS upper
= *ep
, lower
= *ep
;
1120 lower
.X_add_number
= (int32_t) ep
->X_add_number
<< (32-shift
) >> (32-shift
);
1121 upper
.X_add_number
-= lower
.X_add_number
;
1123 if (ep
->X_op
!= O_constant
)
1125 as_bad (_("unsupported large constant"));
1129 if (xlen
> 32 && !IS_SEXT_32BIT_NUM (ep
->X_add_number
))
1131 /* Reduce to a signed 32-bit constant using SLLI and ADDI. */
1132 while (((upper
.X_add_number
>> shift
) & 1) == 0)
1135 upper
.X_add_number
= (int64_t) upper
.X_add_number
>> shift
;
1136 load_const (reg
, &upper
);
1138 macro_build (NULL
, "slli", "d,s,>", reg
, reg
, shift
);
1139 if (lower
.X_add_number
!= 0)
1140 macro_build (&lower
, "addi", "d,s,j", reg
, reg
, BFD_RELOC_RISCV_LO12_I
);
1144 /* Simply emit LUI and/or ADDI to build a 32-bit signed constant. */
1147 if (upper
.X_add_number
!= 0)
1149 macro_build (ep
, "lui", "d,u", reg
, BFD_RELOC_RISCV_HI20
);
1153 if (lower
.X_add_number
!= 0 || hi_reg
== 0)
1154 macro_build (ep
, ADD32_INSN
, "d,s,j", reg
, hi_reg
,
1155 BFD_RELOC_RISCV_LO12_I
);
1159 /* Expand RISC-V assembly macros into one or more instructions. */
1161 macro (struct riscv_cl_insn
*ip
, expressionS
*imm_expr
,
1162 bfd_reloc_code_real_type
*imm_reloc
)
1164 int rd
= (ip
->insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
;
1165 int rs1
= (ip
->insn_opcode
>> OP_SH_RS1
) & OP_MASK_RS1
;
1166 int rs2
= (ip
->insn_opcode
>> OP_SH_RS2
) & OP_MASK_RS2
;
1167 int mask
= ip
->insn_mo
->mask
;
1172 load_const (rd
, imm_expr
);
1177 /* Load the address of a symbol into a register. */
1178 if (!IS_SEXT_32BIT_NUM (imm_expr
->X_add_number
))
1179 as_bad (_("offset too large"));
1181 if (imm_expr
->X_op
== O_constant
)
1182 load_const (rd
, imm_expr
);
1183 else if (riscv_opts
.pic
&& mask
== M_LA
) /* Global PIC symbol */
1184 pcrel_load (rd
, rd
, imm_expr
, LOAD_ADDRESS_INSN
,
1185 BFD_RELOC_RISCV_GOT_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1186 else /* Local PIC symbol, or any non-PIC symbol */
1187 pcrel_load (rd
, rd
, imm_expr
, "addi",
1188 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1192 pcrel_load (rd
, rd
, imm_expr
, "addi",
1193 BFD_RELOC_RISCV_TLS_GD_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1197 pcrel_load (rd
, rd
, imm_expr
, LOAD_ADDRESS_INSN
,
1198 BFD_RELOC_RISCV_TLS_GOT_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1202 pcrel_load (rd
, rd
, imm_expr
, "lb",
1203 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1207 pcrel_load (rd
, rd
, imm_expr
, "lbu",
1208 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1212 pcrel_load (rd
, rd
, imm_expr
, "lh",
1213 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1217 pcrel_load (rd
, rd
, imm_expr
, "lhu",
1218 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1222 pcrel_load (rd
, rd
, imm_expr
, "lw",
1223 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1227 pcrel_load (rd
, rd
, imm_expr
, "lwu",
1228 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1232 pcrel_load (rd
, rd
, imm_expr
, "ld",
1233 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1237 pcrel_load (rd
, rs1
, imm_expr
, "flw",
1238 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1242 pcrel_load (rd
, rs1
, imm_expr
, "fld",
1243 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1247 pcrel_store (rs2
, rs1
, imm_expr
, "sb",
1248 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1252 pcrel_store (rs2
, rs1
, imm_expr
, "sh",
1253 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1257 pcrel_store (rs2
, rs1
, imm_expr
, "sw",
1258 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1262 pcrel_store (rs2
, rs1
, imm_expr
, "sd",
1263 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1267 pcrel_store (rs2
, rs1
, imm_expr
, "fsw",
1268 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1272 pcrel_store (rs2
, rs1
, imm_expr
, "fsd",
1273 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1277 riscv_call (rd
, rs1
, imm_expr
, *imm_reloc
);
1281 as_bad (_("Macro %s not implemented"), ip
->insn_mo
->name
);
1286 static const struct percent_op_match percent_op_utype
[] =
1288 {"%tprel_hi", BFD_RELOC_RISCV_TPREL_HI20
},
1289 {"%pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20
},
1290 {"%tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20
},
1291 {"%tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20
},
1292 {"%hi", BFD_RELOC_RISCV_HI20
},
1296 static const struct percent_op_match percent_op_itype
[] =
1298 {"%lo", BFD_RELOC_RISCV_LO12_I
},
1299 {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I
},
1300 {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I
},
1304 static const struct percent_op_match percent_op_stype
[] =
1306 {"%lo", BFD_RELOC_RISCV_LO12_S
},
1307 {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_S
},
1308 {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_S
},
1312 static const struct percent_op_match percent_op_rtype
[] =
1314 {"%tprel_add", BFD_RELOC_RISCV_TPREL_ADD
},
1318 /* Return true if *STR points to a relocation operator. When returning true,
1319 move *STR over the operator and store its relocation code in *RELOC.
1320 Leave both *STR and *RELOC alone when returning false. */
1323 parse_relocation (char **str
, bfd_reloc_code_real_type
*reloc
,
1324 const struct percent_op_match
*percent_op
)
1326 for ( ; percent_op
->str
; percent_op
++)
1327 if (strncasecmp (*str
, percent_op
->str
, strlen (percent_op
->str
)) == 0)
1329 int len
= strlen (percent_op
->str
);
1331 if (!ISSPACE ((*str
)[len
]) && (*str
)[len
] != '(')
1334 *str
+= strlen (percent_op
->str
);
1335 *reloc
= percent_op
->reloc
;
1337 /* Check whether the output BFD supports this relocation.
1338 If not, issue an error and fall back on something safe. */
1339 if (*reloc
!= BFD_RELOC_UNUSED
1340 && !bfd_reloc_type_lookup (stdoutput
, *reloc
))
1342 as_bad ("relocation %s isn't supported by the current ABI",
1344 *reloc
= BFD_RELOC_UNUSED
;
1352 my_getExpression (expressionS
*ep
, char *str
)
1356 save_in
= input_line_pointer
;
1357 input_line_pointer
= str
;
1359 expr_end
= input_line_pointer
;
1360 input_line_pointer
= save_in
;
1363 /* Parse string STR as a 16-bit relocatable operand. Store the
1364 expression in *EP and the relocation, if any, in RELOC.
1365 Return the number of relocation operators used (0 or 1).
1367 On exit, EXPR_END points to the first character after the expression. */
1370 my_getSmallExpression (expressionS
*ep
, bfd_reloc_code_real_type
*reloc
,
1371 char *str
, const struct percent_op_match
*percent_op
)
1374 unsigned crux_depth
, str_depth
, regno
;
1377 /* First, check for integer registers. */
1378 if (reg_lookup (&str
, RCLASS_GPR
, ®no
))
1380 ep
->X_op
= O_register
;
1381 ep
->X_add_number
= regno
;
1385 /* Search for the start of the main expression.
1386 End the loop with CRUX pointing to the start
1387 of the main expression and with CRUX_DEPTH containing the number
1388 of open brackets at that point. */
1395 crux_depth
= str_depth
;
1397 /* Skip over whitespace and brackets, keeping count of the number
1399 while (*str
== ' ' || *str
== '\t' || *str
== '(')
1405 && parse_relocation (&str
, reloc
, percent_op
));
1407 my_getExpression (ep
, crux
);
1410 /* Match every open bracket. */
1411 while (crux_depth
> 0 && (*str
== ')' || *str
== ' ' || *str
== '\t'))
1416 as_bad ("unclosed '('");
1423 /* Parse opcode name, could be an mnemonics or number. */
1425 my_getOpcodeExpression (expressionS
*ep
, bfd_reloc_code_real_type
*reloc
,
1426 char *str
, const struct percent_op_match
*percent_op
)
1428 const struct opcode_name_t
*o
= opcode_name_lookup (&str
);
1432 ep
->X_op
= O_constant
;
1433 ep
->X_add_number
= o
->val
;
1437 return my_getSmallExpression (ep
, reloc
, str
, percent_op
);
1440 /* Detect and handle implicitly zero load-store offsets. For example,
1441 "lw t0, (t1)" is shorthand for "lw t0, 0(t1)". Return TRUE iff such
1442 an implicit offset was detected. */
1445 riscv_handle_implicit_zero_offset (expressionS
*ep
, const char *s
)
1447 /* Check whether there is only a single bracketed expression left.
1448 If so, it must be the base register and the constant must be zero. */
1449 if (*s
== '(' && strchr (s
+ 1, '(') == 0)
1451 ep
->X_op
= O_constant
;
1452 ep
->X_add_number
= 0;
1459 /* This routine assembles an instruction into its binary format. As a
1460 side effect, it sets the global variable imm_reloc to the type of
1461 relocation to do if one of the operands is an address expression. */
1464 riscv_ip (char *str
, struct riscv_cl_insn
*ip
, expressionS
*imm_expr
,
1465 bfd_reloc_code_real_type
*imm_reloc
, struct hash_control
*hash
)
1470 struct riscv_opcode
*insn
;
1475 const struct percent_op_match
*p
;
1476 const char *error
= "unrecognized opcode";
1478 /* Parse the name of the instruction. Terminate the string if whitespace
1479 is found so that hash_find only sees the name part of the string. */
1480 for (s
= str
; *s
!= '\0'; ++s
)
1488 insn
= (struct riscv_opcode
*) hash_find (hash
, str
);
1491 for ( ; insn
&& insn
->name
&& strcmp (insn
->name
, str
) == 0; insn
++)
1493 if (!riscv_multi_subset_supports (insn
->xlen_requirement
, insn
->subset
))
1496 create_insn (ip
, insn
);
1499 imm_expr
->X_op
= O_absent
;
1500 *imm_reloc
= BFD_RELOC_UNUSED
;
1501 p
= percent_op_itype
;
1503 for (args
= insn
->args
;; ++args
)
1505 s
+= strspn (s
, " \t");
1508 case '\0': /* End of args. */
1509 if (insn
->pinfo
!= INSN_MACRO
)
1511 if (!insn
->match_func (insn
, ip
->insn_opcode
))
1514 /* For .insn, insn->match and insn->mask are 0. */
1515 if (riscv_insn_length ((insn
->match
== 0 && insn
->mask
== 0)
1523 /* Successful assembly. */
1530 case 's': /* RS1 x8-x15 */
1531 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1532 || !(regno
>= 8 && regno
<= 15))
1534 INSERT_OPERAND (CRS1S
, *ip
, regno
% 8);
1536 case 'w': /* RS1 x8-x15, constrained to equal RD x8-x15. */
1537 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1538 || EXTRACT_OPERAND (CRS1S
, ip
->insn_opcode
) + 8 != regno
)
1541 case 't': /* RS2 x8-x15 */
1542 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1543 || !(regno
>= 8 && regno
<= 15))
1545 INSERT_OPERAND (CRS2S
, *ip
, regno
% 8);
1547 case 'x': /* RS2 x8-x15, constrained to equal RD x8-x15. */
1548 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1549 || EXTRACT_OPERAND (CRS2S
, ip
->insn_opcode
) + 8 != regno
)
1552 case 'U': /* RS1, constrained to equal RD. */
1553 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1554 || EXTRACT_OPERAND (RD
, ip
->insn_opcode
) != regno
)
1558 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
))
1560 INSERT_OPERAND (CRS2
, *ip
, regno
);
1562 case 'c': /* RS1, constrained to equal sp. */
1563 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1568 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1569 || imm_expr
->X_op
!= O_constant
1570 || imm_expr
->X_add_number
<= 0
1571 || imm_expr
->X_add_number
>= 64)
1573 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1576 imm_expr
->X_op
= O_absent
;
1579 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1580 || imm_expr
->X_op
!= O_constant
1581 || !VALID_RVC_IMM (imm_expr
->X_add_number
)
1582 || imm_expr
->X_add_number
<= 0
1583 || imm_expr
->X_add_number
>= 32)
1585 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1588 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1589 || imm_expr
->X_op
!= O_constant
1590 || !VALID_RVC_UIMM8 (imm_expr
->X_add_number
)
1591 || imm_expr
->X_add_number
< 0
1592 || imm_expr
->X_add_number
>= 256)
1594 ip
->insn_opcode
|= ENCODE_RVC_UIMM8 (imm_expr
->X_add_number
);
1597 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1598 || imm_expr
->X_op
!= O_constant
1599 || imm_expr
->X_add_number
== 0
1600 || !VALID_RVC_SIMM3 (imm_expr
->X_add_number
))
1602 ip
->insn_opcode
|= ENCODE_RVC_SIMM3 (imm_expr
->X_add_number
);
1605 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1606 || imm_expr
->X_op
!= O_constant
1607 || imm_expr
->X_add_number
== 0
1608 || !VALID_RVC_IMM (imm_expr
->X_add_number
))
1610 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1613 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1615 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1616 || imm_expr
->X_op
!= O_constant
1617 || !VALID_RVC_LW_IMM (imm_expr
->X_add_number
))
1619 ip
->insn_opcode
|= ENCODE_RVC_LW_IMM (imm_expr
->X_add_number
);
1622 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1624 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1625 || imm_expr
->X_op
!= O_constant
1626 || !VALID_RVC_LD_IMM (imm_expr
->X_add_number
))
1628 ip
->insn_opcode
|= ENCODE_RVC_LD_IMM (imm_expr
->X_add_number
);
1631 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1633 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1634 || imm_expr
->X_op
!= O_constant
1635 || !VALID_RVC_LWSP_IMM (imm_expr
->X_add_number
))
1638 ENCODE_RVC_LWSP_IMM (imm_expr
->X_add_number
);
1641 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1643 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1644 || imm_expr
->X_op
!= O_constant
1645 || !VALID_RVC_LDSP_IMM (imm_expr
->X_add_number
))
1648 ENCODE_RVC_LDSP_IMM (imm_expr
->X_add_number
);
1651 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1652 || imm_expr
->X_op
!= O_constant
1653 /* C.addiw, c.li, and c.andi allow zero immediate.
1654 C.addi allows zero immediate as hint. Otherwise this
1656 || !VALID_RVC_IMM (imm_expr
->X_add_number
))
1658 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1661 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1662 || imm_expr
->X_op
!= O_constant
1663 || !VALID_RVC_ADDI4SPN_IMM (imm_expr
->X_add_number
)
1664 || imm_expr
->X_add_number
== 0)
1667 ENCODE_RVC_ADDI4SPN_IMM (imm_expr
->X_add_number
);
1670 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1671 || imm_expr
->X_op
!= O_constant
1672 || !VALID_RVC_ADDI16SP_IMM (imm_expr
->X_add_number
)
1673 || imm_expr
->X_add_number
== 0)
1676 ENCODE_RVC_ADDI16SP_IMM (imm_expr
->X_add_number
);
1679 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1681 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1682 || imm_expr
->X_op
!= O_constant
1683 || !VALID_RVC_SWSP_IMM (imm_expr
->X_add_number
))
1686 ENCODE_RVC_SWSP_IMM (imm_expr
->X_add_number
);
1689 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1691 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1692 || imm_expr
->X_op
!= O_constant
1693 || !VALID_RVC_SDSP_IMM (imm_expr
->X_add_number
))
1696 ENCODE_RVC_SDSP_IMM (imm_expr
->X_add_number
);
1699 p
= percent_op_utype
;
1700 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
))
1703 if (imm_expr
->X_op
!= O_constant
1704 || imm_expr
->X_add_number
<= 0
1705 || imm_expr
->X_add_number
>= RISCV_BIGIMM_REACH
1706 || (imm_expr
->X_add_number
>= RISCV_RVC_IMM_REACH
/ 2
1707 && (imm_expr
->X_add_number
<
1708 RISCV_BIGIMM_REACH
- RISCV_RVC_IMM_REACH
/ 2)))
1710 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1713 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1714 || (imm_expr
->X_add_number
& (RISCV_IMM_REACH
- 1))
1715 || ((int32_t)imm_expr
->X_add_number
1716 != imm_expr
->X_add_number
))
1718 imm_expr
->X_add_number
=
1719 ((uint32_t) imm_expr
->X_add_number
) >> RISCV_IMM_BITS
;
1725 case 'S': /* Floating-point RS1 x8-x15. */
1726 if (!reg_lookup (&s
, RCLASS_FPR
, ®no
)
1727 || !(regno
>= 8 && regno
<= 15))
1729 INSERT_OPERAND (CRS1S
, *ip
, regno
% 8);
1731 case 'D': /* Floating-point RS2 x8-x15. */
1732 if (!reg_lookup (&s
, RCLASS_FPR
, ®no
)
1733 || !(regno
>= 8 && regno
<= 15))
1735 INSERT_OPERAND (CRS2S
, *ip
, regno
% 8);
1737 case 'T': /* Floating-point RS2. */
1738 if (!reg_lookup (&s
, RCLASS_FPR
, ®no
))
1740 INSERT_OPERAND (CRS2
, *ip
, regno
);
1746 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1747 || imm_expr
->X_op
!= O_constant
1748 || imm_expr
->X_add_number
< 0
1749 || imm_expr
->X_add_number
>= 16)
1751 as_bad (_("bad value for funct4 field, "
1752 "value must be 0...15"));
1756 INSERT_OPERAND (CFUNCT4
, *ip
, imm_expr
->X_add_number
);
1757 imm_expr
->X_op
= O_absent
;
1761 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1762 || imm_expr
->X_op
!= O_constant
1763 || imm_expr
->X_add_number
< 0
1764 || imm_expr
->X_add_number
>= 8)
1766 as_bad (_("bad value for funct3 field, "
1767 "value must be 0...7"));
1770 INSERT_OPERAND (CFUNCT3
, *ip
, imm_expr
->X_add_number
);
1771 imm_expr
->X_op
= O_absent
;
1775 as_bad (_("bad compressed FUNCT field"
1776 " specifier 'CF%c'\n"),
1782 as_bad (_("bad RVC field specifier 'C%c'\n"), *args
);
1801 case '<': /* Shift amount, 0 - 31. */
1802 my_getExpression (imm_expr
, s
);
1803 check_absolute_expr (ip
, imm_expr
, FALSE
);
1804 if ((unsigned long) imm_expr
->X_add_number
> 31)
1805 as_bad (_("Improper shift amount (%lu)"),
1806 (unsigned long) imm_expr
->X_add_number
);
1807 INSERT_OPERAND (SHAMTW
, *ip
, imm_expr
->X_add_number
);
1808 imm_expr
->X_op
= O_absent
;
1812 case '>': /* Shift amount, 0 - (XLEN-1). */
1813 my_getExpression (imm_expr
, s
);
1814 check_absolute_expr (ip
, imm_expr
, FALSE
);
1815 if ((unsigned long) imm_expr
->X_add_number
>= xlen
)
1816 as_bad (_("Improper shift amount (%lu)"),
1817 (unsigned long) imm_expr
->X_add_number
);
1818 INSERT_OPERAND (SHAMT
, *ip
, imm_expr
->X_add_number
);
1819 imm_expr
->X_op
= O_absent
;
1823 case 'Z': /* CSRRxI immediate. */
1824 my_getExpression (imm_expr
, s
);
1825 check_absolute_expr (ip
, imm_expr
, FALSE
);
1826 if ((unsigned long) imm_expr
->X_add_number
> 31)
1827 as_bad (_("Improper CSRxI immediate (%lu)"),
1828 (unsigned long) imm_expr
->X_add_number
);
1829 INSERT_OPERAND (RS1
, *ip
, imm_expr
->X_add_number
);
1830 imm_expr
->X_op
= O_absent
;
1834 case 'E': /* Control register. */
1835 if (reg_lookup (&s
, RCLASS_CSR
, ®no
))
1836 INSERT_OPERAND (CSR
, *ip
, regno
);
1839 my_getExpression (imm_expr
, s
);
1840 check_absolute_expr (ip
, imm_expr
, TRUE
);
1841 if ((unsigned long) imm_expr
->X_add_number
> 0xfff)
1842 as_bad (_("Improper CSR address (%lu)"),
1843 (unsigned long) imm_expr
->X_add_number
);
1844 INSERT_OPERAND (CSR
, *ip
, imm_expr
->X_add_number
);
1845 imm_expr
->X_op
= O_absent
;
1850 case 'm': /* Rounding mode. */
1851 if (arg_lookup (&s
, riscv_rm
, ARRAY_SIZE (riscv_rm
), ®no
))
1853 INSERT_OPERAND (RM
, *ip
, regno
);
1859 case 'Q': /* Fence predecessor/successor. */
1860 if (arg_lookup (&s
, riscv_pred_succ
, ARRAY_SIZE (riscv_pred_succ
),
1864 INSERT_OPERAND (PRED
, *ip
, regno
);
1866 INSERT_OPERAND (SUCC
, *ip
, regno
);
1871 case 'd': /* Destination register. */
1872 case 's': /* Source register. */
1873 case 't': /* Target register. */
1874 case 'r': /* rs3. */
1875 if (reg_lookup (&s
, RCLASS_GPR
, ®no
))
1881 /* Now that we have assembled one operand, we use the args
1882 string to figure out where it goes in the instruction. */
1886 INSERT_OPERAND (RS1
, *ip
, regno
);
1889 INSERT_OPERAND (RD
, *ip
, regno
);
1892 INSERT_OPERAND (RS2
, *ip
, regno
);
1895 INSERT_OPERAND (RS3
, *ip
, regno
);
1902 case 'D': /* Floating point rd. */
1903 case 'S': /* Floating point rs1. */
1904 case 'T': /* Floating point rs2. */
1905 case 'U': /* Floating point rs1 and rs2. */
1906 case 'R': /* Floating point rs3. */
1907 if (reg_lookup (&s
, RCLASS_FPR
, ®no
))
1915 INSERT_OPERAND (RD
, *ip
, regno
);
1918 INSERT_OPERAND (RS1
, *ip
, regno
);
1921 INSERT_OPERAND (RS1
, *ip
, regno
);
1924 INSERT_OPERAND (RS2
, *ip
, regno
);
1927 INSERT_OPERAND (RS3
, *ip
, regno
);
1936 my_getExpression (imm_expr
, s
);
1937 if (imm_expr
->X_op
!= O_big
1938 && imm_expr
->X_op
!= O_constant
)
1940 normalize_constant_expr (imm_expr
);
1945 my_getExpression (imm_expr
, s
);
1946 normalize_constant_expr (imm_expr
);
1947 /* The 'A' format specifier must be a symbol. */
1948 if (imm_expr
->X_op
!= O_symbol
)
1950 *imm_reloc
= BFD_RELOC_32
;
1955 my_getExpression (imm_expr
, s
);
1956 normalize_constant_expr (imm_expr
);
1957 /* The 'B' format specifier must be a symbol or a constant. */
1958 if (imm_expr
->X_op
!= O_symbol
&& imm_expr
->X_op
!= O_constant
)
1960 if (imm_expr
->X_op
== O_symbol
)
1961 *imm_reloc
= BFD_RELOC_32
;
1965 case 'j': /* Sign-extended immediate. */
1966 *imm_reloc
= BFD_RELOC_RISCV_LO12_I
;
1967 p
= percent_op_itype
;
1969 case 'q': /* Store displacement. */
1970 p
= percent_op_stype
;
1971 *imm_reloc
= BFD_RELOC_RISCV_LO12_S
;
1973 case 'o': /* Load displacement. */
1974 p
= percent_op_itype
;
1975 *imm_reloc
= BFD_RELOC_RISCV_LO12_I
;
1977 case '0': /* AMO "displacement," which must be zero. */
1978 p
= percent_op_rtype
;
1979 *imm_reloc
= BFD_RELOC_UNUSED
;
1981 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1984 /* If this value won't fit into a 16 bit offset, then go
1985 find a macro that will generate the 32 bit offset
1987 if (!my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
))
1989 normalize_constant_expr (imm_expr
);
1990 if (imm_expr
->X_op
!= O_constant
1991 || (*args
== '0' && imm_expr
->X_add_number
!= 0)
1992 || imm_expr
->X_add_number
>= (signed)RISCV_IMM_REACH
/2
1993 || imm_expr
->X_add_number
< -(signed)RISCV_IMM_REACH
/2)
2000 case 'p': /* PC-relative offset. */
2002 *imm_reloc
= BFD_RELOC_12_PCREL
;
2003 my_getExpression (imm_expr
, s
);
2007 case 'u': /* Upper 20 bits. */
2008 p
= percent_op_utype
;
2009 if (!my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2010 && imm_expr
->X_op
== O_constant
)
2012 if (imm_expr
->X_add_number
< 0
2013 || imm_expr
->X_add_number
>= (signed)RISCV_BIGIMM_REACH
)
2014 as_bad (_("lui expression not in range 0..1048575"));
2016 *imm_reloc
= BFD_RELOC_RISCV_HI20
;
2017 imm_expr
->X_add_number
<<= RISCV_IMM_BITS
;
2022 case 'a': /* 20-bit PC-relative offset. */
2024 my_getExpression (imm_expr
, s
);
2026 *imm_reloc
= BFD_RELOC_RISCV_JMP
;
2030 my_getExpression (imm_expr
, s
);
2032 if (strcmp (s
, "@plt") == 0)
2034 *imm_reloc
= BFD_RELOC_RISCV_CALL_PLT
;
2038 *imm_reloc
= BFD_RELOC_RISCV_CALL
;
2044 if (my_getOpcodeExpression (imm_expr
, imm_reloc
, s
, p
)
2045 || imm_expr
->X_op
!= O_constant
2046 || imm_expr
->X_add_number
< 0
2047 || imm_expr
->X_add_number
>= 128
2048 || (imm_expr
->X_add_number
& 0x3) != 3)
2050 as_bad (_("bad value for opcode field, "
2051 "value must be 0...127 and "
2052 "lower 2 bits must be 0x3"));
2056 INSERT_OPERAND (OP
, *ip
, imm_expr
->X_add_number
);
2057 imm_expr
->X_op
= O_absent
;
2061 if (my_getOpcodeExpression (imm_expr
, imm_reloc
, s
, p
)
2062 || imm_expr
->X_op
!= O_constant
2063 || imm_expr
->X_add_number
< 0
2064 || imm_expr
->X_add_number
>= 3)
2066 as_bad (_("bad value for opcode field, "
2067 "value must be 0...2"));
2071 INSERT_OPERAND (OP2
, *ip
, imm_expr
->X_add_number
);
2072 imm_expr
->X_op
= O_absent
;
2076 as_bad (_("bad Opcode field specifier 'O%c'\n"), *args
);
2084 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2085 || imm_expr
->X_op
!= O_constant
2086 || imm_expr
->X_add_number
< 0
2087 || imm_expr
->X_add_number
>= 128)
2089 as_bad (_("bad value for funct7 field, "
2090 "value must be 0...127"));
2094 INSERT_OPERAND (FUNCT7
, *ip
, imm_expr
->X_add_number
);
2095 imm_expr
->X_op
= O_absent
;
2099 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2100 || imm_expr
->X_op
!= O_constant
2101 || imm_expr
->X_add_number
< 0
2102 || imm_expr
->X_add_number
>= 8)
2104 as_bad (_("bad value for funct3 field, "
2105 "value must be 0...7"));
2109 INSERT_OPERAND (FUNCT3
, *ip
, imm_expr
->X_add_number
);
2110 imm_expr
->X_op
= O_absent
;
2114 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2115 || imm_expr
->X_op
!= O_constant
2116 || imm_expr
->X_add_number
< 0
2117 || imm_expr
->X_add_number
>= 4)
2119 as_bad (_("bad value for funct2 field, "
2120 "value must be 0...3"));
2124 INSERT_OPERAND (FUNCT2
, *ip
, imm_expr
->X_add_number
);
2125 imm_expr
->X_op
= O_absent
;
2130 as_bad (_("bad FUNCT field specifier 'F%c'\n"), *args
);
2135 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2136 || imm_expr
->X_op
!= O_constant
2137 || imm_expr
->X_add_number
!= 0)
2140 imm_expr
->X_op
= O_absent
;
2144 as_fatal (_("internal error: bad argument type %c"), *args
);
2149 error
= _("illegal operands");
2153 /* Restore the character we might have clobbered above. */
2155 *(argsStart
- 1) = save_c
;
2161 md_assemble (char *str
)
2163 struct riscv_cl_insn insn
;
2164 expressionS imm_expr
;
2165 bfd_reloc_code_real_type imm_reloc
= BFD_RELOC_UNUSED
;
2167 const char *error
= riscv_ip (str
, &insn
, &imm_expr
, &imm_reloc
, op_hash
);
2171 as_bad ("%s `%s'", error
, str
);
2175 if (insn
.insn_mo
->pinfo
== INSN_MACRO
)
2176 macro (&insn
, &imm_expr
, &imm_reloc
);
2178 append_insn (&insn
, &imm_expr
, imm_reloc
);
2182 md_atof (int type
, char *litP
, int *sizeP
)
2184 return ieee_md_atof (type
, litP
, sizeP
, TARGET_BYTES_BIG_ENDIAN
);
2188 md_number_to_chars (char *buf
, valueT val
, int n
)
2190 number_to_chars_littleendian (buf
, val
, n
);
2193 const char *md_shortopts
= "O::g::G:";
2197 OPTION_MARCH
= OPTION_MD_BASE
,
2206 struct option md_longopts
[] =
2208 {"march", required_argument
, NULL
, OPTION_MARCH
},
2209 {"fPIC", no_argument
, NULL
, OPTION_PIC
},
2210 {"fpic", no_argument
, NULL
, OPTION_PIC
},
2211 {"fno-pic", no_argument
, NULL
, OPTION_NO_PIC
},
2212 {"mabi", required_argument
, NULL
, OPTION_MABI
},
2213 {"mrelax", no_argument
, NULL
, OPTION_RELAX
},
2214 {"mno-relax", no_argument
, NULL
, OPTION_NO_RELAX
},
2216 {NULL
, no_argument
, NULL
, 0}
2218 size_t md_longopts_size
= sizeof (md_longopts
);
2221 FLOAT_ABI_DEFAULT
= -1,
2227 static enum float_abi float_abi
= FLOAT_ABI_DEFAULT
;
2230 riscv_set_abi (unsigned new_xlen
, enum float_abi new_float_abi
, bfd_boolean rve
)
2232 abi_xlen
= new_xlen
;
2233 float_abi
= new_float_abi
;
2238 md_parse_option (int c
, const char *arg
)
2243 riscv_set_arch (arg
);
2247 riscv_opts
.pic
= FALSE
;
2251 riscv_opts
.pic
= TRUE
;
2255 if (strcmp (arg
, "ilp32") == 0)
2256 riscv_set_abi (32, FLOAT_ABI_SOFT
, FALSE
);
2257 else if (strcmp (arg
, "ilp32e") == 0)
2258 riscv_set_abi (32, FLOAT_ABI_SOFT
, TRUE
);
2259 else if (strcmp (arg
, "ilp32f") == 0)
2260 riscv_set_abi (32, FLOAT_ABI_SINGLE
, FALSE
);
2261 else if (strcmp (arg
, "ilp32d") == 0)
2262 riscv_set_abi (32, FLOAT_ABI_DOUBLE
, FALSE
);
2263 else if (strcmp (arg
, "ilp32q") == 0)
2264 riscv_set_abi (32, FLOAT_ABI_QUAD
, FALSE
);
2265 else if (strcmp (arg
, "lp64") == 0)
2266 riscv_set_abi (64, FLOAT_ABI_SOFT
, FALSE
);
2267 else if (strcmp (arg
, "lp64f") == 0)
2268 riscv_set_abi (64, FLOAT_ABI_SINGLE
, FALSE
);
2269 else if (strcmp (arg
, "lp64d") == 0)
2270 riscv_set_abi (64, FLOAT_ABI_DOUBLE
, FALSE
);
2271 else if (strcmp (arg
, "lp64q") == 0)
2272 riscv_set_abi (64, FLOAT_ABI_QUAD
, FALSE
);
2278 riscv_opts
.relax
= TRUE
;
2281 case OPTION_NO_RELAX
:
2282 riscv_opts
.relax
= FALSE
;
2293 riscv_after_parse_args (void)
2297 if (strcmp (default_arch
, "riscv32") == 0)
2299 else if (strcmp (default_arch
, "riscv64") == 0)
2302 as_bad ("unknown default architecture `%s'", default_arch
);
2305 if (riscv_subsets
== NULL
)
2306 riscv_set_arch (xlen
== 64 ? "rv64g" : "rv32g");
2308 /* Add the RVC extension, regardless of -march, to support .option rvc. */
2309 riscv_set_rvc (FALSE
);
2310 if (riscv_subset_supports (0, "c"))
2311 riscv_set_rvc (TRUE
);
2313 riscv_add_subset ("c");
2315 /* Enable RVE if specified by the -march option. */
2316 riscv_set_rve (FALSE
);
2317 if (riscv_subset_supports (0, "e"))
2318 riscv_set_rve (TRUE
);
2320 /* Infer ABI from ISA if not specified on command line. */
2323 else if (abi_xlen
> xlen
)
2324 as_bad ("can't have %d-bit ABI on %d-bit ISA", abi_xlen
, xlen
);
2325 else if (abi_xlen
< xlen
)
2326 as_bad ("%d-bit ABI not yet supported on %d-bit ISA", abi_xlen
, xlen
);
2328 if (float_abi
== FLOAT_ABI_DEFAULT
)
2330 struct riscv_subset
*subset
;
2332 /* Assume soft-float unless D extension is present. */
2333 float_abi
= FLOAT_ABI_SOFT
;
2335 for (subset
= riscv_subsets
; subset
!= NULL
; subset
= subset
->next
)
2337 if (strcasecmp (subset
->name
, "D") == 0)
2338 float_abi
= FLOAT_ABI_DOUBLE
;
2339 if (strcasecmp (subset
->name
, "Q") == 0)
2340 float_abi
= FLOAT_ABI_QUAD
;
2345 elf_flags
|= EF_RISCV_RVE
;
2347 /* Insert float_abi into the EF_RISCV_FLOAT_ABI field of elf_flags. */
2348 elf_flags
|= float_abi
* (EF_RISCV_FLOAT_ABI
& ~(EF_RISCV_FLOAT_ABI
<< 1));
2352 md_pcrel_from (fixS
*fixP
)
2354 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2357 /* Apply a fixup to the object file. */
2360 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
2362 unsigned int subtype
;
2363 bfd_byte
*buf
= (bfd_byte
*) (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
);
2364 bfd_boolean relaxable
= FALSE
;
2368 /* Remember value for tc_gen_reloc. */
2369 fixP
->fx_addnumber
= *valP
;
2371 switch (fixP
->fx_r_type
)
2373 case BFD_RELOC_RISCV_HI20
:
2374 case BFD_RELOC_RISCV_LO12_I
:
2375 case BFD_RELOC_RISCV_LO12_S
:
2376 bfd_putl32 (riscv_apply_const_reloc (fixP
->fx_r_type
, *valP
)
2377 | bfd_getl32 (buf
), buf
);
2378 if (fixP
->fx_addsy
== NULL
)
2379 fixP
->fx_done
= TRUE
;
2383 case BFD_RELOC_RISCV_GOT_HI20
:
2384 case BFD_RELOC_RISCV_ADD8
:
2385 case BFD_RELOC_RISCV_ADD16
:
2386 case BFD_RELOC_RISCV_ADD32
:
2387 case BFD_RELOC_RISCV_ADD64
:
2388 case BFD_RELOC_RISCV_SUB6
:
2389 case BFD_RELOC_RISCV_SUB8
:
2390 case BFD_RELOC_RISCV_SUB16
:
2391 case BFD_RELOC_RISCV_SUB32
:
2392 case BFD_RELOC_RISCV_SUB64
:
2393 case BFD_RELOC_RISCV_RELAX
:
2396 case BFD_RELOC_RISCV_TPREL_HI20
:
2397 case BFD_RELOC_RISCV_TPREL_LO12_I
:
2398 case BFD_RELOC_RISCV_TPREL_LO12_S
:
2399 case BFD_RELOC_RISCV_TPREL_ADD
:
2403 case BFD_RELOC_RISCV_TLS_GOT_HI20
:
2404 case BFD_RELOC_RISCV_TLS_GD_HI20
:
2405 case BFD_RELOC_RISCV_TLS_DTPREL32
:
2406 case BFD_RELOC_RISCV_TLS_DTPREL64
:
2407 if (fixP
->fx_addsy
!= NULL
)
2408 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2410 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2411 _("TLS relocation against a constant"));
2415 /* Use pc-relative relocation for FDE initial location.
2416 The symbol address in .eh_frame may be adjusted in
2417 _bfd_elf_discard_section_eh_frame, and the content of
2418 .eh_frame will be adjusted in _bfd_elf_write_section_eh_frame.
2419 Therefore, we cannot insert a relocation whose addend symbol is
2420 in .eh_frame. Othrewise, the value may be adjusted twice.*/
2421 if (fixP
->fx_addsy
&& fixP
->fx_subsy
2422 && (sub_segment
= S_GET_SEGMENT (fixP
->fx_subsy
))
2423 && strcmp (sub_segment
->name
, ".eh_frame") == 0
2424 && S_GET_VALUE (fixP
->fx_subsy
)
2425 == fixP
->fx_frag
->fr_address
+ fixP
->fx_where
)
2427 fixP
->fx_r_type
= BFD_RELOC_RISCV_32_PCREL
;
2428 fixP
->fx_subsy
= NULL
;
2435 case BFD_RELOC_RISCV_CFA
:
2436 if (fixP
->fx_addsy
&& fixP
->fx_subsy
)
2438 fixP
->fx_next
= xmemdup (fixP
, sizeof (*fixP
), sizeof (*fixP
));
2439 fixP
->fx_next
->fx_addsy
= fixP
->fx_subsy
;
2440 fixP
->fx_next
->fx_subsy
= NULL
;
2441 fixP
->fx_next
->fx_offset
= 0;
2442 fixP
->fx_subsy
= NULL
;
2444 switch (fixP
->fx_r_type
)
2447 fixP
->fx_r_type
= BFD_RELOC_RISCV_ADD64
;
2448 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB64
;
2452 fixP
->fx_r_type
= BFD_RELOC_RISCV_ADD32
;
2453 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB32
;
2457 fixP
->fx_r_type
= BFD_RELOC_RISCV_ADD16
;
2458 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB16
;
2462 fixP
->fx_r_type
= BFD_RELOC_RISCV_ADD8
;
2463 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB8
;
2466 case BFD_RELOC_RISCV_CFA
:
2467 /* Load the byte to get the subtype. */
2468 subtype
= bfd_get_8 (NULL
, &((fragS
*) (fixP
->fx_frag
->fr_opcode
))->fr_literal
[fixP
->fx_where
]);
2469 loc
= fixP
->fx_frag
->fr_fix
- (subtype
& 7);
2472 case DW_CFA_advance_loc1
:
2473 fixP
->fx_where
= loc
+ 1;
2474 fixP
->fx_next
->fx_where
= loc
+ 1;
2475 fixP
->fx_r_type
= BFD_RELOC_RISCV_SET8
;
2476 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB8
;
2479 case DW_CFA_advance_loc2
:
2481 fixP
->fx_next
->fx_size
= 2;
2482 fixP
->fx_where
= loc
+ 1;
2483 fixP
->fx_next
->fx_where
= loc
+ 1;
2484 fixP
->fx_r_type
= BFD_RELOC_RISCV_SET16
;
2485 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB16
;
2488 case DW_CFA_advance_loc4
:
2490 fixP
->fx_next
->fx_size
= 4;
2491 fixP
->fx_where
= loc
;
2492 fixP
->fx_next
->fx_where
= loc
;
2493 fixP
->fx_r_type
= BFD_RELOC_RISCV_SET32
;
2494 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB32
;
2498 if (subtype
< 0x80 && (subtype
& 0x40))
2500 /* DW_CFA_advance_loc */
2501 fixP
->fx_frag
= (fragS
*) fixP
->fx_frag
->fr_opcode
;
2502 fixP
->fx_next
->fx_frag
= fixP
->fx_frag
;
2503 fixP
->fx_r_type
= BFD_RELOC_RISCV_SET6
;
2504 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB6
;
2507 as_fatal (_("internal error: bad CFA value #%d"), subtype
);
2513 /* This case is unreachable. */
2520 /* If we are deleting this reloc entry, we must fill in the
2521 value now. This can happen if we have a .word which is not
2522 resolved when it appears but is later defined. */
2523 if (fixP
->fx_addsy
== NULL
)
2525 gas_assert (fixP
->fx_size
<= sizeof (valueT
));
2526 md_number_to_chars ((char *) buf
, *valP
, fixP
->fx_size
);
2531 case BFD_RELOC_RISCV_JMP
:
2534 /* Fill in a tentative value to improve objdump readability. */
2535 bfd_vma target
= S_GET_VALUE (fixP
->fx_addsy
) + *valP
;
2536 bfd_vma delta
= target
- md_pcrel_from (fixP
);
2537 bfd_putl32 (bfd_getl32 (buf
) | ENCODE_UJTYPE_IMM (delta
), buf
);
2541 case BFD_RELOC_12_PCREL
:
2544 /* Fill in a tentative value to improve objdump readability. */
2545 bfd_vma target
= S_GET_VALUE (fixP
->fx_addsy
) + *valP
;
2546 bfd_vma delta
= target
- md_pcrel_from (fixP
);
2547 bfd_putl32 (bfd_getl32 (buf
) | ENCODE_SBTYPE_IMM (delta
), buf
);
2551 case BFD_RELOC_RISCV_RVC_BRANCH
:
2554 /* Fill in a tentative value to improve objdump readability. */
2555 bfd_vma target
= S_GET_VALUE (fixP
->fx_addsy
) + *valP
;
2556 bfd_vma delta
= target
- md_pcrel_from (fixP
);
2557 bfd_putl16 (bfd_getl16 (buf
) | ENCODE_RVC_B_IMM (delta
), buf
);
2561 case BFD_RELOC_RISCV_RVC_JUMP
:
2564 /* Fill in a tentative value to improve objdump readability. */
2565 bfd_vma target
= S_GET_VALUE (fixP
->fx_addsy
) + *valP
;
2566 bfd_vma delta
= target
- md_pcrel_from (fixP
);
2567 bfd_putl16 (bfd_getl16 (buf
) | ENCODE_RVC_J_IMM (delta
), buf
);
2571 case BFD_RELOC_RISCV_CALL
:
2572 case BFD_RELOC_RISCV_CALL_PLT
:
2576 case BFD_RELOC_RISCV_PCREL_HI20
:
2577 case BFD_RELOC_RISCV_PCREL_LO12_S
:
2578 case BFD_RELOC_RISCV_PCREL_LO12_I
:
2579 relaxable
= riscv_opts
.relax
;
2582 case BFD_RELOC_RISCV_ALIGN
:
2586 /* We ignore generic BFD relocations we don't know about. */
2587 if (bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
) != NULL
)
2588 as_fatal (_("internal error: bad relocation #%d"), fixP
->fx_r_type
);
2591 if (fixP
->fx_subsy
!= NULL
)
2592 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2593 _("unsupported symbol subtraction"));
2595 /* Add an R_RISCV_RELAX reloc if the reloc is relaxable. */
2596 if (relaxable
&& fixP
->fx_tcbit
&& fixP
->fx_addsy
!= NULL
)
2598 fixP
->fx_next
= xmemdup (fixP
, sizeof (*fixP
), sizeof (*fixP
));
2599 fixP
->fx_next
->fx_addsy
= fixP
->fx_next
->fx_subsy
= NULL
;
2600 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_RELAX
;
2604 /* Because the value of .cfi_remember_state may changed after relaxation,
2605 we insert a fix to relocate it again in link-time. */
2608 riscv_pre_output_hook (void)
2610 const frchainS
*frch
;
2613 for (s
= stdoutput
->sections
; s
; s
= s
->next
)
2614 for (frch
= seg_info (s
)->frchainP
; frch
; frch
= frch
->frch_next
)
2618 for (frag
= frch
->frch_root
; frag
; frag
= frag
->fr_next
)
2620 if (frag
->fr_type
== rs_cfa
)
2624 symbolS
*add_symbol
= frag
->fr_symbol
->sy_value
.X_add_symbol
;
2625 symbolS
*op_symbol
= frag
->fr_symbol
->sy_value
.X_op_symbol
;
2627 exp
.X_op
= O_subtract
;
2628 exp
.X_add_symbol
= add_symbol
;
2629 exp
.X_add_number
= 0;
2630 exp
.X_op_symbol
= op_symbol
;
2632 fix_new_exp (frag
, (int) frag
->fr_offset
, 1, &exp
, 0,
2633 BFD_RELOC_RISCV_CFA
);
2640 /* This structure is used to hold a stack of .option values. */
2642 struct riscv_option_stack
2644 struct riscv_option_stack
*next
;
2645 struct riscv_set_options options
;
2648 static struct riscv_option_stack
*riscv_opts_stack
;
2650 /* Handle the .option pseudo-op. */
2653 s_riscv_option (int x ATTRIBUTE_UNUSED
)
2655 char *name
= input_line_pointer
, ch
;
2657 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2658 ++input_line_pointer
;
2659 ch
= *input_line_pointer
;
2660 *input_line_pointer
= '\0';
2662 if (strcmp (name
, "rvc") == 0)
2663 riscv_set_rvc (TRUE
);
2664 else if (strcmp (name
, "norvc") == 0)
2665 riscv_set_rvc (FALSE
);
2666 else if (strcmp (name
, "pic") == 0)
2667 riscv_opts
.pic
= TRUE
;
2668 else if (strcmp (name
, "nopic") == 0)
2669 riscv_opts
.pic
= FALSE
;
2670 else if (strcmp (name
, "relax") == 0)
2671 riscv_opts
.relax
= TRUE
;
2672 else if (strcmp (name
, "norelax") == 0)
2673 riscv_opts
.relax
= FALSE
;
2674 else if (strcmp (name
, "push") == 0)
2676 struct riscv_option_stack
*s
;
2678 s
= (struct riscv_option_stack
*) xmalloc (sizeof *s
);
2679 s
->next
= riscv_opts_stack
;
2680 s
->options
= riscv_opts
;
2681 riscv_opts_stack
= s
;
2683 else if (strcmp (name
, "pop") == 0)
2685 struct riscv_option_stack
*s
;
2687 s
= riscv_opts_stack
;
2689 as_bad (_(".option pop with no .option push"));
2692 riscv_opts
= s
->options
;
2693 riscv_opts_stack
= s
->next
;
2699 as_warn (_("Unrecognized .option directive: %s\n"), name
);
2701 *input_line_pointer
= ch
;
2702 demand_empty_rest_of_line ();
2705 /* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
2706 a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
2707 use in DWARF debug information. */
2710 s_dtprel (int bytes
)
2717 if (ex
.X_op
!= O_symbol
)
2719 as_bad (_("Unsupported use of %s"), (bytes
== 8
2722 ignore_rest_of_line ();
2725 p
= frag_more (bytes
);
2726 md_number_to_chars (p
, 0, bytes
);
2727 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, bytes
, &ex
, FALSE
,
2729 ? BFD_RELOC_RISCV_TLS_DTPREL64
2730 : BFD_RELOC_RISCV_TLS_DTPREL32
));
2732 demand_empty_rest_of_line ();
2735 /* Handle the .bss pseudo-op. */
2738 s_bss (int ignore ATTRIBUTE_UNUSED
)
2740 subseg_set (bss_section
, 0);
2741 demand_empty_rest_of_line ();
2745 riscv_make_nops (char *buf
, bfd_vma bytes
)
2749 /* RISC-V instructions cannot begin or end on odd addresses, so this case
2750 means we are not within a valid instruction sequence. It is thus safe
2751 to use a zero byte, even though that is not a valid instruction. */
2755 /* Use at most one 2-byte NOP. */
2756 if ((bytes
- i
) % 4 == 2)
2758 md_number_to_chars (buf
+ i
, RVC_NOP
, 2);
2762 /* Fill the remainder with 4-byte NOPs. */
2763 for ( ; i
< bytes
; i
+= 4)
2764 md_number_to_chars (buf
+ i
, RISCV_NOP
, 4);
2767 /* Called from md_do_align. Used to create an alignment frag in a
2768 code section by emitting a worst-case NOP sequence that the linker
2769 will later relax to the correct number of NOPs. We can't compute
2770 the correct alignment now because of other linker relaxations. */
2773 riscv_frag_align_code (int n
)
2775 bfd_vma bytes
= (bfd_vma
) 1 << n
;
2776 bfd_vma insn_alignment
= riscv_opts
.rvc
? 2 : 4;
2777 bfd_vma worst_case_bytes
= bytes
- insn_alignment
;
2781 /* If we are moving to a smaller alignment than the instruction size, then no
2782 alignment is required. */
2783 if (bytes
<= insn_alignment
)
2786 /* When not relaxing, riscv_handle_align handles code alignment. */
2787 if (!riscv_opts
.relax
)
2790 nops
= frag_more (worst_case_bytes
);
2792 ex
.X_op
= O_constant
;
2793 ex
.X_add_number
= worst_case_bytes
;
2795 riscv_make_nops (nops
, worst_case_bytes
);
2797 fix_new_exp (frag_now
, nops
- frag_now
->fr_literal
, 0,
2798 &ex
, FALSE
, BFD_RELOC_RISCV_ALIGN
);
2803 /* Implement HANDLE_ALIGN. */
2806 riscv_handle_align (fragS
*fragP
)
2808 switch (fragP
->fr_type
)
2811 /* When relaxing, riscv_frag_align_code handles code alignment. */
2812 if (!riscv_opts
.relax
)
2814 bfd_signed_vma bytes
= (fragP
->fr_next
->fr_address
2815 - fragP
->fr_address
- fragP
->fr_fix
);
2816 /* We have 4 byte uncompressed nops. */
2817 bfd_signed_vma size
= 4;
2818 bfd_signed_vma excess
= bytes
% size
;
2819 char *p
= fragP
->fr_literal
+ fragP
->fr_fix
;
2824 /* Insert zeros or compressed nops to get 4 byte alignment. */
2827 riscv_make_nops (p
, excess
);
2828 fragP
->fr_fix
+= excess
;
2832 /* Insert variable number of 4 byte uncompressed nops. */
2833 riscv_make_nops (p
, size
);
2834 fragP
->fr_var
= size
;
2844 md_estimate_size_before_relax (fragS
*fragp
, asection
*segtype
)
2846 return (fragp
->fr_var
= relaxed_branch_length (fragp
, segtype
, FALSE
));
2849 /* Translate internal representation of relocation info to BFD target
2853 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
2855 arelent
*reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2857 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2858 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2859 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2860 reloc
->addend
= fixp
->fx_addnumber
;
2862 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2863 if (reloc
->howto
== NULL
)
2865 if ((fixp
->fx_r_type
== BFD_RELOC_16
|| fixp
->fx_r_type
== BFD_RELOC_8
)
2866 && fixp
->fx_addsy
!= NULL
&& fixp
->fx_subsy
!= NULL
)
2868 /* We don't have R_RISCV_8/16, but for this special case,
2869 we can use R_RISCV_ADD8/16 with R_RISCV_SUB8/16. */
2873 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2874 _("cannot represent %s relocation in object file"),
2875 bfd_get_reloc_code_name (fixp
->fx_r_type
));
2883 riscv_relax_frag (asection
*sec
, fragS
*fragp
, long stretch ATTRIBUTE_UNUSED
)
2885 if (RELAX_BRANCH_P (fragp
->fr_subtype
))
2887 offsetT old_var
= fragp
->fr_var
;
2888 fragp
->fr_var
= relaxed_branch_length (fragp
, sec
, TRUE
);
2889 return fragp
->fr_var
- old_var
;
2895 /* Expand far branches to multi-instruction sequences. */
2898 md_convert_frag_branch (fragS
*fragp
)
2906 buf
= (bfd_byte
*)fragp
->fr_literal
+ fragp
->fr_fix
;
2908 exp
.X_op
= O_symbol
;
2909 exp
.X_add_symbol
= fragp
->fr_symbol
;
2910 exp
.X_add_number
= fragp
->fr_offset
;
2912 gas_assert (fragp
->fr_var
== RELAX_BRANCH_LENGTH (fragp
->fr_subtype
));
2914 if (RELAX_BRANCH_RVC (fragp
->fr_subtype
))
2916 switch (RELAX_BRANCH_LENGTH (fragp
->fr_subtype
))
2920 /* Expand the RVC branch into a RISC-V one. */
2921 insn
= bfd_getl16 (buf
);
2922 rs1
= 8 + ((insn
>> OP_SH_CRS1S
) & OP_MASK_CRS1S
);
2923 if ((insn
& MASK_C_J
) == MATCH_C_J
)
2925 else if ((insn
& MASK_C_JAL
) == MATCH_C_JAL
)
2926 insn
= MATCH_JAL
| (X_RA
<< OP_SH_RD
);
2927 else if ((insn
& MASK_C_BEQZ
) == MATCH_C_BEQZ
)
2928 insn
= MATCH_BEQ
| (rs1
<< OP_SH_RS1
);
2929 else if ((insn
& MASK_C_BNEZ
) == MATCH_C_BNEZ
)
2930 insn
= MATCH_BNE
| (rs1
<< OP_SH_RS1
);
2933 bfd_putl32 (insn
, buf
);
2937 /* Invert the branch condition. Branch over the jump. */
2938 insn
= bfd_getl16 (buf
);
2939 insn
^= MATCH_C_BEQZ
^ MATCH_C_BNEZ
;
2940 insn
|= ENCODE_RVC_B_IMM (6);
2941 bfd_putl16 (insn
, buf
);
2946 /* Just keep the RVC branch. */
2947 reloc
= RELAX_BRANCH_UNCOND (fragp
->fr_subtype
)
2948 ? BFD_RELOC_RISCV_RVC_JUMP
: BFD_RELOC_RISCV_RVC_BRANCH
;
2949 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2950 2, &exp
, FALSE
, reloc
);
2959 switch (RELAX_BRANCH_LENGTH (fragp
->fr_subtype
))
2962 gas_assert (!RELAX_BRANCH_UNCOND (fragp
->fr_subtype
));
2964 /* Invert the branch condition. Branch over the jump. */
2965 insn
= bfd_getl32 (buf
);
2966 insn
^= MATCH_BEQ
^ MATCH_BNE
;
2967 insn
|= ENCODE_SBTYPE_IMM (8);
2968 md_number_to_chars ((char *) buf
, insn
, 4);
2972 /* Jump to the target. */
2973 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2974 4, &exp
, FALSE
, BFD_RELOC_RISCV_JMP
);
2975 md_number_to_chars ((char *) buf
, MATCH_JAL
, 4);
2980 reloc
= RELAX_BRANCH_UNCOND (fragp
->fr_subtype
)
2981 ? BFD_RELOC_RISCV_JMP
: BFD_RELOC_12_PCREL
;
2982 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2983 4, &exp
, FALSE
, reloc
);
2992 fixp
->fx_file
= fragp
->fr_file
;
2993 fixp
->fx_line
= fragp
->fr_line
;
2995 gas_assert (buf
== (bfd_byte
*)fragp
->fr_literal
2996 + fragp
->fr_fix
+ fragp
->fr_var
);
2998 fragp
->fr_fix
+= fragp
->fr_var
;
3001 /* Relax a machine dependent frag. This returns the amount by which
3002 the current size of the frag should change. */
3005 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec ATTRIBUTE_UNUSED
,
3008 gas_assert (RELAX_BRANCH_P (fragp
->fr_subtype
));
3009 md_convert_frag_branch (fragp
);
3013 md_show_usage (FILE *stream
)
3015 fprintf (stream
, _("\
3017 -fpic generate position-independent code\n\
3018 -fno-pic don't generate position-independent code (default)\n\
3019 -march=ISA set the RISC-V architecture\n\
3020 -mabi=ABI set the RISC-V ABI\n\
3021 -mrelax enable relax (default)\n\
3022 -mno-relax disable relax\n\
3026 /* Standard calling conventions leave the CFA at SP on entry. */
3028 riscv_cfi_frame_initial_instructions (void)
3030 cfi_add_CFA_def_cfa_register (X_SP
);
3034 tc_riscv_regname_to_dw2regnum (char *regname
)
3038 if ((reg
= reg_lookup_internal (regname
, RCLASS_GPR
)) >= 0)
3041 if ((reg
= reg_lookup_internal (regname
, RCLASS_FPR
)) >= 0)
3044 as_bad (_("unknown register `%s'"), regname
);
3049 riscv_elf_final_processing (void)
3051 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
3054 /* Parse the .sleb128 and .uleb128 pseudos. Only allow constant expressions,
3055 since these directives break relaxation when used with symbol deltas. */
3058 s_riscv_leb128 (int sign
)
3061 char *save_in
= input_line_pointer
;
3064 if (exp
.X_op
!= O_constant
)
3065 as_bad (_("non-constant .%cleb128 is not supported"), sign
? 's' : 'u');
3066 demand_empty_rest_of_line ();
3068 input_line_pointer
= save_in
;
3069 return s_leb128 (sign
);
3072 /* Parse the .insn directive. */
3075 s_riscv_insn (int x ATTRIBUTE_UNUSED
)
3077 char *str
= input_line_pointer
;
3078 struct riscv_cl_insn insn
;
3079 expressionS imm_expr
;
3080 bfd_reloc_code_real_type imm_reloc
= BFD_RELOC_UNUSED
;
3083 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
3084 ++input_line_pointer
;
3086 save_c
= *input_line_pointer
;
3087 *input_line_pointer
= '\0';
3089 const char *error
= riscv_ip (str
, &insn
, &imm_expr
,
3090 &imm_reloc
, insn_type_hash
);
3094 as_bad ("%s `%s'", error
, str
);
3098 gas_assert (insn
.insn_mo
->pinfo
!= INSN_MACRO
);
3099 append_insn (&insn
, &imm_expr
, imm_reloc
);
3102 *input_line_pointer
= save_c
;
3103 demand_empty_rest_of_line ();
3106 /* Pseudo-op table. */
3108 static const pseudo_typeS riscv_pseudo_table
[] =
3110 /* RISC-V-specific pseudo-ops. */
3111 {"option", s_riscv_option
, 0},
3115 {"dtprelword", s_dtprel
, 4},
3116 {"dtpreldword", s_dtprel
, 8},
3118 {"uleb128", s_riscv_leb128
, 0},
3119 {"sleb128", s_riscv_leb128
, 1},
3120 {"insn", s_riscv_insn
, 0},
3126 riscv_pop_insert (void)
3128 extern void pop_insert (const pseudo_typeS
*);
3130 pop_insert (riscv_pseudo_table
);