simd_scalar_two_register_misc: Implement scalar double/single-precision variants of FCM{EQ, GE, GT, LE, LT} (zero)

This commit is contained in:
Lioncash 2018-07-15 19:50:32 -04:00 committed by MerryMage
parent 9db6d1e98b
commit f7f83b76b7
2 changed files with 62 additions and 5 deletions

View file

@ -367,11 +367,11 @@ INST(FACGT_2, "FACGT", "01111
//INST(SCVTF_int_1, "SCVTF (vector, integer)", "0101111001111001110110nnnnnddddd") //INST(SCVTF_int_1, "SCVTF (vector, integer)", "0101111001111001110110nnnnnddddd")
INST(SCVTF_int_2, "SCVTF (vector, integer)", "010111100z100001110110nnnnnddddd") INST(SCVTF_int_2, "SCVTF (vector, integer)", "010111100z100001110110nnnnnddddd")
//INST(FCMGT_zero_1, "FCMGT (zero)", "0101111011111000110010nnnnnddddd") //INST(FCMGT_zero_1, "FCMGT (zero)", "0101111011111000110010nnnnnddddd")
//INST(FCMGT_zero_2, "FCMGT (zero)", "010111101z100000110010nnnnnddddd") INST(FCMGT_zero_2, "FCMGT (zero)", "010111101z100000110010nnnnnddddd")
//INST(FCMEQ_zero_1, "FCMEQ (zero)", "0101111011111000110110nnnnnddddd") //INST(FCMEQ_zero_1, "FCMEQ (zero)", "0101111011111000110110nnnnnddddd")
//INST(FCMEQ_zero_2, "FCMEQ (zero)", "010111101z100000110110nnnnnddddd") INST(FCMEQ_zero_2, "FCMEQ (zero)", "010111101z100000110110nnnnnddddd")
//INST(FCMLT_1, "FCMLT (zero)", "0101111011111000111010nnnnnddddd") //INST(FCMLT_1, "FCMLT (zero)", "0101111011111000111010nnnnnddddd")
//INST(FCMLT_2, "FCMLT (zero)", "010111101z100000111010nnnnnddddd") INST(FCMLT_2, "FCMLT (zero)", "010111101z100000111010nnnnnddddd")
//INST(FCVTPS_1, "FCVTPS (vector)", "0101111011111001101010nnnnnddddd") //INST(FCVTPS_1, "FCVTPS (vector)", "0101111011111001101010nnnnnddddd")
//INST(FCVTPS_2, "FCVTPS (vector)", "010111101z100001101010nnnnnddddd") //INST(FCVTPS_2, "FCVTPS (vector)", "010111101z100001101010nnnnnddddd")
//INST(FCVTZS_int_1, "FCVTZS (vector, integer)", "0101111011111001101110nnnnnddddd") //INST(FCVTZS_int_1, "FCVTZS (vector, integer)", "0101111011111001101110nnnnnddddd")
@ -389,9 +389,9 @@ INST(SCVTF_int_2, "SCVTF (vector, integer)", "01011
//INST(UCVTF_int_1, "UCVTF (vector, integer)", "0111111001111001110110nnnnnddddd") //INST(UCVTF_int_1, "UCVTF (vector, integer)", "0111111001111001110110nnnnnddddd")
INST(UCVTF_int_2, "UCVTF (vector, integer)", "011111100z100001110110nnnnnddddd") INST(UCVTF_int_2, "UCVTF (vector, integer)", "011111100z100001110110nnnnnddddd")
//INST(FCMGE_zero_1, "FCMGE (zero)", "0111111011111000110010nnnnnddddd") //INST(FCMGE_zero_1, "FCMGE (zero)", "0111111011111000110010nnnnnddddd")
//INST(FCMGE_zero_2, "FCMGE (zero)", "011111101z100000110010nnnnnddddd") INST(FCMGE_zero_2, "FCMGE (zero)", "011111101z100000110010nnnnnddddd")
//INST(FCMLE_1, "FCMLE (zero)", "0111111011111000110110nnnnnddddd") //INST(FCMLE_1, "FCMLE (zero)", "0111111011111000110110nnnnnddddd")
//INST(FCMLE_2, "FCMLE (zero)", "011111101z100000110110nnnnnddddd") INST(FCMLE_2, "FCMLE (zero)", "011111101z100000110110nnnnnddddd")
//INST(FCVTPU_1, "FCVTPU (vector)", "0111111011111001101010nnnnnddddd") //INST(FCVTPU_1, "FCVTPU (vector)", "0111111011111001101010nnnnnddddd")
//INST(FCVTPU_2, "FCVTPU (vector)", "011111101z100001101010nnnnnddddd") //INST(FCVTPU_2, "FCVTPU (vector)", "011111101z100001101010nnnnnddddd")
//INST(FCVTZU_int_1, "FCVTZU (vector, integer)", "0111111011111001101110nnnnnddddd") //INST(FCVTZU_int_1, "FCVTZU (vector, integer)", "0111111011111001101110nnnnnddddd")

View file

@ -7,6 +7,43 @@
#include "frontend/A64/translate/impl/impl.h" #include "frontend/A64/translate/impl/impl.h"
namespace Dynarmic::A64 { namespace Dynarmic::A64 {
namespace {
enum class ComparisonType {
EQ,
GE,
GT,
LE,
LT
};
bool ScalarFPCompareAgainstZero(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd, ComparisonType type) {
const size_t esize = sz ? 64 : 32;
const size_t datasize = esize;
const IR::U128 operand = v.V(datasize, Vn);
const IR::U128 zero = v.ir.ZeroVector();
const IR::U128 result = [&] {
switch (type) {
case ComparisonType::EQ:
return v.ir.FPVectorEqual(esize, operand, zero);
case ComparisonType::GE:
return v.ir.FPVectorGreaterEqual(esize, operand, zero);
case ComparisonType::GT:
return v.ir.FPVectorGreater(esize, operand, zero);
case ComparisonType::LE:
return v.ir.FPVectorGreaterEqual(esize, zero, operand);
case ComparisonType::LT:
return v.ir.FPVectorGreater(esize, zero, operand);
}
UNREACHABLE();
return IR::U128{};
}();
v.V_scalar(datasize, Vd, v.ir.VectorGetElement(esize, result, 0));
return true;
}
} // Anonymous namespace
bool TranslatorVisitor::ABS_1(Imm<2> size, Vec Vn, Vec Vd) { bool TranslatorVisitor::ABS_1(Imm<2> size, Vec Vn, Vec Vd) {
if (size != 0b11) { if (size != 0b11) {
@ -21,6 +58,26 @@ bool TranslatorVisitor::ABS_1(Imm<2> size, Vec Vn, Vec Vd) {
return true; return true;
} }
bool TranslatorVisitor::FCMEQ_zero_2(bool sz, Vec Vn, Vec Vd) {
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::EQ);
}
bool TranslatorVisitor::FCMGE_zero_2(bool sz, Vec Vn, Vec Vd) {
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::GE);
}
bool TranslatorVisitor::FCMGT_zero_2(bool sz, Vec Vn, Vec Vd) {
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::GT);
}
bool TranslatorVisitor::FCMLE_2(bool sz, Vec Vn, Vec Vd) {
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::LE);
}
bool TranslatorVisitor::FCMLT_2(bool sz, Vec Vn, Vec Vd) {
return ScalarFPCompareAgainstZero(*this, sz, Vn, Vd, ComparisonType::LT);
}
bool TranslatorVisitor::NEG_1(Imm<2> size, Vec Vn, Vec Vd) { bool TranslatorVisitor::NEG_1(Imm<2> size, Vec Vn, Vec Vd) {
if (size != 0b11) { if (size != 0b11) {
return ReservedValue(); return ReservedValue();