A64: Implement FCVT{N,M,A,P}{U,S} (vector), FCVTZU (vector, integer), single/double variant

This commit is contained in:
MerryMage 2018-07-26 12:46:12 +01:00
parent 28b38916a8
commit dd4ac86f8e
2 changed files with 61 additions and 18 deletions

View file

@ -587,11 +587,11 @@ INST(SQXTN_2, "SQXTN, SQXTN2", "0Q001
//INST(FRINTM_1, "FRINTM (vector)", "0Q00111001111001100110nnnnnddddd")
//INST(FRINTM_2, "FRINTM (vector)", "0Q0011100z100001100110nnnnnddddd")
//INST(FCVTNS_3, "FCVTNS (vector)", "0Q00111001111001101010nnnnnddddd")
//INST(FCVTNS_4, "FCVTNS (vector)", "0Q0011100z100001101010nnnnnddddd")
INST(FCVTNS_4, "FCVTNS (vector)", "0Q0011100z100001101010nnnnnddddd")
//INST(FCVTMS_3, "FCVTMS (vector)", "0Q00111001111001101110nnnnnddddd")
//INST(FCVTMS_4, "FCVTMS (vector)", "0Q0011100z100001101110nnnnnddddd")
INST(FCVTMS_4, "FCVTMS (vector)", "0Q0011100z100001101110nnnnnddddd")
//INST(FCVTAS_3, "FCVTAS (vector)", "0Q00111001111001110010nnnnnddddd")
//INST(FCVTAS_4, "FCVTAS (vector)", "0Q0011100z100001110010nnnnnddddd")
INST(FCVTAS_4, "FCVTAS (vector)", "0Q0011100z100001110010nnnnnddddd")
//INST(SCVTF_int_3, "SCVTF (vector, integer)", "0Q00111001111001110110nnnnnddddd")
INST(SCVTF_int_4, "SCVTF (vector, integer)", "0Q0011100z100001110110nnnnnddddd")
//INST(FCMGT_zero_3, "FCMGT (zero)", "0Q00111011111000110010nnnnnddddd")
@ -607,7 +607,7 @@ INST(FABS_2, "FABS (vector)", "0Q001
//INST(FRINTZ_1, "FRINTZ (vector)", "0Q00111011111001100110nnnnnddddd")
//INST(FRINTZ_2, "FRINTZ (vector)", "0Q0011101z100001100110nnnnnddddd")
//INST(FCVTPS_3, "FCVTPS (vector)", "0Q00111011111001101010nnnnnddddd")
//INST(FCVTPS_4, "FCVTPS (vector)", "0Q0011101z100001101010nnnnnddddd")
INST(FCVTPS_4, "FCVTPS (vector)", "0Q0011101z100001101010nnnnnddddd")
//INST(FCVTZS_int_3, "FCVTZS (vector, integer)", "0Q00111011111001101110nnnnnddddd")
INST(FCVTZS_int_4, "FCVTZS (vector, integer)", "0Q0011101z100001101110nnnnnddddd")
//INST(URECPE, "URECPE", "0Q0011101z100001110010nnnnnddddd")
@ -631,11 +631,11 @@ INST(UQXTN_2, "UQXTN, UQXTN2", "0Q101
//INST(FRINTX_1, "FRINTX (vector)", "0Q10111001111001100110nnnnnddddd")
//INST(FRINTX_2, "FRINTX (vector)", "0Q1011100z100001100110nnnnnddddd")
//INST(FCVTNU_3, "FCVTNU (vector)", "0Q10111001111001101010nnnnnddddd")
//INST(FCVTNU_4, "FCVTNU (vector)", "0Q1011100z100001101010nnnnnddddd")
INST(FCVTNU_4, "FCVTNU (vector)", "0Q1011100z100001101010nnnnnddddd")
//INST(FCVTMU_3, "FCVTMU (vector)", "0Q10111001111001101110nnnnnddddd")
//INST(FCVTMU_4, "FCVTMU (vector)", "0Q1011100z100001101110nnnnnddddd")
INST(FCVTMU_4, "FCVTMU (vector)", "0Q1011100z100001101110nnnnnddddd")
//INST(FCVTAU_3, "FCVTAU (vector)", "0Q10111001111001110010nnnnnddddd")
//INST(FCVTAU_4, "FCVTAU (vector)", "0Q1011100z100001110010nnnnnddddd")
INST(FCVTAU_4, "FCVTAU (vector)", "0Q1011100z100001110010nnnnnddddd")
//INST(UCVTF_int_3, "UCVTF (vector, integer)", "0Q10111001111001110110nnnnnddddd")
INST(UCVTF_int_4, "UCVTF (vector, integer)", "0Q1011100z100001110110nnnnnddddd")
INST(NOT, "NOT", "0Q10111000100000010110nnnnnddddd")
@ -649,9 +649,9 @@ INST(FCMGE_zero_4, "FCMGE (zero)", "0Q101
//INST(FCMLE_3, "FCMLE (zero)", "0Q10111011111000110110nnnnnddddd")
INST(FCMLE_4, "FCMLE (zero)", "0Q1011101z100000110110nnnnnddddd")
//INST(FCVTPU_3, "FCVTPU (vector)", "0Q10111011111001101010nnnnnddddd")
//INST(FCVTPU_4, "FCVTPU (vector)", "0Q1011101z100001101010nnnnnddddd")
INST(FCVTPU_4, "FCVTPU (vector)", "0Q1011101z100001101010nnnnnddddd")
//INST(FCVTZU_int_3, "FCVTZU (vector, integer)", "0Q10111011111001101110nnnnnddddd")
//INST(FCVTZU_int_4, "FCVTZU (vector, integer)", "0Q1011101z100001101110nnnnnddddd")
INST(FCVTZU_int_4, "FCVTZU (vector, integer)", "0Q1011101z100001101110nnnnnddddd")
//INST(URSQRTE, "URSQRTE", "0Q1011101z100001110010nnnnnddddd")
//INST(FRSQRTE_3, "FRSQRTE", "0Q10111011111001110110nnnnnddddd")
INST(FRSQRTE_4, "FRSQRTE", "0Q1011101z100001110110nnnnnddddd")

View file

@ -4,6 +4,7 @@
* General Public License version 2 or any later version.
*/
#include "common/fp/rounding_mode.h"
#include "frontend/A64/translate/impl/impl.h"
namespace Dynarmic::A64 {
@ -107,6 +108,23 @@ bool IntegerConvertToFloat(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd
return true;
}
bool FloatConvertToInteger(TranslatorVisitor& v, bool Q, bool sz, Vec Vn, Vec Vd, Signedness signedness, FP::RoundingMode rounding_mode) {
if (sz && !Q) {
return v.ReservedValue();
}
const size_t datasize = Q ? 128 : 64;
const size_t esize = sz ? 64 : 32;
const IR::U128 operand = v.V(datasize, Vn);
const IR::U128 result = signedness == Signedness::Signed
? v.ir.FPVectorToSignedFixed(esize, operand, 0, rounding_mode)
: v.ir.FPVectorToUnsignedFixed(esize, operand, 0, rounding_mode);
v.V(datasize, Vd, result);
return true;
}
bool SaturatedNarrow(TranslatorVisitor& v, bool Q, Imm<2> size, Vec Vn, Vec Vd, IR::U128 (IR::IREmitter::*fn)(size_t, const IR::U128&)) {
if (size == 0b11) {
return v.ReservedValue();
@ -234,19 +252,44 @@ bool TranslatorVisitor::FCMLT_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FPCompareAgainstZero(*this, Q, sz, Vn, Vd, ComparisonType::LT);
}
bool TranslatorVisitor::FCVTNS_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::ToNearest_TieEven);
}
bool TranslatorVisitor::FCVTMS_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsMinusInfinity);
}
bool TranslatorVisitor::FCVTAS_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::ToNearest_TieAwayFromZero);
}
bool TranslatorVisitor::FCVTPS_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsPlusInfinity);
}
bool TranslatorVisitor::FCVTZS_int_4(bool Q, bool sz, Vec Vn, Vec Vd) {
if (sz && !Q) {
return ReservedValue();
}
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Signed, FP::RoundingMode::TowardsZero);
}
const size_t datasize = Q ? 128 : 64;
const size_t esize = sz ? 64 : 32;
bool TranslatorVisitor::FCVTNU_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::ToNearest_TieEven);
}
const IR::U128 operand = V(datasize, Vn);
const IR::U128 result = ir.FPVectorToSignedFixed(esize, operand, 0, FP::RoundingMode::TowardsZero);
bool TranslatorVisitor::FCVTMU_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsMinusInfinity);
}
V(datasize, Vd, result);
return true;
bool TranslatorVisitor::FCVTAU_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::ToNearest_TieAwayFromZero);
}
bool TranslatorVisitor::FCVTPU_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsPlusInfinity);
}
bool TranslatorVisitor::FCVTZU_int_4(bool Q, bool sz, Vec Vn, Vec Vd) {
return FloatConvertToInteger(*this, Q, sz, Vn, Vd, Signedness::Unsigned, FP::RoundingMode::TowardsZero);
}
bool TranslatorVisitor::FRECPE_4(bool Q, bool sz, Vec Vn, Vec Vd) {