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);
|
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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue