csrrc
Atomic Read and Clear Bits in CSR
This instruction is defined by:
Synopsis
The CSRRC (Atomic Read and Clear Bits in CSR) instruction reads the value of the CSR, zero-extends
the value to XLEN bits, and writes it to integer register rd
. The initial value in integer register rs1
is
treated as a bit mask that specifies bit positions to be cleared in the CSR. Any bit that is high in rs1
will
cause the corresponding bit to be cleared in the CSR, if that CSR bit is writable.
For CSRRC, if rs1=x0
, then the instruction will not write to the CSR at all, and so shall
not cause any of the side effects that might otherwise occur on a CSR write, nor raise illegal-
instruction exceptions on accesses to read-only CSRs. CSRRC always reads the addressed CSR and
cause any read side effects regardless of rs1
and rd
fields.
Note that if rs1
specifies a register other than x0
, and that register holds a zero value,
the instruction will not action any attendant per-field side effects, but will action any
side effects caused by writing to the entire CSR.
Decode Variables
Bits<12> csr = $encoding[31:20];
Bits<5> xs1 = $encoding[19:15];
Bits<5> xd = $encoding[11:7];
Execution
-
Pruned, XLEN == 64
-
Original
Csr csr_handle = direct_csr_lookup(csr);
Boolean will_write = xs1 != 0;
if (csr_handle.valid == false) {
unimplemented_csr($encoding);
} else if (!compatible_mode?(csr_handle.mode, mode())) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if (will_write && csr_handle.writable == false) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}
XReg initial_csr_value = csr_sw_read(csr_handle);
if (xs1 != 0) {
XReg mask = X[xs1];
csr_sw_write(csr_handle, initial_csr_value & ~mask);
}
X[xd] = initial_csr_value;
Csr csr_handle = direct_csr_lookup(csr);
Boolean will_write = xs1 != 0;
if (csr_handle.valid == false) {
unimplemented_csr($encoding);
} else if (!compatible_mode?(csr_handle.mode, mode())) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
} else if (will_write && csr_handle.writable == false) {
raise(ExceptionCode::IllegalInstruction, mode(), $encoding);
}
XReg initial_csr_value = csr_sw_read(csr_handle);
if (xs1 != 0) {
XReg mask = X[xs1];
csr_sw_write(csr_handle, initial_csr_value & ~mask);
}
X[xd] = initial_csr_value;