VFPv4: Implement VCVTB, VCVTT
This commit is contained in:
parent
010fab9a0e
commit
3c86d58064
4 changed files with 82 additions and 2 deletions
|
@ -19,8 +19,8 @@ INST(vfp_VMOV_reg, "VMOV (reg)", "cccc11101D110000dddd101z0
|
||||||
INST(vfp_VABS, "VABS", "cccc11101D110000dddd101z11M0mmmm") // VFPv2
|
INST(vfp_VABS, "VABS", "cccc11101D110000dddd101z11M0mmmm") // VFPv2
|
||||||
INST(vfp_VNEG, "VNEG", "cccc11101D110001dddd101z01M0mmmm") // VFPv2
|
INST(vfp_VNEG, "VNEG", "cccc11101D110001dddd101z01M0mmmm") // VFPv2
|
||||||
INST(vfp_VSQRT, "VSQRT", "cccc11101D110001dddd101z11M0mmmm") // VFPv2
|
INST(vfp_VSQRT, "VSQRT", "cccc11101D110001dddd101z11M0mmmm") // VFPv2
|
||||||
//INST(vfp_VCVTB, "VCVTB", "cccc11101D11001odddd1010T1M0mmmm") // VFPv3HP
|
INST(vfp_VCVTB, "VCVTB", "cccc11101D11001odddd101z01M0mmmm") // VFPv3HP
|
||||||
//INST(vfp_VCVTT, "VCVTT", "cccc11101D11001odddd1010T1M0mmmm") // VFPv3HP
|
INST(vfp_VCVTT, "VCVTT", "cccc11101D11001odddd101z11M0mmmm") // VFPv3HP
|
||||||
INST(vfp_VCMP, "VCMP", "cccc11101D110100dddd101zE1M0mmmm") // VFPv2
|
INST(vfp_VCMP, "VCMP", "cccc11101D110100dddd101zE1M0mmmm") // VFPv2
|
||||||
INST(vfp_VCMP_zero, "VCMP (with zero)", "cccc11101D110101dddd101zE1000000") // VFPv2
|
INST(vfp_VCMP_zero, "VCMP (with zero)", "cccc11101D110101dddd101zE1000000") // VFPv2
|
||||||
INST(vfp_VCVT_f_to_f, "VCVT (f32<->f64)", "cccc11101D110111dddd101z11M0mmmm") // VFPv2
|
INST(vfp_VCVT_f_to_f, "VCVT (f32<->f64)", "cccc11101D110111dddd101z11M0mmmm") // VFPv2
|
||||||
|
|
|
@ -1280,6 +1280,20 @@ public:
|
||||||
return fmt::format("vsqrt{}.{} {}, {}", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vm, M));
|
return fmt::format("vsqrt{}.{} {}, {}", CondToString(cond), sz ? "f64" : "f32", FPRegStr(sz, Vd, D), FPRegStr(sz, Vm, M));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string vfp_VCVTB(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) {
|
||||||
|
const bool convert_from_half = !op;
|
||||||
|
const char* const to = convert_from_half ? (sz ? "f64" : "f32") : "f16";
|
||||||
|
const char* const from = convert_from_half ? "f16" : (sz ? "f64" : "f32");
|
||||||
|
return fmt::format("vcvtb{}.{}.{} {}, {}", CondToString(cond), to, from, FPRegStr(convert_from_half ? sz : false, Vd, D), FPRegStr(convert_from_half ? false : sz, Vm, M));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) {
|
||||||
|
const bool convert_from_half = !op;
|
||||||
|
const char* const to = convert_from_half ? (sz ? "f64" : "f32") : "f16";
|
||||||
|
const char* const from = convert_from_half ? "f16" : (sz ? "f64" : "f32");
|
||||||
|
return fmt::format("vcvtt{}.{}.{} {}, {}", CondToString(cond), to, from, FPRegStr(convert_from_half ? sz : false, Vd, D), FPRegStr(convert_from_half ? false : sz, Vm, M));
|
||||||
|
}
|
||||||
|
|
||||||
std::string vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
|
std::string vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
|
||||||
return fmt::format("vcvt{}.{}.{} {}, {}", CondToString(cond), !sz ? "f64" : "f32", sz ? "f64" : "f32", FPRegStr(!sz, Vd, D), FPRegStr(sz, Vm, M));
|
return fmt::format("vcvt{}.{}.{} {}, {}", CondToString(cond), !sz ? "f64" : "f32", sz ? "f64" : "f32", FPRegStr(!sz, Vd, D), FPRegStr(sz, Vm, M));
|
||||||
}
|
}
|
||||||
|
|
|
@ -391,6 +391,8 @@ struct ArmTranslatorVisitor final {
|
||||||
bool vfp_VABS(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
bool vfp_VABS(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
||||||
bool vfp_VNEG(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
bool vfp_VNEG(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
||||||
bool vfp_VSQRT(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
bool vfp_VSQRT(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
||||||
|
bool vfp_VCVTB(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm);
|
||||||
|
bool vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm);
|
||||||
bool vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
bool vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm);
|
||||||
bool vfp_VCVT_from_int(Cond cond, bool D, size_t Vd, bool sz, bool is_signed, bool M, size_t Vm);
|
bool vfp_VCVT_from_int(Cond cond, bool D, size_t Vd, bool sz, bool is_signed, bool M, size_t Vm);
|
||||||
bool vfp_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm);
|
bool vfp_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool sz, bool round_towards_zero, bool M, size_t Vm);
|
||||||
|
|
|
@ -548,6 +548,70 @@ bool ArmTranslatorVisitor::vfp_VSQRT(Cond cond, bool D, size_t Vd, bool sz, bool
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// VCVTB<c>.f32.f16 <Dd>, <Dm>
|
||||||
|
// VCVTB<c>.f64.f16 <Dd>, <Dm>
|
||||||
|
// VCVTB<c>.f16.f32 <Dd>, <Dm>
|
||||||
|
// VCVTB<c>.f16.f64 <Dd>, <Dm>
|
||||||
|
bool ArmTranslatorVisitor::vfp_VCVTB(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) {
|
||||||
|
if (!ConditionPassed(cond)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool convert_from_half = !op;
|
||||||
|
const auto rounding_mode = ir.current_location.FPSCR().RMode();
|
||||||
|
if (convert_from_half) {
|
||||||
|
const auto d = ToExtReg(sz, Vd, D);
|
||||||
|
const auto m = ToExtReg(false, Vm, M);
|
||||||
|
|
||||||
|
return EmitVfpVectorOperation(sz, d, m, [this, sz, rounding_mode](ExtReg d, ExtReg m) {
|
||||||
|
const auto reg_m = ir.LeastSignificantHalf(ir.GetExtendedRegister(m));
|
||||||
|
const auto result = sz ? IR::U32U64{ir.FPHalfToDouble(reg_m, rounding_mode)} : IR::U32U64{ir.FPHalfToSingle(reg_m, rounding_mode)};
|
||||||
|
ir.SetExtendedRegister(d, result);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const auto d = ToExtReg(false, Vd, D);
|
||||||
|
const auto m = ToExtReg(sz, Vm, M);
|
||||||
|
|
||||||
|
return EmitVfpVectorOperation(sz, d, m, [this, sz, rounding_mode](ExtReg d, ExtReg m) {
|
||||||
|
const auto reg_m = ir.GetExtendedRegister(m);
|
||||||
|
const auto result = sz ? ir.FPDoubleToHalf(reg_m, rounding_mode) : ir.FPSingleToHalf(reg_m, rounding_mode);
|
||||||
|
ir.SetExtendedRegister(d, ir.Or(ir.And(ir.GetExtendedRegister(d), ir.Imm32(0xFFFF0000)), ir.ZeroExtendToWord(result)));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// VCVTT<c>.f32.f16 <Dd>, <Dm>
|
||||||
|
// VCVTT<c>.f64.f16 <Dd>, <Dm>
|
||||||
|
// VCVTT<c>.f16.f32 <Dd>, <Dm>
|
||||||
|
// VCVTT<c>.f16.f64 <Dd>, <Dm>
|
||||||
|
bool ArmTranslatorVisitor::vfp_VCVTT(Cond cond, bool D, bool op, size_t Vd, bool sz, bool M, size_t Vm) {
|
||||||
|
if (!ConditionPassed(cond)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool convert_from_half = !op;
|
||||||
|
const auto rounding_mode = ir.current_location.FPSCR().RMode();
|
||||||
|
if (convert_from_half) {
|
||||||
|
const auto d = ToExtReg(sz, Vd, D);
|
||||||
|
const auto m = ToExtReg(false, Vm, M);
|
||||||
|
|
||||||
|
return EmitVfpVectorOperation(sz, d, m, [this, sz, rounding_mode](ExtReg d, ExtReg m) {
|
||||||
|
const auto reg_m = ir.LeastSignificantHalf(ir.LogicalShiftRight(ir.GetExtendedRegister(m), ir.Imm8(16)));
|
||||||
|
const auto result = sz ? IR::U32U64{ir.FPHalfToDouble(reg_m, rounding_mode)} : IR::U32U64{ir.FPHalfToSingle(reg_m, rounding_mode)};
|
||||||
|
ir.SetExtendedRegister(d, result);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
const auto d = ToExtReg(false, Vd, D);
|
||||||
|
const auto m = ToExtReg(sz, Vm, M);
|
||||||
|
|
||||||
|
return EmitVfpVectorOperation(sz, d, m, [this, sz, rounding_mode](ExtReg d, ExtReg m) {
|
||||||
|
const auto reg_m = ir.GetExtendedRegister(m);
|
||||||
|
const auto result = sz ? ir.FPDoubleToHalf(reg_m, rounding_mode) : ir.FPSingleToHalf(reg_m, rounding_mode);
|
||||||
|
ir.SetExtendedRegister(d, ir.Or(ir.And(ir.GetExtendedRegister(d), ir.Imm32(0x0000FFFF)), ir.LogicalShiftLeft(ir.ZeroExtendToWord(result), ir.Imm8(16))));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// VCVT<c>.F64.F32 <Dd>, <Sm>
|
// VCVT<c>.F64.F32 <Dd>, <Sm>
|
||||||
// VCVT<c>.F32.F64 <Sd>, <Dm>
|
// VCVT<c>.F32.F64 <Sd>, <Dm>
|
||||||
bool ArmTranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
|
bool ArmTranslatorVisitor::vfp_VCVT_f_to_f(Cond cond, bool D, size_t Vd, bool sz, bool M, size_t Vm) {
|
||||||
|
|
Loading…
Reference in a new issue