IR: Simplify FP{Single,Double}ToFixed{U,S}{32,64}
This commit is contained in:
parent
d4b739359b
commit
3415828fb4
7 changed files with 48 additions and 100 deletions
|
@ -441,9 +441,7 @@ bool ArmTranslatorVisitor::vfp2_VCVT_to_u32(Cond cond, bool D, size_t Vd, bool s
|
||||||
// VCVT{,R}.U32.F64 <Sd>, <Dm>
|
// VCVT{,R}.U32.F64 <Sd>, <Dm>
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
auto reg_m = ir.GetExtendedRegister(m);
|
auto reg_m = ir.GetExtendedRegister(m);
|
||||||
auto result = sz
|
auto result = ir.FPToFixedU32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode());
|
||||||
? ir.FPDoubleToFixedU32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode())
|
|
||||||
: ir.FPSingleToFixedU32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode());
|
|
||||||
ir.SetExtendedRegister(d, result);
|
ir.SetExtendedRegister(d, result);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
@ -456,9 +454,7 @@ bool ArmTranslatorVisitor::vfp2_VCVT_to_s32(Cond cond, bool D, size_t Vd, bool s
|
||||||
// VCVT{,R}.S32.F64 <Sd>, <Dm>
|
// VCVT{,R}.S32.F64 <Sd>, <Dm>
|
||||||
if (ConditionPassed(cond)) {
|
if (ConditionPassed(cond)) {
|
||||||
auto reg_m = ir.GetExtendedRegister(m);
|
auto reg_m = ir.GetExtendedRegister(m);
|
||||||
auto result = sz
|
auto result = ir.FPToFixedS32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode());
|
||||||
? ir.FPDoubleToFixedS32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode())
|
|
||||||
: ir.FPSingleToFixedS32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode());
|
|
||||||
ir.SetExtendedRegister(d, result);
|
ir.SetExtendedRegister(d, result);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -21,18 +21,12 @@ bool TranslatorVisitor::FCVTZS_float_fix(bool sf, Imm<2> type, Imm<6> scale, Vec
|
||||||
}
|
}
|
||||||
const u8 fracbits = 64 - scale.ZeroExtend<u8>();
|
const u8 fracbits = 64 - scale.ZeroExtend<u8>();
|
||||||
|
|
||||||
const IR::U32U64 fltscale = I(*fltsize, u64(fracbits + (*fltsize == 32 ? 127 : 1023)) << (*fltsize == 32 ? 23 : 52));
|
const IR::U32U64 fltval = V_scalar(*fltsize, Vn);
|
||||||
const IR::U32U64 fltval = ir.FPMul(V_scalar(*fltsize, Vn), fltscale, true);
|
|
||||||
|
|
||||||
IR::U32U64 intval;
|
IR::U32U64 intval;
|
||||||
if (intsize == 32 && *fltsize == 32) {
|
if (intsize == 32) {
|
||||||
intval = ir.FPSingleToFixedS32(fltval, 0, FP::RoundingMode::TowardsZero);
|
intval = ir.FPToFixedS32(fltval, fracbits, FP::RoundingMode::TowardsZero);
|
||||||
} else if (intsize == 32 && *fltsize == 64) {
|
} else if (intsize == 64) {
|
||||||
intval = ir.FPDoubleToFixedS32(fltval, 0, FP::RoundingMode::TowardsZero);
|
intval = ir.FPToFixedS64(fltval, fracbits, FP::RoundingMode::TowardsZero);
|
||||||
} else if (intsize == 64 && *fltsize == 32) {
|
|
||||||
intval = ir.FPSingleToFixedS64(fltval, 0, FP::RoundingMode::TowardsZero);
|
|
||||||
} else if (intsize == 64 && *fltsize == 64) {
|
|
||||||
intval = ir.FPDoubleToFixedS64(fltval, 0, FP::RoundingMode::TowardsZero);
|
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -52,18 +46,12 @@ bool TranslatorVisitor::FCVTZU_float_fix(bool sf, Imm<2> type, Imm<6> scale, Vec
|
||||||
}
|
}
|
||||||
const u8 fracbits = 64 - scale.ZeroExtend<u8>();
|
const u8 fracbits = 64 - scale.ZeroExtend<u8>();
|
||||||
|
|
||||||
const IR::U32U64 fltscale = I(*fltsize, u64(fracbits + (*fltsize == 32 ? 127 : 1023)) << (*fltsize == 32 ? 23 : 52));
|
const IR::U32U64 fltval = V_scalar(*fltsize, Vn);
|
||||||
const IR::U32U64 fltval = ir.FPMul(V_scalar(*fltsize, Vn), fltscale, true);
|
|
||||||
|
|
||||||
IR::U32U64 intval;
|
IR::U32U64 intval;
|
||||||
if (intsize == 32 && *fltsize == 32) {
|
if (intsize == 32) {
|
||||||
intval = ir.FPSingleToFixedU32(fltval, 0, FP::RoundingMode::TowardsZero);
|
intval = ir.FPToFixedU32(fltval, fracbits, FP::RoundingMode::TowardsZero);
|
||||||
} else if (intsize == 32 && *fltsize == 64) {
|
} else if (intsize == 64) {
|
||||||
intval = ir.FPDoubleToFixedU32(fltval, 0, FP::RoundingMode::TowardsZero);
|
intval = ir.FPToFixedU64(fltval, fracbits, FP::RoundingMode::TowardsZero);
|
||||||
} else if (intsize == 64 && *fltsize == 32) {
|
|
||||||
intval = ir.FPSingleToFixedU64(fltval, 0, FP::RoundingMode::TowardsZero);
|
|
||||||
} else if (intsize == 64 && *fltsize == 64) {
|
|
||||||
intval = ir.FPDoubleToFixedU64(fltval, 0, FP::RoundingMode::TowardsZero);
|
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,14 +134,10 @@ static bool FloaingPointConvertSignedInteger(TranslatorVisitor& v, bool sf, Imm<
|
||||||
const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn);
|
const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn);
|
||||||
IR::U32U64 intval;
|
IR::U32U64 intval;
|
||||||
|
|
||||||
if (intsize == 32 && *fltsize == 32) {
|
if (intsize == 32) {
|
||||||
intval = v.ir.FPSingleToFixedS32(fltval, 0, rounding_mode);
|
intval = v.ir.FPToFixedS32(fltval, 0, rounding_mode);
|
||||||
} else if (intsize == 32 && *fltsize == 64) {
|
} else if (intsize == 64) {
|
||||||
intval = v.ir.FPDoubleToFixedS32(fltval, 0, rounding_mode);
|
intval = v.ir.FPToFixedS64(fltval, 0, rounding_mode);
|
||||||
} else if (intsize == 64 && *fltsize == 32) {
|
|
||||||
intval = v.ir.FPSingleToFixedS64(fltval, 0, rounding_mode);
|
|
||||||
} else if (intsize == 64 && *fltsize == 64) {
|
|
||||||
intval = v.ir.FPDoubleToFixedS64(fltval, 0, rounding_mode);
|
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
@ -161,14 +157,10 @@ static bool FloaingPointConvertUnsignedInteger(TranslatorVisitor& v, bool sf, Im
|
||||||
const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn);
|
const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn);
|
||||||
IR::U32U64 intval;
|
IR::U32U64 intval;
|
||||||
|
|
||||||
if (intsize == 32 && *fltsize == 32) {
|
if (intsize == 32) {
|
||||||
intval = v.ir.FPSingleToFixedU32(fltval, 0, rounding_mode);
|
intval = v.ir.FPToFixedU32(fltval, 0, rounding_mode);
|
||||||
} else if (intsize == 32 && *fltsize == 64) {
|
} else if (intsize == 64) {
|
||||||
intval = v.ir.FPDoubleToFixedU32(fltval, 0, rounding_mode);
|
intval = v.ir.FPToFixedU64(fltval, 0, rounding_mode);
|
||||||
} else if (intsize == 64 && *fltsize == 32) {
|
|
||||||
intval = v.ir.FPSingleToFixedU64(fltval, 0, rounding_mode);
|
|
||||||
} else if (intsize == 64 && *fltsize == 64) {
|
|
||||||
intval = v.ir.FPDoubleToFixedU64(fltval, 0, rounding_mode);
|
|
||||||
} else {
|
} else {
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
|
|
|
@ -140,18 +140,14 @@ 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) {
|
if (esize == 64) {
|
||||||
if (sign == Signedness::Signed) {
|
return sign == Signedness::Signed
|
||||||
return v.ir.FPDoubleToFixedS64(operand, fbits, FP::RoundingMode::TowardsZero);
|
? v.ir.FPToFixedS64(operand, fbits, FP::RoundingMode::TowardsZero)
|
||||||
|
: v.ir.FPToFixedU64(operand, fbits, FP::RoundingMode::TowardsZero);
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.ir.FPDoubleToFixedU64(operand, fbits, FP::RoundingMode::TowardsZero);
|
return sign == Signedness::Signed
|
||||||
}
|
? v.ir.FPToFixedS32(operand, fbits, FP::RoundingMode::TowardsZero)
|
||||||
|
: v.ir.FPToFixedU32(operand, fbits, FP::RoundingMode::TowardsZero);
|
||||||
if (sign == Signedness::Signed) {
|
|
||||||
return v.ir.FPSingleToFixedS32(operand, fbits, FP::RoundingMode::TowardsZero);
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.ir.FPSingleToFixedU32(operand, fbits, FP::RoundingMode::TowardsZero);
|
|
||||||
}();
|
}();
|
||||||
|
|
||||||
v.V_scalar(esize, Vd, result);
|
v.V_scalar(esize, Vd, result);
|
||||||
|
|
|
@ -56,18 +56,14 @@ bool ScalarFPConvertWithRound(TranslatorVisitor& v, bool sz, Vec Vn, Vec Vd,
|
||||||
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 (sz) {
|
if (sz) {
|
||||||
if (sign == Signedness::Signed) {
|
return sign == Signedness::Signed
|
||||||
return v.ir.FPDoubleToFixedS64(operand, 0, rmode);
|
? v.ir.FPToFixedS64(operand, 0, rmode)
|
||||||
|
: v.ir.FPToFixedU64(operand, 0, rmode);
|
||||||
}
|
}
|
||||||
|
|
||||||
return v.ir.FPDoubleToFixedU64(operand, 0, rmode);
|
return sign == Signedness::Signed
|
||||||
}
|
? v.ir.FPToFixedS32(operand, 0, rmode)
|
||||||
|
: v.ir.FPToFixedU32(operand, 0, rmode);
|
||||||
if (sign == Signedness::Signed) {
|
|
||||||
return v.ir.FPSingleToFixedS32(operand, 0, rmode);
|
|
||||||
}
|
|
||||||
|
|
||||||
return v.ir.FPSingleToFixedU32(operand, 0, rmode);
|
|
||||||
}();
|
}();
|
||||||
|
|
||||||
v.V_scalar(esize, Vd, result);
|
v.V_scalar(esize, Vd, result);
|
||||||
|
|
|
@ -1774,44 +1774,28 @@ U64 IREmitter::FPSingleToDouble(const U32& a, bool fpcr_controlled) {
|
||||||
return Inst<U64>(Opcode::FPSingleToDouble, a);
|
return Inst<U64>(Opcode::FPSingleToDouble, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
U32 IREmitter::FPDoubleToFixedS32(const U64& a, size_t fbits, FP::RoundingMode rounding) {
|
U32 IREmitter::FPToFixedS32(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||||
ASSERT(fbits <= 32);
|
ASSERT(fbits <= 32);
|
||||||
return Inst<U32>(Opcode::FPDoubleToFixedS32, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
const Opcode opcode = a.GetType() == Type::U32 ? Opcode::FPSingleToFixedS32 : Opcode::FPDoubleToFixedS32;
|
||||||
|
return Inst<U32>(opcode, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
||||||
}
|
}
|
||||||
|
|
||||||
U64 IREmitter::FPDoubleToFixedS64(const U64& a, size_t fbits, FP::RoundingMode rounding) {
|
U64 IREmitter::FPToFixedS64(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||||
ASSERT(fbits <= 64);
|
ASSERT(fbits <= 64);
|
||||||
return Inst<U64>(Opcode::FPDoubleToFixedS64, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
const Opcode opcode = a.GetType() == Type::U32 ? Opcode::FPSingleToFixedS64 : Opcode::FPDoubleToFixedS64;
|
||||||
|
return Inst<U64>(opcode, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
||||||
}
|
}
|
||||||
|
|
||||||
U32 IREmitter::FPDoubleToFixedU32(const U64& a, size_t fbits, FP::RoundingMode rounding) {
|
U32 IREmitter::FPToFixedU32(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||||
ASSERT(fbits <= 32);
|
ASSERT(fbits <= 32);
|
||||||
return Inst<U32>(Opcode::FPDoubleToFixedU32, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
const Opcode opcode = a.GetType() == Type::U32 ? Opcode::FPSingleToFixedU32 : Opcode::FPDoubleToFixedU32;
|
||||||
|
return Inst<U32>(opcode, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
||||||
}
|
}
|
||||||
|
|
||||||
U64 IREmitter::FPDoubleToFixedU64(const U64& a, size_t fbits, FP::RoundingMode rounding) {
|
U64 IREmitter::FPToFixedU64(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||||
ASSERT(fbits <= 64);
|
ASSERT(fbits <= 64);
|
||||||
return Inst<U64>(Opcode::FPDoubleToFixedU64, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
const Opcode opcode = a.GetType() == Type::U32 ? Opcode::FPSingleToFixedU64 : Opcode::FPDoubleToFixedU64;
|
||||||
}
|
return Inst<U64>(opcode, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
||||||
|
|
||||||
U32 IREmitter::FPSingleToFixedS32(const U32& a, size_t fbits, FP::RoundingMode rounding) {
|
|
||||||
ASSERT(fbits <= 32);
|
|
||||||
return Inst<U32>(Opcode::FPSingleToFixedS32, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
|
||||||
}
|
|
||||||
|
|
||||||
U64 IREmitter::FPSingleToFixedS64(const U32& a, size_t fbits, FP::RoundingMode rounding) {
|
|
||||||
ASSERT(fbits <= 64);
|
|
||||||
return Inst<U64>(Opcode::FPSingleToFixedS64, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
|
||||||
}
|
|
||||||
|
|
||||||
U32 IREmitter::FPSingleToFixedU32(const U32& a, size_t fbits, FP::RoundingMode rounding) {
|
|
||||||
ASSERT(fbits <= 32);
|
|
||||||
return Inst<U32>(Opcode::FPSingleToFixedU32, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
|
||||||
}
|
|
||||||
|
|
||||||
U64 IREmitter::FPSingleToFixedU64(const U32& a, size_t fbits, FP::RoundingMode rounding) {
|
|
||||||
ASSERT(fbits <= 64);
|
|
||||||
return Inst<U64>(Opcode::FPSingleToFixedU64, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
U32 IREmitter::FPS32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled) {
|
U32 IREmitter::FPS32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled) {
|
||||||
|
|
|
@ -295,14 +295,10 @@ public:
|
||||||
U32U64 FPSub(const U32U64& a, const U32U64& b, bool fpcr_controlled);
|
U32U64 FPSub(const U32U64& a, const U32U64& b, bool fpcr_controlled);
|
||||||
U32 FPDoubleToSingle(const U64& a, bool fpcr_controlled);
|
U32 FPDoubleToSingle(const U64& a, bool fpcr_controlled);
|
||||||
U64 FPSingleToDouble(const U32& a, bool fpcr_controlled);
|
U64 FPSingleToDouble(const U32& a, bool fpcr_controlled);
|
||||||
U32 FPDoubleToFixedS32(const U64& a, size_t fbits, FP::RoundingMode rounding);
|
U32 FPToFixedS32(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||||
U64 FPDoubleToFixedS64(const U64& a, size_t fbits, FP::RoundingMode rounding);
|
U64 FPToFixedS64(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||||
U32 FPDoubleToFixedU32(const U64& a, size_t fbits, FP::RoundingMode rounding);
|
U32 FPToFixedU32(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||||
U64 FPDoubleToFixedU64(const U64& a, size_t fbits, FP::RoundingMode rounding);
|
U64 FPToFixedU64(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||||
U32 FPSingleToFixedS32(const U32& a, size_t fbits, FP::RoundingMode rounding);
|
|
||||||
U64 FPSingleToFixedS64(const U32& a, size_t fbits, FP::RoundingMode rounding);
|
|
||||||
U32 FPSingleToFixedU32(const U32& a, size_t fbits, FP::RoundingMode rounding);
|
|
||||||
U64 FPSingleToFixedU64(const U32& a, size_t fbits, FP::RoundingMode rounding);
|
|
||||||
U32 FPS32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled);
|
U32 FPS32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled);
|
||||||
U32 FPU32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled);
|
U32 FPU32ToSingle(const U32& a, bool round_to_nearest, bool fpcr_controlled);
|
||||||
U64 FPS32ToDouble(const U32& a, bool round_to_nearest, bool fpcr_controlled);
|
U64 FPS32ToDouble(const U32& a, bool round_to_nearest, bool fpcr_controlled);
|
||||||
|
|
Loading…
Add table
Reference in a new issue