mirror of
https://git.suyu.dev/suyu/dynarmic.git
synced 2026-01-02 12:44:34 +01:00
frontend/ir_emitter: Add half-precision->fixed-point opcodes
This commit is contained in:
parent
4ecfbc14de
commit
604f39f00a
6 changed files with 270 additions and 163 deletions
|
|
@ -2046,28 +2046,80 @@ U16 IREmitter::FPSingleToHalf(const U32& a, FP::RoundingMode rounding) {
|
|||
return Inst<U16>(Opcode::FPSingleToHalf, a, Imm8(static_cast<u8>(rounding)));
|
||||
}
|
||||
|
||||
U32 IREmitter::FPToFixedS32(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
U32 IREmitter::FPToFixedS32(const U16U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
ASSERT(fbits <= 32);
|
||||
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)));
|
||||
|
||||
const U8 fbits_imm = Imm8(static_cast<u8>(fbits));
|
||||
const U8 rounding_imm = Imm8(static_cast<u8>(rounding));
|
||||
|
||||
switch (a.GetType()) {
|
||||
case Type::U16:
|
||||
return Inst<U32>(Opcode::FPHalfToFixedS32, a, fbits_imm, rounding_imm);
|
||||
case Type::U32:
|
||||
return Inst<U32>(Opcode::FPSingleToFixedS32, a, fbits_imm, rounding_imm);
|
||||
case Type::U64:
|
||||
return Inst<U32>(Opcode::FPDoubleToFixedS32, a, fbits_imm, rounding_imm);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return U32{};
|
||||
}
|
||||
}
|
||||
|
||||
U64 IREmitter::FPToFixedS64(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
U64 IREmitter::FPToFixedS64(const U16U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
ASSERT(fbits <= 64);
|
||||
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)));
|
||||
|
||||
const U8 fbits_imm = Imm8(static_cast<u8>(fbits));
|
||||
const U8 rounding_imm = Imm8(static_cast<u8>(rounding));
|
||||
|
||||
switch (a.GetType()) {
|
||||
case Type::U16:
|
||||
return Inst<U64>(Opcode::FPHalfToFixedS64, a, fbits_imm, rounding_imm);
|
||||
case Type::U32:
|
||||
return Inst<U64>(Opcode::FPSingleToFixedS64, a, fbits_imm, rounding_imm);
|
||||
case Type::U64:
|
||||
return Inst<U64>(Opcode::FPDoubleToFixedS64, a, fbits_imm, rounding_imm);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return U64{};
|
||||
}
|
||||
}
|
||||
|
||||
U32 IREmitter::FPToFixedU32(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
U32 IREmitter::FPToFixedU32(const U16U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
ASSERT(fbits <= 32);
|
||||
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)));
|
||||
|
||||
const U8 fbits_imm = Imm8(static_cast<u8>(fbits));
|
||||
const U8 rounding_imm = Imm8(static_cast<u8>(rounding));
|
||||
|
||||
switch (a.GetType()) {
|
||||
case Type::U16:
|
||||
return Inst<U32>(Opcode::FPHalfToFixedU32, a, fbits_imm, rounding_imm);
|
||||
case Type::U32:
|
||||
return Inst<U32>(Opcode::FPSingleToFixedU32, a, fbits_imm, rounding_imm);
|
||||
case Type::U64:
|
||||
return Inst<U32>(Opcode::FPDoubleToFixedU32, a, fbits_imm, rounding_imm);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return U32{};
|
||||
}
|
||||
}
|
||||
|
||||
U64 IREmitter::FPToFixedU64(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
U64 IREmitter::FPToFixedU64(const U16U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
ASSERT(fbits <= 64);
|
||||
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)));
|
||||
|
||||
const U8 fbits_imm = Imm8(static_cast<u8>(fbits));
|
||||
const U8 rounding_imm = Imm8(static_cast<u8>(rounding));
|
||||
|
||||
switch (a.GetType()) {
|
||||
case Type::U16:
|
||||
return Inst<U64>(Opcode::FPHalfToFixedU64, a, fbits_imm, rounding_imm);
|
||||
case Type::U32:
|
||||
return Inst<U64>(Opcode::FPSingleToFixedU64, a, fbits_imm, rounding_imm);
|
||||
case Type::U64:
|
||||
return Inst<U64>(Opcode::FPDoubleToFixedU64, a, fbits_imm, rounding_imm);
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return U64{};
|
||||
}
|
||||
}
|
||||
|
||||
U32 IREmitter::FPSignedFixedToSingle(const U32U64& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
|
|
@ -2368,24 +2420,38 @@ U128 IREmitter::FPVectorSub(size_t esize, const U128& a, const U128& b) {
|
|||
|
||||
U128 IREmitter::FPVectorToSignedFixed(size_t esize, const U128& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
ASSERT(fbits <= esize);
|
||||
|
||||
const U8 fbits_imm = Imm8(static_cast<u8>(fbits));
|
||||
const U8 rounding_imm = Imm8(static_cast<u8>(rounding));
|
||||
|
||||
switch (esize) {
|
||||
case 16:
|
||||
return Inst<U128>(Opcode::FPVectorToSignedFixed16, a, fbits_imm, rounding_imm);
|
||||
case 32:
|
||||
return Inst<U128>(Opcode::FPVectorToSignedFixed32, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
||||
return Inst<U128>(Opcode::FPVectorToSignedFixed32, a, fbits_imm, rounding_imm);
|
||||
case 64:
|
||||
return Inst<U128>(Opcode::FPVectorToSignedFixed64, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
||||
return Inst<U128>(Opcode::FPVectorToSignedFixed64, a, fbits_imm, rounding_imm);
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
|
||||
U128 IREmitter::FPVectorToUnsignedFixed(size_t esize, const U128& a, size_t fbits, FP::RoundingMode rounding) {
|
||||
ASSERT(fbits <= esize);
|
||||
|
||||
const U8 fbits_imm = Imm8(static_cast<u8>(fbits));
|
||||
const U8 rounding_imm = Imm8(static_cast<u8>(rounding));
|
||||
|
||||
switch (esize) {
|
||||
case 16:
|
||||
return Inst<U128>(Opcode::FPVectorToUnsignedFixed16, a, fbits_imm, rounding_imm);
|
||||
case 32:
|
||||
return Inst<U128>(Opcode::FPVectorToUnsignedFixed32, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
||||
return Inst<U128>(Opcode::FPVectorToUnsignedFixed32, a, fbits_imm, rounding_imm);
|
||||
case 64:
|
||||
return Inst<U128>(Opcode::FPVectorToUnsignedFixed64, a, Imm8(static_cast<u8>(fbits)), Imm8(static_cast<u8>(rounding)));
|
||||
return Inst<U128>(Opcode::FPVectorToUnsignedFixed64, a, fbits_imm, rounding_imm);
|
||||
}
|
||||
|
||||
UNREACHABLE();
|
||||
return {};
|
||||
}
|
||||
|
|
|
|||
|
|
@ -319,10 +319,10 @@ public:
|
|||
U32 FPHalfToSingle(const U16& a, FP::RoundingMode rounding);
|
||||
U16 FPSingleToHalf(const U32& a, FP::RoundingMode rounding);
|
||||
U64 FPSingleToDouble(const U32& a, 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 FPToFixedS32(const U16U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U64 FPToFixedS64(const U16U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U32 FPToFixedU32(const U16U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U64 FPToFixedU64(const U16U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U32 FPSignedFixedToSingle(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U32 FPUnsignedFixedToSingle(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
U64 FPSignedFixedToDouble(const U32U64& a, size_t fbits, FP::RoundingMode rounding);
|
||||
|
|
|
|||
|
|
@ -303,6 +303,10 @@ bool Inst::ReadsFromAndWritesToFPSRCumulativeExceptionBits() const {
|
|||
case Opcode::FPDoubleToFixedS64:
|
||||
case Opcode::FPDoubleToFixedU32:
|
||||
case Opcode::FPDoubleToFixedU64:
|
||||
case Opcode::FPHalfToFixedS32:
|
||||
case Opcode::FPHalfToFixedS64:
|
||||
case Opcode::FPHalfToFixedU32:
|
||||
case Opcode::FPHalfToFixedU64:
|
||||
case Opcode::FPSingleToFixedS32:
|
||||
case Opcode::FPSingleToFixedS64:
|
||||
case Opcode::FPSingleToFixedU32:
|
||||
|
|
@ -356,6 +360,8 @@ bool Inst::ReadsFromAndWritesToFPSRCumulativeExceptionBits() const {
|
|||
case Opcode::FPVectorSqrt64:
|
||||
case Opcode::FPVectorSub32:
|
||||
case Opcode::FPVectorSub64:
|
||||
case Opcode::FPVectorToSignedFixed16:
|
||||
case Opcode::FPVectorToUnsignedFixed16:
|
||||
return true;
|
||||
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -524,6 +524,10 @@ OPCODE(FPDoubleToFixedS32, U32, U64,
|
|||
OPCODE(FPDoubleToFixedS64, U64, U64, U8, U8 )
|
||||
OPCODE(FPDoubleToFixedU32, U32, U64, U8, U8 )
|
||||
OPCODE(FPDoubleToFixedU64, U64, U64, U8, U8 )
|
||||
OPCODE(FPHalfToFixedS32, U32, U16, U8, U8 )
|
||||
OPCODE(FPHalfToFixedS64, U64, U16, U8, U8 )
|
||||
OPCODE(FPHalfToFixedU32, U32, U16, U8, U8 )
|
||||
OPCODE(FPHalfToFixedU64, U64, U16, U8, U8 )
|
||||
OPCODE(FPSingleToFixedS32, U32, U32, U8, U8 )
|
||||
OPCODE(FPSingleToFixedS64, U64, U32, U8, U8 )
|
||||
OPCODE(FPSingleToFixedU32, U32, U32, U8, U8 )
|
||||
|
|
@ -591,8 +595,10 @@ OPCODE(FPVectorSqrt32, U128, U128
|
|||
OPCODE(FPVectorSqrt64, U128, U128 )
|
||||
OPCODE(FPVectorSub32, U128, U128, U128 )
|
||||
OPCODE(FPVectorSub64, U128, U128, U128 )
|
||||
OPCODE(FPVectorToSignedFixed16, U128, U128, U8, U8 )
|
||||
OPCODE(FPVectorToSignedFixed32, U128, U128, U8, U8 )
|
||||
OPCODE(FPVectorToSignedFixed64, U128, U128, U8, U8 )
|
||||
OPCODE(FPVectorToUnsignedFixed16, U128, U128, U8, U8 )
|
||||
OPCODE(FPVectorToUnsignedFixed32, U128, U128, U8, U8 )
|
||||
OPCODE(FPVectorToUnsignedFixed64, U128, U128, U8, U8 )
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue