A64: Implement SCVTF, UCVTF (vector, fixed-point), scalar variant
This commit is contained in:
parent
03ad2072a7
commit
09bf273bc8
2 changed files with 42 additions and 11 deletions
|
@ -473,7 +473,7 @@ INST(SHL_1, "SHL", "01011
|
||||||
//INST(SQSHL_imm_1, "SQSHL (immediate)", "010111110IIIIiii011101nnnnnddddd")
|
//INST(SQSHL_imm_1, "SQSHL (immediate)", "010111110IIIIiii011101nnnnnddddd")
|
||||||
//INST(SQSHRN_1, "SQSHRN, SQSHRN2", "010111110IIIIiii100101nnnnnddddd")
|
//INST(SQSHRN_1, "SQSHRN, SQSHRN2", "010111110IIIIiii100101nnnnnddddd")
|
||||||
//INST(SQRSHRN_1, "SQRSHRN, SQRSHRN2", "010111110IIIIiii100111nnnnnddddd")
|
//INST(SQRSHRN_1, "SQRSHRN, SQRSHRN2", "010111110IIIIiii100111nnnnnddddd")
|
||||||
//INST(SCVTF_fix_1, "SCVTF (vector, fixed-point)", "010111110IIIIiii111001nnnnnddddd")
|
INST(SCVTF_fix_1, "SCVTF (vector, fixed-point)", "010111110IIIIiii111001nnnnnddddd")
|
||||||
INST(FCVTZS_fix_1, "FCVTZS (vector, fixed-point)", "010111110IIIIiii111111nnnnnddddd")
|
INST(FCVTZS_fix_1, "FCVTZS (vector, fixed-point)", "010111110IIIIiii111111nnnnnddddd")
|
||||||
INST(USHR_1, "USHR", "011111110IIIIiii000001nnnnnddddd")
|
INST(USHR_1, "USHR", "011111110IIIIiii000001nnnnnddddd")
|
||||||
INST(USRA_1, "USRA", "011111110IIIIiii000101nnnnnddddd")
|
INST(USRA_1, "USRA", "011111110IIIIiii000101nnnnnddddd")
|
||||||
|
@ -487,7 +487,7 @@ INST(SLI_1, "SLI", "01111
|
||||||
//INST(SQRSHRUN_1, "SQRSHRUN, SQRSHRUN2", "011111110IIIIiii100011nnnnnddddd")
|
//INST(SQRSHRUN_1, "SQRSHRUN, SQRSHRUN2", "011111110IIIIiii100011nnnnnddddd")
|
||||||
//INST(UQSHRN_1, "UQSHRN, UQSHRN2", "011111110IIIIiii100101nnnnnddddd")
|
//INST(UQSHRN_1, "UQSHRN, UQSHRN2", "011111110IIIIiii100101nnnnnddddd")
|
||||||
//INST(UQRSHRN_1, "UQRSHRN, UQRSHRN2", "011111110IIIIiii100111nnnnnddddd")
|
//INST(UQRSHRN_1, "UQRSHRN, UQRSHRN2", "011111110IIIIiii100111nnnnnddddd")
|
||||||
//INST(UCVTF_fix_1, "UCVTF (vector, fixed-point)", "011111110IIIIiii111001nnnnnddddd")
|
INST(UCVTF_fix_1, "UCVTF (vector, fixed-point)", "011111110IIIIiii111001nnnnnddddd")
|
||||||
INST(FCVTZU_fix_1, "FCVTZU (vector, fixed-point)", "011111110IIIIiii111111nnnnnddddd")
|
INST(FCVTZU_fix_1, "FCVTZU (vector, fixed-point)", "011111110IIIIiii111111nnnnnddddd")
|
||||||
|
|
||||||
// Data Processing - FP and SIMD - SIMD Scalar x indexed element
|
// Data Processing - FP and SIMD - SIMD Scalar x indexed element
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
* General Public License version 2 or any later version.
|
* General Public License version 2 or any later version.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include "common/fp/rounding_mode.h"
|
||||||
#include "frontend/A64/translate/impl/impl.h"
|
#include "frontend/A64/translate/impl/impl.h"
|
||||||
|
|
||||||
namespace Dynarmic::A64 {
|
namespace Dynarmic::A64 {
|
||||||
|
@ -18,6 +19,11 @@ enum class Signedness {
|
||||||
Unsigned,
|
Unsigned,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class FloatConversionDirection {
|
||||||
|
FixedToFloat,
|
||||||
|
FloatToFixed,
|
||||||
|
};
|
||||||
|
|
||||||
bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
bool ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||||
ShiftExtraBehavior behavior, Signedness signedness) {
|
ShiftExtraBehavior behavior, Signedness signedness) {
|
||||||
if (!immh.Bit<3>()) {
|
if (!immh.Bit<3>()) {
|
||||||
|
@ -121,7 +127,7 @@ bool ShiftAndInsert(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign) {
|
bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd, Signedness sign, FloatConversionDirection direction, FP::RoundingMode rounding_mode) {
|
||||||
const u32 immh_value = immh.ZeroExtend();
|
const u32 immh_value = immh.ZeroExtend();
|
||||||
|
|
||||||
if ((immh_value & 0b1110) == 0b0000) {
|
if ((immh_value & 0b1110) == 0b0000) {
|
||||||
|
@ -139,15 +145,32 @@ bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Ve
|
||||||
|
|
||||||
const IR::U32U64 operand = v.V_scalar(esize, Vn);
|
const IR::U32U64 operand = v.V_scalar(esize, Vn);
|
||||||
const IR::U32U64 result = [&]() -> IR::U32U64 {
|
const IR::U32U64 result = [&]() -> IR::U32U64 {
|
||||||
if (esize == 64) {
|
switch (direction) {
|
||||||
|
case FloatConversionDirection::FloatToFixed:
|
||||||
|
if (esize == 64) {
|
||||||
|
return sign == Signedness::Signed
|
||||||
|
? v.ir.FPToFixedS64(operand, fbits, rounding_mode)
|
||||||
|
: v.ir.FPToFixedU64(operand, fbits, rounding_mode);
|
||||||
|
}
|
||||||
|
|
||||||
return sign == Signedness::Signed
|
return sign == Signedness::Signed
|
||||||
? v.ir.FPToFixedS64(operand, fbits, FP::RoundingMode::TowardsZero)
|
? v.ir.FPToFixedS32(operand, fbits, rounding_mode)
|
||||||
: v.ir.FPToFixedU64(operand, fbits, FP::RoundingMode::TowardsZero);
|
: v.ir.FPToFixedU32(operand, fbits, rounding_mode);
|
||||||
|
|
||||||
|
case FloatConversionDirection::FixedToFloat:
|
||||||
|
if (esize == 64) {
|
||||||
|
return sign == Signedness::Signed
|
||||||
|
? v.ir.FPSignedFixedToDouble(operand, fbits, rounding_mode)
|
||||||
|
: v.ir.FPUnsignedFixedToDouble(operand, fbits, rounding_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sign == Signedness::Signed
|
||||||
|
? v.ir.FPSignedFixedToSingle(operand, fbits, rounding_mode)
|
||||||
|
: v.ir.FPUnsignedFixedToSingle(operand, fbits, rounding_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sign == Signedness::Signed
|
UNREACHABLE();
|
||||||
? v.ir.FPToFixedS32(operand, fbits, FP::RoundingMode::TowardsZero)
|
return {};
|
||||||
: v.ir.FPToFixedU32(operand, fbits, FP::RoundingMode::TowardsZero);
|
|
||||||
}();
|
}();
|
||||||
|
|
||||||
v.V_scalar(esize, Vd, result);
|
v.V_scalar(esize, Vd, result);
|
||||||
|
@ -156,11 +179,19 @@ bool ScalarFPConvertWithRound(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Ve
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool TranslatorVisitor::FCVTZS_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::FCVTZS_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Signed);
|
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Signed, FloatConversionDirection::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::FCVTZU_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::FCVTZU_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Unsigned);
|
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Unsigned, FloatConversionDirection::FloatToFixed, FP::RoundingMode::TowardsZero);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::SCVTF_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
|
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Signed, FloatConversionDirection::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::UCVTF_fix_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
|
return ScalarFPConvertWithRound(*this, immh, immb, Vn, Vd, Signedness::Unsigned, FloatConversionDirection::FixedToFloat, ir.current_location->FPCR().RMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool TranslatorVisitor::SLI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SLI_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||||
|
|
Loading…
Reference in a new issue