RISC-V: Support the read-only CSR checking.

CSRRW and CSRRWI always write CSR.  CSRRS, CSRRC, CSRRSI and CSRRCI write CSR
when RS1 isn't zero.  The CSR is read only if the [11:10] bits of CSR address
is 0x3.  The read-only CSR can not be written by the CSR instructions.

	gas/
	* config/tc-riscv.c (riscv_ip): New boolean insn_with_csr to indicate
	we are assembling instruction with CSR.  Call riscv_csr_read_only_check
	after parsing all arguments.
	(enum csr_insn_type): New enum is used to classify the CSR instruction.
	(riscv_csr_insn_type, riscv_csr_read_only_check): New functions.  These
	are used to check if we write a read-only CSR by the CSR instruction.

	* testsuite/gas/riscv/priv-reg-fail-read-only-01.s: New testcase.  Test
	all CSR for the read-only CSR checking.
	* testsuite/gas/riscv/priv-reg-fail-read-only-01.d: Likewise.
	* testsuite/gas/riscv/priv-reg-fail-read-only-01.l: Likewise.
	* testsuite/gas/riscv/priv-reg-fail-read-only-02.s: New testcase.  Test
	all CSR instructions for the read-only CSR checking.
	* testsuite/gas/riscv/priv-reg-fail-read-only-02.d: Likewise.
	* testsuite/gas/riscv/priv-reg-fail-read-only-02.l: Likewise.
This commit is contained in:
Nelson Chu 2020-02-12 02:18:51 -08:00 committed by Jim Wilson
parent 2ca89224b1
commit 54b2aec10d
8 changed files with 543 additions and 0 deletions

View File

@ -1,5 +1,20 @@
2020-02-20 Nelson Chu <nelson.chu@sifive.com>
* config/tc-riscv.c (riscv_ip): New boolean insn_with_csr to indicate
we are assembling instruction with CSR. Call riscv_csr_read_only_check
after parsing all arguments.
(enum csr_insn_type): New enum is used to classify the CSR instruction.
(riscv_csr_insn_type, riscv_csr_read_only_check): New functions. These
are used to check if we write a read-only CSR by the CSR instruction.
* testsuite/gas/riscv/priv-reg-fail-read-only-01.s: New testcase. Test
all CSR for the read-only CSR checking.
* testsuite/gas/riscv/priv-reg-fail-read-only-01.d: Likewise.
* testsuite/gas/riscv/priv-reg-fail-read-only-01.l: Likewise.
* testsuite/gas/riscv/priv-reg-fail-read-only-02.s: New testcase. Test
all CSR instructions for the read-only CSR checking.
* testsuite/gas/riscv/priv-reg-fail-read-only-02.d: Likewise.
* testsuite/gas/riscv/priv-reg-fail-read-only-02.l: Likewise.
* config/tc-riscv.c (struct riscv_set_options): New field csr_check.
(riscv_opts): Initialize it.
(reg_lookup_internal): Check the `riscv_opts.csr_check`

View File

@ -1486,6 +1486,56 @@ riscv_handle_implicit_zero_offset (expressionS *ep, const char *s)
return FALSE;
}
/* All RISC-V CSR instructions belong to one of these classes. */
enum csr_insn_type
{
INSN_NOT_CSR,
INSN_CSRRW,
INSN_CSRRS,
INSN_CSRRC
};
/* Return which CSR instruction is checking. */
static enum csr_insn_type
riscv_csr_insn_type (insn_t insn)
{
if (((insn ^ MATCH_CSRRW) & MASK_CSRRW) == 0
|| ((insn ^ MATCH_CSRRWI) & MASK_CSRRWI) == 0)
return INSN_CSRRW;
else if (((insn ^ MATCH_CSRRS) & MASK_CSRRS) == 0
|| ((insn ^ MATCH_CSRRSI) & MASK_CSRRSI) == 0)
return INSN_CSRRS;
else if (((insn ^ MATCH_CSRRC) & MASK_CSRRC) == 0
|| ((insn ^ MATCH_CSRRCI) & MASK_CSRRCI) == 0)
return INSN_CSRRC;
else
return INSN_NOT_CSR;
}
/* CSRRW and CSRRWI always write CSR. CSRRS, CSRRC, CSRRSI and CSRRCI write
CSR when RS1 isn't zero. The CSR is read only if the [11:10] bits of
CSR address is 0x3. */
static bfd_boolean
riscv_csr_read_only_check (insn_t insn)
{
int csr = (insn & (OP_MASK_CSR << OP_SH_CSR)) >> OP_SH_CSR;
int rs1 = (insn & (OP_MASK_RS1 << OP_SH_RS1)) >> OP_SH_RS1;
int readonly = (((csr & (0x3 << 10)) >> 10) == 0x3);
enum csr_insn_type csr_insn = riscv_csr_insn_type (insn);
if (readonly
&& (((csr_insn == INSN_CSRRS
|| csr_insn == INSN_CSRRC)
&& rs1 != 0)
|| csr_insn == INSN_CSRRW))
return FALSE;
return TRUE;
}
/* This routine assembles an instruction into its binary format. As a
side effect, it sets the global variable imm_reloc to the type of
relocation to do if one of the operands is an address expression. */
@ -1504,6 +1554,8 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
int argnum;
const struct percent_op_match *p;
const char *error = "unrecognized opcode";
/* Indicate we are assembling instruction with CSR. */
bfd_boolean insn_with_csr = FALSE;
/* Parse the name of the instruction. Terminate the string if whitespace
is found so that hash_find only sees the name part of the string. */
@ -1550,11 +1602,26 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr,
: insn->match) == 2
&& !riscv_opts.rvc)
break;
/* Check if we write a read-only CSR by the CSR
instruction. */
if (insn_with_csr
&& riscv_opts.csr_check
&& !riscv_csr_read_only_check (ip->insn_opcode))
{
/* Restore the character in advance, since we want to
report the detailed warning message here. */
if (save_c)
*(argsStart - 1) = save_c;
as_warn (_("Read-only CSR is written `%s'"), str);
insn_with_csr = FALSE;
}
}
if (*s != '\0')
break;
/* Successful assembly. */
error = NULL;
insn_with_csr = FALSE;
goto out;
case 'C': /* RVC */
@ -1899,6 +1966,7 @@ rvc_lui:
continue;
case 'E': /* Control register. */
insn_with_csr = TRUE;
if (reg_lookup (&s, RCLASS_CSR, &regno))
INSERT_OPERAND (CSR, *ip, regno);
else
@ -2219,6 +2287,7 @@ jump:
}
s = argsStart;
error = _("illegal operands");
insn_with_csr = FALSE;
}
out:

View File

@ -0,0 +1,3 @@
#as: -march=rv32if -mcsr-check
#source: priv-reg-fail-read-only-01.s
#warning_output: priv-reg-fail-read-only-01.l

View File

@ -0,0 +1,69 @@
.*Assembler messages:
.*Warning: Read-only CSR is written `csrw cycle,a1'
.*Warning: Read-only CSR is written `csrw time,a1'
.*Warning: Read-only CSR is written `csrw instret,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter3,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter4,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter5,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter6,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter7,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter8,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter9,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter10,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter11,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter12,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter13,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter14,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter15,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter16,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter17,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter18,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter19,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter20,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter21,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter22,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter23,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter24,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter25,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter26,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter27,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter28,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter29,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter30,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter31,a1'
.*Warning: Read-only CSR is written `csrw cycleh,a1'
.*Warning: Read-only CSR is written `csrw timeh,a1'
.*Warning: Read-only CSR is written `csrw instreth,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter3h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter4h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter5h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter6h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter7h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter8h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter9h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter10h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter11h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter12h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter13h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter14h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter15h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter16h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter17h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter18h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter19h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter20h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter21h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter22h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter23h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter24h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter25h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter26h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter27h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter28h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter29h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter30h,a1'
.*Warning: Read-only CSR is written `csrw hpmcounter31h,a1'
.*Warning: Read-only CSR is written `csrw mvendorid,a1'
.*Warning: Read-only CSR is written `csrw marchid,a1'
.*Warning: Read-only CSR is written `csrw mimpid,a1'
.*Warning: Read-only CSR is written `csrw mhartid,a1'

View File

@ -0,0 +1,269 @@
.macro csr val
csrw \val, a1
.endm
# 1.9.1 registers
csr ustatus
csr uie
csr utvec
csr uscratch
csr uepc
csr ucause
csr ubadaddr
csr uip
csr fflags
csr frm
csr fcsr
csr cycle
csr time
csr instret
csr hpmcounter3
csr hpmcounter4
csr hpmcounter5
csr hpmcounter6
csr hpmcounter7
csr hpmcounter8
csr hpmcounter9
csr hpmcounter10
csr hpmcounter11
csr hpmcounter12
csr hpmcounter13
csr hpmcounter14
csr hpmcounter15
csr hpmcounter16
csr hpmcounter17
csr hpmcounter18
csr hpmcounter19
csr hpmcounter20
csr hpmcounter21
csr hpmcounter22
csr hpmcounter23
csr hpmcounter24
csr hpmcounter25
csr hpmcounter26
csr hpmcounter27
csr hpmcounter28
csr hpmcounter29
csr hpmcounter30
csr hpmcounter31
csr cycleh
csr timeh
csr instreth
csr hpmcounter3h
csr hpmcounter4h
csr hpmcounter5h
csr hpmcounter6h
csr hpmcounter7h
csr hpmcounter8h
csr hpmcounter9h
csr hpmcounter10h
csr hpmcounter11h
csr hpmcounter12h
csr hpmcounter13h
csr hpmcounter14h
csr hpmcounter15h
csr hpmcounter16h
csr hpmcounter17h
csr hpmcounter18h
csr hpmcounter19h
csr hpmcounter20h
csr hpmcounter21h
csr hpmcounter22h
csr hpmcounter23h
csr hpmcounter24h
csr hpmcounter25h
csr hpmcounter26h
csr hpmcounter27h
csr hpmcounter28h
csr hpmcounter29h
csr hpmcounter30h
csr hpmcounter31h
csr sstatus
csr sedeleg
csr sideleg
csr sie
csr stvec
csr sscratch
csr sepc
csr scause
csr sbadaddr
csr sip
csr sptbr
csr hstatus
csr hedeleg
csr hideleg
csr hie
csr htvec
csr hscratch
csr hepc
csr hcause
csr hbadaddr
csr hip
csr mvendorid
csr marchid
csr mimpid
csr mhartid
csr mstatus
csr misa
csr medeleg
csr mideleg
csr mie
csr mtvec
csr mscratch
csr mepc
csr mcause
csr mbadaddr
csr mip
csr mbase
csr mbound
csr mibase
csr mibound
csr mdbase
csr mdbound
csr mcycle
csr minstret
csr mhpmcounter3
csr mhpmcounter4
csr mhpmcounter5
csr mhpmcounter6
csr mhpmcounter7
csr mhpmcounter8
csr mhpmcounter9
csr mhpmcounter10
csr mhpmcounter11
csr mhpmcounter12
csr mhpmcounter13
csr mhpmcounter14
csr mhpmcounter15
csr mhpmcounter16
csr mhpmcounter17
csr mhpmcounter18
csr mhpmcounter19
csr mhpmcounter20
csr mhpmcounter21
csr mhpmcounter22
csr mhpmcounter23
csr mhpmcounter24
csr mhpmcounter25
csr mhpmcounter26
csr mhpmcounter27
csr mhpmcounter28
csr mhpmcounter29
csr mhpmcounter30
csr mhpmcounter31
csr mcycleh
csr minstreth
csr mhpmcounter3h
csr mhpmcounter4h
csr mhpmcounter5h
csr mhpmcounter6h
csr mhpmcounter7h
csr mhpmcounter8h
csr mhpmcounter9h
csr mhpmcounter10h
csr mhpmcounter11h
csr mhpmcounter12h
csr mhpmcounter13h
csr mhpmcounter14h
csr mhpmcounter15h
csr mhpmcounter16h
csr mhpmcounter17h
csr mhpmcounter18h
csr mhpmcounter19h
csr mhpmcounter20h
csr mhpmcounter21h
csr mhpmcounter22h
csr mhpmcounter23h
csr mhpmcounter24h
csr mhpmcounter25h
csr mhpmcounter26h
csr mhpmcounter27h
csr mhpmcounter28h
csr mhpmcounter29h
csr mhpmcounter30h
csr mhpmcounter31h
csr mucounteren
csr mscounteren
csr mhcounteren
csr mhpmevent3
csr mhpmevent4
csr mhpmevent5
csr mhpmevent6
csr mhpmevent7
csr mhpmevent8
csr mhpmevent9
csr mhpmevent10
csr mhpmevent11
csr mhpmevent12
csr mhpmevent13
csr mhpmevent14
csr mhpmevent15
csr mhpmevent16
csr mhpmevent17
csr mhpmevent18
csr mhpmevent19
csr mhpmevent20
csr mhpmevent21
csr mhpmevent22
csr mhpmevent23
csr mhpmevent24
csr mhpmevent25
csr mhpmevent26
csr mhpmevent27
csr mhpmevent28
csr mhpmevent29
csr mhpmevent30
csr mhpmevent31
csr tselect
csr tdata1
csr tdata2
csr tdata3
csr dcsr
csr dpc
csr dscratch
# 1.10 registers
csr utval
csr scounteren
csr stval
csr satp
csr mcounteren
csr mtval
csr pmpcfg0
csr pmpcfg1
csr pmpcfg2
csr pmpcfg3
csr pmpaddr0
csr pmpaddr1
csr pmpaddr2
csr pmpaddr3
csr pmpaddr4
csr pmpaddr5
csr pmpaddr6
csr pmpaddr7
csr pmpaddr8
csr pmpaddr9
csr pmpaddr10
csr pmpaddr11
csr pmpaddr12
csr pmpaddr13
csr pmpaddr14
csr pmpaddr15

View File

@ -0,0 +1,3 @@
#as: -march=rv32if -mcsr-check
#source: priv-reg-fail-read-only-02.s
#warning_output: priv-reg-fail-read-only-02.l

View File

@ -0,0 +1,25 @@
.*Assembler messages:
.*Warning: Read-only CSR is written `csrrw a0,cycle,a1'
.*Warning: Read-only CSR is written `csrrw a0,cycle,zero'
.*Warning: Read-only CSR is written `csrrw zero,cycle,a1'
.*Warning: Read-only CSR is written `csrrw zero,cycle,zero'
.*Warning: Read-only CSR is written `csrw cycle,a1'
.*Warning: Read-only CSR is written `csrw cycle,zero'
.*Warning: Read-only CSR is written `csrrwi a0,cycle,0xb'
.*Warning: Read-only CSR is written `csrrwi a0,cycle,0x0'
.*Warning: Read-only CSR is written `csrrwi zero,cycle,0xb'
.*Warning: Read-only CSR is written `csrrwi zero,cycle,0x0'
.*Warning: Read-only CSR is written `csrwi cycle,0xb'
.*Warning: Read-only CSR is written `csrwi cycle,0x0'
.*Warning: Read-only CSR is written `csrrs a0,cycle,a1'
.*Warning: Read-only CSR is written `csrrs zero,cycle,a1'
.*Warning: Read-only CSR is written `csrs cycle,a0'
.*Warning: Read-only CSR is written `csrrsi a0,cycle,0xb'
.*Warning: Read-only CSR is written `csrrsi zero,cycle,0xb'
.*Warning: Read-only CSR is written `csrsi cycle,0xb'
.*Warning: Read-only CSR is written `csrrc a0,cycle,a1'
.*Warning: Read-only CSR is written `csrrc zero,cycle,a1'
.*Warning: Read-only CSR is written `csrc cycle,a0'
.*Warning: Read-only CSR is written `csrrci a0,cycle,0xb'
.*Warning: Read-only CSR is written `csrrci zero,cycle,0xb'
.*Warning: Read-only CSR is written `csrci cycle,0xb'

View File

@ -0,0 +1,90 @@
# CSRRW and CSRRWI always write CSR
# CSRRS, CSRRC, CSRRSI and CSRRCI write CSR when rs isn't zero.
# csrrw rd, csr, rs
csrrw a0, ustatus, a1
csrrw a0, cycle, a1
csrrw a0, cycle, zero
csrrw zero, cycle, a1
csrrw zero, cycle, zero
fscsr a0, a1
fsrm a0, a1
fsflags a0, a1
# csrrw zero, csr, rs
csrw ustatus, a1
csrw cycle, a1
csrw cycle, zero
fscsr a1
fsrm a1
fsflags a1
# csrrwi rd, csr, imm
csrrwi a0, ustatus, 0xb
csrrwi a0, cycle, 0xb
csrrwi a0, cycle, 0x0
csrrwi zero, cycle, 0xb
csrrwi zero, cycle, 0x0
# csrrwi zero, csr, imm
csrwi ustatus, 0xb
csrwi cycle, 0xb
csrwi cycle, 0x0
# csrrs rd, csr, rs
csrrs a0, ustatus, a1
csrrs a0, cycle, a1
csrrs a0, cycle, zero
csrrs zero, cycle, a1
csrrs zero, cycle, zero
# csrrs rd, csr, zero
csrr a0, ustatus
csrr a0, cycle
csrr zero, cycle
rdinstret a0
rdinstret zero
rdinstreth a0
rdinstreth zero
rdcycle a0
rdcycle zero
rdcycleh a0
rdcycleh zero
rdtime a0
rdtime zero
rdtimeh a0
rdtimeh zero
frcsr a0
frrm a0
frflags a0
# csrrs zero, csr, rs
csrs ustatus, a0
csrs cycle, a0
csrs cycle, zero
# csrrsi rd, csr, imm
csrrsi a0, ustatus, 0xb
csrrsi a0, cycle, 0xb
csrrsi a0, cycle, 0x0
csrrsi zero, cycle, 0xb
csrrsi zero, cycle, 0x0
# csrrsi zero, csr, imm
csrsi ustatus, 0xb
csrsi cycle, 0xb
csrsi cycle, 0x0
# csrrc a0, csr, a1
csrrc a0, ustatus, a1
csrrc a0, cycle, a1
csrrc a0, cycle, zero
csrrc zero, cycle, a1
csrrc zero, cycle, zero
# csrrc zero, csr, rs
csrc ustatus, a0
csrc cycle, a0
csrc cycle, zero
# csrrci rd, csr, imm
csrrci a0, ustatus, 0xb
csrrci a0, cycle, 0xb
csrrci a0, cycle, 0x0
csrrci zero, cycle, 0xb
csrrci zero, cycle, 0x0
# csrrci zero, csr, imm
csrci ustatus, 0xb
csrci cycle, 0xb
csrci cycle, 0x0