shithub: riscv

Download patch

ref: 511421003a44633d8907828aef280acc762cc56b
parent: f88a55e79b5bf656e7f9578d1318a955b9a4963a
author: Jacob Moody <moody@posixcafe.org>
date: Thu May 16 22:55:53 EDT 2024

gefs: riscv64 atomics

--- /dev/null
+++ b/sys/src/cmd/gefs/atomic-riscv64.s
@@ -1,0 +1,95 @@
+#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