diff --git a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp index f32c0a3a4..d1589230e 100644 --- a/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp +++ b/FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp @@ -5737,17 +5737,24 @@ void OpDispatchBuilder::RDTSCPOp(OpcodeArgs) { } void OpDispatchBuilder::CRC32(OpcodeArgs) { + const uint8_t GPRSize = CTX->GetGPRSize(); + // Destination GPR size is always 4 or 8 bytes depending on widening uint8_t DstSize = Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_REX_WIDENING ? 8 : 4; - OrderedNode *Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, DstSize, Op->Flags, -1); + OrderedNode *Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, GPRSize, Op->Flags, -1); // Incoming memory is 8, 16, 32, or 64 - OrderedNode *Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, 1); + OrderedNode *Src{}; + if (Op->Src[0].IsGPR()) { + Src = LoadSource_WithOpSize(GPRClass, Op, Op->Src[0], GPRSize, Op->Flags, -1); + } + else { + Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, 1); + } auto Result = _CRC32(Dest, Src, GetSrcSize(Op)); StoreResult_WithOpSize(GPRClass, Op, Op->Dest, Result, DstSize, -1); } - template void OpDispatchBuilder::RDRANDOp(OpcodeArgs) { auto Res = _RDRAND(Reseed); diff --git a/unittests/InstructionCountCI/H0F38.json b/unittests/InstructionCountCI/H0F38.json index 2092337cd..3f1d5b6e0 100644 --- a/unittests/InstructionCountCI/H0F38.json +++ b/unittests/InstructionCountCI/H0F38.json @@ -1046,50 +1046,43 @@ ] }, "crc32 eax, bl": { - "ExpectedInstructionCount": 3, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": [ "0xf2 0x0f 0x38 0xf0" ], "ExpectedArm64ASM": [ - "lsr w20, w4, #0", - "uxtb w21, w7", - "crc32cb w4, w20, w21" + "crc32cb w4, w4, w7" ] }, "crc32 eax, bx": { - "ExpectedInstructionCount": 3, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": [ "0xf2 0x0f 0x38 0xf1" ], "ExpectedArm64ASM": [ - "lsr w20, w4, #0", - "uxth w21, w7", - "crc32ch w4, w20, w21" + "crc32ch w4, w4, w7" ] }, "crc32 eax, ebx": { - "ExpectedInstructionCount": 3, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": [ "0xf2 0x0f 0x38 0xf1" ], "ExpectedArm64ASM": [ - "lsr w20, w4, #0", - "lsr w21, w7, #0", - "crc32cw w4, w20, w21" + "crc32cw w4, w4, w7" ] }, "crc32 rax, bl": { - "ExpectedInstructionCount": 2, - "Optimal": "No", + "ExpectedInstructionCount": 1, + "Optimal": "Yes", "Comment": [ "0xf2 0x0f 0x38 0xf0" ], "ExpectedArm64ASM": [ - "uxtb w20, w7", - "crc32cb w4, w4, w20" + "crc32cb w4, w4, w7" ] }, "crc32 rax, rbx": {