1
0
forked from 0ad/0ad

mixed C/asm function CAS_ now no longer __declspec(naked) - less efficient but avoids VC problems with its parameters

This was SVN commit r2468.
This commit is contained in:
janwas 2005-07-04 02:43:54 +00:00
parent af4b399cde
commit 36a40479c8

View File

@ -562,26 +562,29 @@ void ia32_get_cpu_info()
// run on 386. we could replace cmpxchg with a simple mov (since 386
// CPUs aren't MP-capable), but it's not worth the trouble.
__declspec(naked) bool __cdecl CAS_(uintptr_t* location, uintptr_t expected, uintptr_t new_value)
// note: don't use __declspec(naked) because we need to access one parameter
// from C code and VC can't handle that correctly.
bool __cdecl CAS_(uintptr_t* location, uintptr_t expected, uintptr_t new_value)
{
// try to see if caller isn't passing in an address
// (CAS's arguments are silently casted)
debug_assert(location >= (uintptr_t*)0x10000);
bool was_updated;
__asm
{
cmp byte ptr [cpus], 1
mov eax, [esp+8] // expected
mov edx, [esp+4] // location
mov ecx, [esp+12] // new_value
mov eax, [expected]
mov edx, [location]
mov ecx, [new_value]
je $no_lock
_emit 0xf0 // LOCK prefix
$no_lock:
cmpxchg [edx], ecx
mov eax, 0
sete al
ret
mov [was_updated], al
}
return was_updated;
}
@ -620,19 +623,19 @@ void serialize()
bool CAS_(uintptr_t* location, uintptr_t expected, uintptr_t new_value)
{
uintptr_t prev;
debug_assert(location >= (uintptr_t *)0x10000);
debug_assert(location >= (uintptr_t*)0x10000);
__asm__ __volatile__("lock; cmpxchgl %1,%2"
: "=a"(prev) // %0: Result in eax should be stored in prev
: "q"(new_value), // %1: new_value -> e[abcd]x
"m"(*location), // %2: Memory operand
"0"(expected) // Stored in same place as %0
: "memory"); // We make changes in memory
return prev==expected;
return prev == expected;
}
void atomic_add(intptr_t *location, intptr_t increment)
void atomic_add(intptr_t* location, intptr_t increment)
{
__asm__ __volatile__ (
"cmpb $1, %1;"