[v2,3/4] RISC-V: Support the read-only CSR checking.

Message ID 1575358697-17241-4-git-send-email-nelson.chu@sifive.com
State New
Headers show
Series
  • [v2,1/4] RISC-V: Update the CSR to privilege spec 1.12.
Related show

Commit Message

Nelson Chu Dec. 3, 2019, 7:38 a.m.
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 (insn_with_csr): New boolean to indicate we are
	assembling instruction with CSR.
	(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.
	(riscv_ip): Call riscv_csr_read_only_check after parsing all arguments.
	* 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.
---
 gas/config/tc-riscv.c                              |  65 +++++
 .../gas/riscv/priv-reg-fail-read-only-01.d         |   3 +
 .../gas/riscv/priv-reg-fail-read-only-01.l         |  69 +++++
 .../gas/riscv/priv-reg-fail-read-only-01.s         | 295 +++++++++++++++++++++
 .../gas/riscv/priv-reg-fail-read-only-02.d         |   3 +
 .../gas/riscv/priv-reg-fail-read-only-02.l         |  25 ++
 .../gas/riscv/priv-reg-fail-read-only-02.s         |  90 +++++++
 7 files changed, 550 insertions(+)
 create mode 100644 gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.d
 create mode 100644 gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.l
 create mode 100644 gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.s
 create mode 100644 gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.d
 create mode 100644 gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.l
 create mode 100644 gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.s

-- 
2.7.4

Patch

diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c
index dd85194..7ab7de2 100644
--- a/gas/config/tc-riscv.c
+++ b/gas/config/tc-riscv.c
@@ -195,6 +195,9 @@  static bfd_boolean start_assemble = FALSE;
 /* Indicate arch attribute is explictly set.  */
 static bfd_boolean explicit_arch_attr = FALSE;
 
+/* Indicate we are assembling instruction with CSR.  */
+static bfd_boolean insn_with_csr = FALSE;
+
 /* Macros for encoding relaxation state for RVC branches and far jumps.  */
 #define RELAX_BRANCH_ENCODE(uncond, rvc, length)	\
   ((relax_substateT) 					\
@@ -1473,6 +1476,52 @@  riscv_handle_implicit_zero_offset (expressionS *ep, const char *s)
   return FALSE;
 }
 
+enum csr_insn_type
+{
+  INSN_NOT_CSR,
+  INSN_CSRRW,
+  INSN_CSRRS,
+  INSN_CSRRC
+};
+
+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.  */
@@ -1537,11 +1586,25 @@  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_csr_read_only_check (ip->insn_opcode))
+		    {
+		      /* Don't parse the next insn in the riscv_opcode.
+			 Otherwise, we will get multiple unexpected error
+			 message.  */
+		      error = _("Read-only CSR is used");
+		      insn_with_csr = FALSE;
+		      goto out;
+		    }
 		}
 	      if (*s != '\0')
 		break;
 	      /* Successful assembly.  */
 	      error = NULL;
+	      insn_with_csr = FALSE;
 	      goto out;
 
 	    case 'C': /* RVC */
@@ -1886,6 +1949,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
@@ -2206,6 +2270,7 @@  jump:
 	}
       s = argsStart;
       error = _("illegal operands");
+      insn_with_csr = FALSE;
     }
 
 out:
diff --git a/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.d b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.d
new file mode 100644
index 0000000..9c93d8a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.d
@@ -0,0 +1,3 @@ 
+#as: -march=rv32if
+#source: priv-reg-fail-read-only-01.s
+#error_output: priv-reg-fail-read-only-01.l
diff --git a/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.l b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.l
new file mode 100644
index 0000000..43beeb7
--- /dev/null
+++ b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.l
@@ -0,0 +1,69 @@ 
+.*Assembler messages:
+.*Error: Read-only CSR is used `csrw cycle,a1'
+.*Error: Read-only CSR is used `csrw time,a1'
+.*Error: Read-only CSR is used `csrw instret,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter3,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter4,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter5,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter6,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter7,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter8,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter9,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter10,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter11,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter12,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter13,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter14,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter15,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter16,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter17,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter18,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter19,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter20,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter21,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter22,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter23,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter24,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter25,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter26,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter27,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter28,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter29,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter30,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter31,a1'
+.*Error: Read-only CSR is used `csrw cycleh,a1'
+.*Error: Read-only CSR is used `csrw timeh,a1'
+.*Error: Read-only CSR is used `csrw instreth,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter3h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter4h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter5h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter6h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter7h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter8h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter9h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter10h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter11h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter12h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter13h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter14h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter15h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter16h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter17h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter18h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter19h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter20h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter21h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter22h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter23h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter24h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter25h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter26h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter27h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter28h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter29h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter30h,a1'
+.*Error: Read-only CSR is used `csrw hpmcounter31h,a1'
+.*Error: Read-only CSR is used `csrw mvendorid,a1'
+.*Error: Read-only CSR is used `csrw marchid,a1'
+.*Error: Read-only CSR is used `csrw mimpid,a1'
+.*Error: Read-only CSR is used `csrw mhartid,a1'
diff --git a/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.s b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.s
new file mode 100644
index 0000000..9e8937a
--- /dev/null
+++ b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.s
@@ -0,0 +1,295 @@ 
+# From priv spec 1.9.1 to 1.12 registers.
+
+	.macro csr val
+	csrw \val, a1
+	.endm
+
+# User-Level CSR Addresses in 1.12.
+	csr ustatus
+	csr uie
+	csr utvec
+
+	csr uscratch
+	csr uepc
+	csr ucause
+	csr utval
+	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
+
+# Supervisor-level CSR Addresses in 1.12.
+	csr sstatus
+	csr sedeleg
+	csr sideleg
+	csr sie
+	csr stvec
+	csr scounteren
+
+	csr sscratch
+	csr sepc
+	csr scause
+	csr stval
+	csr sip
+
+	csr satp
+
+# Hypervisor-Level CSR Addresses in 1.12.
+	csr hstatus
+	csr hedeleg
+	csr hideleg
+	csr hcounteren
+
+	csr hgatp
+
+	csr htimedelta
+	csr htimedeltah
+
+	csr vsstatus
+	csr vsie
+	csr vstvec
+	csr vsscratch
+	csr vsepc
+	csr vscause
+	csr vstval
+	csr vsip
+	csr vsatp
+
+# Machine-Level CSR Addresses in 1.12.
+	csr mvendorid
+	csr marchid
+	csr mimpid
+	csr mhartid
+
+	csr mstatus
+	csr misa
+	csr medeleg
+	csr mideleg
+	csr mie
+	csr mtvec
+	csr mcounteren
+	csr mstatush
+
+	csr mscratch
+	csr mepc
+	csr mcause
+	csr mtval
+	csr mip
+
+	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
+
+	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 mcountinhibit
+	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 dscratch0
+	csr dscratch1
+
+# Defined in 1.9.1, but alias for another CSR in 1.12.
+	csr ubadaddr	# utval
+	csr sbadaddr	# stval
+	csr sptbr	# satp
+	csr hie		# vsie
+	csr htvec	# vstvec
+	csr hscratch	# vsscratch
+	csr hepc	# vsepc
+	csr hcause	# vscause
+	csr hbadaddr	# vstval
+	csr hip		# vsip
+	csr mbadaddr	# mtval
+	csr mucounteren	# mcountinhibit
+
+# Defined in 1.9.1, but dropped in 1.10.
+	csr mscounteren
+	csr mhcounteren
+	csr mbase
+	csr mbound
+	csr mibase
+	csr mibound
+	csr mdbase
+	csr mdbound
+
+# Defined in 1.10, but dropped in 1.12.
+	csr dscratch	# dscratch0
diff --git a/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.d b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.d
new file mode 100644
index 0000000..ede45c5
--- /dev/null
+++ b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.d
@@ -0,0 +1,3 @@ 
+#as: -march=rv32if
+#source: priv-reg-fail-read-only-02.s
+#error_output: priv-reg-fail-read-only-02.l
diff --git a/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.l b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.l
new file mode 100644
index 0000000..dce8e0e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.l
@@ -0,0 +1,25 @@ 
+.*Assembler messages:
+.*Error: Read-only CSR is used `csrrw a0,cycle,a1'
+.*Error: Read-only CSR is used `csrrw a0,cycle,zero'
+.*Error: Read-only CSR is used `csrrw zero,cycle,a1'
+.*Error: Read-only CSR is used `csrrw zero,cycle,zero'
+.*Error: Read-only CSR is used `csrw cycle,a1'
+.*Error: Read-only CSR is used `csrw cycle,zero'
+.*Error: Read-only CSR is used `csrrwi a0,cycle,0xb'
+.*Error: Read-only CSR is used `csrrwi a0,cycle,0x0'
+.*Error: Read-only CSR is used `csrrwi zero,cycle,0xb'
+.*Error: Read-only CSR is used `csrrwi zero,cycle,0x0'
+.*Error: Read-only CSR is used `csrwi cycle,0xb'
+.*Error: Read-only CSR is used `csrwi cycle,0x0'
+.*Error: Read-only CSR is used `csrrs a0,cycle,a1'
+.*Error: Read-only CSR is used `csrrs zero,cycle,a1'
+.*Error: Read-only CSR is used `csrs cycle,a0'
+.*Error: Read-only CSR is used `csrrsi a0,cycle,0xb'
+.*Error: Read-only CSR is used `csrrsi zero,cycle,0xb'
+.*Error: Read-only CSR is used `csrsi cycle,0xb'
+.*Error: Read-only CSR is used `csrrc a0,cycle,a1'
+.*Error: Read-only CSR is used `csrrc zero,cycle,a1'
+.*Error: Read-only CSR is used `csrc cycle,a0'
+.*Error: Read-only CSR is used `csrrci a0,cycle,0xb'
+.*Error: Read-only CSR is used `csrrci zero,cycle,0xb'
+.*Error: Read-only CSR is used `csrci cycle,0xb'
diff --git a/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.s b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.s
new file mode 100644
index 0000000..7afb26e
--- /dev/null
+++ b/gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.s
@@ -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