summaryrefslogtreecommitdiffstats
path: root/sys/amd64
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2006-08-28 02:28:15 +0000
committerdavidxu <davidxu@FreeBSD.org>2006-08-28 02:28:15 +0000
commit87b5aa08ee93b317c4d88805ce8e361853411027 (patch)
tree7be2d51c02f47e64ee8dc4e4ec29bd1716dd3c70 /sys/amd64
parentf2ccfe95252579f4a77ff68a316f2f07850f0277 (diff)
downloadFreeBSD-src-87b5aa08ee93b317c4d88805ce8e361853411027.zip
FreeBSD-src-87b5aa08ee93b317c4d88805ce8e361853411027.tar.gz
Implement casuword32, compare and set user integer, thank Marcel Moolenarr
who wrote the IA64 version of casuword32.
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/amd64/support.S28
1 files changed, 28 insertions, 0 deletions
diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S
index ea547f9..4e8efdf 100644
--- a/sys/amd64/amd64/support.S
+++ b/sys/amd64/amd64/support.S
@@ -314,6 +314,34 @@ copyin_fault:
ret
/*
+ * casuword32. Compare and set user integer. Returns -1 or the current value.
+ * dst = %rdi, old = %rsi, new = %rdx
+ */
+ENTRY(casuword32)
+ movq PCPU(CURPCB),%rcx
+ movq $fusufault,PCB_ONFAULT(%rcx)
+
+ movq $VM_MAXUSER_ADDRESS-4,%rax
+ cmpq %rax,%rdi /* verify address is valid */
+ ja fusufault
+
+ movl %esi,%eax /* old */
+#ifdef SMP
+ lock
+#endif
+ cmpxchgl %edx,(%rdi) /* new = %edx */
+
+ /*
+ * The old value is in %eax. If the store succeeded it will be the
+ * value we expected (old) from before the store, otherwise it will
+ * be the current value.
+ */
+
+ movq PCPU(CURPCB),%rcx
+ movq $0,PCB_ONFAULT(%rcx)
+ ret
+
+/*
* casuptr. Compare and set user pointer. Returns -1 or the current value.
* dst = %rdi, old = %rsi, new = %rdx
*/
OpenPOWER on IntegriCloud