ref: 511421003a44633d8907828aef280acc762cc56b
dir: /sys/src/cmd/gefs/atomic-riscv64.s/
#include <atom.h> #define ARG 8 /* get variants */ TEXT agetl+0(SB),1,$0 FENCE_RW LRW(ARG, ARG) FENCE_RW RET TEXT agetv+0(SB),1,$0 TEXT agetp+0(SB),1,$0 FENCE_RW LRD(ARG, ARG) FENCE_RW RET /* set variants */ TEXT asetl+0(SB),1,$0 MOVW val+XLEN(FP), R12 FENCE_RW AMOW(Amoswap, AQ|RL, 12, ARG, 10) FENCE_RW MOVW R10, R(ARG) RET TEXT asetv+0(SB),1,$0 TEXT asetp+0(SB),1,$0 MOV val+XLEN(FP), R12 FENCE_RW AMOD(Amoswap, AQ|RL, 12, ARG, 10) FENCE_RW MOV R10, R(ARG) RET /* inc variants */ TEXT aincl+0(SB),1,$0 MOV $1, R9 FENCE_RW /* flush changes to ram in case releasing a lock */ /* after: value before add in R10, value after add in memory */ AMOW(Amoadd, AQ|RL, 9, ARG, 10) FENCE_RW ADDW $1, R10, R(ARG) /* old value ±1 for ainc/adec */ RET TEXT aincv+0(SB),1,$0 TEXT aincp+0(SB),1,$0 MOV $1, R9 FENCE_RW /* flush changes to ram in case releasing a lock */ /* after: value before add in R10, value after add in memory */ AMOD(Amoadd, AQ|RL, 9, ARG, 10) FENCE_RW ADDW $1, R10, R(ARG) /* old value ±1 for ainc/adec */ RET /* cas variants */ TEXT acasl+0(SB),1,$0 MOVWU ov+XLEN(FP), R12 MOVWU nv+(XLEN+4)(FP), R13 MOV R0, R11 /* default to failure */ FENCE_RW spincas: LRW(ARG, 14) /* (R(ARG)) -> R14 */ SLL $32, R14 SRL $32, R14 /* don't sign extend */ BNE R12, R14, fail FENCE_RW SCW(13, ARG, 14) /* R13 -> (R(ARG)) maybe, R14=0 if ok */ BNE R14, spincas /* R14 != 0 means store failed */ ok: MOV $1, R11 fail: FENCE_RW MOV R11, R(ARG) RET TEXT acasv+0(SB),1,$0 TEXT acasp+0(SB),1,$0 MOV ov+XLEN(FP), R12 MOV nv+(2*XLEN)(FP), R13 MOV R0, R11 /* default to failure */ FENCE_RW spincasp: LRD(ARG, 14) /* (R(ARG)) -> R14 */ BNE R12, R14, fail FENCE_RW SCD(13, ARG, 14) /* R13 -> (R(ARG)) maybe, R14=0 if ok */ BNE R14, spincasp /* R14 != 0 means store failed */ JMP ok /* barriers */ TEXT coherence+0(SB),1,$0 FENCE_RW RET