有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
本帖最后由 皋陶 于 2021-3-6 15:30 编辑
Riscv中每个硬件线程(hart)有4096个独立地址空间的状态寄存器。我们可以通过Zicsr指令读写csr寄存器。总共有6条csr读写指令,这些指令之前都在RV32I/RV64I基础指令集里面,在最新文档中,被放在了Zicsr扩展指令集中。
6条指令的编码如下,其中[31-20]总共12位表示4096个csr寄存器地址。
| | csr | | | | | | | | | | | | | | | | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | rs1/imm | func3 | rd | opcode | name | type | 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 | csrrw | I | | | | | | | | | | | | | | | | | | 0 | 0 | 1 | | | | | | 1 | 1 | 1 | 0 | 0 | 1 | 1 | csrrs | I | | | | | | | | | | | | | | | | | | 0 | 1 | 0 | | | | | | 1 | 1 | 1 | 0 | 0 | 1 | 1 | csrrc | I | | | | | | | | | | | | | | | | | | 0 | 1 | 1 | | | | | | 1 | 1 | 1 | 0 | 0 | 1 | 1 | csrrwi | I | | | | | | | | | | | | | | | | | | 1 | 0 | 1 | | | | | | 1 | 1 | 1 | 0 | 0 | 1 | 1 | csrrsi | I | | | | | | | | | | | | | | | | | | 1 | 1 | 0 | | | | | | 1 | 1 | 1 | 0 | 0 | 1 | 1 | csrrci | I | | | | | | | | | | | | | | | | | | 1 | 1 | 1 | | | | | | 1 | 1 | 1 | 0 | 0 | 1 | 1 |
csr指令读写csr寄存器都是原子操作。 - 对于csrrw和csrwi,如果rd索引值为0,csr指令将不会发起csr寄存器的读操作,也不会带来任何读操作的副作用。
- 对于csrrs和csrrc指令而言,如果rs1的索引值为0,csr指令将不会发起csr寄存器的写操作,也不会带来任何写操作的副作用。
- 对于csrrsi和csrrci指令而言,如果立即数的索引值为0,csr指令将不会发起csr寄存器的写操作,也不会带来任何写操作的副作用。
下面介绍这六条指令的功能:
csrrwcsrrw rd, csr, zimm[4:0] //t = CSRs[csr]; CSRs[csr] = x[rs1]; x[rd] = t
读后写控制状态寄存器 (Control and Status Register Read and Write). I-type, RV32I and RV64I.
记控制状态寄存器 csr 中的值为 t。 把寄存器 x[rs1]的值写入 csr,再把 t 写入 x[rd]。 例子: to do
csrrscsrrs rd, csr, rs1 //t = CSRs[csr]; CSRs[csr] = t | x[rs1]; x[rd] = t
读后置位控制状态寄存器 (Control and Status Register Read and Set). I-type, RV32I and RV64I.
记控制状态寄存器 csr 中的值为 t。 把 t 和寄存器 x[rs1]按位或的结果写入 csr,再把 t 写入x[rd]。 例子: to do
csrrccsrrc rd, csr, rs1 //t = CSRs[csr]; CSRs[csr] = t &~x[rs1]; x[rd] = t
读后清除控制状态寄存器 (Control and Status Register Read and Clear). I-type, RV32I andRV64I.
记控制状态寄存器 csr 中的值为 t。 把 t 和寄存器 x[rs1]按位与的结果写入 csr,再把 t 写入x[rd] 例子: to do
csrrwicsrrwi rd, csr, zimm[4:0] //x[rd] = CSRs[csr]; CSRs[csr] = zimm
立即数读后写控制状态寄存器 (Control and Status Register Read and Write Immediate). I-type,RV32I and RV64I.
把控制状态寄存器 csr 中的值拷贝到 x[rd]中,再把五位的零扩展的立即数 zimm 的值写入csr。 例子: to do
csrrsicsrrsi rd, csr, zimm[4:0] //t = CSRs[csr]; CSRs[csr] = t | zimm; x[rd] = t
立即数读后设置控制状态寄存器 (Control and Status Register Read and Set Immediate). I-type,RV32I and RV64I.
记控制状态寄存器 csr 中的值为 t。 把 t 和五位的零扩展的立即数 zimm 按位或的结果写入csr,再把 t 写入 x[rd](csr 寄存器的第 5 位及更高位不变)。 例子: to do
csrrcicsrrci rd, csr, zimm[4:0] //t = CSRs[csr]; CSRs[csr] = t &~zimm; x[rd] = t
立即数读后清除控制状态寄存器 (Control and Status Register Read and Clear Immediate). Itype, RV32I and RV64I.
记控制状态寄存器 csr 中的值为 t。 把 t 和五位的零扩展的立即数 zimm 按位与的结果写入csr,再把 t 写入 x[rd](csr 寄存器的第 5 位及更高位不变)。 例子: to do
下面是一些常用的csr伪指令:
rdinstret[h] rd | csrrs rd,instret[h],x0 | 读取过时指令计数器 | rdcycle[h] rd | csrrs rd,cycle[h],x1 | 读取时钟周期计数器 | rdtime[h] rd | csrrs rd,time[h],x2 | 读取实时时钟 | csrr rd, csr | csrrs rd, csr,x0 | 读csr寄存器 | csrw csr,rs | csrrw x0,csr,rs | 写csr寄存器 | csrs csr,rs | csrrs x0,csr,rs | csr寄存器置位0 | csrc csr,rs | csrrc x0,csr,rs | csr寄存器清0 | csrwi csr,imm | csrrwi x0,csr,imm | 立即数写csr | csrsi csr,imm | csrrsi x1,csr,imm | 立即数置位csr | csrci csr,imm | csrrci x2,csr,imm | 立即数复位csr | frcsr rd | csrrs rd,frm,x0 | 读取fp舍入模式 | fscsr rs | csrrw x0,frm,rs | 写入fp舍入模式 | frflags rd | csrrs rd,fflags,x0 | 读取fp异常模式 | fsflags rs | csrrw x0,fflags,rs | 写入fp异常模式 |
fscsr rd,rs | csrrw rd,fcsr,rs | 交换fp控制状态寄存器 | fsrm rd,rs | csrrw rd,frm,rs | 交换fp舍入模式 | fsflags rd,rs | csrrw,rd,fflags,rs | 交换fp异常标志 |
完 |