mirror of
https://github.com/KytyPS5/KytyPS5.git
synced 2026-10-28 13:56:59 +01:00
shader: drop BFM mask bits shifted past bit 31 instead of an out-of-range bit-field insert
This commit is contained in:
@@ -380,9 +380,8 @@ void Translator::S_QUADMASK_B64(const Decoder::Instruction& inst) {
|
|||||||
void Translator::BFM_B32(const Decoder::Instruction& inst) {
|
void Translator::BFM_B32(const Decoder::Instruction& inst) {
|
||||||
const auto count = ir.BitwiseAnd(ReadU32(inst.src0), IR::U32(IR::Value(31u)));
|
const auto count = ir.BitwiseAnd(ReadU32(inst.src0), IR::U32(IR::Value(31u)));
|
||||||
const auto offset = ir.BitwiseAnd(ReadU32(inst.src1), IR::U32(IR::Value(31u)));
|
const auto offset = ir.BitwiseAnd(ReadU32(inst.src1), IR::U32(IR::Value(31u)));
|
||||||
const auto result = ir.Emit(IR::ValueOpcode::BitFieldInsert,
|
// Mask bits shifted past bit 31 are dropped.
|
||||||
{IR::Value(0u), IR::Value(0xffffffffu), offset, count});
|
WriteOperand(DestinationOperand(inst), ir.ShiftLeftLogical(RightMask32(count), offset));
|
||||||
WriteOperand(DestinationOperand(inst), result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IR::U32 Translator::RightMask32(IR::U32 count) {
|
IR::U32 Translator::RightMask32(IR::U32 count) {
|
||||||
|
|||||||
@@ -25622,6 +25622,31 @@ TestCase VectorBfeI32SignExtendsField() {
|
|||||||
return test;
|
return test;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TestCase VectorBfmDropsMaskBitsPastBit31() {
|
||||||
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
|
std::vector<u32> code;
|
||||||
|
for (u32 vgpr = 0; vgpr < 4; vgpr++) {
|
||||||
|
AppendVMovU32(&code, 30, vgpr * sizeof(u32));
|
||||||
|
AppendBufferLoadDword(&code, vgpr, 30);
|
||||||
|
}
|
||||||
|
AppendVop3(&code, 0x363, 10, Vgpr(0), Vgpr(1));
|
||||||
|
AppendVop3(&code, 0x363, 11, Vgpr(2), Vgpr(3));
|
||||||
|
AppendStoreVgpr(&code, 10, 0);
|
||||||
|
AppendStoreVgpr(&code, 11, 1);
|
||||||
|
AppendEnd(&code);
|
||||||
|
|
||||||
|
TestCase test;
|
||||||
|
test.name = "VectorBfmDropsMaskBitsPastBit31";
|
||||||
|
test.code = std::move(code);
|
||||||
|
// Size and offset use bits [4:0]; mask bits shifted past bit 31 are dropped.
|
||||||
|
test.initial = {24, 16, 0x3fu, 0x21u};
|
||||||
|
test.expected = {0xffff0000u, 0xfffffffeu};
|
||||||
|
test.opcodes = {O::V_MOV_B32, O::BUFFER_LOAD_DWORD, O::V_BFM_B32,
|
||||||
|
O::BUFFER_STORE_DWORD, O::S_ENDPGM};
|
||||||
|
return test;
|
||||||
|
}
|
||||||
|
|
||||||
TestCase VectorAlignByteUsesTwoBitByteOffset() {
|
TestCase VectorAlignByteUsesTwoBitByteOffset() {
|
||||||
using O = ShaderOpcode;
|
using O = ShaderOpcode;
|
||||||
|
|
||||||
@@ -42981,6 +43006,7 @@ std::vector<TestCase> MakeCases() {
|
|||||||
AddCase(VectorVop3LshlrevB64Captured);
|
AddCase(VectorVop3LshlrevB64Captured);
|
||||||
AddCase(VectorVop3IntegerOps);
|
AddCase(VectorVop3IntegerOps);
|
||||||
AddCase(VectorBfeI32SignExtendsField);
|
AddCase(VectorBfeI32SignExtendsField);
|
||||||
|
AddCase(VectorBfmDropsMaskBitsPastBit31);
|
||||||
AddCase(VectorAlignByteUsesTwoBitByteOffset);
|
AddCase(VectorAlignByteUsesTwoBitByteOffset);
|
||||||
AddCase(VectorCarryAndBitCountOps);
|
AddCase(VectorCarryAndBitCountOps);
|
||||||
AddCase(ScalarVector64BitFloatInlineConstants);
|
AddCase(ScalarVector64BitFloatInlineConstants);
|
||||||
|
|||||||
Reference in New Issue
Block a user