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

Method IMULOp

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

Source from the content-addressed store, hash-verified

2619}
2620
2621void OpDispatchBuilder::IMULOp(OpcodeArgs) {
2622 const auto Size = OpSizeFromSrc(Op);
2623 const auto SizeBits = IR::OpSizeAsBits(Size);
2624
2625 Ref Src1 = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = true});
2626 Ref Src2 = LoadGPRRegister(X86State::REG_RAX);
2627
2628 if (Size != OpSize::i64Bit) {
2629 Src1 = _Sbfe(OpSize::i64Bit, SizeBits, 0, Src1);
2630 Src2 = _Sbfe(OpSize::i64Bit, SizeBits, 0, Src2);
2631 }
2632
2633 // 64-bit special cased to save a move
2634 Ref Result = Size < OpSize::i64Bit ? _Mul(OpSize::i64Bit, Src1, Src2) : nullptr;
2635 Ref ResultHigh {};
2636 if (Size == OpSize::i8Bit) {
2637 // Result is stored in AX
2638 StoreGPRRegister(X86State::REG_RAX, Result, OpSize::i16Bit);
2639 ResultHigh = _Sbfe(OpSize::i64Bit, 8, 8, Result);
2640 } else if (Size == OpSize::i16Bit) {
2641 // 16bits stored in AX
2642 // 16bits stored in DX
2643 StoreGPRRegister(X86State::REG_RAX, Result, Size);
2644 ResultHigh = _Sbfe(OpSize::i64Bit, 16, 16, Result);
2645 StoreGPRRegister(X86State::REG_RDX, ResultHigh, Size);
2646 } else if (Size == OpSize::i32Bit) {
2647 // 32bits stored in EAX
2648 // 32bits stored in EDX
2649 // Make sure they get Zext correctly
2650 auto LocalResult = _Bfe(OpSize::i64Bit, 32, 0, Result);
2651 auto LocalResultHigh = _Bfe(OpSize::i64Bit, 32, 32, Result);
2652 ResultHigh = _Sbfe(OpSize::i64Bit, 32, 32, Result);
2653 Result = _Sbfe(OpSize::i64Bit, 32, 0, Result);
2654 StoreGPRRegister(X86State::REG_RAX, LocalResult);
2655 StoreGPRRegister(X86State::REG_RDX, LocalResultHigh);
2656 } else if (Size == OpSize::i64Bit) {
2657 if (!Is64BitMode) {
2658 LogMan::Msg::EFmt("Doesn't exist in 32bit mode");
2659 DecodeFailure = true;
2660 return;
2661 }
2662 // 64bits stored in RAX
2663 // 64bits stored in RDX
2664 ResultHigh = _MulH(OpSize::i64Bit, Src1, Src2);
2665 Result = _Mul(OpSize::i64Bit, Src1, Src2);
2666 StoreGPRRegister(X86State::REG_RAX, Result);
2667 StoreGPRRegister(X86State::REG_RDX, ResultHigh);
2668 }
2669
2670 CalculateFlags_MUL(Size, Result, ResultHigh);
2671}
2672
2673void OpDispatchBuilder::MULOp(OpcodeArgs) {
2674 const auto Size = OpSizeFromSrc(Op);

Callers

nothing calls this directly

Calls 2

OpSizeAsBitsFunction · 0.85
EFmtFunction · 0.85

Tested by

no test coverage detected