皋陶 发表于 2021-3-5 22:33:45

RV32A/RV64A指令集

本帖最后由 皋陶 于 2021-3-5 22:37 编辑

RV32A/RV64A指令包括两类:AMO(atomic memory operation)指令,Load-Reserved/Store-Conditional指令
      计算机体系结构中的存储器模型(或者说存储器一致性模型)主要分为三类:按序一致性模型,松散一致性模型,释放一致性模型。
      更详细存储器一致性介绍请看:https://blog.csdn.net/jfengamarsoft/article/details/70923658?utm_source=blogxgwz2
      按序一致性模型就是严格按序模型,如果处理器指令集架构符合按序一致性模型,那么多个处理器核上执行的程序就好像一个单核处理器上顺序执行一样。例如两个处理器核core0,core1,core0上执行了A,B,C,D四条存储器访问指令,core1 上执行了a,b,c,d四条访存指令。按序一致性模型系统上执行这8条指令的效果就好像在一个core上顺序执行了A a B b C c D d的指令流,或者A B a b C c D d,或者其他顺序,总之,只要符合core0和core1程序顺序,即从core0看,是A,B,C,D,从core1看是a,b,c,d的任意顺序都是合法的。
   按序一致性模型的两条规则:

[*]各个处理器核按照其程序顺序来执行,执行完一条后启动执行下一条指令,不能改变存储器访问指令的顺序(即便访问的是不同的存储器地址)。
[*]从全局看,每一个存储器写指令的操作都需要能够被系统中的所有处理器核同时观测到。就好像处理器系统(包括所有的处理器核)和存储系统之间有一个开关,一次只会连接一个处理器核和存储系统,因此对存储器的访问都是原子的,串行化的。

      松散一致性模型:对于不同存储器访问指令,就单核而言,理论上是可以改变其执行顺序的。
      松散一致性模型允许多核系统中,每个单核改变其存储器访问指令(比如是访问不同的地址)的执行顺序。
      松散一致性模型可以通过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 = AMO64(M] + x)
原子加双字(Atomic Memory Operation: Add Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 t+x,把x设为 t。

 

aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoadd.dR00000











011




0101111
示例:0:    003332af            amoadd.d    x5,x3,(x6)


二、amoadd.w
amoadd.w rd, rs2, (rs1)    //x = AMO32(M] + x)
原子加字(Atomic Memory Operation: Add Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 t+x,把 x设为符号位扩展的 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoadd.wR00000            010     0101111
示例:4:    003322af            amoadd.w    x5,x3,(x6)



三、amoand.d
amoand.d rd, rs2, (rs1)    //x = AMO64(M] & x)
原子双字与 (Atomic Memory Operation: AND Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 t 和 x位与的结果, 把 x设为 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoand.dR01100            011     0101111
示例:8:    603332af            amoand.d    x5,x3,(x6)



四、amoand.w
amoand.w rd, rs2, (rs1)    //x = AMO32(M] & x)
原子字与 (Atomic Memory Operation: AND Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 t 和 x位与的结果, 把 x设为符号位扩展的 t

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoand.wR01100            010     0101111
示例:c:    603322af            amoand.w    x5,x3,(x6)



五、amomax.d
amomax.d rd, rs2, (rs1)    //x = AMO64(M] MAX x)
原子最大双字(Atomic Memory Operation: Maximum Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 t 和 x中较大的一个(用二进制补码比较), 把 x设为 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amomax.dR10100            011     0101111
示例:20:    a03332af            amomax.d    x5,x3,(x6)

六、amomax.w
amomax.w rd, rs2, (rs1)    //x = AMO32(M] MAX x)
原子最大字(Atomic Memory Operation: Maximum Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 t 和 x中较大的一个(用二进制补码比较), 把 x设为符号位扩展的 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amomax.wR10100            010     0101111
示例:24:    a03322af            amomax.w    x5,x3,(x6)
七、amomaxu.d
amomaxu.d rd, rs2, (rs1)//x = AMO64(M] MAXU x)
原子无符号最大双字(Atomic Memory Operation: Maximum Doubleword, Unsigned). R-type,RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 t 和 x中较大的一个(用无符号比较), 把 x设为 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amomaxu.dR11100            011     0101111
示例:38:    e03332af            amomaxu.d    x5,x3,(x6)


八、amomaxu.w
amomaxu.w rd, rs2, (rs1)   //x = AMO32(M] MAXU x)
原子无符号最大字(Atomic Memory Operation: Maximum Word, Unsigned). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 t 和 x中较大的一个(用无符号比较), 把 x设为符号位扩展的 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amomaxu.wR11100            010     0101111
示例:3c:    e03322af            amomaxu.w    x5,x3,(x6)


九、amomin.d
amomin.d rd, rs2, (rs1)   //x = AMO64(M] MIN x)
原子最小双字(Atomic Memory Operation: Minimum Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 t 和 x中较小的一个(用二进制补码比较), 把 x设为 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amomin.dR10000            011     0101111
示例:28:    803332af            amomin.d    x5,x3,(x6)

十、amomin.w
amomin.w rd, rs2, (rs1)   //x = AMO32(M] MIN x)
原子最小字(Atomic Memory Operation: Minimum Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 t 和 x中较小的一个(用二进制补码比较), 把 x设为符号位扩展的 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amomin.wR10000            010     0101111
示例:2c:    803322af            amomin.w    x5,x3,(x6)

十一、amominu.d
amominu.d rd, rs2,(rs1)   //x = AMO64(M] MINU x)
原子无符号最小双字(Atomic Memory Operation: Minimum Doubleword, Unsigned). R-type,RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 t 和 x中较小的一个(用无符号比较), 把 x设为 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amominu.dR11000            011     0101111
示例:30:    c03332af            amominu.d    x5,x3,(x6)十二、amominu.w
amominu.w rd, rs2, (rs1)   //x = AMO32(M] MINU x)
原子无符号最大字(Atomic Memory Operation: Minimum Word, Unsigned). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 t 和 x中较小的一个(用无符号比较), 把 x设为符号位扩展的 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amominu.wR11000            010     0101111
示例:
34:    c03322af            amominu.w    x5,x3,(x6)

十三、amoor.d
amoor.d rd, rs2, (rs1)    //x = AMO64(M] | x)
原子双字或 (Atomic Memory Operation: OR Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 t 和 x位或的结果, 把 x设为 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoor.dR01000            011     0101111

示例:10:    403332af            amoor.d    x5,x3,(x6)

十四、amoor.w
amoor.w rd, rs2, (rs1)    //x = AMO32(M] | x)
原子字或 (Atomic Memory Operation: OR Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 t 和 x位或的结果, 把 x设为符号位扩展的 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoor.wR01000            010     0101111
示例:14:    403322af            amoor.w    x5,x3,(x6)

十五、amoswap.d
amoswap.d rd, rs2, (rs1)    //x = AMO64(M] SWAP x)
原子双字交换 (Atomic Memory Operation: Swap Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 x的值,把 x设为 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoswap.dR00001            011     0101111
示例:40:    083332af            amoswap.d    x5,x3,(x6)
十六、amoswap.w
amoswap.w rd, rs2, (rs1)    //x = AMO32(M] SWAP x)
原子字交换 (Atomic Memory Operation: Swap Doubleword). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 x的值,把 x设为 符号位扩展的t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoswap.wR00001            010     0101111
示例:44:    083322af            amoswap.w    x5,x3,(x6)十七、amoxor.d
amoxor.d rd, rs2, (rs1)    //x = AMO64(M] ^ x)
原子双字异或 (Atomic Memory Operation: XOR Doubleword). R-type, RV64A.
进行如下的原子操作:将内存中地址为 x中的双字记为 t,把这个双字变为 t 和 x按位异或的结果, 把 x设为 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoxor.dR00100            011     0101111
示例:18:    203332af            amoxor.d    x5,x3,(x6)

十八、amoxor.w
amoxor.w rd, rs2, (rs1)    //x = AMO32(M] ^ x)
原子字异或 (Atomic Memory Operation: XOR Word). R-type, RV32A and RV64A.
进行如下的原子操作:将内存中地址为 x中的字记为 t,把这个字变为 t 和 x按位异或的结果, 把 x设为符号位扩展的 t。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
amoxor.wR00100            010     0101111
示例:1c:    203322af            amoxor.w    x5,x3,(x6)

十九、lr.d
lr.d rd, (rs1)      //x = LoadReserved64(M])
加载保留双字(Load-Reserved Doubleword). R-type, RV64A.
从内存中地址为 x中加载八个字节,写入 x, 并对这个内存双字注册保留。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
lr.dR00010            011     0101111
示例:48:    100332af            lr.d    x5,(x6)


二十、lr.w
lr.w rd, (rs1)    //x = LoadReserved32(M])
加载保留字(Load-Reserved Word). R-type, RV32A and RV64A.
从内存中地址为 x中加载四个字节,符号位扩展后写入 x, 并对这个内存字注册保留。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
lr.wR00010            010     0101111
示例:4c:    100322af            lr.w    x5,(x6)


二十一、sc.d
sc.d rd, rs2, (rs1)    //x = StoreConditonal64(M, x)
条件存入双字(Store-Conditional Doubleword). R-type, RV64A only.
如果内存地址 x上存在加载保留,将 x寄存器中的 8 字节数存入该地址。如果存入成功,向寄存器 x中存入 0,否则存入一个非 0 的错误码。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
sc.dR00011            011     0101111
示例:50:    183332af            sc.d    x5,x3,(x6)



二十二、sc.w
sc.w rd, rs2, (rs1)    //x = StoreConditonal32(M, x)
条件存入字(Store-Conditional Word). R-type, RV32A and RV64A.
内存地址 x上存在加载保留,将 x寄存器中的 4 字节数存入该地址。如果存入成功,向寄存器 x中存入 0,否则存入一个非 0 的错误码。

   aqrlrs2rs1func3rdopcode
nametype313029282726252423222120191817161514131211109876543210
sc.wR00011            010     0101111
示例:54:    183322af            sc.w    x5,x3,(x6)

页: [1]
查看完整版本: RV32A/RV64A指令集