A32: Implement VCEQ/VCGE/VCGT (floating point)
This commit is contained in:
parent
faefb264a6
commit
e319257ec0
3 changed files with 51 additions and 3 deletions
|
@ -41,9 +41,9 @@ INST(asimd_VABD_float, "VABD (floating-point)", "111100110D1znnnndddd110
|
|||
INST(asimd_VMLA_float, "VMLA (floating-point)", "111100100D0znnnndddd1101NQM1mmmm") // ASIMD
|
||||
INST(asimd_VMLS_float, "VMLS (floating-point)", "111100100D1znnnndddd1101NQM1mmmm") // ASIMD
|
||||
INST(asimd_VMUL_float, "VMUL (floating-point)", "111100110D0znnnndddd1101NQM1mmmm") // ASIMD
|
||||
//INST(asimd_VCEQ_reg, "VCEQ (register)", "111100100-0C--------1110---0----") // ASIMD
|
||||
//INST(asimd_VCGE_reg, "VCGE (register)", "111100110-0C--------1110---0----") // ASIMD
|
||||
//INST(asimd_VCGT_reg, "VCGT (register)", "111100110-1C--------1110---0----") // ASIMD
|
||||
INST(asimd_VCEQ_reg_float, "VCEQ (register)", "111100100D0znnnndddd1110NQM0mmmm") // ASIMD
|
||||
INST(asimd_VCGE_reg_float, "VCGE (register)", "111100110D0znnnndddd1110NQM0mmmm") // ASIMD
|
||||
INST(asimd_VCGT_reg_float, "VCGT (register)", "111100110D1znnnndddd1110NQM0mmmm") // ASIMD
|
||||
//INST(asimd_VACGE, "VACGE", "111100110-CC--------1110---1----") // ASIMD
|
||||
INST(asimd_VMAX_float, "VMAX (floating-point)", "111100100D0znnnndddd1111NQM0mmmm") // ASIMD
|
||||
INST(asimd_VMIN_float, "VMIN (floating-point)", "111100100D1znnnndddd1111NQM0mmmm") // ASIMD
|
||||
|
|
|
@ -99,6 +99,39 @@ bool IntegerComparison(ArmTranslatorVisitor& v, bool U, bool D, size_t sz, size_
|
|||
v.ir.SetVector(d, result);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FloatComparison(ArmTranslatorVisitor& v, bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm,
|
||||
Comparison comparison) {
|
||||
if (sz) {
|
||||
return v.UndefinedInstruction();
|
||||
}
|
||||
|
||||
if (Q && (Common::Bit<0>(Vd) || Common::Bit<0>(Vn) || Common::Bit<0>(Vm))) {
|
||||
return v.UndefinedInstruction();
|
||||
}
|
||||
|
||||
const auto d = ToVector(Q, Vd, D);
|
||||
const auto m = ToVector(Q, Vm, M);
|
||||
const auto n = ToVector(Q, Vn, N);
|
||||
|
||||
const auto reg_n = v.ir.GetVector(n);
|
||||
const auto reg_m = v.ir.GetVector(m);
|
||||
const auto result = [&] {
|
||||
switch (comparison) {
|
||||
case Comparison::GE:
|
||||
return v.ir.FPVectorGreaterEqual(32, reg_n, reg_m, false);
|
||||
case Comparison::GT:
|
||||
return v.ir.FPVectorGreater(32, reg_n, reg_m, false);
|
||||
case Comparison::EQ:
|
||||
return v.ir.FPVectorEqual(32, reg_n, reg_m, false);
|
||||
default:
|
||||
return IR::U128{};
|
||||
}
|
||||
}();
|
||||
|
||||
v.ir.SetVector(d, result);
|
||||
return true;
|
||||
}
|
||||
} // Anonymous namespace
|
||||
|
||||
bool ArmTranslatorVisitor::asimd_VHADD(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
|
||||
|
@ -528,6 +561,18 @@ bool ArmTranslatorVisitor::asimd_VMUL_float(bool D, bool sz, size_t Vn, size_t V
|
|||
});
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::asimd_VCEQ_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
|
||||
return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::EQ);
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::asimd_VCGE_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
|
||||
return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GE);
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::asimd_VCGT_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
|
||||
return FloatComparison(*this, D, sz, Vn, Vd, N, Q, M, Vm, Comparison::GT);
|
||||
}
|
||||
|
||||
bool ArmTranslatorVisitor::asimd_VMAX_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) {
|
||||
return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) {
|
||||
return ir.FPVectorMax(32, reg_n, reg_m, false);
|
||||
|
|
|
@ -483,6 +483,9 @@ struct ArmTranslatorVisitor final {
|
|||
bool asimd_VMLA_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VMLS_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VMUL_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VCEQ_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VCGE_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VCGT_reg_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VMAX_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VMIN_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
bool asimd_VRECPS(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm);
|
||||
|
|
Loading…
Reference in a new issue