diff options
author | Nelson Chu <nelson.chu@sifive.com> | 2020-06-08 10:54:53 +0800 |
---|---|---|
committer | Nelson Chu <nelson.chu@sifive.com> | 2020-06-30 09:54:55 +0800 |
commit | 08ccfccf0ed825be9be2972594d4be4a2207ef13 (patch) | |
tree | 7908da4df49bac7d8959e58fc898780ec47f4154 /gas/config/tc-riscv.c | |
parent | 83d7d99e75538a1ce6facb2e5fb18f4f37f15991 (diff) | |
download | gdb-08ccfccf0ed825be9be2972594d4be4a2207ef13.zip gdb-08ccfccf0ed825be9be2972594d4be4a2207ef13.tar.gz gdb-08ccfccf0ed825be9be2972594d4be4a2207ef13.tar.bz2 |
RISC-V: Support debug and float CSR as the unprivileged ones.
The unprivileged CSR should be controlled by other specific specs rather
than the privileged spec. For example, the debug CSR should be controlled
by the debug spec, and the float CSR should be controlled by the float
spec. User may use assembler options to choose what the debug and other
specs they want, or may encode the versions of specs into the architecture
string directly. Since we haven't decided which one is better, we set the
defined and aborted versions of unprivileged CSR to PRIV_SPEC_CLASS_NONE
in the include/opcode/riscv-opc.h, to tell assembler don't check priv spec
versions for them. However, these PRIV_SPEC_CLASS_NONE will be changed
to FLOAT_SPEC_CLASS_* and DEBUG_SPEC_CLASS_* in the future.
gas/
* config/tc-riscv.c (riscv_csr_class_check): Removed. Move the
checking into riscv_csr_address.
(riscv_csr_version_check): Likewise.
(riscv_csr_address): New function. Return the suitable CSR address
after checking the ISA dependency and versions. Issue warnings if
we find any conflict and -mcsr-check is set. CSR_CLASS_F and
CSR_CLASS_DEBUG are unprivileged CSR for now, so don't check the
priv spec versions for them.
(reg_csr_lookup_internal): Call riscv_csr_address to find the
suitable CSR address.
* testsuite/gas/riscv/priv-reg-fail-fext.d: Remove -mpriv-spec=1.11.
* testsuite/gas/riscv/priv-reg-fail-read-only-01.d: Likewise.
* testsuite/gas/riscv/priv-reg-fail-rv32-only.d: Likewise.
* testsuite/gas/riscv/priv-reg-fail-fext.l: We don't care the
priv spec warnings here. These warnings are added by accident.
Remove them and only focus on the ISA dependency warnings.
* testsuite/gas/riscv/priv-reg-fail-rv32-only.l: Likewise.
* testsuite/gas/riscv/priv-reg-fail-read-only-01.l: Likewise.
* testsuite/gas/riscv/priv-reg-fail-version-1p9.l: Updated since
dscratch0 and dscratch1 are regarded as the unprivileged CSR rather
than the privileged ones.
* testsuite/gas/riscv/priv-reg-fail-version-1p9p1.l: Likewise.
* testsuite/gas/riscv/priv-reg-fail-version-1p10.l: Likewise.
* testsuite/gas/riscv/priv-reg-fail-version-1p11.l: Likewise.
* testsuite/gas/riscv/priv-reg.s: Likewise. Add missing debug CSR.
* testsuite/gas/riscv/priv-reg-version-1p9.d: Likewise.
* testsuite/gas/riscv/priv-reg-version-1p9p1.d: Likewise.
* testsuite/gas/riscv/priv-reg-version-1p10.d: Likewise.
* testsuite/gas/riscv/priv-reg-version-1p11.d: Likewise.
* testsuite/gas/riscv/csr-dw-regnums.d: Likewise.
* testsuite/gas/riscv/csr-dw-regnums.s: Likewise.
include/
* opcode/riscv-opc.h: Support the unprivileged CSR. The versions
of the unprivileged CSR should be PRIV_SPEC_CLASS_NONE for now.
* opcode/riscv.h (enum riscv_csr_class): Add CSR_CLASS_DEBUG.
opcodes/
* riscv-dis.c (print_insn_args, case 'E'): Updated. Let the
unprivileged CSR can also be initialized.
Diffstat (limited to 'gas/config/tc-riscv.c')
-rw-r--r-- | gas/config/tc-riscv.c | 53 |
1 files changed, 24 insertions, 29 deletions
diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index ca62f46..28be198 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -700,53 +700,49 @@ riscv_init_csr_hash (const char *name, pre_entry->next = entry; } -/* Check wether the CSR is valid according to the ISA. */ +/* Return the suitable CSR address after checking the ISA dependency and + priv spec versions. */ -static void -riscv_csr_class_check (const char *s, - enum riscv_csr_class csr_class) +static unsigned int +riscv_csr_address (const char *csr_name, + struct riscv_csr_extra *entry) { + struct riscv_csr_extra *saved_entry = entry; + enum riscv_csr_class csr_class = entry->csr_class; + bfd_boolean need_check_version = TRUE; bfd_boolean result = TRUE; - /* Don't check the ISA dependency when -mcsr-check isn't set. */ - if (!riscv_opts.csr_check) - return; - switch (csr_class) { case CSR_CLASS_I: result = riscv_subset_supports ("i"); break; + case CSR_CLASS_I_32: + result = (xlen == 32 && riscv_subset_supports ("i")); + break; case CSR_CLASS_F: result = riscv_subset_supports ("f"); + need_check_version = FALSE; break; - case CSR_CLASS_I_32: - result = (xlen == 32 && riscv_subset_supports ("i")); + case CSR_CLASS_DEBUG: + need_check_version = FALSE; break; default: as_bad (_("internal: bad RISC-V CSR class (0x%x)"), csr_class); } - if (!result) - as_warn (_("Invalid CSR `%s' for the current ISA"), s); -} - -/* Check and find the CSR address according to the privilege spec version. */ - -static void -riscv_csr_version_check (const char *csr_name, - struct riscv_csr_extra **entryP) -{ - struct riscv_csr_extra *entry = *entryP; + /* Don't report the ISA conflict when -mcsr-check isn't set. */ + if (riscv_opts.csr_check && !result) + as_warn (_("Invalid CSR `%s' for the current ISA"), csr_name); while (entry != NULL) { - if (default_priv_spec >= entry->define_version - && default_priv_spec < entry->abort_version) + if (!need_check_version + || (default_priv_spec >= entry->define_version + && default_priv_spec < entry->abort_version)) { /* Find the suitable CSR according to the specific version. */ - *entryP = entry; - return; + return entry->address; } entry = entry->next; } @@ -763,6 +759,8 @@ riscv_csr_version_check (const char *csr_name, as_warn (_("Invalid CSR `%s' for the privilege spec `%s'"), csr_name, priv_name); } + + return saved_entry->address; } /* Once the CSR is defined, including the old privilege spec, then we call @@ -785,10 +783,7 @@ reg_csr_lookup_internal (const char *s) will regard it as a "Unknown CSR" and report error. If user use number to set the CSR, but over the range (> 0xfff), then assembler will report "Improper CSR" error for it. */ - riscv_csr_class_check (s, r->csr_class); - riscv_csr_version_check (s, &r); - - return r->address; + return riscv_csr_address (s, r); } static unsigned int |