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

Method NOTOp

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

Source from the content-addressed store, hash-verified

2722}
2723
2724void OpDispatchBuilder::NOTOp(OpcodeArgs) {
2725 const auto Size = OpSizeFromSrc(Op);
2726 const auto SizeBits = IR::OpSizeAsBits(Size);
2727 LOGMAN_THROW_A_FMT(Size >= IR::OpSize::i8Bit && Size <= IR::OpSize::i64Bit, "Invalid size");
2728
2729 Ref MaskConst {};
2730 if (Size == OpSize::i64Bit) {
2731 MaskConst = Constant(~0ULL);
2732 } else {
2733 MaskConst = Constant((1ULL << SizeBits) - 1);
2734 }
2735
2736 if (DestIsLockedMem(Op)) {
2737 HandledLock = true;
2738 Ref DestMem = MakeSegmentAddress(Op, Op->Dest);
2739 _AtomicXor(Size, MaskConst, DestMem);
2740 } else if (!Op->Dest.IsGPR()) {
2741 // GPR version plays fast and loose with sizes, be safe for memory tho.
2742 Ref Src = LoadSource(GPRClass, Op, Op->Dest, Op->Flags);
2743 Src = _Xor(OpSize::i64Bit, Src, MaskConst);
2744 StoreResult(GPRClass, Op, Src, OpSize::iInvalid);
2745 } else {
2746 // Specially handle high bits so we can invert in place with the correct
2747 // mask and a larger type.
2748 auto Dest = Op->Dest;
2749 if (Dest.Data.GPR.HighBits) {
2750 LOGMAN_THROW_A_FMT(Size == OpSize::i8Bit, "Only 8-bit GPRs get high bits");
2751 MaskConst = Constant(0xFF00);
2752 Dest.Data.GPR.HighBits = false;
2753 }
2754
2755 // Always load full size, we explicitly want the upper bits to get the
2756 // insert behaviour for free/implicitly.
2757 const auto GPRSize = GetGPROpSize();
2758 Ref Src = LoadSource_WithOpSize(GPRClass, Op, Dest, GPRSize, Op->Flags);
2759
2760 // For 8/16-bit, use 64-bit invert so we invert in place, while getting
2761 // insert behaviour. For 32-bit, use 32-bit invert to zero the upper bits.
2762 const auto EffectiveSize = Size == OpSize::i32Bit ? OpSize::i32Bit : GPRSize;
2763
2764 // If we're inverting the whole thing, use Not instead of Xor to save a constant.
2765 if (Size >= OpSize::i32Bit) {
2766 Src = _Not(EffectiveSize, Src);
2767 } else {
2768 Src = _Xor(EffectiveSize, Src, MaskConst);
2769 }
2770
2771 // Always store 64-bit, the Not/Xor correctly handle the upper bits and this
2772 // way we can delete the store.
2773 StoreResult_WithOpSize(GPRClass, Op, Dest, Src, GPRSize, OpSize::iInvalid);
2774 }
2775}
2776
2777void OpDispatchBuilder::XADDOp(OpcodeArgs) {
2778 Ref Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});

Callers

nothing calls this directly

Calls 2

OpSizeAsBitsFunction · 0.85
IsGPRMethod · 0.45

Tested by

no test coverage detected