RISC-V: Support the read-only CSR checking.
authorNelson Chu <nelson.chu@sifive.com>
Wed, 12 Feb 2020 10:18:51 +0000 (02:18 -0800)
committerJim Wilson <jimw@sifive.com>
Fri, 21 Feb 2020 00:49:09 +0000 (16:49 -0800)
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.

gas/ChangeLog
gas/config/tc-riscv.c
gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.d [new file with mode: 0644]
gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.l [new file with mode: 0644]
gas/testsuite/gas/riscv/priv-reg-fail-read-only-01.s [new file with mode: 0644]
gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.d [new file with mode: 0644]
gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.l [new file with mode: 0644]
gas/testsuite/gas/riscv/priv-reg-fail-read-only-02.s [new file with mode: 0644]

index 643f8c7e45b7aad714a522a33a17f60243d7560b..d47235320185770089f3e38c166cc249db5e399f 100644 (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`
index 5972f02656d61698dd1f7c2ba53bf4ef4f98e6f9..1559b08402a05f0953d2c6ad264f0ed63982c6e5 100644 (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:
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 (file)
index 0000000..ae190c0
--- /dev/null
@@ -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
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 (file)
index 0000000..7e52bd7
--- /dev/null
@@ -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'
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 (file)
index 0000000..501a52e
--- /dev/null
@@ -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
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 (file)
index 0000000..3c4715f
--- /dev/null
@@ -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
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 (file)
index 0000000..660f19d
--- /dev/null
@@ -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'
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 (file)
index 0000000..7afb26e
--- /dev/null
@@ -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