Implement casuword32, compare and set user integer, thank Marcel Moolenarr

who wrote the IA64 version of casuword32.
This commit is contained in:
David Xu 2006-08-28 02:28:15 +00:00
parent eb4bbba83a
commit 66e1c26dba
8 changed files with 96 additions and 2 deletions

View File

@ -313,6 +313,34 @@ copyin_fault:
movq $EFAULT,%rax
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

View File

@ -52,6 +52,7 @@ __FBSDID("$FreeBSD$");
* Fetch an int from the user's address space.
*/
ALTENTRY(casuword32)
ENTRY(casuptr)
#ifdef MULTIPROCESSOR
/* XXX Probably not appropriate for non-Hydra SMPs */

View File

@ -1142,6 +1142,8 @@ fastmove_tail_fault:
/*
* casuptr. Compare and set user pointer. Returns -1 or the current value.
*/
ALTENTRY(casuword32)
ENTRY(casuptr)
movl PCPU(CURPCB),%ecx
movl $fusufault,PCB_ONFAULT(%ecx)

View File

@ -241,6 +241,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)

View File

@ -322,6 +322,12 @@ fuword32(const void *addr)
return ((int32_t)fuword(addr));
}
int32_t
casuword32(int32_t *base, int32_t oldval, int32_t newval)
{
return (casuptr(base, oldval, newval));
}
intptr_t
casuptr(intptr_t *addr, intptr_t old, intptr_t new)
{

View File

@ -322,6 +322,12 @@ fuword32(const void *addr)
return ((int32_t)fuword(addr));
}
int32_t
casuword32(int32_t *base, int32_t oldval, int32_t newval)
{
return (casuptr(base, oldval, newval));
}
intptr_t
casuptr(intptr_t *addr, intptr_t old, intptr_t new)
{

View File

@ -402,7 +402,7 @@ fs_nofault_begin:
.set susword, suword16
.set suword, suword64
.globl casuptr, fuptr, suptr
.globl casuword32, casuptr, fuptr, suptr
.set casuptr, casuword64
.set fuptr, fuword64
.set suptr, suword64

View File

@ -203,7 +203,8 @@ int suword(void *base, long word);
int suword16(void *base, int word);
int suword32(void *base, int32_t word);
int suword64(void *base, int64_t word);
intptr_t casuptr(intptr_t *p, intptr_t old, intptr_t new);
int32_t casuword32(int32_t *base, int32_t oldval, int32_t newval);
intptr_t casuptr(intptr_t *p, intptr_t oldval, intptr_t newval);
void realitexpire(void *);