shader: mask ALIGNBYTE offsets to the two-bit selector

Co-authored-by: shadowbeat070 <70843316+shadowbeat070@users.noreply.github.com>
Co-authored-by: TheCruZ <thecruzwtf@gmail.com>
This commit is contained in:
nmzik
2026-10-04 02:55:33 +04:00
parent 284d58d1d5
commit f18679e0cd
4 changed files with 25 additions and 34 deletions
@@ -483,10 +483,11 @@ void Translator::S_BITCMP_B64(const Decoder::Instruction& inst, bool expected) {
WriteCompareResult(inst.dst, ir.IEqual(bit, IR::U32(IR::Value(expected ? 1u : 0u))));
}
void Translator::V_ALIGNBIT_B32(const Decoder::Instruction& inst) {
const auto hi = ReadU32(inst.src0);
const auto lo = ReadU32(inst.src1);
const auto shift = ir.BitwiseAnd(ReadU32(inst.src2), IR::U32(IR::Value(31u)));
void Translator::V_ALIGN_B32(const Decoder::Instruction& inst, bool byte_offset) {
const auto hi = ReadU32(inst.src0);
const auto lo = ReadU32(inst.src1);
auto shift = ir.BitwiseAnd(ReadU32(inst.src2), IR::U32(IR::Value(byte_offset ? 3u : 31u)));
if (byte_offset) shift = ir.ShiftLeftLogical(shift, IR::U32(IR::Value(3u)));
const auto lo_part = ir.ShiftRightLogical(lo, shift);
const auto inverse =
ir.BitwiseAnd(ir.ISub(IR::U32(IR::Value(32u)), shift), IR::U32(IR::Value(31u)));
@@ -496,21 +497,6 @@ void Translator::V_ALIGNBIT_B32(const Decoder::Instruction& inst) {
WriteOperand(DestinationOperand(inst), ir.BitwiseOr(lo_part, hi_part));
}
void Translator::V_ALIGNBYTE_B32(const Decoder::Instruction& inst) {
const auto hi = ReadU32(inst.src0);
const auto lo = ReadU32(inst.src1);
const auto byte_offset = ir.BitwiseAnd(ReadU32(inst.src2), IR::U32(IR::Value(31u)));
const auto bit_offset = ir.ShiftLeftLogical(byte_offset, IR::U32(IR::Value(3u)));
const auto concatenated = ir.ConstructU64(lo, hi);
const auto shifted =
IR::U64(ir.Emit(IR::ValueOpcode::ShiftRightLogical64,
{concatenated, ir.BitwiseAnd(bit_offset, IR::U32(IR::Value(63u)))}));
const auto in_range =
IR::U1(ir.Emit(IR::ValueOpcode::ULessThan32, {byte_offset, IR::Value(8u)}));
WriteOperand(DestinationOperand(inst),
ir.Select(in_range, ExtractU64(shifted)[0], IR::U32(IR::Value(0u))));
}
void Translator::V_LSHL_ADD_U32(const Decoder::Instruction& inst) {
const auto shift = ir.BitwiseAnd(ReadU32(inst.src1), IR::U32(IR::Value(31u)));
const auto result = ir.IAdd(ir.ShiftLeftLogical(ReadU32(inst.src0), shift), ReadU32(inst.src2));
@@ -208,8 +208,7 @@ private:
void V_BFI_B32(const Decoder::Instruction& inst);
void S_BITCMP_B32(const Decoder::Instruction& inst, bool expected);
void S_BITCMP_B64(const Decoder::Instruction& inst, bool expected);
void V_ALIGNBIT_B32(const Decoder::Instruction& inst);
void V_ALIGNBYTE_B32(const Decoder::Instruction& inst);
void V_ALIGN_B32(const Decoder::Instruction& inst, bool byte_offset);
void V_LSHL_ADD_U32(const Decoder::Instruction& inst);
void V_ADD_LSHL_U32(const Decoder::Instruction& inst);
void V_XAD_U32(const Decoder::Instruction& inst);
@@ -592,8 +592,8 @@ void Translator::EmitVector(const Decoder::Instruction& inst) {
case O::V_BFE_U32: return V_BFE_U32(inst, false);
case O::V_BFE_I32: return V_BFE_U32(inst, true);
case O::V_BFI_B32: return V_BFI_B32(inst);
case O::V_ALIGNBIT_B32: return V_ALIGNBIT_B32(inst);
case O::V_ALIGNBYTE_B32: return V_ALIGNBYTE_B32(inst);
case O::V_ALIGNBIT_B32: return V_ALIGN_B32(inst, false);
case O::V_ALIGNBYTE_B32: return V_ALIGN_B32(inst, true);
case O::V_LSHL_ADD_U32: return V_LSHL_ADD_U32(inst);
case O::V_ADD_LSHL_U32: return V_ADD_LSHL_U32(inst);
case O::V_XAD_U32: return V_XAD_U32(inst);