mirror of
https://github.com/FEX-Emu/FEX.git
synced 2026-10-25 22:00:13 +01:00
Fixes a case of the BT ops failing to test the correct bit
When the `BT mem` operation was accessing memory where the bit offset wasn't a multiple of the access size, then we were dividing the offset by bytes and accessing bits at `mem[byteOffset] &= (BitOffset)`. BitOffset wasn't adjusted to compensate for the access size being added to the address. Causing a mismatch of testing the wrong bits. Unit tests didn't capture this. Trying to run glxgears on i965/iris showed extensive corruption because of it though.
This commit is contained in:
1 parent
b287d9f903
commit
b25f1c4e3b
1 file changed
+11
-24
+11
-24
@@ -1655,12 +1655,9 @@ void OpDispatchBuilder::BTOp(OpcodeArgs) {
|
||||
else {
|
||||
// Load the address to the memory location
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1, false);
|
||||
uint32_t Size = GetSrcSize(Op);
|
||||
uint32_t Mask = Size * 8 - 1;
|
||||
OrderedNode *SizeMask = _Constant(Mask);
|
||||
|
||||
// Get the bit selection from the src
|
||||
OrderedNode *BitSelect = _And(Src, SizeMask);
|
||||
OrderedNode *BitSelect = _Bfe(3, 0, Src);
|
||||
|
||||
// Address is provided as bits we want BYTE offsets
|
||||
// Just shift by 3 to get the offset
|
||||
@@ -1671,7 +1668,7 @@ void OpDispatchBuilder::BTOp(OpcodeArgs) {
|
||||
|
||||
// Now add the addresses together and load the memory
|
||||
OrderedNode *MemoryLocation = _Add(Dest, Src);
|
||||
Result = _LoadMem(GPRClass, Size, MemoryLocation, Size);
|
||||
Result = _LoadMem(GPRClass, 1, MemoryLocation, 1);
|
||||
|
||||
// Now shift in to the correct bit location
|
||||
Result = _Lshr(Result, BitSelect);
|
||||
@@ -1703,12 +1700,9 @@ void OpDispatchBuilder::BTROp(OpcodeArgs) {
|
||||
else {
|
||||
// Load the address to the memory location
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1, false);
|
||||
uint32_t Size = GetSrcSize(Op);
|
||||
uint32_t Mask = Size * 8 - 1;
|
||||
OrderedNode *SizeMask = _Constant(Mask);
|
||||
|
||||
// Get the bit selection from the src
|
||||
OrderedNode *BitSelect = _And(Src, SizeMask);
|
||||
OrderedNode *BitSelect = _Bfe(3, 0, Src);
|
||||
|
||||
// Address is provided as bits we want BYTE offsets
|
||||
// Just shift by 3 to get the offset
|
||||
@@ -1719,14 +1713,14 @@ void OpDispatchBuilder::BTROp(OpcodeArgs) {
|
||||
|
||||
// Now add the addresses together and load the memory
|
||||
OrderedNode *MemoryLocation = _Add(Dest, Src);
|
||||
OrderedNode *Value = _LoadMem(GPRClass, Size, MemoryLocation, Size);
|
||||
OrderedNode *Value = _LoadMem(GPRClass, 1, MemoryLocation, 1);
|
||||
|
||||
// Now shift in to the correct bit location
|
||||
Result = _Lshr(Value, BitSelect);
|
||||
OrderedNode *BitMask = _Lshl(_Constant(1), BitSelect);
|
||||
BitMask = _Not(BitMask);
|
||||
Value = _And(Value, BitMask);
|
||||
_StoreMem(GPRClass, Size, MemoryLocation, Value, Size);
|
||||
_StoreMem(GPRClass, 1, MemoryLocation, Value, 1);
|
||||
}
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_LOC>(Result);
|
||||
}
|
||||
@@ -1754,12 +1748,9 @@ void OpDispatchBuilder::BTSOp(OpcodeArgs) {
|
||||
else {
|
||||
// Load the address to the memory location
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1, false);
|
||||
uint32_t Size = GetSrcSize(Op);
|
||||
uint32_t Mask = Size * 8 - 1;
|
||||
OrderedNode *SizeMask = _Constant(Mask);
|
||||
|
||||
// Get the bit selection from the src
|
||||
OrderedNode *BitSelect = _And(Src, SizeMask);
|
||||
OrderedNode *BitSelect = _Bfe(3, 0, Src);
|
||||
|
||||
// Address is provided as bits we want BYTE offsets
|
||||
// Just shift by 3 to get the offset
|
||||
@@ -1770,13 +1761,13 @@ void OpDispatchBuilder::BTSOp(OpcodeArgs) {
|
||||
|
||||
// Now add the addresses together and load the memory
|
||||
OrderedNode *MemoryLocation = _Add(Dest, Src);
|
||||
OrderedNode *Value = _LoadMem(GPRClass, Size, MemoryLocation, Size);
|
||||
OrderedNode *Value = _LoadMem(GPRClass, 1, MemoryLocation, 1);
|
||||
|
||||
// Now shift in to the correct bit location
|
||||
Result = _Lshr(Value, BitSelect);
|
||||
OrderedNode *BitMask = _Lshl(_Constant(1), BitSelect);
|
||||
Value = _Or(Value, BitMask);
|
||||
_StoreMem(GPRClass, Size, MemoryLocation, Value, Size);
|
||||
_StoreMem(GPRClass, 1, MemoryLocation, Value, 1);
|
||||
}
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_LOC>(Result);
|
||||
}
|
||||
@@ -1804,12 +1795,8 @@ void OpDispatchBuilder::BTCOp(OpcodeArgs) {
|
||||
else {
|
||||
// Load the address to the memory location
|
||||
OrderedNode *Dest = LoadSource(GPRClass, Op, Op->Dest, Op->Flags, -1, false);
|
||||
uint32_t Size = GetSrcSize(Op);
|
||||
uint32_t Mask = Size * 8 - 1;
|
||||
OrderedNode *SizeMask = _Constant(Mask);
|
||||
|
||||
// Get the bit selection from the src
|
||||
OrderedNode *BitSelect = _And(Src, SizeMask);
|
||||
OrderedNode *BitSelect = _Bfe(3, 0, Src);
|
||||
|
||||
// Address is provided as bits we want BYTE offsets
|
||||
// Just shift by 3 to get the offset
|
||||
@@ -1820,13 +1807,13 @@ void OpDispatchBuilder::BTCOp(OpcodeArgs) {
|
||||
|
||||
// Now add the addresses together and load the memory
|
||||
OrderedNode *MemoryLocation = _Add(Dest, Src);
|
||||
OrderedNode *Value = _LoadMem(GPRClass, Size, MemoryLocation, Size);
|
||||
OrderedNode *Value = _LoadMem(GPRClass, 1, MemoryLocation, 1);
|
||||
|
||||
// Now shift in to the correct bit location
|
||||
Result = _Lshr(Value, BitSelect);
|
||||
OrderedNode *BitMask = _Lshl(_Constant(1), BitSelect);
|
||||
Value = _Xor(Value, BitMask);
|
||||
_StoreMem(GPRClass, Size, MemoryLocation, Value, Size);
|
||||
_StoreMem(GPRClass, 1, MemoryLocation, Value, 1);
|
||||
}
|
||||
SetRFLAG<FEXCore::X86State::RFLAG_CF_LOC>(Result);
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user