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)