According to the riscv privilege spec, some CSR are only valid when rv32 or
the specific extension is set. We extend the DECLARE_CSR and DECLARE_CSR_ALIAS
to record more informaton we need, and then check whether the CSR is valid
according to these information. We report warning message when the CSR is
invalid, so we have a choice between error and warning by --fatal-warnings
option. Also, a --no-warn/-W option is used to turn the warnings off, if
people don't want the warnings.
gas/
* config/tc-riscv.c (enum riscv_csr_class): New enum. Used to decide
whether or not this CSR is legal in the current ISA string.
(struct riscv_csr_extra): New structure to hold all extra information
of CSR.
(riscv_init_csr_hash): New function. According to the DECLARE_CSR and
DECLARE_CSR_ALIAS, insert CSR extra information into csr_extra_hash.
Call hash_reg_name to insert CSR address into reg_names_hash.
(md_begin): Call riscv_init_csr_hashes for each DECLARE_CSR.
(reg_csr_lookup_internal, riscv_csr_class_check): New functions.
Decide whether the CSR is valid according to the csr_extra_hash.
(init_opcode_hash): Update 'if (hash_error != NULL)' as hash_error is
not a boolean. This is same as riscv_init_csr_hash, so keep the
consistent usage.
* testsuite/gas/riscv/csr-dw-regnums.d: Add -march=rv32if option.
* testsuite/gas/riscv/priv-reg.d: Add f-ext by -march option.
* testsuite/gas/riscv/priv-reg-fail-fext.d: New testcase. The source
file is `priv-reg.s`, and the ISA is rv32i without f-ext, so the
f-ext CSR are not allowed.
* testsuite/gas/riscv/priv-reg-fail-fext.l: Likewise.
* testsuite/gas/riscv/priv-reg-fail-rv32-only.d: New testcase. The
source file is `priv-reg.s`, and the ISA is rv64if, so the
rv32-only CSR are not allowed.
* testsuite/gas/riscv/priv-reg-fail-rv32-only.l: Likewise.
include/
* opcode/riscv-opc.h: Extend DECLARE_CSR and DECLARE_CSR_ALIAS to
record riscv_csr_class.
opcodes/
* riscv-dis.c (print_insn_args): Updated since the DECLARE_CSR is changed.
gdb/
* riscv-tdep.c: Updated since the DECLARE_CSR is changed.
* riscv-tdep.h: Likewise.
* features/riscv/rebuild-csr-xml.sh: Generate the 64bit-csr.xml without
rv32-only CSR.
* features/riscv/64bit-csr.xml: Regernated.
binutils/
* dwarf.c: Updated since the DECLARE_CSR is changed.
Without the ELF header to set info->endian, it ends up as BFD_UNKNOWN_ENDIAN
which gets printed as big-endian. But RISC-V instructions are always little
endian, so we can set endian_code correctly, and then set display_endian from
that. This is similar to how the aarch64 support works, but without the
support for constant pools, as we don't have that on RISC-V.
opcodes/
PR binutils/24739
* riscv-dis.c (riscv_disasemble_insn): Set info->endian_code.
Set info->display_endian to info->endian_code.
The RISC-V assembler generates fake labels with the name '.L0 ' as
part of the debug information (see
gas/config/tc-riscv.h:FAKE_LABEL_NAME).
The problem is that currently, when disassembling an object file, the
output looks like this (this is an example from the GDB testsuite, but
is pretty representative of anything with debug information):
000000000000001e <main>:
1e: 7179 addi sp,sp,-48
20: f406 sd ra,40(sp)
22: f022 sd s0,32(sp)
24: 1800 addi s0,sp,48
0000000000000026 <.L0 >:
26: 87aa mv a5,a0
28: feb43023 sd a1,-32(s0)
2c: fcc43c23 sd a2,-40(s0)
30: fef42623 sw a5,-20(s0)
0000000000000034 <.L0 >:
34: fec42783 lw a5,-20(s0)
38: 0007871b sext.w a4,a5
3c: 678d lui a5,0x3
3e: 03978793 addi a5,a5,57 # 3039 <.LASF30+0x2a9d>
42: 02f71463 bne a4,a5,6a <.L0 >
0000000000000046 <.L0 >:
46: 000007b7 lui a5,0x0
4a: 0007b783 ld a5,0(a5) # 0 <need_malloc>
4e: 6f9c ld a5,24(a5)
0000000000000050 <.L0 >:
50: 86be mv a3,a5
52: 466d li a2,27
54: 4585 li a1,1
56: 000007b7 lui a5,0x0
5a: 00078513 mv a0,a5
5e: 00000097 auipc ra,0x0
62: 000080e7 jalr ra # 5e <.L0 +0xe>
0000000000000066 <.L0 >:
66: 4785 li a5,1
68: a869 j 102 <.L0 >
000000000000006a <.L0 >:
6a: 000007b7 lui a5,0x0
6e: 00078513 mv a0,a5
72: 00000097 auipc ra,0x0
76: 000080e7 jalr ra # 72 <.L0 +0x8>
The frequent repeated '.L0 ' labels are pointless, as they are
non-unique there's no way to match a use of '.L0 ' to its appearence
in the output, so we'd be better off just not printing it at all.
That's what this patch does by defining a 'symbol_is_valid' method for
RISC-V. With this commit, the same disassembly now looks like this:
000000000000001e <main>:
1e: 7179 addi sp,sp,-48
20: f406 sd ra,40(sp)
22: f022 sd s0,32(sp)
24: 1800 addi s0,sp,48
26: 87aa mv a5,a0
28: feb43023 sd a1,-32(s0)
2c: fcc43c23 sd a2,-40(s0)
30: fef42623 sw a5,-20(s0)
34: fec42783 lw a5,-20(s0)
38: 0007871b sext.w a4,a5
3c: 678d lui a5,0x3
3e: 03978793 addi a5,a5,57 # 3039 <.LASF30+0x2a9d>
42: 02f71463 bne a4,a5,6a <.L4>
46: 000007b7 lui a5,0x0
4a: 0007b783 ld a5,0(a5) # 0 <need_malloc>
4e: 6f9c ld a5,24(a5)
50: 86be mv a3,a5
52: 466d li a2,27
54: 4585 li a1,1
56: 000007b7 lui a5,0x0
5a: 00078513 mv a0,a5
5e: 00000097 auipc ra,0x0
62: 000080e7 jalr ra # 5e <main+0x40>
66: 4785 li a5,1
68: a869 j 102 <.L5>
000000000000006a <.L4>:
6a: 000007b7 lui a5,0x0
6e: 00078513 mv a0,a5
72: 00000097 auipc ra,0x0
76: 000080e7 jalr ra # 72 <.L4+0x8>
In order to share the fake label between the assembler and the
libopcodes library, I've added some new defines RISCV_FAKE_LABEL_NAME
and RISCV_FAKE_LABEL_CHAR in include/opcode/riscv.h. I could have
just moved FAKE_LABEL_NAME to the include file, however, I thnk this
would be confusing, someone working on the assembler would likely not
expect to find FAKE_LABEL_NAME defined outside of the assembler source
tree. By introducing the RISCV_FAKE_LABEL_* defines I can leave the
assembler standard FAKE_LABEL_ defines in the assembler source, but
still share the RISCV_FAKE_LABEL_* with libopcodes.
gas/ChangeLog:
* config/tc-riscv.h (FAKE_LABEL_NAME): Define as
RISCV_FAKE_LABEL_NAME.
(FAKE_LABEL_CHAR): Define as RISCV_FAKE_LABEL_CHAR.
include/ChangeLog:
* dis-asm.h (riscv_symbol_is_valid): Declare.
* opcode/riscv.h (RISCV_FAKE_LABEL_NAME): Define.
(RISCV_FAKE_LABEL_CHAR): Define.
opcodes/ChangeLog:
* disassembler.c (disassemble_init_for_target): Add RISC-V
initialisation.
* riscv-dis.c (riscv_symbol_is_valid): New function.
2018-08-29 Kito Cheng <kito@andestech.com>
gas/
* config/tc-riscv.c (riscv_subset_supports): New argument:
xlen_required.
(riscv_multi_subset_supports): New function, able to check more
than one extension.
(riscv_ip): Use riscv_multi_subset_supports instead of
riscv_subset_supports.
(riscv_set_arch): Update call-site for riscv_subset_supports.
(riscv_after_parse_args): Likewise.
include/
*opcode/riscv.h (MAX_SUBSET_NUM): New.
(riscv_opcode): Add xlen_requirement field and change type of
subset.
opcodes/
* riscv-dis.c (riscv_disassemble_insn): Check XLEN by
riscv_opcode.xlen_requirement.
* riscv-opc.c (riscv_opcodes): Update for struct change.
gas/
* testsuite/gas/riscv/auipc-x0.d: New.
* testsuite/gas/riscv/auipc-x0.s: New.
opcodes/
* riscv-dis.c (maybe_print_address): If base_reg is zero,
then the hi_addr value is zero.
We missed a "_gp" when changing the GP symbol. To make sure that
doesn't happen again, we now use the same definition everywhere (thanks,
Nick).
include/ChangeLog:
2017-04-03 Palmer Dabbelt <palmer@dabbelt.com>
* elf/riscv.h (RISCV_GP_SYMBOL): New define.
bfd/ChangeLog:
2017-04-03 Palmer Dabbelt <palmer@dabbelt.com>
* elfnn-riscv.c (GP_NAME): Delete.
(riscv_global_pointer_value): Change GP_NAME to RISCV_GP_SYMBOL.
(_bfd_riscv_relax_lui): Likewise.
opcodes/ChangeLog:
2017-04-03 Palmer Dabbelt <palmer@dabbelt.com>
* riscv-dis.c (riscv_disassemble_insn): Change "_gp" to
RISCV_GP_SYMBOL.
We've decided to standardize on two flags for RISC-V: "-march" sets the
target architecture (which determines which instructions can be
generated), and "-mabi" sets the target ABI. We needed to rework this
because the old flag set didn't support soft-float or single-float ABIs,
and didn't support an x32-style ABI on RISC-V.
Additionally, we've changed the behavior of the -march flag: it's now a
lot stricter and only parses things we can actually understand.
Additionally, it's now lowercase-only: the rationale is that while the
RISC-V ISA manual specifies that ISA strings are case-insensitive, in
Linux-land things are usually case-sensitive. Since this flag can be
used to determine library paths, we didn't want to bake some
case-insensitivity in there that would case trouble later.
This patch implements these two new flags and removes the old flags that
could conflict with these. There wasn't a RISC-V release before, so we
want to just support a clean flag set.
include/
* elf/riscv.h (EF_RISCV_SOFT_FLOAT): Don't define.
(EF_RISCV_FLOAT_ABI, EF_RISCV_FLOAT_ABI_SOFT): Define.
(EF_RISCV_FLOAT_ABI_SINGLE, EF_RISCV_FLOAT_ABI_DOUBLE): Define.
(EF_RISCV_FLOAT_ABI_QUAD): Define.
bfd/
* elfnn-riscv.c (_bfd_riscv_elf_merge_private_bfd_data): Use
EF_RISCV_FLOAT_ABI_SOFT instead of EF_RISCV_SOFT_FLOAT.
binutils/
* readelf.c (get_machine_flags): Use
EF_RISCV_FLOAT_ABI_{SOFT,SINGLE,DOBULE,QUAD) instead of
EF_RISCV_{SOFT,HARD}_FLOAT.
gas/
* config/tc-riscv.h (xlen): Delete.
* config/tc-riscv.c (xlen): Make static.
(abi_xlen): New variable.
(options): Replace OPTION_{M32,M64,MSOFT_FLOAT,MHARD_FLOAT,MRVC}
with OPTION_MABI.
(md_longopts): Likewise.
(md_parse_option): Likewise.
(riscv_elf_final_processing): Likewise.
* doc/as.texinfo (Target RISC-V options): Likewise.
* doc/c-riscv.texi (OPTIONS): Likewise.
* config/tc-riscv.c (float_mode): Removed.
(float_abi): New type, specifies the floating-point ABI.
(riscv_set_abi): New function.
(riscv_add_subset): Only allow lower-case ISA names and require
them to start with "rv".
(riscv_after_parse_args): Likewise.
opcodes/
* riscv-dis.c (riscv_disassemble_insn): Default to the ELF's
XLEN when none is provided.