MCPcopy Create free account
hub / github.com/danoon2/Boxedwine / common_cmpxchg8b_lock

Function common_cmpxchg8b_lock

source/emulation/cpu/common/common_lock.cpp:39–71  ·  view source on GitHub ↗

U64 value1 = ((U64)EDX) << 32 | EAX; U64 value2 = cpu->memory->readq(address); cpu->fillFlags(); if (value1 == value2) { cpu->addZF(); cpu->memory->writed(address, EBX); cpu->memory->writed(address + 4, ECX); } else { cpu->removeZF(); EDX = (U32)(value2 >> 32); EAX = (U32)value2; } */

Source from the content-addressed store, hash-verified

37 }
38*/
39void common_cmpxchg8b_lock(CPU* cpu, U32 address) {
40 U64 expected = ((U64)EDX) << 32 | EAX;
41 if (address & 7) {
42 BOXEDWINE_CRITICAL_SECTION_WITH_MUTEX(lockMutex); // hope for the best
43
44 U64 oldValue = cpu->memory->readq(address);
45 cpu->fillFlags();
46 if (expected == oldValue) {
47 cpu->addZF();
48 cpu->memory->writed(address, EBX);
49 cpu->memory->writed(address + 4, ECX);
50 } else {
51 cpu->removeZF();
52 EDX = (U32)(oldValue >> 32);
53 EAX = (U32)oldValue;
54 }
55 } else {
56 U64 value = ((U64)ECX) << 32 | EBX;
57
58 cpu->fillFlags();
59
60 LockData64* p = (LockData64*)cpu->memory->getRamPtr(address, 8, true);
61 std::atomic_ref<U64> mem(p->data);
62
63 if (mem.compare_exchange_strong(expected, value)) {
64 cpu->addZF();
65 } else {
66 cpu->removeZF();
67 EDX = (U32)(expected >> 32);
68 EAX = (U32)expected;
69 }
70 }
71}
72
73/*
74 cpu->dst.u32 = EAX;

Callers 1

normal_cmpxchg8b_lockFunction · 0.85

Calls 7

readqMethod · 0.80
addZFMethod · 0.80
removeZFMethod · 0.80
fillFlagsMethod · 0.45
writedMethod · 0.45
getRamPtrMethod · 0.45

Tested by

no test coverage detected