csrrc

Atomic Read and Clear Bits in CSR

This instruction is defined by:

Encoding

svg

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.

Access

M

HS

U

VS

VU

Always

Always

Always

Always

Always

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;

Exceptions

This instruction may result in the following synchronous exceptions:

  • IllegalInstruction