首页/指令库/CSR读后清零
CSRRC

RISC-V CSRRC 指令详解

指令手册I-type

读取 CSR 旧值到 rd,并以 rs1 为位掩码原子清除 CSR 位;rs1=x0 时不写 CSR

指令语法

csrrc rd, csr, rs1
操作数说明
目标寄存器 rd:存放运算结果的通用寄存器。
源寄存器 rs1:第一个操作数所在的寄存器。
立即数 imm:12 位有符号立即数,符号扩展后与 rs1 进行运算。
ZicsrCSR操作系统

指令行为说明

CSRRC 是 Zicsr 的 CSR 原子读并清位指令:先读取 CSR 旧值并零扩展到 XLEN 写入 rd,再把 rs1 中为 1 的位作为掩码,清除目标 CSR 中对应位。若 rs1=x0,指令不写 CSR,也不产生 CSR 写副作用;此时仍读取 CSR。

CSRRC 指令解析与执行动画

展示 Zicsr CSR 读-改-写的 ISA 可见流程:解析 SYSTEM 编码、读取 CSR、按写/置位/清位语义计算,再更新 rd 与 CSR。

rd
csr
rs1
csrrc
,
,
执行环境
执行环境

CSR 名称/地址属于指令语法;旧 CSR 值和 rs1 示例值属于执行上下文。动画不赋予示例 CSR 任何具体平台字段含义。

31..20
19..15
14..12
11..7
6..0
011111000000
csr[11:0]
00110
rs1
011
funct3
00101
rd
1110011
opcode
执行数据路径
instruction
0x7C0332F3
opcode
1110011 -> SYSTEM
funct3
011 -> CSRRC
operands
rd=t0(x5), csr=0x7C0, rs1=t1(x6)
CSR read
0x7C0 -> 0x0000000A
rs1 source
t1(x6) -> 0x00000005
CSR update
CSR = 0x0000000A
rd update
t0(x5) = 0x0000000A
当前步骤

拿到 CSRRC 的 32-bit SYSTEM 编码

CSRRC 是 Zicsr 定义的 I-type SYSTEM 指令,CSR 地址位于 bits 31..20。

encoding: 0x7C0332F3
syntax : csrrc t0(x5), 0x7C0, t1(x6)
result : t0(x5) = 0x0000000A; CSR = 0x0000000A
CSR 位级结果
31
30
29
28
27
26
25
24
23
22
21
20
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
0
old CSR
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
0
1
mask
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
&~
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-

位级视图显示当前 XLEN 的 CSR 值计算。

该动画只展示 Zicsr 定义的 ISA 可见 CSR 读写、副作用抑制和位掩码语义;不模拟具体 CSR 字段含义、异常处理器、流水线或时序。

快速理解与检索要点

CSRRC 读取 CSR 旧值,并用 rs1 的 1 位作为清位掩码。rs1=x0 时仍读 CSR,但不写 CSR。

对普通读写位,CSRRC 的新 CSR 值可理解为 old_csr AND NOT rs1_mask;特殊 CSR 字段仍受官方读回值与字段副作用规则约束。
rs1=x0 抑制 CSR 写入和写副作用。
CSRRC 与 CSRRS 的区别是清位而不是置位。
CSR 地址高两位为 11 的只读 CSR 不能通过会写 CSR 的形式写入;这类写入会触发 illegal-instruction,CSRRS/CSRRC 的零源只读特例除外。

常见使用场景

原子与同步

结合 «csrrc x5, mip, x6 # x5 = old mip; clear bits in mip per x6» 等实际代码理解该场景。

系统与特权

结合 «csrrc x5, mip, x6 # x5 = old mip; clear bits in mip per x6» 等实际代码理解该场景。

使用前检查清单

语法检查
  • 确认当前指令格式为 I-type。
  • 确认操作数排列顺序与示例一致。
语义检查
  • 确认目标寄存器用途和调用约定兼容。
  • 确认该指令不是伪指令展开后的底层形式。

容易混淆 / 常见误区

rs1=x0 是只读特例,不会清除任何 CSR 位。
对普通读写位,CSRRC 只清除 rs1 为 1 的位;但若某些 CSR 位读回值不同于底层值,RMW 写回读值时可能影响掩码为 0 的位。
rd=x0 会丢弃旧值写回,但对 CSRRC 不抑制 CSR 读取。

常见问题

CSR 指令里的 atomic 是内存原子吗?

不是。Zicsr 里的 atomic 指 CSR 读和写在同一条 CSR 指令中完成,不是对内存地址执行 AMO。

rd=x0 和 rs1/uimm=0 的效果一样吗?

不一样。rd=x0 只在 CSRRW/CSRRWI 中抑制 CSR 读取;rs1=x0 或 uimm=0 只在 CSRRS/CSRRC 及其立即数形式中抑制 CSR 写入。