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; } */
| 37 | } |
| 38 | */ |
| 39 | void 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; |
no test coverage detected