translator: Merge ANDN2 with AND and impl ORN2

This commit is contained in:
IndecisiveTurtle 2024-06-26 18:16:01 +03:00
parent e94149340e
commit c081663aac
3 changed files with 28 additions and 48 deletions

View File

@ -46,40 +46,6 @@ void Translator::S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst) {
ir.SetScc(result); ir.SetScc(result);
} }
void Translator::S_ANDN2_B64(const GcnInst& inst) {
// TODO: What if this is used for something other than EXEC masking?
const auto get_src = [&](const InstOperand& operand) {
switch (operand.field) {
case OperandField::VccLo:
return ir.GetVcc();
case OperandField::ExecLo:
return ir.GetExec();
case OperandField::ScalarGPR:
return ir.GetThreadBitScalarReg(IR::ScalarReg(operand.code));
default:
UNREACHABLE();
}
};
const IR::U1 src0{get_src(inst.src[0])};
const IR::U1 src1{get_src(inst.src[1])};
const IR::U1 result{ir.LogicalAnd(src0, ir.LogicalNot(src1))};
ir.SetScc(result);
switch (inst.dst[0].field) {
case OperandField::VccLo:
ir.SetVcc(result);
break;
case OperandField::ExecLo:
ir.SetExec(result);
break;
case OperandField::ScalarGPR:
ir.SetThreadBitScalarReg(IR::ScalarReg(inst.dst[0].code), result);
break;
default:
UNREACHABLE();
}
}
void Translator::S_AND_SAVEEXEC_B64(const GcnInst& inst) { void Translator::S_AND_SAVEEXEC_B64(const GcnInst& inst) {
// This instruction normally operates on 64-bit data (EXEC, VCC, SGPRs) // This instruction normally operates on 64-bit data (EXEC, VCC, SGPRs)
// However here we flatten it to 1-bit EXEC and 1-bit VCC. For the destination // However here we flatten it to 1-bit EXEC and 1-bit VCC. For the destination
@ -138,7 +104,7 @@ void Translator::S_MOV_B64(const GcnInst& inst) {
} }
} }
void Translator::S_OR_B64(bool negate, const GcnInst& inst) { void Translator::S_OR_B64(NegateMode negate, const GcnInst& inst) {
const auto get_src = [&](const InstOperand& operand) { const auto get_src = [&](const InstOperand& operand) {
switch (operand.field) { switch (operand.field) {
case OperandField::VccLo: case OperandField::VccLo:
@ -151,9 +117,12 @@ void Translator::S_OR_B64(bool negate, const GcnInst& inst) {
}; };
const IR::U1 src0{get_src(inst.src[0])}; const IR::U1 src0{get_src(inst.src[0])};
const IR::U1 src1{get_src(inst.src[1])}; IR::U1 src1{get_src(inst.src[1])};
if (negate == NegateMode::Src1) {
src1 = ir.LogicalNot(src1);
}
IR::U1 result = ir.LogicalOr(src0, src1); IR::U1 result = ir.LogicalOr(src0, src1);
if (negate) { if (negate == NegateMode::Result) {
result = ir.LogicalNot(result); result = ir.LogicalNot(result);
} }
ir.SetScc(result); ir.SetScc(result);
@ -169,7 +138,7 @@ void Translator::S_OR_B64(bool negate, const GcnInst& inst) {
} }
} }
void Translator::S_AND_B64(bool negate, const GcnInst& inst) { void Translator::S_AND_B64(NegateMode negate, const GcnInst& inst) {
const auto get_src = [&](const InstOperand& operand) { const auto get_src = [&](const InstOperand& operand) {
switch (operand.field) { switch (operand.field) {
case OperandField::VccLo: case OperandField::VccLo:
@ -183,9 +152,12 @@ void Translator::S_AND_B64(bool negate, const GcnInst& inst) {
} }
}; };
const IR::U1 src0{get_src(inst.src[0])}; const IR::U1 src0{get_src(inst.src[0])};
const IR::U1 src1{get_src(inst.src[1])}; IR::U1 src1{get_src(inst.src[1])};
if (negate == NegateMode::Src1) {
src1 = ir.LogicalNot(src1);
}
IR::U1 result = ir.LogicalAnd(src0, src1); IR::U1 result = ir.LogicalAnd(src0, src1);
if (negate) { if (negate == NegateMode::Result) {
result = ir.LogicalNot(result); result = ir.LogicalNot(result);
} }
ir.SetScc(result); ir.SetScc(result);

View File

@ -469,7 +469,10 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
translator.V_RSQ_F32(inst); translator.V_RSQ_F32(inst);
break; break;
case Opcode::S_ANDN2_B64: case Opcode::S_ANDN2_B64:
translator.S_ANDN2_B64(inst); translator.S_AND_B64(NegateMode::Src1, inst);
break;
case Opcode::S_ORN2_B64:
translator.S_OR_B64(NegateMode::Src1, inst);
break; break;
case Opcode::V_SIN_F32: case Opcode::V_SIN_F32:
translator.V_SIN_F32(inst); translator.V_SIN_F32(inst);
@ -608,19 +611,19 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
translator.V_CMP_U32(ConditionOp::TRU, false, true, inst); translator.V_CMP_U32(ConditionOp::TRU, false, true, inst);
break; break;
case Opcode::S_OR_B64: case Opcode::S_OR_B64:
translator.S_OR_B64(false, inst); translator.S_OR_B64(NegateMode::None, inst);
break; break;
case Opcode::S_NOR_B64: case Opcode::S_NOR_B64:
translator.S_OR_B64(true, inst); translator.S_OR_B64(NegateMode::Result, inst);
break; break;
case Opcode::S_AND_B64: case Opcode::S_AND_B64:
translator.S_AND_B64(false, inst); translator.S_AND_B64(NegateMode::None, inst);
break; break;
case Opcode::S_NOT_B64: case Opcode::S_NOT_B64:
translator.S_NOT_B64(inst); translator.S_NOT_B64(inst);
break; break;
case Opcode::S_NAND_B64: case Opcode::S_NAND_B64:
translator.S_AND_B64(true, inst); translator.S_AND_B64(NegateMode::Result, inst);
break; break;
case Opcode::V_LSHRREV_B32: case Opcode::V_LSHRREV_B32:
translator.V_LSHRREV_B32(inst); translator.V_LSHRREV_B32(inst);

View File

@ -26,6 +26,12 @@ enum class ConditionOp : u32 {
TRU, TRU,
}; };
enum class NegateMode : u32 {
None,
Src1,
Result,
};
class Translator { class Translator {
public: public:
explicit Translator(IR::Block* block_, Info& info); explicit Translator(IR::Block* block_, Info& info);
@ -38,11 +44,10 @@ public:
void S_MOV(const GcnInst& inst); void S_MOV(const GcnInst& inst);
void S_MUL_I32(const GcnInst& inst); void S_MUL_I32(const GcnInst& inst);
void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst); void S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst);
void S_ANDN2_B64(const GcnInst& inst);
void S_AND_SAVEEXEC_B64(const GcnInst& inst); void S_AND_SAVEEXEC_B64(const GcnInst& inst);
void S_MOV_B64(const GcnInst& inst); void S_MOV_B64(const GcnInst& inst);
void S_OR_B64(bool negate, const GcnInst& inst); void S_OR_B64(NegateMode negate, const GcnInst& inst);
void S_AND_B64(bool negate, const GcnInst& inst); void S_AND_B64(NegateMode negate, const GcnInst& inst);
void S_ADD_I32(const GcnInst& inst); void S_ADD_I32(const GcnInst& inst);
void S_AND_B32(const GcnInst& inst); void S_AND_B32(const GcnInst& inst);
void S_OR_B32(const GcnInst& inst); void S_OR_B32(const GcnInst& inst);