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>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto reg_m = ir.GetExtendedRegister(m);
|
||||
auto result = sz
|
||||
? 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());
|
||||
auto result = ir.FPToFixedU32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode());
|
||||
ir.SetExtendedRegister(d, result);
|
||||
}
|
||||
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>
|
||||
if (ConditionPassed(cond)) {
|
||||
auto reg_m = ir.GetExtendedRegister(m);
|
||||
auto result = sz
|
||||
? 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());
|
||||
auto result = ir.FPToFixedS32(reg_m, 0, round_towards_zero ? FP::RoundingMode::TowardsZero : ir.current_location.FPSCR().RMode());
|
||||
ir.SetExtendedRegister(d, result);
|
||||
}
|
||||
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 IR::U32U64 fltscale = I(*fltsize, u64(fracbits + (*fltsize == 32 ? 127 : 1023)) << (*fltsize == 32 ? 23 : 52));
|
||||
const IR::U32U64 fltval = ir.FPMul(V_scalar(*fltsize, Vn), fltscale, true);
|
||||
|
||||
const IR::U32U64 fltval = V_scalar(*fltsize, Vn);
|
||||
IR::U32U64 intval;
|
||||
if (intsize == 32 && *fltsize == 32) {
|
||||
intval = ir.FPSingleToFixedS32(fltval, 0, FP::RoundingMode::TowardsZero);
|
||||
} else if (intsize == 32 && *fltsize == 64) {
|
||||
intval = ir.FPDoubleToFixedS32(fltval, 0, 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);
|
||||
if (intsize == 32) {
|
||||
intval = ir.FPToFixedS32(fltval, fracbits, FP::RoundingMode::TowardsZero);
|
||||
} else if (intsize == 64) {
|
||||
intval = ir.FPToFixedS64(fltval, fracbits, FP::RoundingMode::TowardsZero);
|
||||
} else {
|
||||
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 IR::U32U64 fltscale = I(*fltsize, u64(fracbits + (*fltsize == 32 ? 127 : 1023)) << (*fltsize == 32 ? 23 : 52));
|
||||
const IR::U32U64 fltval = ir.FPMul(V_scalar(*fltsize, Vn), fltscale, true);
|
||||
|
||||
const IR::U32U64 fltval = V_scalar(*fltsize, Vn);
|
||||
IR::U32U64 intval;
|
||||
if (intsize == 32 && *fltsize == 32) {
|
||||
intval = ir.FPSingleToFixedU32(fltval, 0, FP::RoundingMode::TowardsZero);
|
||||
} else if (intsize == 32 && *fltsize == 64) {
|
||||
intval = ir.FPDoubleToFixedU32(fltval, 0, 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);
|
||||
if (intsize == 32) {
|
||||
intval = ir.FPToFixedU32(fltval, fracbits, FP::RoundingMode::TowardsZero);
|
||||
} else if (intsize == 64) {
|
||||
intval = ir.FPToFixedU64(fltval, fracbits, FP::RoundingMode::TowardsZero);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
|
|
@ -134,14 +134,10 @@ static bool FloaingPointConvertSignedInteger(TranslatorVisitor& v, bool sf, Imm<
|
|||
const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn);
|
||||
IR::U32U64 intval;
|
||||
|
||||
if (intsize == 32 && *fltsize == 32) {
|
||||
intval = v.ir.FPSingleToFixedS32(fltval, 0, rounding_mode);
|
||||
} else if (intsize == 32 && *fltsize == 64) {
|
||||
intval = v.ir.FPDoubleToFixedS32(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);
|
||||
if (intsize == 32) {
|
||||
intval = v.ir.FPToFixedS32(fltval, 0, rounding_mode);
|
||||
} else if (intsize == 64) {
|
||||
intval = v.ir.FPToFixedS64(fltval, 0, rounding_mode);
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
@ -161,14 +157,10 @@ static bool FloaingPointConvertUnsignedInteger(TranslatorVisitor& v, bool sf, Im
|
|||
const IR::U32U64 fltval = v.V_scalar(*fltsize, Vn);
|
||||
IR::U32U64 intval;
|
||||
|
||||
if (intsize == 32 && *fltsize == 32) {
|
||||
intval = v.ir.FPSingleToFixedU32(fltval, 0, rounding_mode);
|
||||
} else if (intsize == 32 && *fltsize == 64) {
|
||||
intval = v.ir.FPDoubleToFixedU32(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);
|
||||
if (intsize == 32) {
|
||||
intval = v.ir.FPToFixedU32(fltval, 0, rounding_mode);
|
||||
} else if (intsize == 64) {
|
||||
intval = v.ir.FPToFixedU64(fltval, 0, rounding_mode);
|
||||
} else {
|
||||
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 result = [&]() -> IR::U32U64 {
|
||||
if (esize == 64) {
|
||||
if (sign == Signedness::Signed) {
|
||||
return v.ir.FPDoubleToFixedS64(operand, fbits, FP::RoundingMode::TowardsZero);
|
||||
}
|
||||
|
||||
return v.ir.FPDoubleToFixedU64(operand, fbits, FP::RoundingMode::TowardsZero);
|
||||
return sign == Signedness::Signed
|
||||
? v.ir.FPToFixedS64(operand, fbits, FP::RoundingMode::TowardsZero)
|
||||
: v.ir.FPToFixedU64(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);
|
||||
return sign == Signedness::Signed
|
||||
? v.ir.FPToFixedS32(operand, fbits, FP::RoundingMode::TowardsZero)
|
||||
: v.ir.FPToFixedU32(operand, fbits, FP::RoundingMode::TowardsZero);
|
||||
}();
|
||||
|
||||
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 result = [&]() -> IR::U32U64 {
|
||||
if (sz) {
|
||||
if (sign == Signedness::Signed) {
|
||||
return v.ir.FPDoubleToFixedS64(operand, 0, rmode);
|
||||
}
|
||||
|
||||
return v.ir.FPDoubleToFixedU64(operand, 0, rmode);
|
||||
return sign == Signedness::Signed
|
||||
? v.ir.FPToFixedS64(operand, 0, rmode)
|
||||
: v.ir.FPToFixedU64(operand, 0, rmode);
|
||||
}
|
||||
|
||||
if (sign == Signedness::Signed) {
|
||||
return v.ir.FPSingleToFixedS32(operand, 0, rmode);
|
||||
}
|
||||
|
||||
return v.ir.FPSingleToFixedU32(operand, 0, rmode);
|
||||
return sign == Signedness::Signed
|
||||
? v.ir.FPToFixedS32(operand, 0, rmode)
|
||||
: v.ir.FPToFixedU32(operand, 0, rmode);
|
||||
}();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
return Inst<U64>(Opcode::FPDoubleToFixedU64, 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)));
|
||||
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::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);
|
||||
U32 FPDoubleToSingle(const U64& a, bool fpcr_controlled);
|
||||
U64 FPSingleToDouble(const U32& a, bool fpcr_controlled);
|
||||
U32 FPDoubleToFixedS32(const U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U64 FPDoubleToFixedS64(const U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U32 FPDoubleToFixedU32(const U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U64 FPDoubleToFixedU64(const U64& 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 FPToFixedS32(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U64 FPToFixedS64(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U32 FPToFixedU32(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U64 FPToFixedU64(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U32 FPS32ToSingle(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);
|
||||
|
|
Loading…
Reference in a new issue