IR: Simplify FP{Single,Double}ToFixed{U,S}{32,64}

This commit is contained in:
MerryMage 2018-09-05 20:12:37 +01:00
parent d4b739359b
commit 3415828fb4
7 changed files with 48 additions and 100 deletions

View file

@ -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;

View file

@ -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();
}

View file

@ -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();
}

View file

@ -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);

View file

@ -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);

View file

@ -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) {

View file

@ -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);