RV32A/RV64A指令集
RV32A/RV64A指令包括两类:AMO(atomic memory operation)指令,Load-Reserved/Store-Conditional指令
计算机体系结构中的存储器模型(或者说存储器一致性模型)主要分为三类:按序一致性模型,松散一致性模型,释放一致性模型。
更详细存储器一致性介绍请看:https://blog.csdn.net/jfengamarsoft/article/details/70923658?utm_source=blogxgwz2
按序一致性模型的两条规则:
- 各个处理器核按照其程序顺序来执行,执行完一条后启动执行下一条指令,不能改变存储器访问指令的顺序(即便访问的是不同的存储器地址)。
- 从全局看,每一个存储器写指令的操作都需要能够被系统中的所有处理器核同时观测到。就好像处理器系统(包括所有的处理器核)和存储系统之间有一个开关,一次只会连接一个处理器核和存储系统,因此对存储器的访问都是原子的,串行化的。
松散一致性模型:对于不同存储器访问指令,就单核而言,理论上是可以改变其执行顺序的。松散一致性模型允许多核系统中,每个单核改变其存储器访问指令(比如是访问不同的地址)的执行顺序。松散一致性模型可以通过fence指令,来同步多核之间的存储器访问。在fence之前的所有存储器访问指令,必须比该fence指令之后的所有存储器访问指令先执行。
释放一致性模型进一步支持获取(acquire)释放(release)机制:
- 定义一种获取acquire指令,它仅屏障其之前的所有存储器访问操作。
- 定义一种释放release指令,它仅屏障其之后的所有存储器访问。
AMO指令要求整个读出,计算,写回必须为原子性质,就是读出和写回之间,该存储器地址不能被其它进程访问,通常总线会锁定。
AMO指令也可以支持释放一致性模型,可以通过指令中的aq/rl位,来设置获取或释放属性。
amoswap.w rd, rs2,(rs1) 指令不具有获取和释放属性,不具备屏障功能。
amoswap.w.aq rd, rs2,(rs1) 指令具有获取属性,能够屏蔽其之后的所有存储器访问操作。
amoswap.w.rl rd, rs2,(rs1)指令具有释放属性,能够屏蔽其之前的所有存储器访问操作。
amoswap.w.aqrl rd, rs2,(rs1)指令具有获取释放属性,能够屏蔽其之前之后的所有存储器访问操作。
AMO指令实现上锁操作例子:
li t0, 1 #t0寄存器初始值为1 again: amoswap.w.aq t0, t0, (a0) bnez t0, again #如果锁中的值非0,意味着当前的锁仍然被其它进程占用,因此从新读取该锁的值。 … critical section … amoswap.w.rl x0, x0,(a0) #写操作完成,向锁中写0
对于RV32A,LR/SC指令访问的地址,必须32位对齐,否则会产生异常,LR/SC指令也支持释放一致性模型,和AMO指令类似。
LR指令用于从存储器中(地址为rs1寄存器的值指定)读出一个32/64位数据,存放至rd寄存器中。
SC指令用于向存储器(地址为rs1寄存器的值指定)中写入一个32/64位数据,数据的值来自于rs2寄存器中的值。SC指令不一定执行成功,只有满足如下条件,SC指令才能执行成功。
- LR和SC指令成对地访问相同的地址。
- LR和SC指令之间没有任何其它的写操作(来自任何一个hart)访问同样的地址。
- LR和SC指令之间没有任何中断与异常发生。
- LR和SC指令之间没有执行MRET指令。
如果执行成功,则向rd寄存器写回数值0,如果执行失败,则向rd寄存器写回一个非0值。如果执行失败,意味着没有真正写入存储器。
LR/SC 能够实现lock-free 数据结构.
下面是一个inline的比较交换函数,仅需要3条指令。
# a0 holds address of memory location # a1 holds expected value # a2 holds desired value # a0 holds return value, 0 if successful, !0 otherwise cas: lr.w t0, (a0) # Load original value. bne t0, a1, fail # Doesn’t match, so fail. sc.w a0, a2, (a0) # Try to update. jr ra # Return. fail: li a0, 1 # Set return to failure. jr ra # Return.
RV32A/RV64A都支持的原子指令共11条,另外还有11条指令仅支持RV64A。
amoadd.d
amoadd.d rd, rs2, (rs1) //x[rd] = AMO64(M[x[rs1]] + x[rs2])
原子加双字(Atomic Memory Operation: Add Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 t+x[rs2],把x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amoadd.d | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
0: 003332af amoadd.d x5,x3,(x6)
amoadd.w
amoadd.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] + x[rs2])
原子加字(Atomic Memory Operation: Add Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 t+x[rs2],把 x[rd]设为符号位扩展的 t。
aq | rl | rs2 | rs1 | 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 |
amoadd.w | R | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
4: 003322af amoadd.w x5,x3,(x6)amoand.d
amoand.d rd, rs2, (rs1) //x[rd] = AMO64(M[x[rs1]] & x[rs2])
原子双字与 (Atomic Memory Operation: AND Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 t 和 x[rs2]位与的结果, 把 x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amoand.d | R | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
8: 603332af amoand.d x5,x3,(x6)amoand.w
amoand.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] & x[rs2])
原子字与 (Atomic Memory Operation: AND Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 t 和 x[rs2]位与的结果, 把 x[rd]设为符号位扩展的 t
aq | rl | rs2 | rs1 | 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 |
amoand.w | R | 0 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
c: 603322af amoand.w x5,x3,(x6)amomax.d
amomax.d rd, rs2, (rs1) //x[rd] = AMO64(M[x[rs1]] MAX x[rs2])
原子最大双字(Atomic Memory Operation: Maximum Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 t 和 x[rs2]中较大的一个(用二进制补码比较), 把 x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amomax.d | R | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
20: a03332af amomax.d x5,x3,(x6)amomax.w
amomax.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] MAX x[rs2])
原子最大字(Atomic Memory Operation: Maximum Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 t 和 x[rs2]中较大的一个(用二进制补码比较), 把 x[rd]设为符号位扩展的 t。
aq | rl | rs2 | rs1 | 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 |
amomax.w | R | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
24: a03322af amomax.w x5,x3,(x6)
amomaxu.d
amomaxu.d rd, rs2, (rs1) //x[rd] = AMO64(M[x[rs1]] MAXU x[rs2])
原子无符号最大双字(Atomic Memory Operation: Maximum Doubleword, Unsigned). R-type,RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 t 和 x[rs2]中较大的一个(用无符号比较), 把 x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amomaxu.d | R | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
38: e03332af amomaxu.d x5,x3,(x6)amomaxu.w
amomaxu.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] MAXU x[rs2])
原子无符号最大字(Atomic Memory Operation: Maximum Word, Unsigned). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 t 和 x[rs2]中较大的一个(用无符号比较), 把 x[rd]设为符号位扩展的 t。
aq | rl | rs2 | rs1 | 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 |
amomaxu.w | R | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
3c: e03322af amomaxu.w x5,x3,(x6)amomin.d
amomin.d rd, rs2, (rs1) //x[rd] = AMO64(M[x[rs1]] MIN x[rs2])
原子最小双字(Atomic Memory Operation: Minimum Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 t 和 x[rs2]中较小的一个(用二进制补码比较), 把 x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amomin.d | R | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
28: 803332af amomin.d x5,x3,(x6)
amomin.w
amomin.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] MIN x[rs2])
原子最小字(Atomic Memory Operation: Minimum Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 t 和 x[rs2]中较小的一个(用二进制补码比较), 把 x[rd]设为符号位扩展的 t。
aq | rl | rs2 | rs1 | 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 |
amomin.w | R | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
2c: 803322af amomin.w x5,x3,(x6)
amominu.d
amominu.d rd, rs2,(rs1) //x[rd] = AMO64(M[x[rs1]] MINU x[rs2])原子无符号最小双字(Atomic Memory Operation: Minimum Doubleword, Unsigned). R-type,RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 t 和 x[rs2]中较小的一个(用无符号比较), 把 x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amominu.d | R | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
30: c03332af amominu.d x5,x3,(x6)
amominu.w
amominu.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] MINU x[rs2])
原子无符号最大字(Atomic Memory Operation: Minimum Word, Unsigned). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 t 和 x[rs2]中较小的一个(用无符号比较), 把 x[rd]设为符号位扩展的 t。
aq | rl | rs2 | rs1 | 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 |
amominu.w | R | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
34: c03322af amominu.w x5,x3,(x6)
amoor.d
amoor.d rd, rs2, (rs1) //x[rd] = AMO64(M[x[rs1]] | x[rs2])
原子双字或 (Atomic Memory Operation: OR Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 t 和 x[rs2]位或的结果, 把 x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amoor.d | R | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
10: 403332af amoor.d x5,x3,(x6)
amoor.w
amoor.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] | x[rs2])
原子字或 (Atomic Memory Operation: OR Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 t 和 x[rs2]位或的结果, 把 x[rd]设为符号位扩展的 t。
aq | rl | rs2 | rs1 | 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 |
amoor.w | R | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
14: 403322af amoor.w x5,x3,(x6)amoswap.d
amoswap.d rd, rs2, (rs1) //x[rd] = AMO64(M[x[rs1]] SWAP x[rs2])
原子双字交换 (Atomic Memory Operation: Swap Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 x[rs2]的值,把 x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amoswap.d | R | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
40: 083332af amoswap.d x5,x3,(x6)
amoswap.w
amoswap.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] SWAP x[rs2])原子字交换 (Atomic Memory Operation: Swap Doubleword). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 x[rs2]的值,把 x[rd]设为 符号位扩展的t。
aq | rl | rs2 | rs1 | 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 |
amoswap.w | R | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
44: 083322af amoswap.w x5,x3,(x6)
amoxor.d
amoxor.d rd, rs2, (rs1) //x[rd] = AMO64(M[x[rs1]] ^ x[rs2])
原子双字异或 (Atomic Memory Operation: XOR Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的双字记为 t,把这个双字变为 t 和 x[rs2]按位异或的结果, 把 x[rd]设为 t。
aq | rl | rs2 | rs1 | 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 |
amoxor.d | R | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
18: 203332af amoxor.d x5,x3,(x6)amoxor.w
amoxor.w rd, rs2, (rs1) //x[rd] = AMO32(M[x[rs1]] ^ x[rs2])
原子字异或 (Atomic Memory Operation: XOR Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x[rs1]中的字记为 t,把这个字变为 t 和 x[rs2]按位异或的结果, 把 x[rd]设为符号位扩展的 t。
aq | rl | rs2 | rs1 | 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 |
amoxor.w | R | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
1c: 203322af amoxor.w x5,x3,(x6)
lr.d
lr.d rd, (rs1) //x[rd] = LoadReserved64(M[x[rs1]])
加载保留双字(Load-Reserved Doubleword). R-type, RV64A.
从内存中地址为 x[rs1]中加载八个字节,写入 x[rd], 并对这个内存双字注册保留。
aq | rl | rs2 | rs1 | 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 |
lr.d | R | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
48: 100332af lr.d x5,(x6)lr.w
lr.w rd, (rs1) //x[rd] = LoadReserved32(M[x[rs1]])
加载保留字(Load-Reserved Word). R-type, RV32A and RV64A.
从内存中地址为 x[rs1]中加载四个字节,符号位扩展后写入 x[rd], 并对这个内存字注册保留。
aq | rl | rs2 | rs1 | 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 |
lr.w | R | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
4c: 100322af lr.w x5,(x6)sc.d
sc.d rd, rs2, (rs1) //x[rd] = StoreConditonal64(M[x[rs1], x[rs2])
条件存入双字(Store-Conditional Doubleword). R-type, RV64A only.
如果内存地址 x[rs1]上存在加载保留,将 x[rs2]寄存器中的 8 字节数存入该地址。如果存入成功,向寄存器 x[rd]中存入 0,否则存入一个非 0 的错误码。
aq | rl | rs2 | rs1 | 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 |
sc.d | R | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
50: 183332af sc.d x5,x3,(x6)sc.w
sc.w rd, rs2, (rs1) //x[rd] = StoreConditonal32(M[x[rs1], x[rs2])
条件存入字(Store-Conditional Word). R-type, RV32A and RV64A.
内存地址 x[rs1]上存在加载保留,将 x[rs2]寄存器中的 4 字节数存入该地址。如果存入成功,向寄存器 x[rd]中存入 0,否则存入一个非 0 的错误码。
aq | rl | rs2 | rs1 | 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 |
sc.w | R | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 1 | 0 | 1 | 1 | 1 | 1 |
示例:
54: 183322af sc.w x5,x3,(x6)