A32: Implement VCVT{A,N,P,M} (ASIMD)
This commit is contained in:
parent
c9fcb695a4
commit
05f38d1989
3 changed files with 45 additions and 4 deletions
|
@ -133,10 +133,10 @@ INST(v8_VRINTM, "VRINTM", "111100111D11zz10dddd011
|
||||||
INST(v8_VRINTP, "VRINTP", "111100111D11zz10dddd01111QM0mmmm") // v8
|
INST(v8_VRINTP, "VRINTP", "111100111D11zz10dddd01111QM0mmmm") // v8
|
||||||
INST(asimd_VCVT_half, "VCVT (half-precision)", "111100111D11zz10dddd011o00M0mmmm") // ASIMD
|
INST(asimd_VCVT_half, "VCVT (half-precision)", "111100111D11zz10dddd011o00M0mmmm") // ASIMD
|
||||||
INST(arm_UDF, "UNALLOCATED", "111100111-11--10----011-01-0----") // ASIMD
|
INST(arm_UDF, "UNALLOCATED", "111100111-11--10----011-01-0----") // ASIMD
|
||||||
INST(arm_UDF, "UNALLOCATED (VCVTA)", "111100111-11--11----0000---0----")
|
INST(v8_VCVTA, "VCVTA", "111100111D11zz11dddd0000oQM0mmmm") // v8
|
||||||
INST(arm_UDF, "UNALLOCATED (VCVTN)", "111100111-11--11----0001---0----")
|
INST(v8_VCVTN, "VCVTN", "111100111D11zz11dddd0001oQM0mmmm") // v8
|
||||||
INST(arm_UDF, "UNALLOCATED (VCVTP)", "111100111-11--11----0010---0----")
|
INST(v8_VCVTP, "VCVTP", "111100111D11zz11dddd0010oQM0mmmm") // v8
|
||||||
INST(arm_UDF, "UNALLOCATED (VCVTM)", "111100111-11--11----0011---0----")
|
INST(v8_VCVTM, "VCVTM", "111100111D11zz11dddd0011oQM0mmmm") // v8
|
||||||
INST(asimd_VRECPE, "VRECPE", "111100111D11zz11dddd010F0QM0mmmm") // ASIMD
|
INST(asimd_VRECPE, "VRECPE", "111100111D11zz11dddd010F0QM0mmmm") // ASIMD
|
||||||
INST(asimd_VRSQRTE, "VRSQRTE", "111100111D11zz11dddd010F1QM0mmmm") // ASIMD
|
INST(asimd_VRSQRTE, "VRSQRTE", "111100111D11zz11dddd010F1QM0mmmm") // ASIMD
|
||||||
INST(asimd_VCVT_integer, "VCVT (integer)", "111100111D11zz11dddd011oUQM0mmmm") // ASIMD
|
INST(asimd_VCVT_integer, "VCVT (integer)", "111100111D11zz11dddd011oUQM0mmmm") // ASIMD
|
||||||
|
|
|
@ -957,6 +957,10 @@ struct TranslatorVisitor final {
|
||||||
bool v8_VRINTM(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm);
|
bool v8_VRINTM(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm);
|
||||||
bool v8_VRINTP(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm);
|
bool v8_VRINTP(bool D, size_t sz, size_t Vd, bool Q, bool M, size_t Vm);
|
||||||
bool asimd_VCVT_half(bool D, size_t sz, size_t Vd, bool op, bool M, size_t Vm);
|
bool asimd_VCVT_half(bool D, size_t sz, size_t Vd, bool op, bool M, size_t Vm);
|
||||||
|
bool v8_VCVTA(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm);
|
||||||
|
bool v8_VCVTN(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm);
|
||||||
|
bool v8_VCVTP(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm);
|
||||||
|
bool v8_VCVTM(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm);
|
||||||
bool asimd_VRECPE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm);
|
bool asimd_VRECPE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm);
|
||||||
bool asimd_VRSQRTE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm);
|
bool asimd_VRSQRTE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm);
|
||||||
bool asimd_VCVT_integer(bool D, size_t sz, size_t Vd, bool op, bool U, bool Q, bool M, size_t Vm);
|
bool asimd_VCVT_integer(bool D, size_t sz, size_t Vd, bool op, bool U, bool Q, bool M, size_t Vm);
|
||||||
|
|
|
@ -123,6 +123,30 @@ bool RoundFloatToInteger(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, boo
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ConvertFloatToInteger(TranslatorVisitor& v, bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm, FP::RoundingMode rounding_mode) {
|
||||||
|
if (Q && (mcl::bit::get_bit<0>(Vd) || mcl::bit::get_bit<0>(Vm))) {
|
||||||
|
return v.UndefinedInstruction();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sz != 0b10) {
|
||||||
|
return v.UndefinedInstruction(); // TODO: FP16
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool unsigned_ = op;
|
||||||
|
const size_t esize = 8 << sz;
|
||||||
|
|
||||||
|
const auto d = ToVector(Q, Vd, D);
|
||||||
|
const auto m = ToVector(Q, Vm, M);
|
||||||
|
|
||||||
|
const auto reg_m = v.ir.GetVector(m);
|
||||||
|
const auto result = unsigned_
|
||||||
|
? v.ir.FPVectorToUnsignedFixed(esize, reg_m, 0, rounding_mode, false)
|
||||||
|
: v.ir.FPVectorToSignedFixed(esize, reg_m, 0, rounding_mode, false);
|
||||||
|
|
||||||
|
v.ir.SetVector(d, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool TranslatorVisitor::asimd_VREV(bool D, size_t sz, size_t Vd, size_t op, bool Q, bool M, size_t Vm) {
|
bool TranslatorVisitor::asimd_VREV(bool D, size_t sz, size_t Vd, size_t op, bool Q, bool M, size_t Vm) {
|
||||||
|
@ -653,6 +677,19 @@ bool TranslatorVisitor::asimd_VCVT_half(bool D, size_t sz, size_t Vd, bool half_
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::v8_VCVTA(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm) {
|
||||||
|
return ConvertFloatToInteger(*this, D, sz, Vd, op, Q, M, Vm, FP::RoundingMode::ToNearest_TieAwayFromZero);
|
||||||
|
}
|
||||||
|
bool TranslatorVisitor::v8_VCVTN(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm) {
|
||||||
|
return ConvertFloatToInteger(*this, D, sz, Vd, op, Q, M, Vm, FP::RoundingMode::ToNearest_TieEven);
|
||||||
|
}
|
||||||
|
bool TranslatorVisitor::v8_VCVTP(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm) {
|
||||||
|
return ConvertFloatToInteger(*this, D, sz, Vd, op, Q, M, Vm, FP::RoundingMode::TowardsPlusInfinity);
|
||||||
|
}
|
||||||
|
bool TranslatorVisitor::v8_VCVTM(bool D, size_t sz, size_t Vd, bool op, bool Q, bool M, size_t Vm) {
|
||||||
|
return ConvertFloatToInteger(*this, D, sz, Vd, op, Q, M, Vm, FP::RoundingMode::TowardsMinusInfinity);
|
||||||
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::asimd_VRECPE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
|
bool TranslatorVisitor::asimd_VRECPE(bool D, size_t sz, size_t Vd, bool F, bool Q, bool M, size_t Vm) {
|
||||||
if (Q && (mcl::bit::get_bit<0>(Vd) || mcl::bit::get_bit<0>(Vm))) {
|
if (Q && (mcl::bit::get_bit<0>(Vd) || mcl::bit::get_bit<0>(Vm))) {
|
||||||
return UndefinedInstruction();
|
return UndefinedInstruction();
|
||||||
|
|
Loading…
Reference in a new issue