translator: Merge ANDN2 with AND and impl ORN2
This commit is contained in:
parent
e94149340e
commit
c081663aac
|
@ -46,40 +46,6 @@ void Translator::S_CMP(ConditionOp cond, bool is_signed, const GcnInst& inst) {
|
|||
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) {
|
||||
// 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
|
||||
|
@ -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) {
|
||||
switch (operand.field) {
|
||||
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 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);
|
||||
if (negate) {
|
||||
if (negate == NegateMode::Result) {
|
||||
result = ir.LogicalNot(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) {
|
||||
switch (operand.field) {
|
||||
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 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);
|
||||
if (negate) {
|
||||
if (negate == NegateMode::Result) {
|
||||
result = ir.LogicalNot(result);
|
||||
}
|
||||
ir.SetScc(result);
|
||||
|
|
|
@ -469,7 +469,10 @@ void Translate(IR::Block* block, std::span<const GcnInst> inst_list, Info& info)
|
|||
translator.V_RSQ_F32(inst);
|
||||
break;
|
||||
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;
|
||||
case Opcode::V_SIN_F32:
|
||||
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);
|
||||
break;
|
||||
case Opcode::S_OR_B64:
|
||||
translator.S_OR_B64(false, inst);
|
||||
translator.S_OR_B64(NegateMode::None, inst);
|
||||
break;
|
||||
case Opcode::S_NOR_B64:
|
||||
translator.S_OR_B64(true, inst);
|
||||
translator.S_OR_B64(NegateMode::Result, inst);
|
||||
break;
|
||||
case Opcode::S_AND_B64:
|
||||
translator.S_AND_B64(false, inst);
|
||||
translator.S_AND_B64(NegateMode::None, inst);
|
||||
break;
|
||||
case Opcode::S_NOT_B64:
|
||||
translator.S_NOT_B64(inst);
|
||||
break;
|
||||
case Opcode::S_NAND_B64:
|
||||
translator.S_AND_B64(true, inst);
|
||||
translator.S_AND_B64(NegateMode::Result, inst);
|
||||
break;
|
||||
case Opcode::V_LSHRREV_B32:
|
||||
translator.V_LSHRREV_B32(inst);
|
||||
|
|
|
@ -26,6 +26,12 @@ enum class ConditionOp : u32 {
|
|||
TRU,
|
||||
};
|
||||
|
||||
enum class NegateMode : u32 {
|
||||
None,
|
||||
Src1,
|
||||
Result,
|
||||
};
|
||||
|
||||
class Translator {
|
||||
public:
|
||||
explicit Translator(IR::Block* block_, Info& info);
|
||||
|
@ -38,11 +44,10 @@ public:
|
|||
void S_MOV(const GcnInst& inst);
|
||||
void S_MUL_I32(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_MOV_B64(const GcnInst& inst);
|
||||
void S_OR_B64(bool negate, const GcnInst& inst);
|
||||
void S_AND_B64(bool negate, const GcnInst& inst);
|
||||
void S_OR_B64(NegateMode negate, const GcnInst& inst);
|
||||
void S_AND_B64(NegateMode negate, const GcnInst& inst);
|
||||
void S_ADD_I32(const GcnInst& inst);
|
||||
void S_AND_B32(const GcnInst& inst);
|
||||
void S_OR_B32(const GcnInst& inst);
|
||||
|
|
Loading…
Reference in New Issue