MCPcopy Create free account
hub / github.com/FEX-Emu/FEX / MULOp

Method MULOp

FEXCore/Source/Interface/Core/OpcodeDispatcher.cpp:2673–2722  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2671}
2672
2673void OpDispatchBuilder::MULOp(OpcodeArgs) {
2674 const auto Size = OpSizeFromSrc(Op);
2675 const auto SizeBits = IR::OpSizeAsBits(Size);
2676
2677 Ref Src1 = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
2678 Ref Src2 = LoadGPRRegister(X86State::REG_RAX);
2679 Ref Result {};
2680
2681 if (Size != OpSize::i64Bit) {
2682 Src1 = _Bfe(OpSize::i64Bit, SizeBits, 0, Src1);
2683 Src2 = _Bfe(OpSize::i64Bit, SizeBits, 0, Src2);
2684 Result = _UMul(OpSize::i64Bit, Src1, Src2);
2685 }
2686 Ref ResultHigh {};
2687
2688 if (Size == OpSize::i8Bit) {
2689 // Result is stored in AX
2690 StoreGPRRegister(X86State::REG_RAX, Result, OpSize::i16Bit);
2691 ResultHigh = _Bfe(OpSize::i64Bit, 8, 8, Result);
2692 } else if (Size == OpSize::i16Bit) {
2693 // 16bits stored in AX
2694 // 16bits stored in DX
2695 StoreGPRRegister(X86State::REG_RAX, Result, Size);
2696 ResultHigh = _Bfe(OpSize::i64Bit, 16, 16, Result);
2697 StoreGPRRegister(X86State::REG_RDX, ResultHigh, Size);
2698 } else if (Size == OpSize::i32Bit) {
2699 // 32bits stored in EAX
2700 // 32bits stored in EDX
2701 Ref ResultLow = _Bfe(OpSize::i64Bit, 32, 0, Result);
2702 ResultHigh = _Bfe(OpSize::i64Bit, 32, 32, Result);
2703 StoreGPRRegister(X86State::REG_RAX, ResultLow);
2704 StoreGPRRegister(X86State::REG_RDX, ResultHigh);
2705 } else if (Size == OpSize::i64Bit) {
2706 if (!Is64BitMode) {
2707 LogMan::Msg::EFmt("Doesn't exist in 32bit mode");
2708 DecodeFailure = true;
2709 return;
2710 }
2711 // 64bits stored in RAX
2712 // 64bits stored in RDX
2713 //
2714 // Calculate high first to allow better RA.
2715 ResultHigh = _UMulH(OpSize::i64Bit, Src1, Src2);
2716 Result = _UMul(OpSize::i64Bit, Src1, Src2);
2717 StoreGPRRegister(X86State::REG_RAX, Result);
2718 StoreGPRRegister(X86State::REG_RDX, ResultHigh);
2719 }
2720
2721 CalculateFlags_UMUL(ResultHigh);
2722}
2723
2724void OpDispatchBuilder::NOTOp(OpcodeArgs) {
2725 const auto Size = OpSizeFromSrc(Op);

Callers

nothing calls this directly

Calls 2

OpSizeAsBitsFunction · 0.85
EFmtFunction · 0.85

Tested by

no test coverage detected