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

Method DECOp

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

Source from the content-addressed store, hash-verified

3142}
3143
3144void OpDispatchBuilder::DECOp(OpcodeArgs) {
3145 Ref Dest;
3146 Ref Result;
3147 const auto Size = GetSrcBitSize(Op);
3148 const bool IsLocked = DestIsLockedMem(Op);
3149
3150 if (IsLocked) {
3151 HandledLock = true;
3152
3153 Ref DestAddress = MakeSegmentAddress(Op, Op->Dest);
3154
3155 // Use Add instead of Sub to avoid a NEG
3156 Dest = _AtomicFetchAdd(OpSizeFromSrc(Op), Constant(Size == 64 ? -1 : ((1ULL << Size) - 1)), DestAddress);
3157 } else {
3158 Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.AllowUpperGarbage = Size >= 32});
3159 }
3160
3161 CalculateDeferredFlags();
3162
3163 if (Size < 32 && CTX->HostFeatures.SupportsFlagM) {
3164 // Subtraction producing upper garbage
3165 Result = Sub(OpSize::i32Bit, Dest, 1);
3166 CalculatePF(Result);
3167 CalculateAF(Dest, Constant(1));
3168
3169 // Correctly set NZ flags, preserving C
3170 HandleNZCV_RMW();
3171 _SetSmallNZV(OpSizeFromSrc(Op), Result);
3172
3173 // Fix up V flag. DEC overflows only when decrementing a negative and
3174 // getting a positive. So compare the sign bits to calculate V.
3175 _RmifNZCV(_Andn(OpSize::i32Bit, Dest, Result), Size - 1, 1);
3176 } else {
3177 Result = CalculateFlags_SUB(OpSizeFromSrc(Op), Dest, Constant(1), false);
3178 }
3179
3180 if (!IsLocked) {
3181 StoreResult(GPRClass, Op, Result, OpSize::iInvalid);
3182 }
3183}
3184
3185void OpDispatchBuilder::STOSOp(OpcodeArgs) {
3186 if (Op->Flags & FEXCore::X86Tables::DecodeFlags::FLAG_ADDRESS_SIZE) {

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected