mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-24 21:00:47 +02:00
OpcodeDispatcher: Fixes segment prefixing on vector element loadstores
These had completely forgotten to load segment prefixes on the element loadstore operations. This had caused a crash on the Linux version of "Halls of Tormet" (steamid 2218750). This game has TLS vector data which it was loading with a movhps and hit this path.
This commit is contained in:
2 files changed
+10
-10
No files matched your search
@@ -857,7 +857,7 @@ void OpDispatchBuilder::AVX128_VMOVLP(OpcodeArgs) {
|
||||
///< VMOVLPS/PD xmm1, xmm2, mem64
|
||||
// Bits[63:0] come from Src2[63:0]
|
||||
// Bits[127:64] come from Src1[127:64]
|
||||
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Op->Src[1], OpSize::i64Bit, Op->Flags, {.LoadData = false});
|
||||
auto Src2 = MakeSegmentAddress(Op, Op->Src[1]);
|
||||
Ref Result_Low = _VLoadVectorElement(OpSize::i128Bit, OpSize::i64Bit, Src1.Low, 0, Src2);
|
||||
Ref ZeroVector = LoadZeroVector(OpSize::i128Bit);
|
||||
|
||||
@@ -879,11 +879,11 @@ void OpDispatchBuilder::AVX128_VMOVHP(OpcodeArgs) {
|
||||
if (!Op->Dest.IsGPR()) {
|
||||
///< VMOVHPS/PD mem64, xmm1
|
||||
// Need to store Bits[127:64]. Use a vector element store.
|
||||
auto Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, OpSize::i64Bit, Op->Flags, {.LoadData = false});
|
||||
auto Dest = MakeSegmentAddress(Op, Op->Dest);
|
||||
_VStoreVectorElement(OpSize::i128Bit, OpSize::i64Bit, Src1.Low, 1, Dest);
|
||||
} else if (!Op->Src[1].IsGPR()) {
|
||||
///< VMOVHPS/PD xmm2, xmm1, mem64
|
||||
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Op->Src[1], OpSize::i64Bit, Op->Flags, {.LoadData = false});
|
||||
auto Src2 = MakeSegmentAddress(Op, Op->Src[1]);
|
||||
|
||||
// Bits[63:0] come from Src1[63:0]
|
||||
// Bits[127:64] come from Src2[63:0]
|
||||
@@ -1236,7 +1236,7 @@ void OpDispatchBuilder::AVX128_PExtr(OpcodeArgs) {
|
||||
}
|
||||
|
||||
// If we are storing to memory then we store the size of the element extracted
|
||||
Ref Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
|
||||
Ref Dest = MakeSegmentAddress(Op, Op->Dest);
|
||||
_VStoreVectorElement(OpSize::i128Bit, OverridenElementSize, Src.Low, Index, Dest);
|
||||
}
|
||||
|
||||
@@ -1386,7 +1386,7 @@ void OpDispatchBuilder::AVX128_PINSRImpl(OpcodeArgs, size_t ElementSize, const X
|
||||
Result.Low = _VInsGPR(OpSize::i128Bit, ElementSize, Index, Src1.Low, Src2);
|
||||
} else {
|
||||
// If loading from memory then we only load the element size
|
||||
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Src2Op, ElementSize, Op->Flags, {.LoadData = false});
|
||||
auto Src2 = MakeSegmentAddress(Op, Src2Op);
|
||||
Result.Low = _VLoadVectorElement(OpSize::i128Bit, ElementSize, Src1.Low, Index, Src2);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ void OpDispatchBuilder::MOVHPDOp(OpcodeArgs) {
|
||||
} else {
|
||||
// If the destination is a GPR then the source is memory
|
||||
// xmm1[127:64] = src
|
||||
Ref Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.LoadData = false});
|
||||
Ref Src = MakeSegmentAddress(Op, Op->Src[0]);
|
||||
Ref Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, 16, Op->Flags);
|
||||
auto Result = _VLoadVectorElement(16, 8, Dest, 1, Src);
|
||||
StoreResult(FPRClass, Op, Result, -1);
|
||||
@@ -115,7 +115,7 @@ void OpDispatchBuilder::MOVHPDOp(OpcodeArgs) {
|
||||
// In this case memory is the destination and the high bits of the XMM are source
|
||||
// Mem64 = xmm1[127:64]
|
||||
Ref Src = LoadSource(FPRClass, Op, Op->Src[0], Op->Flags);
|
||||
Ref Dest = LoadSource_WithOpSize(GPRClass, Op, Op->Dest, 8, Op->Flags, {.LoadData = false});
|
||||
Ref Dest = MakeSegmentAddress(Op, Op->Dest);
|
||||
_VStoreVectorElement(16, 8, Src, 1, Dest);
|
||||
}
|
||||
}
|
||||
@@ -144,7 +144,7 @@ void OpDispatchBuilder::MOVLPOp(OpcodeArgs) {
|
||||
StoreResult_WithOpSize(FPRClass, Op, Op->Dest, Result, 16, 16);
|
||||
} else {
|
||||
auto DstSize = GetDstSize(Op);
|
||||
Ref Src = LoadSource(GPRClass, Op, Op->Src[0], Op->Flags, {.Align = 8, .LoadData = false});
|
||||
Ref Src = MakeSegmentAddress(Op, Op->Src[0]);
|
||||
Ref Dest = LoadSource_WithOpSize(FPRClass, Op, Op->Dest, DstSize, Op->Flags);
|
||||
auto Result = _VLoadVectorElement(16, 8, Dest, 0, Src);
|
||||
StoreResult(FPRClass, Op, Result, -1);
|
||||
@@ -1515,7 +1515,7 @@ Ref OpDispatchBuilder::PINSROpImpl(OpcodeArgs, size_t ElementSize, const X86Tabl
|
||||
}
|
||||
|
||||
// If loading from memory then we only load the element size
|
||||
auto Src2 = LoadSource_WithOpSize(GPRClass, Op, Src2Op, ElementSize, Op->Flags, {.LoadData = false});
|
||||
Ref Src2 = MakeSegmentAddress(Op, Src2Op);
|
||||
return _VLoadVectorElement(Size, ElementSize, Src1, Index, Src2);
|
||||
}
|
||||
|
||||
@@ -1639,7 +1639,7 @@ void OpDispatchBuilder::PExtrOp(OpcodeArgs, size_t ElementSize) {
|
||||
}
|
||||
|
||||
// If we are storing to memory then we store the size of the element extracted
|
||||
Ref Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, {.LoadData = false});
|
||||
Ref Dest = MakeSegmentAddress(Op, Op->Dest);
|
||||
_VStoreVectorElement(16, OverridenElementSize, Src, Index, Dest);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user