diff options
author | davidxu <davidxu@FreeBSD.org> | 2006-08-28 02:28:15 +0000 |
---|---|---|
committer | davidxu <davidxu@FreeBSD.org> | 2006-08-28 02:28:15 +0000 |
commit | 87b5aa08ee93b317c4d88805ce8e361853411027 (patch) | |
tree | 7be2d51c02f47e64ee8dc4e4ec29bd1716dd3c70 /sys/ia64 | |
parent | f2ccfe95252579f4a77ff68a316f2f07850f0277 (diff) | |
download | FreeBSD-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/ia64')
-rw-r--r-- | sys/ia64/ia64/support.S | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/sys/ia64/ia64/support.S b/sys/ia64/ia64/support.S index 95686b3..4a21274 100644 --- a/sys/ia64/ia64/support.S +++ b/sys/ia64/ia64/support.S @@ -242,6 +242,56 @@ ENTRY(casuptr, 3) END(casuptr) /* + * casuword32(int32_t *p, int32_t old, int32_t new) + * Perform a 32-bit compare-exchange in user space. + */ +ENTRY(casuword32, 3) +{ .mlx + add r15=PC_CURTHREAD,r13 + movl r14=VM_MAX_ADDRESS + ;; +} +{ .mib + ld8 r15=[r15] // r15 = curthread + cmp.geu p6,p0=in0,r14 +(p6) br.dpnt.few 1f + ;; +} +{ .mlx + add r15=TD_PCB,r15 + movl r14=fusufault + ;; +} +{ .mmi + ld8 r15=[r15] // r15 = PCB + ;; + mov ar.ccv=in1 + add r15=PCB_ONFAULT,r15 + ;; +} +{ .mmi + st8 [r15]=r14 // Set onfault + ;; + cmpxchg4.rel ret0=[in0],in2,ar.ccv + nop 0 + ;; +} +{ .mfb + st8.rel [r15]=r0 // Clear onfault + nop 0 + br.ret.sptk rp + ;; +} +1: +{ .mfb + add ret0=-1,r0 + nop 0 + br.ret.sptk rp + ;; +} +END(casuword32) + +/* * subyte(void *addr, int byte) * suword16(void *addr, int word) * suword32(void *addr, int word) |