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 (const char *feature
)
118 struct riscv_subset
*s
;
120 unsigned xlen_required
= strtoul (feature
, &p
, 10);
122 if (xlen_required
&& xlen
!= xlen_required
)
125 for (s
= riscv_subsets
; s
!= NULL
; s
= s
->next
)
126 if (strcasecmp (s
->name
, p
) == 0)
133 riscv_clear_subsets (void)
135 while (riscv_subsets
!= NULL
)
137 struct riscv_subset
*next
= riscv_subsets
->next
;
138 free ((void *) riscv_subsets
->name
);
139 free (riscv_subsets
);
140 riscv_subsets
= next
;
145 riscv_add_subset (const char *subset
)
147 struct riscv_subset
*s
= xmalloc (sizeof *s
);
149 s
->name
= xstrdup (subset
);
150 s
->next
= riscv_subsets
;
154 /* Set which ISA and extensions are available. */
157 riscv_set_arch (const char *s
)
159 const char *all_subsets
= "imafdqc";
160 char *extension
= NULL
;
163 riscv_clear_subsets();
165 if (strncmp (p
, "rv32", 4) == 0)
170 else if (strncmp (p
, "rv64", 4) == 0)
176 as_fatal ("-march=%s: ISA string must begin with rv32 or rv64", s
);
185 riscv_add_subset ("e");
186 riscv_add_subset ("i");
189 as_fatal ("-march=%s: rv%de is not a valid base ISA", s
, xlen
);
195 for ( ; *all_subsets
!= 'q'; all_subsets
++)
197 const char subset
[] = {*all_subsets
, '\0'};
198 riscv_add_subset (subset
);
203 as_fatal ("-march=%s: first ISA subset must be `e', `i' or `g'", s
);
210 char *subset
= xstrdup (p
);
213 while (*++q
!= '\0' && *q
!= '_')
218 as_fatal ("-march=%s: only one non-standard extension is supported"
219 " (found `%s' and `%s')", s
, extension
, subset
);
221 riscv_add_subset (subset
);
222 p
+= strlen (subset
);
226 else if ((all_subsets
= strchr (all_subsets
, *p
)) != NULL
)
228 const char subset
[] = {*p
, 0};
229 riscv_add_subset (subset
);
234 as_fatal ("-march=%s: unsupported ISA subset `%c'", s
, *p
);
237 if (riscv_subset_supports ("e") && riscv_subset_supports ("f"))
238 as_fatal ("-march=%s: rv32e does not support the `f' extension", s
);
240 if (riscv_subset_supports ("d") && !riscv_subset_supports ("f"))
241 as_fatal ("-march=%s: `d' extension requires `f' extension", s
);
243 if (riscv_subset_supports ("q") && !riscv_subset_supports ("d"))
244 as_fatal ("-march=%s: `q' extension requires `d' extension", s
);
246 if (riscv_subset_supports ("q") && xlen
< 64)
247 as_fatal ("-march=%s: rv32 does not support the `q' extension", s
);
252 /* Handle of the OPCODE hash table. */
253 static struct hash_control
*op_hash
= NULL
;
255 /* Handle of the type of .insn hash table. */
256 static struct hash_control
*insn_type_hash
= NULL
;
258 /* This array holds the chars that always start a comment. If the
259 pre-processor is disabled, these aren't very useful */
260 const char comment_chars
[] = "#";
262 /* This array holds the chars that only start a comment at the beginning of
263 a line. If the line seems to have the form '# 123 filename'
264 .line and .file directives will appear in the pre-processed output */
265 /* Note that input_file.c hand checks for '#' at the beginning of the
266 first line of the input file. This is because the compiler outputs
267 #NO_APP at the beginning of its output. */
268 /* Also note that C style comments are always supported. */
269 const char line_comment_chars
[] = "#";
271 /* This array holds machine specific line separator characters. */
272 const char line_separator_chars
[] = ";";
274 /* Chars that can be used to separate mant from exp in floating point nums */
275 const char EXP_CHARS
[] = "eE";
277 /* Chars that mean this number is a floating point constant */
280 const char FLT_CHARS
[] = "rRsSfFdDxXpP";
282 /* Macros for encoding relaxation state for RVC branches and far jumps. */
283 #define RELAX_BRANCH_ENCODE(uncond, rvc, length) \
286 | ((uncond) ? 1 : 0) \
289 #define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
290 #define RELAX_BRANCH_LENGTH(i) (((i) >> 2) & 0xF)
291 #define RELAX_BRANCH_RVC(i) (((i) & 2) != 0)
292 #define RELAX_BRANCH_UNCOND(i) (((i) & 1) != 0)
294 /* Is the given value a sign-extended 32-bit value? */
295 #define IS_SEXT_32BIT_NUM(x) \
296 (((x) &~ (offsetT) 0x7fffffff) == 0 \
297 || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
299 /* Is the given value a zero-extended 32-bit value? Or a negated one? */
300 #define IS_ZEXT_32BIT_NUM(x) \
301 (((x) &~ (offsetT) 0xffffffff) == 0 \
302 || (((x) &~ (offsetT) 0xffffffff) == ~ (offsetT) 0xffffffff))
304 /* Change INSN's opcode so that the operand given by FIELD has value VALUE.
305 INSN is a riscv_cl_insn structure and VALUE is evaluated exactly once. */
306 #define INSERT_OPERAND(FIELD, INSN, VALUE) \
307 INSERT_BITS ((INSN).insn_opcode, VALUE, OP_MASK_##FIELD, OP_SH_##FIELD)
309 /* Determine if an instruction matches an opcode. */
310 #define OPCODE_MATCHES(OPCODE, OP) \
311 (((OPCODE) & MASK_##OP) == MATCH_##OP)
313 static char *expr_end
;
315 /* The default target format to use. */
318 riscv_target_format (void)
320 return xlen
== 64 ? "elf64-littleriscv" : "elf32-littleriscv";
323 /* Return the length of instruction INSN. */
325 static inline unsigned int
326 insn_length (const struct riscv_cl_insn
*insn
)
328 return riscv_insn_length (insn
->insn_opcode
);
331 /* Initialise INSN from opcode entry MO. Leave its position unspecified. */
334 create_insn (struct riscv_cl_insn
*insn
, const struct riscv_opcode
*mo
)
337 insn
->insn_opcode
= mo
->match
;
343 /* Install INSN at the location specified by its "frag" and "where" fields. */
346 install_insn (const struct riscv_cl_insn
*insn
)
348 char *f
= insn
->frag
->fr_literal
+ insn
->where
;
349 md_number_to_chars (f
, insn
->insn_opcode
, insn_length (insn
));
352 /* Move INSN to offset WHERE in FRAG. Adjust the fixups accordingly
353 and install the opcode in the new location. */
356 move_insn (struct riscv_cl_insn
*insn
, fragS
*frag
, long where
)
360 if (insn
->fixp
!= NULL
)
362 insn
->fixp
->fx_frag
= frag
;
363 insn
->fixp
->fx_where
= where
;
368 /* Add INSN to the end of the output. */
371 add_fixed_insn (struct riscv_cl_insn
*insn
)
373 char *f
= frag_more (insn_length (insn
));
374 move_insn (insn
, frag_now
, f
- frag_now
->fr_literal
);
378 add_relaxed_insn (struct riscv_cl_insn
*insn
, int max_chars
, int var
,
379 relax_substateT subtype
, symbolS
*symbol
, offsetT offset
)
381 frag_grow (max_chars
);
382 move_insn (insn
, frag_now
, frag_more (0) - frag_now
->fr_literal
);
383 frag_var (rs_machine_dependent
, max_chars
, var
,
384 subtype
, symbol
, offset
, NULL
);
387 /* Compute the length of a branch sequence, and adjust the stored length
388 accordingly. If FRAGP is NULL, the worst-case length is returned. */
391 relaxed_branch_length (fragS
*fragp
, asection
*sec
, int update
)
393 int jump
, rvc
, length
= 8;
398 jump
= RELAX_BRANCH_UNCOND (fragp
->fr_subtype
);
399 rvc
= RELAX_BRANCH_RVC (fragp
->fr_subtype
);
400 length
= RELAX_BRANCH_LENGTH (fragp
->fr_subtype
);
402 /* Assume jumps are in range; the linker will catch any that aren't. */
403 length
= jump
? 4 : 8;
405 if (fragp
->fr_symbol
!= NULL
406 && S_IS_DEFINED (fragp
->fr_symbol
)
407 && !S_IS_WEAK (fragp
->fr_symbol
)
408 && sec
== S_GET_SEGMENT (fragp
->fr_symbol
))
410 offsetT val
= S_GET_VALUE (fragp
->fr_symbol
) + fragp
->fr_offset
;
411 bfd_vma rvc_range
= jump
? RVC_JUMP_REACH
: RVC_BRANCH_REACH
;
412 val
-= fragp
->fr_address
+ fragp
->fr_fix
;
414 if (rvc
&& (bfd_vma
)(val
+ rvc_range
/2) < rvc_range
)
416 else if ((bfd_vma
)(val
+ RISCV_BRANCH_REACH
/2) < RISCV_BRANCH_REACH
)
418 else if (!jump
&& rvc
)
423 fragp
->fr_subtype
= RELAX_BRANCH_ENCODE (jump
, rvc
, length
);
428 /* Information about an opcode name, mnemonics and its value. */
435 /* List for all supported opcode name. */
436 static const struct opcode_name_t opcode_name_list
[] =
481 /* Hash table for lookup opcode name. */
482 static struct hash_control
*opcode_names_hash
= NULL
;
484 /* Initialization for hash table of opcode name. */
486 init_opcode_names_hash (void)
489 const struct opcode_name_t
*opcode
;
491 for (opcode
= &opcode_name_list
[0]; opcode
->name
!= NULL
; ++opcode
)
493 retval
= hash_insert (opcode_names_hash
, opcode
->name
, (void *)opcode
);
496 as_fatal (_("internal error: can't hash `%s': %s"),
497 opcode
->name
, retval
);
501 /* Find `s` is a valid opcode name or not,
502 return the opcode name info if found. */
503 static const struct opcode_name_t
*
504 opcode_name_lookup (char **s
)
508 struct opcode_name_t
*o
;
510 /* Find end of name. */
512 if (is_name_beginner (*e
))
514 while (is_part_of_name (*e
))
517 /* Terminate name. */
521 o
= (struct opcode_name_t
*) hash_find (opcode_names_hash
, *s
);
523 /* Advance to next token if one was recognized. */
547 static struct hash_control
*reg_names_hash
= NULL
;
549 #define ENCODE_REG_HASH(cls, n) \
550 ((void *)(uintptr_t)((n) * RCLASS_MAX + (cls) + 1))
551 #define DECODE_REG_CLASS(hash) (((uintptr_t)(hash) - 1) % RCLASS_MAX)
552 #define DECODE_REG_NUM(hash) (((uintptr_t)(hash) - 1) / RCLASS_MAX)
555 hash_reg_name (enum reg_class
class, const char *name
, unsigned n
)
557 void *hash
= ENCODE_REG_HASH (class, n
);
558 const char *retval
= hash_insert (reg_names_hash
, name
, hash
);
561 as_fatal (_("internal error: can't hash `%s': %s"), name
, retval
);
565 hash_reg_names (enum reg_class
class, const char * const names
[], unsigned n
)
569 for (i
= 0; i
< n
; i
++)
570 hash_reg_name (class, names
[i
], i
);
574 reg_lookup_internal (const char *s
, enum reg_class
class)
576 struct regname
*r
= (struct regname
*) hash_find (reg_names_hash
, s
);
578 if (r
== NULL
|| DECODE_REG_CLASS (r
) != class)
581 if (riscv_opts
.rve
&& class == RCLASS_GPR
&& DECODE_REG_NUM (r
) > 15)
584 return DECODE_REG_NUM (r
);
588 reg_lookup (char **s
, enum reg_class
class, unsigned int *regnop
)
594 /* Find end of name. */
596 if (is_name_beginner (*e
))
598 while (is_part_of_name (*e
))
601 /* Terminate name. */
605 /* Look for the register. Advance to next token if one was recognized. */
606 if ((reg
= reg_lookup_internal (*s
, class)) >= 0)
616 arg_lookup (char **s
, const char *const *array
, size_t size
, unsigned *regnop
)
618 const char *p
= strchr (*s
, ',');
619 size_t i
, len
= p
? (size_t)(p
- *s
) : strlen (*s
);
621 for (i
= 0; i
< size
; i
++)
622 if (array
[i
] != NULL
&& strncmp (array
[i
], *s
, len
) == 0)
632 /* For consistency checking, verify that all bits are specified either
633 by the match/mask part of the instruction definition, or by the
636 `length` could be 0, 4 or 8, 0 for auto detection. */
638 validate_riscv_insn (const struct riscv_opcode
*opc
, int length
)
640 const char *p
= opc
->args
;
642 insn_t used_bits
= opc
->mask
;
644 insn_t required_bits
;
647 insn_width
= 8 * riscv_insn_length (opc
->match
);
649 insn_width
= 8 * length
;
651 required_bits
= ~0ULL >> (64 - insn_width
);
653 if ((used_bits
& opc
->match
) != (opc
->match
& required_bits
))
655 as_bad (_("internal: bad RISC-V opcode (mask error): %s %s"),
656 opc
->name
, opc
->args
);
660 #define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift)))
667 case 'a': used_bits
|= ENCODE_RVC_J_IMM (-1U); break;
668 case 'c': break; /* RS1, constrained to equal sp */
669 case 'i': used_bits
|= ENCODE_RVC_SIMM3(-1U); break;
670 case 'j': used_bits
|= ENCODE_RVC_IMM (-1U); break;
671 case 'o': used_bits
|= ENCODE_RVC_IMM (-1U); break;
672 case 'k': used_bits
|= ENCODE_RVC_LW_IMM (-1U); break;
673 case 'l': used_bits
|= ENCODE_RVC_LD_IMM (-1U); break;
674 case 'm': used_bits
|= ENCODE_RVC_LWSP_IMM (-1U); break;
675 case 'n': used_bits
|= ENCODE_RVC_LDSP_IMM (-1U); break;
676 case 'p': used_bits
|= ENCODE_RVC_B_IMM (-1U); break;
677 case 's': USE_BITS (OP_MASK_CRS1S
, OP_SH_CRS1S
); break;
678 case 't': USE_BITS (OP_MASK_CRS2S
, OP_SH_CRS2S
); break;
679 case 'u': used_bits
|= ENCODE_RVC_IMM (-1U); break;
680 case 'v': used_bits
|= ENCODE_RVC_IMM (-1U); break;
681 case 'w': break; /* RS1S, constrained to equal RD */
682 case 'x': break; /* RS2S, constrained to equal RD */
683 case 'K': used_bits
|= ENCODE_RVC_ADDI4SPN_IMM (-1U); break;
684 case 'L': used_bits
|= ENCODE_RVC_ADDI16SP_IMM (-1U); break;
685 case 'M': used_bits
|= ENCODE_RVC_SWSP_IMM (-1U); break;
686 case 'N': used_bits
|= ENCODE_RVC_SDSP_IMM (-1U); break;
687 case 'U': break; /* RS1, constrained to equal RD */
688 case 'V': USE_BITS (OP_MASK_CRS2
, OP_SH_CRS2
); break;
689 case '<': used_bits
|= ENCODE_RVC_IMM (-1U); break;
690 case '>': used_bits
|= ENCODE_RVC_IMM (-1U); break;
691 case '8': used_bits
|= ENCODE_RVC_UIMM8 (-1U); break;
692 case 'S': USE_BITS (OP_MASK_CRS1S
, OP_SH_CRS1S
); break;
693 case 'T': USE_BITS (OP_MASK_CRS2
, OP_SH_CRS2
); break;
694 case 'D': USE_BITS (OP_MASK_CRS2S
, OP_SH_CRS2S
); break;
695 case 'F': /* funct */
698 case '4': USE_BITS (OP_MASK_CFUNCT4
, OP_SH_CFUNCT4
); break;
699 case '3': USE_BITS (OP_MASK_CFUNCT3
, OP_SH_CFUNCT3
); break;
701 as_bad (_("internal: bad RISC-V opcode"
702 " (unknown operand type `CF%c'): %s %s"),
703 c
, opc
->name
, opc
->args
);
708 as_bad (_("internal: bad RISC-V opcode (unknown operand type `C%c'): %s %s"),
709 c
, opc
->name
, opc
->args
);
716 case '<': USE_BITS (OP_MASK_SHAMTW
, OP_SH_SHAMTW
); break;
717 case '>': USE_BITS (OP_MASK_SHAMT
, OP_SH_SHAMT
); break;
719 case 'D': USE_BITS (OP_MASK_RD
, OP_SH_RD
); break;
720 case 'Z': USE_BITS (OP_MASK_RS1
, OP_SH_RS1
); break;
721 case 'E': USE_BITS (OP_MASK_CSR
, OP_SH_CSR
); break;
723 case 'R': USE_BITS (OP_MASK_RS3
, OP_SH_RS3
); break;
724 case 'S': USE_BITS (OP_MASK_RS1
, OP_SH_RS1
); break;
725 case 'U': USE_BITS (OP_MASK_RS1
, OP_SH_RS1
); /* fallthru */
726 case 'T': USE_BITS (OP_MASK_RS2
, OP_SH_RS2
); break;
727 case 'd': USE_BITS (OP_MASK_RD
, OP_SH_RD
); break;
728 case 'm': USE_BITS (OP_MASK_RM
, OP_SH_RM
); break;
729 case 's': USE_BITS (OP_MASK_RS1
, OP_SH_RS1
); break;
730 case 't': USE_BITS (OP_MASK_RS2
, OP_SH_RS2
); break;
731 case 'r': USE_BITS (OP_MASK_RS3
, OP_SH_RS3
); break;
732 case 'P': USE_BITS (OP_MASK_PRED
, OP_SH_PRED
); break;
733 case 'Q': USE_BITS (OP_MASK_SUCC
, OP_SH_SUCC
); break;
735 case 'j': used_bits
|= ENCODE_ITYPE_IMM (-1U); break;
736 case 'a': used_bits
|= ENCODE_UJTYPE_IMM (-1U); break;
737 case 'p': used_bits
|= ENCODE_SBTYPE_IMM (-1U); break;
738 case 'q': used_bits
|= ENCODE_STYPE_IMM (-1U); break;
739 case 'u': used_bits
|= ENCODE_UTYPE_IMM (-1U); break;
744 case 'F': /* funct */
747 case '7': USE_BITS (OP_MASK_FUNCT7
, OP_SH_FUNCT7
); break;
748 case '3': USE_BITS (OP_MASK_FUNCT3
, OP_SH_FUNCT3
); break;
749 case '2': USE_BITS (OP_MASK_FUNCT2
, OP_SH_FUNCT2
); break;
751 as_bad (_("internal: bad RISC-V opcode"
752 " (unknown operand type `F%c'): %s %s"),
753 c
, opc
->name
, opc
->args
);
757 case 'O': /* opcode */
760 case '4': USE_BITS (OP_MASK_OP
, OP_SH_OP
); break;
761 case '2': USE_BITS (OP_MASK_OP2
, OP_SH_OP2
); break;
763 as_bad (_("internal: bad RISC-V opcode"
764 " (unknown operand type `F%c'): %s %s"),
765 c
, opc
->name
, opc
->args
);
770 as_bad (_("internal: bad RISC-V opcode "
771 "(unknown operand type `%c'): %s %s"),
772 c
, opc
->name
, opc
->args
);
776 if (used_bits
!= required_bits
)
778 as_bad (_("internal: bad RISC-V opcode (bits 0x%lx undefined): %s %s"),
779 ~(unsigned long)(used_bits
& required_bits
),
780 opc
->name
, opc
->args
);
786 struct percent_op_match
789 bfd_reloc_code_real_type reloc
;
792 /* Common hash table initialization function for
793 instruction and .insn directive. */
794 static struct hash_control
*
795 init_opcode_hash (const struct riscv_opcode
*opcodes
,
796 bfd_boolean insn_directive_p
)
800 struct hash_control
*hash
= hash_new ();
801 while (opcodes
[i
].name
)
803 const char *name
= opcodes
[i
].name
;
804 const char *hash_error
=
805 hash_insert (hash
, name
, (void *) &opcodes
[i
]);
809 fprintf (stderr
, _("internal error: can't hash `%s': %s\n"),
810 opcodes
[i
].name
, hash_error
);
811 /* Probably a memory allocation problem? Give up now. */
812 as_fatal (_("Broken assembler. No assembly attempted."));
817 if (opcodes
[i
].pinfo
!= INSN_MACRO
)
819 if (insn_directive_p
)
820 length
= ((name
[0] == 'c') ? 2 : 4);
822 length
= 0; /* Let assembler determine the length. */
823 if (!validate_riscv_insn (&opcodes
[i
], length
))
824 as_fatal (_("Broken assembler. No assembly attempted."));
827 gas_assert (!insn_directive_p
);
830 while (opcodes
[i
].name
&& !strcmp (opcodes
[i
].name
, name
));
836 /* This function is called once, at assembler startup time. It should set up
837 all the tables, etc. that the MD part of the assembler will need. */
842 unsigned long mach
= xlen
== 64 ? bfd_mach_riscv64
: bfd_mach_riscv32
;
844 if (! bfd_set_arch_mach (stdoutput
, bfd_arch_riscv
, mach
))
845 as_warn (_("Could not set architecture and machine"));
847 op_hash
= init_opcode_hash (riscv_opcodes
, FALSE
);
848 insn_type_hash
= init_opcode_hash (riscv_insn_types
, TRUE
);
850 reg_names_hash
= hash_new ();
851 hash_reg_names (RCLASS_GPR
, riscv_gpr_names_numeric
, NGPR
);
852 hash_reg_names (RCLASS_GPR
, riscv_gpr_names_abi
, NGPR
);
853 hash_reg_names (RCLASS_FPR
, riscv_fpr_names_numeric
, NFPR
);
854 hash_reg_names (RCLASS_FPR
, riscv_fpr_names_abi
, NFPR
);
856 /* Add "fp" as an alias for "s0". */
857 hash_reg_name (RCLASS_GPR
, "fp", 8);
859 opcode_names_hash
= hash_new ();
860 init_opcode_names_hash ();
862 #define DECLARE_CSR(name, num) hash_reg_name (RCLASS_CSR, #name, num);
863 #define DECLARE_CSR_ALIAS(name, num) DECLARE_CSR(name, num);
864 #include "opcode/riscv-opc.h"
867 /* Set the default alignment for the text section. */
868 record_alignment (text_section
, riscv_opts
.rvc
? 1 : 2);
872 riscv_apply_const_reloc (bfd_reloc_code_real_type reloc_type
, bfd_vma value
)
879 case BFD_RELOC_RISCV_HI20
:
880 return ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value
));
882 case BFD_RELOC_RISCV_LO12_S
:
883 return ENCODE_STYPE_IMM (value
);
885 case BFD_RELOC_RISCV_LO12_I
:
886 return ENCODE_ITYPE_IMM (value
);
893 /* Output an instruction. IP is the instruction information.
894 ADDRESS_EXPR is an operand of the instruction to be used with
898 append_insn (struct riscv_cl_insn
*ip
, expressionS
*address_expr
,
899 bfd_reloc_code_real_type reloc_type
)
901 dwarf2_emit_insn (0);
903 if (reloc_type
!= BFD_RELOC_UNUSED
)
905 reloc_howto_type
*howto
;
907 gas_assert (address_expr
);
908 if (reloc_type
== BFD_RELOC_12_PCREL
909 || reloc_type
== BFD_RELOC_RISCV_JMP
)
911 int j
= reloc_type
== BFD_RELOC_RISCV_JMP
;
912 int best_case
= riscv_insn_length (ip
->insn_opcode
);
913 unsigned worst_case
= relaxed_branch_length (NULL
, NULL
, 0);
914 add_relaxed_insn (ip
, worst_case
, best_case
,
915 RELAX_BRANCH_ENCODE (j
, best_case
== 2, worst_case
),
916 address_expr
->X_add_symbol
,
917 address_expr
->X_add_number
);
922 howto
= bfd_reloc_type_lookup (stdoutput
, reloc_type
);
924 as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type
);
926 ip
->fixp
= fix_new_exp (ip
->frag
, ip
->where
,
927 bfd_get_reloc_size (howto
),
928 address_expr
, FALSE
, reloc_type
);
930 ip
->fixp
->fx_tcbit
= riscv_opts
.relax
;
937 /* We need to start a new frag after any instruction that can be
938 optimized away or compressed by the linker during relaxation, to prevent
939 the assembler from computing static offsets across such an instruction.
940 This is necessary to get correct EH info. */
941 if (reloc_type
== BFD_RELOC_RISCV_CALL
942 || reloc_type
== BFD_RELOC_RISCV_CALL_PLT
943 || reloc_type
== BFD_RELOC_RISCV_HI20
944 || reloc_type
== BFD_RELOC_RISCV_PCREL_HI20
945 || reloc_type
== BFD_RELOC_RISCV_TPREL_HI20
946 || reloc_type
== BFD_RELOC_RISCV_TPREL_ADD
)
948 frag_wane (frag_now
);
953 /* Build an instruction created by a macro expansion. This is passed
954 a pointer to the count of instructions created so far, an
955 expression, the name of the instruction to build, an operand format
956 string, and corresponding arguments. */
959 macro_build (expressionS
*ep
, const char *name
, const char *fmt
, ...)
961 const struct riscv_opcode
*mo
;
962 struct riscv_cl_insn insn
;
963 bfd_reloc_code_real_type r
;
966 va_start (args
, fmt
);
968 r
= BFD_RELOC_UNUSED
;
969 mo
= (struct riscv_opcode
*) hash_find (op_hash
, name
);
972 /* Find a non-RVC variant of the instruction. append_insn will compress
974 while (riscv_insn_length (mo
->match
) < 4)
976 gas_assert (strcmp (name
, mo
->name
) == 0);
978 create_insn (&insn
, mo
);
984 INSERT_OPERAND (RD
, insn
, va_arg (args
, int));
988 INSERT_OPERAND (RS1
, insn
, va_arg (args
, int));
992 INSERT_OPERAND (RS2
, insn
, va_arg (args
, int));
996 INSERT_OPERAND (SHAMT
, insn
, va_arg (args
, int));
1002 gas_assert (ep
!= NULL
);
1003 r
= va_arg (args
, int);
1011 as_fatal (_("internal error: invalid macro"));
1016 gas_assert (r
== BFD_RELOC_UNUSED
? ep
== NULL
: ep
!= NULL
);
1018 append_insn (&insn
, ep
, r
);
1021 /* Sign-extend 32-bit mode constants that have bit 31 set and all higher bits
1024 normalize_constant_expr (expressionS
*ex
)
1028 if ((ex
->X_op
== O_constant
|| ex
->X_op
== O_symbol
)
1029 && IS_ZEXT_32BIT_NUM (ex
->X_add_number
))
1030 ex
->X_add_number
= (((ex
->X_add_number
& 0xffffffff) ^ 0x80000000)
1034 /* Fail if an expression EX is not a constant. IP is the instruction using EX.
1035 MAYBE_CSR is true if the symbol may be an unrecognized CSR name. */
1038 check_absolute_expr (struct riscv_cl_insn
*ip
, expressionS
*ex
,
1039 bfd_boolean maybe_csr
)
1041 if (ex
->X_op
== O_big
)
1042 as_bad (_("unsupported large constant"));
1043 else if (maybe_csr
&& ex
->X_op
== O_symbol
)
1044 as_bad (_("unknown CSR `%s'"),
1045 S_GET_NAME (ex
->X_add_symbol
));
1046 else if (ex
->X_op
!= O_constant
)
1047 as_bad (_("Instruction %s requires absolute expression"),
1049 normalize_constant_expr (ex
);
1053 make_internal_label (void)
1055 return (symbolS
*) local_symbol_make (FAKE_LABEL_NAME
, now_seg
,
1056 (valueT
) frag_now_fix (), frag_now
);
1059 /* Load an entry from the GOT. */
1061 pcrel_access (int destreg
, int tempreg
, expressionS
*ep
,
1062 const char *lo_insn
, const char *lo_pattern
,
1063 bfd_reloc_code_real_type hi_reloc
,
1064 bfd_reloc_code_real_type lo_reloc
)
1067 ep2
.X_op
= O_symbol
;
1068 ep2
.X_add_symbol
= make_internal_label ();
1069 ep2
.X_add_number
= 0;
1071 macro_build (ep
, "auipc", "d,u", tempreg
, hi_reloc
);
1072 macro_build (&ep2
, lo_insn
, lo_pattern
, destreg
, tempreg
, lo_reloc
);
1076 pcrel_load (int destreg
, int tempreg
, expressionS
*ep
, const char *lo_insn
,
1077 bfd_reloc_code_real_type hi_reloc
,
1078 bfd_reloc_code_real_type lo_reloc
)
1080 pcrel_access (destreg
, tempreg
, ep
, lo_insn
, "d,s,j", hi_reloc
, lo_reloc
);
1084 pcrel_store (int srcreg
, int tempreg
, expressionS
*ep
, const char *lo_insn
,
1085 bfd_reloc_code_real_type hi_reloc
,
1086 bfd_reloc_code_real_type lo_reloc
)
1088 pcrel_access (srcreg
, tempreg
, ep
, lo_insn
, "t,s,q", hi_reloc
, lo_reloc
);
1091 /* PC-relative function call using AUIPC/JALR, relaxed to JAL. */
1093 riscv_call (int destreg
, int tempreg
, expressionS
*ep
,
1094 bfd_reloc_code_real_type reloc
)
1096 macro_build (ep
, "auipc", "d,u", tempreg
, reloc
);
1097 macro_build (NULL
, "jalr", "d,s", destreg
, tempreg
);
1100 /* Load an integer constant into a register. */
1103 load_const (int reg
, expressionS
*ep
)
1105 int shift
= RISCV_IMM_BITS
;
1106 expressionS upper
= *ep
, lower
= *ep
;
1107 lower
.X_add_number
= (int32_t) ep
->X_add_number
<< (32-shift
) >> (32-shift
);
1108 upper
.X_add_number
-= lower
.X_add_number
;
1110 if (ep
->X_op
!= O_constant
)
1112 as_bad (_("unsupported large constant"));
1116 if (xlen
> 32 && !IS_SEXT_32BIT_NUM (ep
->X_add_number
))
1118 /* Reduce to a signed 32-bit constant using SLLI and ADDI. */
1119 while (((upper
.X_add_number
>> shift
) & 1) == 0)
1122 upper
.X_add_number
= (int64_t) upper
.X_add_number
>> shift
;
1123 load_const (reg
, &upper
);
1125 macro_build (NULL
, "slli", "d,s,>", reg
, reg
, shift
);
1126 if (lower
.X_add_number
!= 0)
1127 macro_build (&lower
, "addi", "d,s,j", reg
, reg
, BFD_RELOC_RISCV_LO12_I
);
1131 /* Simply emit LUI and/or ADDI to build a 32-bit signed constant. */
1134 if (upper
.X_add_number
!= 0)
1136 macro_build (ep
, "lui", "d,u", reg
, BFD_RELOC_RISCV_HI20
);
1140 if (lower
.X_add_number
!= 0 || hi_reg
== 0)
1141 macro_build (ep
, ADD32_INSN
, "d,s,j", reg
, hi_reg
,
1142 BFD_RELOC_RISCV_LO12_I
);
1146 /* Expand RISC-V assembly macros into one or more instructions. */
1148 macro (struct riscv_cl_insn
*ip
, expressionS
*imm_expr
,
1149 bfd_reloc_code_real_type
*imm_reloc
)
1151 int rd
= (ip
->insn_opcode
>> OP_SH_RD
) & OP_MASK_RD
;
1152 int rs1
= (ip
->insn_opcode
>> OP_SH_RS1
) & OP_MASK_RS1
;
1153 int rs2
= (ip
->insn_opcode
>> OP_SH_RS2
) & OP_MASK_RS2
;
1154 int mask
= ip
->insn_mo
->mask
;
1159 load_const (rd
, imm_expr
);
1164 /* Load the address of a symbol into a register. */
1165 if (!IS_SEXT_32BIT_NUM (imm_expr
->X_add_number
))
1166 as_bad (_("offset too large"));
1168 if (imm_expr
->X_op
== O_constant
)
1169 load_const (rd
, imm_expr
);
1170 else if (riscv_opts
.pic
&& mask
== M_LA
) /* Global PIC symbol */
1171 pcrel_load (rd
, rd
, imm_expr
, LOAD_ADDRESS_INSN
,
1172 BFD_RELOC_RISCV_GOT_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1173 else /* Local PIC symbol, or any non-PIC symbol */
1174 pcrel_load (rd
, rd
, imm_expr
, "addi",
1175 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1179 pcrel_load (rd
, rd
, imm_expr
, "addi",
1180 BFD_RELOC_RISCV_TLS_GD_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1184 pcrel_load (rd
, rd
, imm_expr
, LOAD_ADDRESS_INSN
,
1185 BFD_RELOC_RISCV_TLS_GOT_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1189 pcrel_load (rd
, rd
, imm_expr
, "lb",
1190 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1194 pcrel_load (rd
, rd
, imm_expr
, "lbu",
1195 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1199 pcrel_load (rd
, rd
, imm_expr
, "lh",
1200 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1204 pcrel_load (rd
, rd
, imm_expr
, "lhu",
1205 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1209 pcrel_load (rd
, rd
, imm_expr
, "lw",
1210 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1214 pcrel_load (rd
, rd
, imm_expr
, "lwu",
1215 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1219 pcrel_load (rd
, rd
, imm_expr
, "ld",
1220 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1224 pcrel_load (rd
, rs1
, imm_expr
, "flw",
1225 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1229 pcrel_load (rd
, rs1
, imm_expr
, "fld",
1230 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_I
);
1234 pcrel_store (rs2
, rs1
, imm_expr
, "sb",
1235 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1239 pcrel_store (rs2
, rs1
, imm_expr
, "sh",
1240 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1244 pcrel_store (rs2
, rs1
, imm_expr
, "sw",
1245 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1249 pcrel_store (rs2
, rs1
, imm_expr
, "sd",
1250 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1254 pcrel_store (rs2
, rs1
, imm_expr
, "fsw",
1255 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1259 pcrel_store (rs2
, rs1
, imm_expr
, "fsd",
1260 BFD_RELOC_RISCV_PCREL_HI20
, BFD_RELOC_RISCV_PCREL_LO12_S
);
1264 riscv_call (rd
, rs1
, imm_expr
, *imm_reloc
);
1268 as_bad (_("Macro %s not implemented"), ip
->insn_mo
->name
);
1273 static const struct percent_op_match percent_op_utype
[] =
1275 {"%tprel_hi", BFD_RELOC_RISCV_TPREL_HI20
},
1276 {"%pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20
},
1277 {"%tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20
},
1278 {"%tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20
},
1279 {"%hi", BFD_RELOC_RISCV_HI20
},
1283 static const struct percent_op_match percent_op_itype
[] =
1285 {"%lo", BFD_RELOC_RISCV_LO12_I
},
1286 {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I
},
1287 {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I
},
1291 static const struct percent_op_match percent_op_stype
[] =
1293 {"%lo", BFD_RELOC_RISCV_LO12_S
},
1294 {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_S
},
1295 {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_S
},
1299 static const struct percent_op_match percent_op_rtype
[] =
1301 {"%tprel_add", BFD_RELOC_RISCV_TPREL_ADD
},
1305 /* Return true if *STR points to a relocation operator. When returning true,
1306 move *STR over the operator and store its relocation code in *RELOC.
1307 Leave both *STR and *RELOC alone when returning false. */
1310 parse_relocation (char **str
, bfd_reloc_code_real_type
*reloc
,
1311 const struct percent_op_match
*percent_op
)
1313 for ( ; percent_op
->str
; percent_op
++)
1314 if (strncasecmp (*str
, percent_op
->str
, strlen (percent_op
->str
)) == 0)
1316 int len
= strlen (percent_op
->str
);
1318 if (!ISSPACE ((*str
)[len
]) && (*str
)[len
] != '(')
1321 *str
+= strlen (percent_op
->str
);
1322 *reloc
= percent_op
->reloc
;
1324 /* Check whether the output BFD supports this relocation.
1325 If not, issue an error and fall back on something safe. */
1326 if (*reloc
!= BFD_RELOC_UNUSED
1327 && !bfd_reloc_type_lookup (stdoutput
, *reloc
))
1329 as_bad ("relocation %s isn't supported by the current ABI",
1331 *reloc
= BFD_RELOC_UNUSED
;
1339 my_getExpression (expressionS
*ep
, char *str
)
1343 save_in
= input_line_pointer
;
1344 input_line_pointer
= str
;
1346 expr_end
= input_line_pointer
;
1347 input_line_pointer
= save_in
;
1350 /* Parse string STR as a 16-bit relocatable operand. Store the
1351 expression in *EP and the relocation, if any, in RELOC.
1352 Return the number of relocation operators used (0 or 1).
1354 On exit, EXPR_END points to the first character after the expression. */
1357 my_getSmallExpression (expressionS
*ep
, bfd_reloc_code_real_type
*reloc
,
1358 char *str
, const struct percent_op_match
*percent_op
)
1361 unsigned crux_depth
, str_depth
, regno
;
1364 /* First, check for integer registers. */
1365 if (reg_lookup (&str
, RCLASS_GPR
, ®no
))
1367 ep
->X_op
= O_register
;
1368 ep
->X_add_number
= regno
;
1372 /* Search for the start of the main expression.
1373 End the loop with CRUX pointing to the start
1374 of the main expression and with CRUX_DEPTH containing the number
1375 of open brackets at that point. */
1382 crux_depth
= str_depth
;
1384 /* Skip over whitespace and brackets, keeping count of the number
1386 while (*str
== ' ' || *str
== '\t' || *str
== '(')
1392 && parse_relocation (&str
, reloc
, percent_op
));
1394 my_getExpression (ep
, crux
);
1397 /* Match every open bracket. */
1398 while (crux_depth
> 0 && (*str
== ')' || *str
== ' ' || *str
== '\t'))
1403 as_bad ("unclosed '('");
1410 /* Parse opcode name, could be an mnemonics or number. */
1412 my_getOpcodeExpression (expressionS
*ep
, bfd_reloc_code_real_type
*reloc
,
1413 char *str
, const struct percent_op_match
*percent_op
)
1415 const struct opcode_name_t
*o
= opcode_name_lookup (&str
);
1419 ep
->X_op
= O_constant
;
1420 ep
->X_add_number
= o
->val
;
1424 return my_getSmallExpression (ep
, reloc
, str
, percent_op
);
1427 /* Detect and handle implicitly zero load-store offsets. For example,
1428 "lw t0, (t1)" is shorthand for "lw t0, 0(t1)". Return TRUE iff such
1429 an implicit offset was detected. */
1432 riscv_handle_implicit_zero_offset (expressionS
*ep
, const char *s
)
1434 /* Check whether there is only a single bracketed expression left.
1435 If so, it must be the base register and the constant must be zero. */
1436 if (*s
== '(' && strchr (s
+ 1, '(') == 0)
1438 ep
->X_op
= O_constant
;
1439 ep
->X_add_number
= 0;
1446 /* This routine assembles an instruction into its binary format. As a
1447 side effect, it sets the global variable imm_reloc to the type of
1448 relocation to do if one of the operands is an address expression. */
1451 riscv_ip (char *str
, struct riscv_cl_insn
*ip
, expressionS
*imm_expr
,
1452 bfd_reloc_code_real_type
*imm_reloc
, struct hash_control
*hash
)
1457 struct riscv_opcode
*insn
;
1462 const struct percent_op_match
*p
;
1463 const char *error
= "unrecognized opcode";
1465 /* Parse the name of the instruction. Terminate the string if whitespace
1466 is found so that hash_find only sees the name part of the string. */
1467 for (s
= str
; *s
!= '\0'; ++s
)
1475 insn
= (struct riscv_opcode
*) hash_find (hash
, str
);
1478 for ( ; insn
&& insn
->name
&& strcmp (insn
->name
, str
) == 0; insn
++)
1480 if (!riscv_subset_supports (insn
->subset
))
1483 create_insn (ip
, insn
);
1486 imm_expr
->X_op
= O_absent
;
1487 *imm_reloc
= BFD_RELOC_UNUSED
;
1488 p
= percent_op_itype
;
1490 for (args
= insn
->args
;; ++args
)
1492 s
+= strspn (s
, " \t");
1495 case '\0': /* End of args. */
1496 if (insn
->pinfo
!= INSN_MACRO
)
1498 if (!insn
->match_func (insn
, ip
->insn_opcode
))
1501 /* For .insn, insn->match and insn->mask are 0. */
1502 if (riscv_insn_length ((insn
->match
== 0 && insn
->mask
== 0)
1510 /* Successful assembly. */
1517 case 's': /* RS1 x8-x15 */
1518 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1519 || !(regno
>= 8 && regno
<= 15))
1521 INSERT_OPERAND (CRS1S
, *ip
, regno
% 8);
1523 case 'w': /* RS1 x8-x15, constrained to equal RD x8-x15. */
1524 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1525 || EXTRACT_OPERAND (CRS1S
, ip
->insn_opcode
) + 8 != regno
)
1528 case 't': /* RS2 x8-x15 */
1529 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1530 || !(regno
>= 8 && regno
<= 15))
1532 INSERT_OPERAND (CRS2S
, *ip
, regno
% 8);
1534 case 'x': /* RS2 x8-x15, constrained to equal RD x8-x15. */
1535 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1536 || EXTRACT_OPERAND (CRS2S
, ip
->insn_opcode
) + 8 != regno
)
1539 case 'U': /* RS1, constrained to equal RD. */
1540 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1541 || EXTRACT_OPERAND (RD
, ip
->insn_opcode
) != regno
)
1545 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
))
1547 INSERT_OPERAND (CRS2
, *ip
, regno
);
1549 case 'c': /* RS1, constrained to equal sp. */
1550 if (!reg_lookup (&s
, RCLASS_GPR
, ®no
)
1555 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1556 || imm_expr
->X_op
!= O_constant
1557 || imm_expr
->X_add_number
<= 0
1558 || imm_expr
->X_add_number
>= 64)
1560 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1563 imm_expr
->X_op
= O_absent
;
1566 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1567 || imm_expr
->X_op
!= O_constant
1568 || !VALID_RVC_IMM (imm_expr
->X_add_number
)
1569 || imm_expr
->X_add_number
<= 0
1570 || imm_expr
->X_add_number
>= 32)
1572 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1575 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1576 || imm_expr
->X_op
!= O_constant
1577 || !VALID_RVC_UIMM8 (imm_expr
->X_add_number
)
1578 || imm_expr
->X_add_number
< 0
1579 || imm_expr
->X_add_number
>= 256)
1581 ip
->insn_opcode
|= ENCODE_RVC_UIMM8 (imm_expr
->X_add_number
);
1584 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1585 || imm_expr
->X_op
!= O_constant
1586 || imm_expr
->X_add_number
== 0
1587 || !VALID_RVC_SIMM3 (imm_expr
->X_add_number
))
1589 ip
->insn_opcode
|= ENCODE_RVC_SIMM3 (imm_expr
->X_add_number
);
1592 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1593 || imm_expr
->X_op
!= O_constant
1594 || imm_expr
->X_add_number
== 0
1595 || !VALID_RVC_IMM (imm_expr
->X_add_number
))
1597 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1600 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1602 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1603 || imm_expr
->X_op
!= O_constant
1604 || !VALID_RVC_LW_IMM (imm_expr
->X_add_number
))
1606 ip
->insn_opcode
|= ENCODE_RVC_LW_IMM (imm_expr
->X_add_number
);
1609 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1611 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1612 || imm_expr
->X_op
!= O_constant
1613 || !VALID_RVC_LD_IMM (imm_expr
->X_add_number
))
1615 ip
->insn_opcode
|= ENCODE_RVC_LD_IMM (imm_expr
->X_add_number
);
1618 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1620 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1621 || imm_expr
->X_op
!= O_constant
1622 || !VALID_RVC_LWSP_IMM (imm_expr
->X_add_number
))
1625 ENCODE_RVC_LWSP_IMM (imm_expr
->X_add_number
);
1628 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1630 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1631 || imm_expr
->X_op
!= O_constant
1632 || !VALID_RVC_LDSP_IMM (imm_expr
->X_add_number
))
1635 ENCODE_RVC_LDSP_IMM (imm_expr
->X_add_number
);
1638 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1639 || imm_expr
->X_op
!= O_constant
1640 /* C.addiw, c.li, and c.andi allow zero immediate.
1641 C.addi allows zero immediate as hint. Otherwise this
1643 || !VALID_RVC_IMM (imm_expr
->X_add_number
))
1645 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1648 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1649 || imm_expr
->X_op
!= O_constant
1650 || !VALID_RVC_ADDI4SPN_IMM (imm_expr
->X_add_number
)
1651 || imm_expr
->X_add_number
== 0)
1654 ENCODE_RVC_ADDI4SPN_IMM (imm_expr
->X_add_number
);
1657 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1658 || imm_expr
->X_op
!= O_constant
1659 || !VALID_RVC_ADDI16SP_IMM (imm_expr
->X_add_number
)
1660 || imm_expr
->X_add_number
== 0)
1663 ENCODE_RVC_ADDI16SP_IMM (imm_expr
->X_add_number
);
1666 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1668 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1669 || imm_expr
->X_op
!= O_constant
1670 || !VALID_RVC_SWSP_IMM (imm_expr
->X_add_number
))
1673 ENCODE_RVC_SWSP_IMM (imm_expr
->X_add_number
);
1676 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1678 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1679 || imm_expr
->X_op
!= O_constant
1680 || !VALID_RVC_SDSP_IMM (imm_expr
->X_add_number
))
1683 ENCODE_RVC_SDSP_IMM (imm_expr
->X_add_number
);
1686 p
= percent_op_utype
;
1687 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
))
1690 if (imm_expr
->X_op
!= O_constant
1691 || imm_expr
->X_add_number
<= 0
1692 || imm_expr
->X_add_number
>= RISCV_BIGIMM_REACH
1693 || (imm_expr
->X_add_number
>= RISCV_RVC_IMM_REACH
/ 2
1694 && (imm_expr
->X_add_number
<
1695 RISCV_BIGIMM_REACH
- RISCV_RVC_IMM_REACH
/ 2)))
1697 ip
->insn_opcode
|= ENCODE_RVC_IMM (imm_expr
->X_add_number
);
1700 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1701 || (imm_expr
->X_add_number
& (RISCV_IMM_REACH
- 1))
1702 || ((int32_t)imm_expr
->X_add_number
1703 != imm_expr
->X_add_number
))
1705 imm_expr
->X_add_number
=
1706 ((uint32_t) imm_expr
->X_add_number
) >> RISCV_IMM_BITS
;
1712 case 'S': /* Floating-point RS1 x8-x15. */
1713 if (!reg_lookup (&s
, RCLASS_FPR
, ®no
)
1714 || !(regno
>= 8 && regno
<= 15))
1716 INSERT_OPERAND (CRS1S
, *ip
, regno
% 8);
1718 case 'D': /* Floating-point RS2 x8-x15. */
1719 if (!reg_lookup (&s
, RCLASS_FPR
, ®no
)
1720 || !(regno
>= 8 && regno
<= 15))
1722 INSERT_OPERAND (CRS2S
, *ip
, regno
% 8);
1724 case 'T': /* Floating-point RS2. */
1725 if (!reg_lookup (&s
, RCLASS_FPR
, ®no
))
1727 INSERT_OPERAND (CRS2
, *ip
, regno
);
1733 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1734 || imm_expr
->X_op
!= O_constant
1735 || imm_expr
->X_add_number
< 0
1736 || imm_expr
->X_add_number
>= 16)
1738 as_bad (_("bad value for funct4 field, "
1739 "value must be 0...15"));
1743 INSERT_OPERAND (CFUNCT4
, *ip
, imm_expr
->X_add_number
);
1744 imm_expr
->X_op
= O_absent
;
1748 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1749 || imm_expr
->X_op
!= O_constant
1750 || imm_expr
->X_add_number
< 0
1751 || imm_expr
->X_add_number
>= 8)
1753 as_bad (_("bad value for funct3 field, "
1754 "value must be 0...7"));
1757 INSERT_OPERAND (CFUNCT3
, *ip
, imm_expr
->X_add_number
);
1758 imm_expr
->X_op
= O_absent
;
1762 as_bad (_("bad compressed FUNCT field"
1763 " specifier 'CF%c'\n"),
1769 as_bad (_("bad RVC field specifier 'C%c'\n"), *args
);
1788 case '<': /* Shift amount, 0 - 31. */
1789 my_getExpression (imm_expr
, s
);
1790 check_absolute_expr (ip
, imm_expr
, FALSE
);
1791 if ((unsigned long) imm_expr
->X_add_number
> 31)
1792 as_bad (_("Improper shift amount (%lu)"),
1793 (unsigned long) imm_expr
->X_add_number
);
1794 INSERT_OPERAND (SHAMTW
, *ip
, imm_expr
->X_add_number
);
1795 imm_expr
->X_op
= O_absent
;
1799 case '>': /* Shift amount, 0 - (XLEN-1). */
1800 my_getExpression (imm_expr
, s
);
1801 check_absolute_expr (ip
, imm_expr
, FALSE
);
1802 if ((unsigned long) imm_expr
->X_add_number
>= xlen
)
1803 as_bad (_("Improper shift amount (%lu)"),
1804 (unsigned long) imm_expr
->X_add_number
);
1805 INSERT_OPERAND (SHAMT
, *ip
, imm_expr
->X_add_number
);
1806 imm_expr
->X_op
= O_absent
;
1810 case 'Z': /* CSRRxI immediate. */
1811 my_getExpression (imm_expr
, s
);
1812 check_absolute_expr (ip
, imm_expr
, FALSE
);
1813 if ((unsigned long) imm_expr
->X_add_number
> 31)
1814 as_bad (_("Improper CSRxI immediate (%lu)"),
1815 (unsigned long) imm_expr
->X_add_number
);
1816 INSERT_OPERAND (RS1
, *ip
, imm_expr
->X_add_number
);
1817 imm_expr
->X_op
= O_absent
;
1821 case 'E': /* Control register. */
1822 if (reg_lookup (&s
, RCLASS_CSR
, ®no
))
1823 INSERT_OPERAND (CSR
, *ip
, regno
);
1826 my_getExpression (imm_expr
, s
);
1827 check_absolute_expr (ip
, imm_expr
, TRUE
);
1828 if ((unsigned long) imm_expr
->X_add_number
> 0xfff)
1829 as_bad (_("Improper CSR address (%lu)"),
1830 (unsigned long) imm_expr
->X_add_number
);
1831 INSERT_OPERAND (CSR
, *ip
, imm_expr
->X_add_number
);
1832 imm_expr
->X_op
= O_absent
;
1837 case 'm': /* Rounding mode. */
1838 if (arg_lookup (&s
, riscv_rm
, ARRAY_SIZE (riscv_rm
), ®no
))
1840 INSERT_OPERAND (RM
, *ip
, regno
);
1846 case 'Q': /* Fence predecessor/successor. */
1847 if (arg_lookup (&s
, riscv_pred_succ
, ARRAY_SIZE (riscv_pred_succ
),
1851 INSERT_OPERAND (PRED
, *ip
, regno
);
1853 INSERT_OPERAND (SUCC
, *ip
, regno
);
1858 case 'd': /* Destination register. */
1859 case 's': /* Source register. */
1860 case 't': /* Target register. */
1861 case 'r': /* rs3. */
1862 if (reg_lookup (&s
, RCLASS_GPR
, ®no
))
1868 /* Now that we have assembled one operand, we use the args
1869 string to figure out where it goes in the instruction. */
1873 INSERT_OPERAND (RS1
, *ip
, regno
);
1876 INSERT_OPERAND (RD
, *ip
, regno
);
1879 INSERT_OPERAND (RS2
, *ip
, regno
);
1882 INSERT_OPERAND (RS3
, *ip
, regno
);
1889 case 'D': /* Floating point rd. */
1890 case 'S': /* Floating point rs1. */
1891 case 'T': /* Floating point rs2. */
1892 case 'U': /* Floating point rs1 and rs2. */
1893 case 'R': /* Floating point rs3. */
1894 if (reg_lookup (&s
, RCLASS_FPR
, ®no
))
1902 INSERT_OPERAND (RD
, *ip
, regno
);
1905 INSERT_OPERAND (RS1
, *ip
, regno
);
1908 INSERT_OPERAND (RS1
, *ip
, regno
);
1911 INSERT_OPERAND (RS2
, *ip
, regno
);
1914 INSERT_OPERAND (RS3
, *ip
, regno
);
1923 my_getExpression (imm_expr
, s
);
1924 if (imm_expr
->X_op
!= O_big
1925 && imm_expr
->X_op
!= O_constant
)
1927 normalize_constant_expr (imm_expr
);
1932 my_getExpression (imm_expr
, s
);
1933 normalize_constant_expr (imm_expr
);
1934 /* The 'A' format specifier must be a symbol. */
1935 if (imm_expr
->X_op
!= O_symbol
)
1937 *imm_reloc
= BFD_RELOC_32
;
1942 my_getExpression (imm_expr
, s
);
1943 normalize_constant_expr (imm_expr
);
1944 /* The 'B' format specifier must be a symbol or a constant. */
1945 if (imm_expr
->X_op
!= O_symbol
&& imm_expr
->X_op
!= O_constant
)
1947 if (imm_expr
->X_op
== O_symbol
)
1948 *imm_reloc
= BFD_RELOC_32
;
1952 case 'j': /* Sign-extended immediate. */
1953 *imm_reloc
= BFD_RELOC_RISCV_LO12_I
;
1954 p
= percent_op_itype
;
1956 case 'q': /* Store displacement. */
1957 p
= percent_op_stype
;
1958 *imm_reloc
= BFD_RELOC_RISCV_LO12_S
;
1960 case 'o': /* Load displacement. */
1961 p
= percent_op_itype
;
1962 *imm_reloc
= BFD_RELOC_RISCV_LO12_I
;
1964 case '0': /* AMO "displacement," which must be zero. */
1965 p
= percent_op_rtype
;
1966 *imm_reloc
= BFD_RELOC_UNUSED
;
1968 if (riscv_handle_implicit_zero_offset (imm_expr
, s
))
1971 /* If this value won't fit into a 16 bit offset, then go
1972 find a macro that will generate the 32 bit offset
1974 if (!my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
))
1976 normalize_constant_expr (imm_expr
);
1977 if (imm_expr
->X_op
!= O_constant
1978 || (*args
== '0' && imm_expr
->X_add_number
!= 0)
1979 || imm_expr
->X_add_number
>= (signed)RISCV_IMM_REACH
/2
1980 || imm_expr
->X_add_number
< -(signed)RISCV_IMM_REACH
/2)
1987 case 'p': /* PC-relative offset. */
1989 *imm_reloc
= BFD_RELOC_12_PCREL
;
1990 my_getExpression (imm_expr
, s
);
1994 case 'u': /* Upper 20 bits. */
1995 p
= percent_op_utype
;
1996 if (!my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
1997 && imm_expr
->X_op
== O_constant
)
1999 if (imm_expr
->X_add_number
< 0
2000 || imm_expr
->X_add_number
>= (signed)RISCV_BIGIMM_REACH
)
2001 as_bad (_("lui expression not in range 0..1048575"));
2003 *imm_reloc
= BFD_RELOC_RISCV_HI20
;
2004 imm_expr
->X_add_number
<<= RISCV_IMM_BITS
;
2009 case 'a': /* 20-bit PC-relative offset. */
2011 my_getExpression (imm_expr
, s
);
2013 *imm_reloc
= BFD_RELOC_RISCV_JMP
;
2017 my_getExpression (imm_expr
, s
);
2019 if (strcmp (s
, "@plt") == 0)
2021 *imm_reloc
= BFD_RELOC_RISCV_CALL_PLT
;
2025 *imm_reloc
= BFD_RELOC_RISCV_CALL
;
2031 if (my_getOpcodeExpression (imm_expr
, imm_reloc
, s
, p
)
2032 || imm_expr
->X_op
!= O_constant
2033 || imm_expr
->X_add_number
< 0
2034 || imm_expr
->X_add_number
>= 128
2035 || (imm_expr
->X_add_number
& 0x3) != 3)
2037 as_bad (_("bad value for opcode field, "
2038 "value must be 0...127 and "
2039 "lower 2 bits must be 0x3"));
2043 INSERT_OPERAND (OP
, *ip
, imm_expr
->X_add_number
);
2044 imm_expr
->X_op
= O_absent
;
2048 if (my_getOpcodeExpression (imm_expr
, imm_reloc
, s
, p
)
2049 || imm_expr
->X_op
!= O_constant
2050 || imm_expr
->X_add_number
< 0
2051 || imm_expr
->X_add_number
>= 3)
2053 as_bad (_("bad value for opcode field, "
2054 "value must be 0...2"));
2058 INSERT_OPERAND (OP2
, *ip
, imm_expr
->X_add_number
);
2059 imm_expr
->X_op
= O_absent
;
2063 as_bad (_("bad Opcode field specifier 'O%c'\n"), *args
);
2071 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2072 || imm_expr
->X_op
!= O_constant
2073 || imm_expr
->X_add_number
< 0
2074 || imm_expr
->X_add_number
>= 128)
2076 as_bad (_("bad value for funct7 field, "
2077 "value must be 0...127"));
2081 INSERT_OPERAND (FUNCT7
, *ip
, imm_expr
->X_add_number
);
2082 imm_expr
->X_op
= O_absent
;
2086 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2087 || imm_expr
->X_op
!= O_constant
2088 || imm_expr
->X_add_number
< 0
2089 || imm_expr
->X_add_number
>= 8)
2091 as_bad (_("bad value for funct3 field, "
2092 "value must be 0...7"));
2096 INSERT_OPERAND (FUNCT3
, *ip
, imm_expr
->X_add_number
);
2097 imm_expr
->X_op
= O_absent
;
2101 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2102 || imm_expr
->X_op
!= O_constant
2103 || imm_expr
->X_add_number
< 0
2104 || imm_expr
->X_add_number
>= 4)
2106 as_bad (_("bad value for funct2 field, "
2107 "value must be 0...3"));
2111 INSERT_OPERAND (FUNCT2
, *ip
, imm_expr
->X_add_number
);
2112 imm_expr
->X_op
= O_absent
;
2117 as_bad (_("bad FUNCT field specifier 'F%c'\n"), *args
);
2122 if (my_getSmallExpression (imm_expr
, imm_reloc
, s
, p
)
2123 || imm_expr
->X_op
!= O_constant
2124 || imm_expr
->X_add_number
!= 0)
2127 imm_expr
->X_op
= O_absent
;
2131 as_fatal (_("internal error: bad argument type %c"), *args
);
2136 error
= _("illegal operands");
2140 /* Restore the character we might have clobbered above. */
2142 *(argsStart
- 1) = save_c
;
2148 md_assemble (char *str
)
2150 struct riscv_cl_insn insn
;
2151 expressionS imm_expr
;
2152 bfd_reloc_code_real_type imm_reloc
= BFD_RELOC_UNUSED
;
2154 const char *error
= riscv_ip (str
, &insn
, &imm_expr
, &imm_reloc
, op_hash
);
2158 as_bad ("%s `%s'", error
, str
);
2162 if (insn
.insn_mo
->pinfo
== INSN_MACRO
)
2163 macro (&insn
, &imm_expr
, &imm_reloc
);
2165 append_insn (&insn
, &imm_expr
, imm_reloc
);
2169 md_atof (int type
, char *litP
, int *sizeP
)
2171 return ieee_md_atof (type
, litP
, sizeP
, TARGET_BYTES_BIG_ENDIAN
);
2175 md_number_to_chars (char *buf
, valueT val
, int n
)
2177 number_to_chars_littleendian (buf
, val
, n
);
2180 const char *md_shortopts
= "O::g::G:";
2184 OPTION_MARCH
= OPTION_MD_BASE
,
2193 struct option md_longopts
[] =
2195 {"march", required_argument
, NULL
, OPTION_MARCH
},
2196 {"fPIC", no_argument
, NULL
, OPTION_PIC
},
2197 {"fpic", no_argument
, NULL
, OPTION_PIC
},
2198 {"fno-pic", no_argument
, NULL
, OPTION_NO_PIC
},
2199 {"mabi", required_argument
, NULL
, OPTION_MABI
},
2200 {"mrelax", no_argument
, NULL
, OPTION_RELAX
},
2201 {"mno-relax", no_argument
, NULL
, OPTION_NO_RELAX
},
2203 {NULL
, no_argument
, NULL
, 0}
2205 size_t md_longopts_size
= sizeof (md_longopts
);
2208 FLOAT_ABI_DEFAULT
= -1,
2214 static enum float_abi float_abi
= FLOAT_ABI_DEFAULT
;
2217 riscv_set_abi (unsigned new_xlen
, enum float_abi new_float_abi
, bfd_boolean rve
)
2219 abi_xlen
= new_xlen
;
2220 float_abi
= new_float_abi
;
2225 md_parse_option (int c
, const char *arg
)
2230 riscv_set_arch (arg
);
2234 riscv_opts
.pic
= FALSE
;
2238 riscv_opts
.pic
= TRUE
;
2242 if (strcmp (arg
, "ilp32") == 0)
2243 riscv_set_abi (32, FLOAT_ABI_SOFT
, FALSE
);
2244 else if (strcmp (arg
, "ilp32e") == 0)
2245 riscv_set_abi (32, FLOAT_ABI_SOFT
, TRUE
);
2246 else if (strcmp (arg
, "ilp32f") == 0)
2247 riscv_set_abi (32, FLOAT_ABI_SINGLE
, FALSE
);
2248 else if (strcmp (arg
, "ilp32d") == 0)
2249 riscv_set_abi (32, FLOAT_ABI_DOUBLE
, FALSE
);
2250 else if (strcmp (arg
, "ilp32q") == 0)
2251 riscv_set_abi (32, FLOAT_ABI_QUAD
, FALSE
);
2252 else if (strcmp (arg
, "lp64") == 0)
2253 riscv_set_abi (64, FLOAT_ABI_SOFT
, FALSE
);
2254 else if (strcmp (arg
, "lp64f") == 0)
2255 riscv_set_abi (64, FLOAT_ABI_SINGLE
, FALSE
);
2256 else if (strcmp (arg
, "lp64d") == 0)
2257 riscv_set_abi (64, FLOAT_ABI_DOUBLE
, FALSE
);
2258 else if (strcmp (arg
, "lp64q") == 0)
2259 riscv_set_abi (64, FLOAT_ABI_QUAD
, FALSE
);
2265 riscv_opts
.relax
= TRUE
;
2268 case OPTION_NO_RELAX
:
2269 riscv_opts
.relax
= FALSE
;
2280 riscv_after_parse_args (void)
2284 if (strcmp (default_arch
, "riscv32") == 0)
2286 else if (strcmp (default_arch
, "riscv64") == 0)
2289 as_bad ("unknown default architecture `%s'", default_arch
);
2292 if (riscv_subsets
== NULL
)
2293 riscv_set_arch (xlen
== 64 ? "rv64g" : "rv32g");
2295 /* Add the RVC extension, regardless of -march, to support .option rvc. */
2296 riscv_set_rvc (FALSE
);
2297 if (riscv_subset_supports ("c"))
2298 riscv_set_rvc (TRUE
);
2300 riscv_add_subset ("c");
2302 /* Enable RVE if specified by the -march option. */
2303 riscv_set_rve (FALSE
);
2304 if (riscv_subset_supports ("e"))
2305 riscv_set_rve (TRUE
);
2307 /* Infer ABI from ISA if not specified on command line. */
2310 else if (abi_xlen
> xlen
)
2311 as_bad ("can't have %d-bit ABI on %d-bit ISA", abi_xlen
, xlen
);
2312 else if (abi_xlen
< xlen
)
2313 as_bad ("%d-bit ABI not yet supported on %d-bit ISA", abi_xlen
, xlen
);
2315 if (float_abi
== FLOAT_ABI_DEFAULT
)
2317 struct riscv_subset
*subset
;
2319 /* Assume soft-float unless D extension is present. */
2320 float_abi
= FLOAT_ABI_SOFT
;
2322 for (subset
= riscv_subsets
; subset
!= NULL
; subset
= subset
->next
)
2324 if (strcasecmp (subset
->name
, "D") == 0)
2325 float_abi
= FLOAT_ABI_DOUBLE
;
2326 if (strcasecmp (subset
->name
, "Q") == 0)
2327 float_abi
= FLOAT_ABI_QUAD
;
2332 elf_flags
|= EF_RISCV_RVE
;
2334 /* Insert float_abi into the EF_RISCV_FLOAT_ABI field of elf_flags. */
2335 elf_flags
|= float_abi
* (EF_RISCV_FLOAT_ABI
& ~(EF_RISCV_FLOAT_ABI
<< 1));
2339 md_pcrel_from (fixS
*fixP
)
2341 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
2344 /* Apply a fixup to the object file. */
2347 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
2349 unsigned int subtype
;
2350 bfd_byte
*buf
= (bfd_byte
*) (fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
);
2351 bfd_boolean relaxable
= FALSE
;
2355 /* Remember value for tc_gen_reloc. */
2356 fixP
->fx_addnumber
= *valP
;
2358 switch (fixP
->fx_r_type
)
2360 case BFD_RELOC_RISCV_HI20
:
2361 case BFD_RELOC_RISCV_LO12_I
:
2362 case BFD_RELOC_RISCV_LO12_S
:
2363 bfd_putl32 (riscv_apply_const_reloc (fixP
->fx_r_type
, *valP
)
2364 | bfd_getl32 (buf
), buf
);
2365 if (fixP
->fx_addsy
== NULL
)
2366 fixP
->fx_done
= TRUE
;
2370 case BFD_RELOC_RISCV_GOT_HI20
:
2371 case BFD_RELOC_RISCV_ADD8
:
2372 case BFD_RELOC_RISCV_ADD16
:
2373 case BFD_RELOC_RISCV_ADD32
:
2374 case BFD_RELOC_RISCV_ADD64
:
2375 case BFD_RELOC_RISCV_SUB6
:
2376 case BFD_RELOC_RISCV_SUB8
:
2377 case BFD_RELOC_RISCV_SUB16
:
2378 case BFD_RELOC_RISCV_SUB32
:
2379 case BFD_RELOC_RISCV_SUB64
:
2380 case BFD_RELOC_RISCV_RELAX
:
2383 case BFD_RELOC_RISCV_TPREL_HI20
:
2384 case BFD_RELOC_RISCV_TPREL_LO12_I
:
2385 case BFD_RELOC_RISCV_TPREL_LO12_S
:
2386 case BFD_RELOC_RISCV_TPREL_ADD
:
2390 case BFD_RELOC_RISCV_TLS_GOT_HI20
:
2391 case BFD_RELOC_RISCV_TLS_GD_HI20
:
2392 case BFD_RELOC_RISCV_TLS_DTPREL32
:
2393 case BFD_RELOC_RISCV_TLS_DTPREL64
:
2394 if (fixP
->fx_addsy
!= NULL
)
2395 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
2397 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2398 _("TLS relocation against a constant"));
2402 /* Use pc-relative relocation for FDE initial location.
2403 The symbol address in .eh_frame may be adjusted in
2404 _bfd_elf_discard_section_eh_frame, and the content of
2405 .eh_frame will be adjusted in _bfd_elf_write_section_eh_frame.
2406 Therefore, we cannot insert a relocation whose addend symbol is
2407 in .eh_frame. Othrewise, the value may be adjusted twice.*/
2408 if (fixP
->fx_addsy
&& fixP
->fx_subsy
2409 && (sub_segment
= S_GET_SEGMENT (fixP
->fx_subsy
))
2410 && strcmp (sub_segment
->name
, ".eh_frame") == 0
2411 && S_GET_VALUE (fixP
->fx_subsy
)
2412 == fixP
->fx_frag
->fr_address
+ fixP
->fx_where
)
2414 fixP
->fx_r_type
= BFD_RELOC_RISCV_32_PCREL
;
2415 fixP
->fx_subsy
= NULL
;
2422 case BFD_RELOC_RISCV_CFA
:
2423 if (fixP
->fx_addsy
&& fixP
->fx_subsy
)
2425 fixP
->fx_next
= xmemdup (fixP
, sizeof (*fixP
), sizeof (*fixP
));
2426 fixP
->fx_next
->fx_addsy
= fixP
->fx_subsy
;
2427 fixP
->fx_next
->fx_subsy
= NULL
;
2428 fixP
->fx_next
->fx_offset
= 0;
2429 fixP
->fx_subsy
= NULL
;
2431 switch (fixP
->fx_r_type
)
2434 fixP
->fx_r_type
= BFD_RELOC_RISCV_ADD64
;
2435 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB64
;
2439 fixP
->fx_r_type
= BFD_RELOC_RISCV_ADD32
;
2440 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB32
;
2444 fixP
->fx_r_type
= BFD_RELOC_RISCV_ADD16
;
2445 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB16
;
2449 fixP
->fx_r_type
= BFD_RELOC_RISCV_ADD8
;
2450 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB8
;
2453 case BFD_RELOC_RISCV_CFA
:
2454 /* Load the byte to get the subtype. */
2455 subtype
= bfd_get_8 (NULL
, &((fragS
*) (fixP
->fx_frag
->fr_opcode
))->fr_literal
[fixP
->fx_where
]);
2456 loc
= fixP
->fx_frag
->fr_fix
- (subtype
& 7);
2459 case DW_CFA_advance_loc1
:
2460 fixP
->fx_where
= loc
+ 1;
2461 fixP
->fx_next
->fx_where
= loc
+ 1;
2462 fixP
->fx_r_type
= BFD_RELOC_RISCV_SET8
;
2463 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB8
;
2466 case DW_CFA_advance_loc2
:
2468 fixP
->fx_next
->fx_size
= 2;
2469 fixP
->fx_where
= loc
+ 1;
2470 fixP
->fx_next
->fx_where
= loc
+ 1;
2471 fixP
->fx_r_type
= BFD_RELOC_RISCV_SET16
;
2472 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB16
;
2475 case DW_CFA_advance_loc4
:
2477 fixP
->fx_next
->fx_size
= 4;
2478 fixP
->fx_where
= loc
;
2479 fixP
->fx_next
->fx_where
= loc
;
2480 fixP
->fx_r_type
= BFD_RELOC_RISCV_SET32
;
2481 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB32
;
2485 if (subtype
< 0x80 && (subtype
& 0x40))
2487 /* DW_CFA_advance_loc */
2488 fixP
->fx_frag
= (fragS
*) fixP
->fx_frag
->fr_opcode
;
2489 fixP
->fx_next
->fx_frag
= fixP
->fx_frag
;
2490 fixP
->fx_r_type
= BFD_RELOC_RISCV_SET6
;
2491 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_SUB6
;
2494 as_fatal (_("internal error: bad CFA value #%d"), subtype
);
2500 /* This case is unreachable. */
2507 /* If we are deleting this reloc entry, we must fill in the
2508 value now. This can happen if we have a .word which is not
2509 resolved when it appears but is later defined. */
2510 if (fixP
->fx_addsy
== NULL
)
2512 gas_assert (fixP
->fx_size
<= sizeof (valueT
));
2513 md_number_to_chars ((char *) buf
, *valP
, fixP
->fx_size
);
2518 case BFD_RELOC_RISCV_JMP
:
2521 /* Fill in a tentative value to improve objdump readability. */
2522 bfd_vma target
= S_GET_VALUE (fixP
->fx_addsy
) + *valP
;
2523 bfd_vma delta
= target
- md_pcrel_from (fixP
);
2524 bfd_putl32 (bfd_getl32 (buf
) | ENCODE_UJTYPE_IMM (delta
), buf
);
2528 case BFD_RELOC_12_PCREL
:
2531 /* Fill in a tentative value to improve objdump readability. */
2532 bfd_vma target
= S_GET_VALUE (fixP
->fx_addsy
) + *valP
;
2533 bfd_vma delta
= target
- md_pcrel_from (fixP
);
2534 bfd_putl32 (bfd_getl32 (buf
) | ENCODE_SBTYPE_IMM (delta
), buf
);
2538 case BFD_RELOC_RISCV_RVC_BRANCH
:
2541 /* Fill in a tentative value to improve objdump readability. */
2542 bfd_vma target
= S_GET_VALUE (fixP
->fx_addsy
) + *valP
;
2543 bfd_vma delta
= target
- md_pcrel_from (fixP
);
2544 bfd_putl16 (bfd_getl16 (buf
) | ENCODE_RVC_B_IMM (delta
), buf
);
2548 case BFD_RELOC_RISCV_RVC_JUMP
:
2551 /* Fill in a tentative value to improve objdump readability. */
2552 bfd_vma target
= S_GET_VALUE (fixP
->fx_addsy
) + *valP
;
2553 bfd_vma delta
= target
- md_pcrel_from (fixP
);
2554 bfd_putl16 (bfd_getl16 (buf
) | ENCODE_RVC_J_IMM (delta
), buf
);
2558 case BFD_RELOC_RISCV_CALL
:
2559 case BFD_RELOC_RISCV_CALL_PLT
:
2563 case BFD_RELOC_RISCV_PCREL_HI20
:
2564 case BFD_RELOC_RISCV_PCREL_LO12_S
:
2565 case BFD_RELOC_RISCV_PCREL_LO12_I
:
2566 relaxable
= riscv_opts
.relax
;
2569 case BFD_RELOC_RISCV_ALIGN
:
2573 /* We ignore generic BFD relocations we don't know about. */
2574 if (bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
) != NULL
)
2575 as_fatal (_("internal error: bad relocation #%d"), fixP
->fx_r_type
);
2578 if (fixP
->fx_subsy
!= NULL
)
2579 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
2580 _("unsupported symbol subtraction"));
2582 /* Add an R_RISCV_RELAX reloc if the reloc is relaxable. */
2583 if (relaxable
&& fixP
->fx_tcbit
&& fixP
->fx_addsy
!= NULL
)
2585 fixP
->fx_next
= xmemdup (fixP
, sizeof (*fixP
), sizeof (*fixP
));
2586 fixP
->fx_next
->fx_addsy
= fixP
->fx_next
->fx_subsy
= NULL
;
2587 fixP
->fx_next
->fx_r_type
= BFD_RELOC_RISCV_RELAX
;
2591 /* Because the value of .cfi_remember_state may changed after relaxation,
2592 we insert a fix to relocate it again in link-time. */
2595 riscv_pre_output_hook (void)
2597 const frchainS
*frch
;
2600 for (s
= stdoutput
->sections
; s
; s
= s
->next
)
2601 for (frch
= seg_info (s
)->frchainP
; frch
; frch
= frch
->frch_next
)
2605 for (frag
= frch
->frch_root
; frag
; frag
= frag
->fr_next
)
2607 if (frag
->fr_type
== rs_cfa
)
2611 symbolS
*add_symbol
= frag
->fr_symbol
->sy_value
.X_add_symbol
;
2612 symbolS
*op_symbol
= frag
->fr_symbol
->sy_value
.X_op_symbol
;
2614 exp
.X_op
= O_subtract
;
2615 exp
.X_add_symbol
= add_symbol
;
2616 exp
.X_add_number
= 0;
2617 exp
.X_op_symbol
= op_symbol
;
2619 fix_new_exp (frag
, (int) frag
->fr_offset
, 1, &exp
, 0,
2620 BFD_RELOC_RISCV_CFA
);
2627 /* This structure is used to hold a stack of .option values. */
2629 struct riscv_option_stack
2631 struct riscv_option_stack
*next
;
2632 struct riscv_set_options options
;
2635 static struct riscv_option_stack
*riscv_opts_stack
;
2637 /* Handle the .option pseudo-op. */
2640 s_riscv_option (int x ATTRIBUTE_UNUSED
)
2642 char *name
= input_line_pointer
, ch
;
2644 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
2645 ++input_line_pointer
;
2646 ch
= *input_line_pointer
;
2647 *input_line_pointer
= '\0';
2649 if (strcmp (name
, "rvc") == 0)
2650 riscv_set_rvc (TRUE
);
2651 else if (strcmp (name
, "norvc") == 0)
2652 riscv_set_rvc (FALSE
);
2653 else if (strcmp (name
, "pic") == 0)
2654 riscv_opts
.pic
= TRUE
;
2655 else if (strcmp (name
, "nopic") == 0)
2656 riscv_opts
.pic
= FALSE
;
2657 else if (strcmp (name
, "relax") == 0)
2658 riscv_opts
.relax
= TRUE
;
2659 else if (strcmp (name
, "norelax") == 0)
2660 riscv_opts
.relax
= FALSE
;
2661 else if (strcmp (name
, "push") == 0)
2663 struct riscv_option_stack
*s
;
2665 s
= (struct riscv_option_stack
*) xmalloc (sizeof *s
);
2666 s
->next
= riscv_opts_stack
;
2667 s
->options
= riscv_opts
;
2668 riscv_opts_stack
= s
;
2670 else if (strcmp (name
, "pop") == 0)
2672 struct riscv_option_stack
*s
;
2674 s
= riscv_opts_stack
;
2676 as_bad (_(".option pop with no .option push"));
2679 riscv_opts
= s
->options
;
2680 riscv_opts_stack
= s
->next
;
2686 as_warn (_("Unrecognized .option directive: %s\n"), name
);
2688 *input_line_pointer
= ch
;
2689 demand_empty_rest_of_line ();
2692 /* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
2693 a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
2694 use in DWARF debug information. */
2697 s_dtprel (int bytes
)
2704 if (ex
.X_op
!= O_symbol
)
2706 as_bad (_("Unsupported use of %s"), (bytes
== 8
2709 ignore_rest_of_line ();
2712 p
= frag_more (bytes
);
2713 md_number_to_chars (p
, 0, bytes
);
2714 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, bytes
, &ex
, FALSE
,
2716 ? BFD_RELOC_RISCV_TLS_DTPREL64
2717 : BFD_RELOC_RISCV_TLS_DTPREL32
));
2719 demand_empty_rest_of_line ();
2722 /* Handle the .bss pseudo-op. */
2725 s_bss (int ignore ATTRIBUTE_UNUSED
)
2727 subseg_set (bss_section
, 0);
2728 demand_empty_rest_of_line ();
2732 riscv_make_nops (char *buf
, bfd_vma bytes
)
2736 /* RISC-V instructions cannot begin or end on odd addresses, so this case
2737 means we are not within a valid instruction sequence. It is thus safe
2738 to use a zero byte, even though that is not a valid instruction. */
2742 /* Use at most one 2-byte NOP. */
2743 if ((bytes
- i
) % 4 == 2)
2745 md_number_to_chars (buf
+ i
, RVC_NOP
, 2);
2749 /* Fill the remainder with 4-byte NOPs. */
2750 for ( ; i
< bytes
; i
+= 4)
2751 md_number_to_chars (buf
+ i
, RISCV_NOP
, 4);
2754 /* Called from md_do_align. Used to create an alignment frag in a
2755 code section by emitting a worst-case NOP sequence that the linker
2756 will later relax to the correct number of NOPs. We can't compute
2757 the correct alignment now because of other linker relaxations. */
2760 riscv_frag_align_code (int n
)
2762 bfd_vma bytes
= (bfd_vma
) 1 << n
;
2763 bfd_vma insn_alignment
= riscv_opts
.rvc
? 2 : 4;
2764 bfd_vma worst_case_bytes
= bytes
- insn_alignment
;
2768 /* If we are moving to a smaller alignment than the instruction size, then no
2769 alignment is required. */
2770 if (bytes
<= insn_alignment
)
2773 /* When not relaxing, riscv_handle_align handles code alignment. */
2774 if (!riscv_opts
.relax
)
2777 nops
= frag_more (worst_case_bytes
);
2779 ex
.X_op
= O_constant
;
2780 ex
.X_add_number
= worst_case_bytes
;
2782 riscv_make_nops (nops
, worst_case_bytes
);
2784 fix_new_exp (frag_now
, nops
- frag_now
->fr_literal
, 0,
2785 &ex
, FALSE
, BFD_RELOC_RISCV_ALIGN
);
2790 /* Implement HANDLE_ALIGN. */
2793 riscv_handle_align (fragS
*fragP
)
2795 switch (fragP
->fr_type
)
2798 /* When relaxing, riscv_frag_align_code handles code alignment. */
2799 if (!riscv_opts
.relax
)
2801 bfd_signed_vma bytes
= (fragP
->fr_next
->fr_address
2802 - fragP
->fr_address
- fragP
->fr_fix
);
2803 /* We have 4 byte uncompressed nops. */
2804 bfd_signed_vma size
= 4;
2805 bfd_signed_vma excess
= bytes
% size
;
2806 char *p
= fragP
->fr_literal
+ fragP
->fr_fix
;
2811 /* Insert zeros or compressed nops to get 4 byte alignment. */
2814 riscv_make_nops (p
, excess
);
2815 fragP
->fr_fix
+= excess
;
2819 /* Insert variable number of 4 byte uncompressed nops. */
2820 riscv_make_nops (p
, size
);
2821 fragP
->fr_var
= size
;
2831 md_estimate_size_before_relax (fragS
*fragp
, asection
*segtype
)
2833 return (fragp
->fr_var
= relaxed_branch_length (fragp
, segtype
, FALSE
));
2836 /* Translate internal representation of relocation info to BFD target
2840 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
2842 arelent
*reloc
= (arelent
*) xmalloc (sizeof (arelent
));
2844 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
2845 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
2846 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
2847 reloc
->addend
= fixp
->fx_addnumber
;
2849 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
2850 if (reloc
->howto
== NULL
)
2852 if ((fixp
->fx_r_type
== BFD_RELOC_16
|| fixp
->fx_r_type
== BFD_RELOC_8
)
2853 && fixp
->fx_addsy
!= NULL
&& fixp
->fx_subsy
!= NULL
)
2855 /* We don't have R_RISCV_8/16, but for this special case,
2856 we can use R_RISCV_ADD8/16 with R_RISCV_SUB8/16. */
2860 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
2861 _("cannot represent %s relocation in object file"),
2862 bfd_get_reloc_code_name (fixp
->fx_r_type
));
2870 riscv_relax_frag (asection
*sec
, fragS
*fragp
, long stretch ATTRIBUTE_UNUSED
)
2872 if (RELAX_BRANCH_P (fragp
->fr_subtype
))
2874 offsetT old_var
= fragp
->fr_var
;
2875 fragp
->fr_var
= relaxed_branch_length (fragp
, sec
, TRUE
);
2876 return fragp
->fr_var
- old_var
;
2882 /* Expand far branches to multi-instruction sequences. */
2885 md_convert_frag_branch (fragS
*fragp
)
2893 buf
= (bfd_byte
*)fragp
->fr_literal
+ fragp
->fr_fix
;
2895 exp
.X_op
= O_symbol
;
2896 exp
.X_add_symbol
= fragp
->fr_symbol
;
2897 exp
.X_add_number
= fragp
->fr_offset
;
2899 gas_assert (fragp
->fr_var
== RELAX_BRANCH_LENGTH (fragp
->fr_subtype
));
2901 if (RELAX_BRANCH_RVC (fragp
->fr_subtype
))
2903 switch (RELAX_BRANCH_LENGTH (fragp
->fr_subtype
))
2907 /* Expand the RVC branch into a RISC-V one. */
2908 insn
= bfd_getl16 (buf
);
2909 rs1
= 8 + ((insn
>> OP_SH_CRS1S
) & OP_MASK_CRS1S
);
2910 if ((insn
& MASK_C_J
) == MATCH_C_J
)
2912 else if ((insn
& MASK_C_JAL
) == MATCH_C_JAL
)
2913 insn
= MATCH_JAL
| (X_RA
<< OP_SH_RD
);
2914 else if ((insn
& MASK_C_BEQZ
) == MATCH_C_BEQZ
)
2915 insn
= MATCH_BEQ
| (rs1
<< OP_SH_RS1
);
2916 else if ((insn
& MASK_C_BNEZ
) == MATCH_C_BNEZ
)
2917 insn
= MATCH_BNE
| (rs1
<< OP_SH_RS1
);
2920 bfd_putl32 (insn
, buf
);
2924 /* Invert the branch condition. Branch over the jump. */
2925 insn
= bfd_getl16 (buf
);
2926 insn
^= MATCH_C_BEQZ
^ MATCH_C_BNEZ
;
2927 insn
|= ENCODE_RVC_B_IMM (6);
2928 bfd_putl16 (insn
, buf
);
2933 /* Just keep the RVC branch. */
2934 reloc
= RELAX_BRANCH_UNCOND (fragp
->fr_subtype
)
2935 ? BFD_RELOC_RISCV_RVC_JUMP
: BFD_RELOC_RISCV_RVC_BRANCH
;
2936 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2937 2, &exp
, FALSE
, reloc
);
2946 switch (RELAX_BRANCH_LENGTH (fragp
->fr_subtype
))
2949 gas_assert (!RELAX_BRANCH_UNCOND (fragp
->fr_subtype
));
2951 /* Invert the branch condition. Branch over the jump. */
2952 insn
= bfd_getl32 (buf
);
2953 insn
^= MATCH_BEQ
^ MATCH_BNE
;
2954 insn
|= ENCODE_SBTYPE_IMM (8);
2955 md_number_to_chars ((char *) buf
, insn
, 4);
2959 /* Jump to the target. */
2960 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2961 4, &exp
, FALSE
, BFD_RELOC_RISCV_JMP
);
2962 md_number_to_chars ((char *) buf
, MATCH_JAL
, 4);
2967 reloc
= RELAX_BRANCH_UNCOND (fragp
->fr_subtype
)
2968 ? BFD_RELOC_RISCV_JMP
: BFD_RELOC_12_PCREL
;
2969 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2970 4, &exp
, FALSE
, reloc
);
2979 fixp
->fx_file
= fragp
->fr_file
;
2980 fixp
->fx_line
= fragp
->fr_line
;
2982 gas_assert (buf
== (bfd_byte
*)fragp
->fr_literal
2983 + fragp
->fr_fix
+ fragp
->fr_var
);
2985 fragp
->fr_fix
+= fragp
->fr_var
;
2988 /* Relax a machine dependent frag. This returns the amount by which
2989 the current size of the frag should change. */
2992 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec ATTRIBUTE_UNUSED
,
2995 gas_assert (RELAX_BRANCH_P (fragp
->fr_subtype
));
2996 md_convert_frag_branch (fragp
);
3000 md_show_usage (FILE *stream
)
3002 fprintf (stream
, _("\
3004 -fpic generate position-independent code\n\
3005 -fno-pic don't generate position-independent code (default)\n\
3006 -march=ISA set the RISC-V architecture\n\
3007 -mabi=ABI set the RISC-V ABI\n\
3008 -mrelax enable relax (default)\n\
3009 -mno-relax disable relax\n\
3013 /* Standard calling conventions leave the CFA at SP on entry. */
3015 riscv_cfi_frame_initial_instructions (void)
3017 cfi_add_CFA_def_cfa_register (X_SP
);
3021 tc_riscv_regname_to_dw2regnum (char *regname
)
3025 if ((reg
= reg_lookup_internal (regname
, RCLASS_GPR
)) >= 0)
3028 if ((reg
= reg_lookup_internal (regname
, RCLASS_FPR
)) >= 0)
3031 as_bad (_("unknown register `%s'"), regname
);
3036 riscv_elf_final_processing (void)
3038 elf_elfheader (stdoutput
)->e_flags
|= elf_flags
;
3041 /* Parse the .sleb128 and .uleb128 pseudos. Only allow constant expressions,
3042 since these directives break relaxation when used with symbol deltas. */
3045 s_riscv_leb128 (int sign
)
3048 char *save_in
= input_line_pointer
;
3051 if (exp
.X_op
!= O_constant
)
3052 as_bad (_("non-constant .%cleb128 is not supported"), sign
? 's' : 'u');
3053 demand_empty_rest_of_line ();
3055 input_line_pointer
= save_in
;
3056 return s_leb128 (sign
);
3059 /* Parse the .insn directive. */
3062 s_riscv_insn (int x ATTRIBUTE_UNUSED
)
3064 char *str
= input_line_pointer
;
3065 struct riscv_cl_insn insn
;
3066 expressionS imm_expr
;
3067 bfd_reloc_code_real_type imm_reloc
= BFD_RELOC_UNUSED
;
3070 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
3071 ++input_line_pointer
;
3073 save_c
= *input_line_pointer
;
3074 *input_line_pointer
= '\0';
3076 const char *error
= riscv_ip (str
, &insn
, &imm_expr
,
3077 &imm_reloc
, insn_type_hash
);
3081 as_bad ("%s `%s'", error
, str
);
3085 gas_assert (insn
.insn_mo
->pinfo
!= INSN_MACRO
);
3086 append_insn (&insn
, &imm_expr
, imm_reloc
);
3089 *input_line_pointer
= save_c
;
3090 demand_empty_rest_of_line ();
3093 /* Pseudo-op table. */
3095 static const pseudo_typeS riscv_pseudo_table
[] =
3097 /* RISC-V-specific pseudo-ops. */
3098 {"option", s_riscv_option
, 0},
3102 {"dtprelword", s_dtprel
, 4},
3103 {"dtpreldword", s_dtprel
, 8},
3105 {"uleb128", s_riscv_leb128
, 0},
3106 {"sleb128", s_riscv_leb128
, 1},
3107 {"insn", s_riscv_insn
, 0},
3113 riscv_pop_insert (void)
3115 extern void pop_insert (const pseudo_typeS
*);
3117 pop_insert (riscv_pseudo_table
);