From 5eb0bdecdf6e7f263c71f6229a29901e8d5114ba Mon Sep 17 00:00:00 2001 From: MerryMage Date: Fri, 19 Jan 2018 01:09:46 +0000 Subject: [PATCH] IR: Simplify types. F32 -> U32, F64 -> U64, F128 -> U128 ARM's Architecture Specification Language doesn't distinguish between floats and integers as much as we do. This makes some things difficult to implement. Since our register allocator is now capable of allocating values to XMMs and GPRs as necessary, the Transfer IR instructions are no longer necessary as they used to be and they can be removed. --- src/backend_x64/emit_x64.cpp | 36 ------ src/backend_x64/reg_alloc.cpp | 6 +- src/frontend/A32/ir_emitter.cpp | 8 +- src/frontend/A32/ir_emitter.h | 4 +- .../A32/translate/translate_arm/vfp2.cpp | 71 +++++------ src/frontend/ir/ir_emitter.cpp | 116 ++++++++---------- src/frontend/ir/ir_emitter.h | 56 ++++----- src/frontend/ir/opcodes.h | 10 +- src/frontend/ir/opcodes.inc | 64 +++++----- src/frontend/ir/value.h | 5 +- 10 files changed, 150 insertions(+), 226 deletions(-) diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index b20146f1..30f9d3f1 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -2351,42 +2351,6 @@ static void FPTwoOp64(BlockOfCode* code, EmitContext& ctx, IR::Inst* inst, void ctx.reg_alloc.DefineValue(inst, result); } -template -void EmitX64::EmitTransferFromFP32(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - ctx.reg_alloc.DefineValue(inst, args[0]); -} - -template -void EmitX64::EmitTransferFromFP64(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - ctx.reg_alloc.DefineValue(inst, args[0]); -} - -template -void EmitX64::EmitTransferToFP32(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - if (args[0].IsImmediate() && args[0].GetImmediateU32() == 0) { - Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(); - code->xorps(result, result); - ctx.reg_alloc.DefineValue(inst, result); - } else { - ctx.reg_alloc.DefineValue(inst, args[0]); - } -} - -template -void EmitX64::EmitTransferToFP64(EmitContext& ctx, IR::Inst* inst) { - auto args = ctx.reg_alloc.GetArgumentInfo(inst); - if (args[0].IsImmediate() && args[0].GetImmediateU64() == 0) { - Xbyak::Xmm result = ctx.reg_alloc.ScratchXmm(); - code->xorps(result, result); - ctx.reg_alloc.DefineValue(inst, result); - } else { - ctx.reg_alloc.DefineValue(inst, args[0]); - } -} - template void EmitX64::EmitFPAbs32(EmitContext& ctx, IR::Inst* inst) { auto args = ctx.reg_alloc.GetArgumentInfo(inst); diff --git a/src/backend_x64/reg_alloc.cpp b/src/backend_x64/reg_alloc.cpp index 2f611fb9..20daac21 100644 --- a/src/backend_x64/reg_alloc.cpp +++ b/src/backend_x64/reg_alloc.cpp @@ -64,11 +64,7 @@ static size_t GetBitWidth(IR::Type type) { return 32; case IR::Type::U64: return 64; - case IR::Type::F32: - return 32; - case IR::Type::F64: - return 64; - case IR::Type::F128: + case IR::Type::U128: return 128; case IR::Type::NZCVFlags: return 32; // TODO: Update to 16 when flags optimization is done diff --git a/src/frontend/A32/ir_emitter.cpp b/src/frontend/A32/ir_emitter.cpp index ae829847..8eebc48a 100644 --- a/src/frontend/A32/ir_emitter.cpp +++ b/src/frontend/A32/ir_emitter.cpp @@ -30,13 +30,13 @@ IR::U32 IREmitter::GetRegister(Reg reg) { return Inst(Opcode::A32GetRegister, IR::Value(reg)); } -IR::F32F64 IREmitter::GetExtendedRegister(ExtReg reg) { +IR::U32U64 IREmitter::GetExtendedRegister(ExtReg reg) { if (A32::IsSingleExtReg(reg)) { - return Inst(Opcode::A32GetExtendedRegister32, IR::Value(reg)); + return Inst(Opcode::A32GetExtendedRegister32, IR::Value(reg)); } if (A32::IsDoubleExtReg(reg)) { - return Inst(Opcode::A32GetExtendedRegister64, IR::Value(reg)); + return Inst(Opcode::A32GetExtendedRegister64, IR::Value(reg)); } ASSERT_MSG(false, "Invalid reg."); @@ -47,7 +47,7 @@ void IREmitter::SetRegister(const Reg reg, const IR::U32& value) { Inst(Opcode::A32SetRegister, IR::Value(reg), value); } -void IREmitter::SetExtendedRegister(const ExtReg reg, const IR::F32F64& value) { +void IREmitter::SetExtendedRegister(const ExtReg reg, const IR::U32U64& value) { if (A32::IsSingleExtReg(reg)) { Inst(Opcode::A32SetExtendedRegister32, IR::Value(reg), value); } else if (A32::IsDoubleExtReg(reg)) { diff --git a/src/frontend/A32/ir_emitter.h b/src/frontend/A32/ir_emitter.h index 44210dc9..5f735603 100644 --- a/src/frontend/A32/ir_emitter.h +++ b/src/frontend/A32/ir_emitter.h @@ -34,9 +34,9 @@ public: u32 AlignPC(size_t alignment); IR::U32 GetRegister(Reg source_reg); - IR::F32F64 GetExtendedRegister(ExtReg source_reg); + IR::U32U64 GetExtendedRegister(ExtReg source_reg); void SetRegister(const Reg dest_reg, const IR::U32& value); - void SetExtendedRegister(const ExtReg dest_reg, const IR::F32F64& value); + void SetExtendedRegister(const ExtReg dest_reg, const IR::U32U64& value); void ALUWritePC(const IR::U32& value); void BranchWritePC(const IR::U32& value); diff --git a/src/frontend/A32/translate/translate_arm/vfp2.cpp b/src/frontend/A32/translate/translate_arm/vfp2.cpp index a56239da..cd6ef39c 100644 --- a/src/frontend/A32/translate/translate_arm/vfp2.cpp +++ b/src/frontend/A32/translate/translate_arm/vfp2.cpp @@ -9,9 +9,6 @@ namespace Dynarmic { namespace A32 { -using F32 = IR::F32; -using F64 = IR::F64; - static ExtReg ToExtReg(bool sz, size_t base, bool bit) { if (sz) { return static_cast(static_cast(ExtReg::D0) + base + (bit ? 16 : 0)); @@ -292,13 +289,11 @@ bool ArmTranslatorVisitor::vfp2_VMOV_u32_f64(Cond cond, size_t Vd, Reg t, bool D return UnpredictableInstruction(); // VMOV.32 , if (ConditionPassed(cond)) { - auto d_f64 = ir.GetExtendedRegister(d); - auto t_u32 = ir.GetRegister(t); + auto reg_d = ir.GetExtendedRegister(d); + auto reg_t = ir.GetRegister(t); + auto result = ir.Pack2x32To1x64(reg_t, ir.MostSignificantWord(reg_d).result); - auto d_u64 = ir.TransferFromFP64(d_f64); - auto result = ir.Pack2x32To1x64(t_u32, ir.MostSignificantWord(d_u64).result); - - ir.SetExtendedRegister(d, ir.TransferToFP64(result)); + ir.SetExtendedRegister(d, result); } return true; } @@ -309,8 +304,8 @@ bool ArmTranslatorVisitor::vfp2_VMOV_f64_u32(Cond cond, size_t Vn, Reg t, bool N return UnpredictableInstruction(); // VMOV.32 , if (ConditionPassed(cond)) { - auto n_f64 = ir.GetExtendedRegister(n); - ir.SetRegister(t, ir.LeastSignificantWord(ir.TransferFromFP64(n_f64))); + auto reg_n = ir.GetExtendedRegister(n); + ir.SetRegister(t, ir.LeastSignificantWord(reg_n)); } return true; } @@ -321,7 +316,7 @@ bool ArmTranslatorVisitor::vfp2_VMOV_u32_f32(Cond cond, size_t Vn, Reg t, bool N return UnpredictableInstruction(); // VMOV , if (ConditionPassed(cond)) { - ir.SetExtendedRegister(n, ir.TransferToFP32(ir.GetRegister(t))); + ir.SetExtendedRegister(n, ir.GetRegister(t)); } return true; } @@ -332,7 +327,7 @@ bool ArmTranslatorVisitor::vfp2_VMOV_f32_u32(Cond cond, size_t Vn, Reg t, bool N return UnpredictableInstruction(); // VMOV , if (ConditionPassed(cond)) { - ir.SetRegister(t, ir.TransferFromFP32(ir.GetExtendedRegister(n))); + ir.SetRegister(t, ir.GetExtendedRegister(n)); } return true; } @@ -343,8 +338,8 @@ bool ArmTranslatorVisitor::vfp2_VMOV_2u32_2f32(Cond cond, Reg t2, Reg t, bool M, return UnpredictableInstruction(); // VMOV , , , if (ConditionPassed(cond)) { - ir.SetExtendedRegister(m, ir.TransferToFP32(ir.GetRegister(t))); - ir.SetExtendedRegister(m+1, ir.TransferToFP32(ir.GetRegister(t2))); + ir.SetExtendedRegister(m, ir.GetRegister(t)); + ir.SetExtendedRegister(m+1, ir.GetRegister(t2)); } return true; } @@ -357,8 +352,8 @@ bool ArmTranslatorVisitor::vfp2_VMOV_2f32_2u32(Cond cond, Reg t2, Reg t, bool M, return UnpredictableInstruction(); // VMOV , , , if (ConditionPassed(cond)) { - ir.SetRegister(t, ir.TransferFromFP32(ir.GetExtendedRegister(m))); - ir.SetRegister(t2, ir.TransferFromFP32(ir.GetExtendedRegister(m+1))); + ir.SetRegister(t, ir.GetExtendedRegister(m)); + ir.SetRegister(t2, ir.GetExtendedRegister(m+1)); } return true; } @@ -370,7 +365,7 @@ bool ArmTranslatorVisitor::vfp2_VMOV_2u32_f64(Cond cond, Reg t2, Reg t, bool M, // VMOV , , if (ConditionPassed(cond)) { auto value = ir.Pack2x32To1x64(ir.GetRegister(t), ir.GetRegister(t2)); - ir.SetExtendedRegister(m, ir.TransferToFP64(value)); + ir.SetExtendedRegister(m, value); } return true; } @@ -383,7 +378,7 @@ bool ArmTranslatorVisitor::vfp2_VMOV_f64_2u32(Cond cond, Reg t2, Reg t, bool M, return UnpredictableInstruction(); // VMOV , , if (ConditionPassed(cond)) { - auto value = ir.TransferFromFP64(ir.GetExtendedRegister(m)); + auto value = ir.GetExtendedRegister(m); ir.SetRegister(t, ir.LeastSignificantWord(value)); ir.SetRegister(t2, ir.MostSignificantWord(value).result); } @@ -556,11 +551,9 @@ bool ArmTranslatorVisitor::vfp2_VCMP_zero(Cond cond, bool D, size_t Vd, bool sz, if (ConditionPassed(cond)) { auto reg_d = ir.GetExtendedRegister(d); if (sz) { - auto zero = ir.TransferToFP64(ir.Imm64(0)); - ir.FPCompare64(reg_d, zero, exc_on_qnan, true); + ir.FPCompare64(reg_d, ir.Imm64(0), exc_on_qnan, true); } else { - auto zero = ir.TransferToFP32(ir.Imm32(0)); - ir.FPCompare32(reg_d, zero, exc_on_qnan, true); + ir.FPCompare32(reg_d, ir.Imm32(0), exc_on_qnan, true); } } return true; @@ -615,10 +608,10 @@ bool ArmTranslatorVisitor::vfp2_VPOP(Cond cond, bool D, size_t Vd, bool sz, Imm8 auto hi = ir.ReadMemory32(address); address = ir.Add(address, ir.Imm32(4)); if (ir.current_location.EFlag()) std::swap(lo, hi); - ir.SetExtendedRegister(d + i, ir.TransferToFP64(ir.Pack2x32To1x64(lo, hi))); + ir.SetExtendedRegister(d + i, ir.Pack2x32To1x64(lo, hi)); } else { auto res = ir.ReadMemory32(address); - ir.SetExtendedRegister(d + i, ir.TransferToFP32(res)); + ir.SetExtendedRegister(d + i, res); address = ir.Add(address, ir.Imm32(4)); } } @@ -645,16 +638,16 @@ bool ArmTranslatorVisitor::vfp2_VPUSH(Cond cond, bool D, size_t Vd, bool sz, Imm for (size_t i = 0; i < regs; ++i) { if (sz) { - const auto d_u64 = ir.TransferFromFP64(ir.GetExtendedRegister(d + i)); - auto lo = ir.LeastSignificantWord(d_u64); - auto hi = ir.MostSignificantWord(d_u64).result; + const auto reg_d = ir.GetExtendedRegister(d + i); + auto lo = ir.LeastSignificantWord(reg_d); + auto hi = ir.MostSignificantWord(reg_d).result; if (ir.current_location.EFlag()) std::swap(lo, hi); ir.WriteMemory32(address, lo); address = ir.Add(address, ir.Imm32(4)); ir.WriteMemory32(address, hi); address = ir.Add(address, ir.Imm32(4)); } else { - ir.WriteMemory32(address, ir.TransferFromFP32(ir.GetExtendedRegister(d + i))); + ir.WriteMemory32(address, ir.GetExtendedRegister(d + i)); address = ir.Add(address, ir.Imm32(4)); } } @@ -673,9 +666,9 @@ bool ArmTranslatorVisitor::vfp2_VLDR(Cond cond, bool U, bool D, Reg n, size_t Vd auto lo = ir.ReadMemory32(address); auto hi = ir.ReadMemory32(ir.Add(address, ir.Imm32(4))); if (ir.current_location.EFlag()) std::swap(lo, hi); - ir.SetExtendedRegister(d, ir.TransferToFP64(ir.Pack2x32To1x64(lo, hi))); + ir.SetExtendedRegister(d, ir.Pack2x32To1x64(lo, hi)); } else { - ir.SetExtendedRegister(d, ir.TransferToFP32(ir.ReadMemory32(address))); + ir.SetExtendedRegister(d, ir.ReadMemory32(address)); } } return true; @@ -689,14 +682,14 @@ bool ArmTranslatorVisitor::vfp2_VSTR(Cond cond, bool U, bool D, Reg n, size_t Vd auto base = n == Reg::PC ? ir.Imm32(ir.AlignPC(4)) : ir.GetRegister(n); auto address = U ? ir.Add(base, ir.Imm32(imm32)) : ir.Sub(base, ir.Imm32(imm32)); if (sz) { - auto d_u64 = ir.TransferFromFP64(ir.GetExtendedRegister(d)); - auto lo = ir.LeastSignificantWord(d_u64); - auto hi = ir.MostSignificantWord(d_u64).result; + auto reg_d = ir.GetExtendedRegister(d); + auto lo = ir.LeastSignificantWord(reg_d); + auto hi = ir.MostSignificantWord(reg_d).result; if (ir.current_location.EFlag()) std::swap(lo, hi); ir.WriteMemory32(address, lo); ir.WriteMemory32(ir.Add(address, ir.Imm32(4)), hi); } else { - ir.WriteMemory32(address, ir.TransferFromFP32(ir.GetExtendedRegister(d))); + ir.WriteMemory32(address, ir.GetExtendedRegister(d)); } } return true; @@ -725,7 +718,7 @@ bool ArmTranslatorVisitor::vfp2_VSTM_a1(Cond cond, bool p, bool u, bool D, bool if (w) ir.SetRegister(n, u ? ir.Add(address, ir.Imm32(imm32)) : address); for (size_t i = 0; i < regs; i++) { - auto value = ir.TransferFromFP64(ir.GetExtendedRegister(d + i)); + auto value = ir.GetExtendedRegister(d + i); auto word1 = ir.LeastSignificantWord(value); auto word2 = ir.MostSignificantWord(value).result; if (ir.current_location.EFlag()) std::swap(word1, word2); @@ -761,7 +754,7 @@ bool ArmTranslatorVisitor::vfp2_VSTM_a2(Cond cond, bool p, bool u, bool D, bool if (w) ir.SetRegister(n, u ? ir.Add(address, ir.Imm32(imm32)) : address); for (size_t i = 0; i < regs; i++) { - auto word = ir.TransferFromFP32(ir.GetExtendedRegister(d + i)); + auto word = ir.GetExtendedRegister(d + i); ir.WriteMemory32(address, word); address = ir.Add(address, ir.Imm32(4)); } @@ -797,7 +790,7 @@ bool ArmTranslatorVisitor::vfp2_VLDM_a1(Cond cond, bool p, bool u, bool D, bool auto word2 = ir.ReadMemory32(address); address = ir.Add(address, ir.Imm32(4)); if (ir.current_location.EFlag()) std::swap(word1, word2); - ir.SetExtendedRegister(d + i, ir.TransferToFP64(ir.Pack2x32To1x64(word1, word2))); + ir.SetExtendedRegister(d + i, ir.Pack2x32To1x64(word1, word2)); } } return true; @@ -828,7 +821,7 @@ bool ArmTranslatorVisitor::vfp2_VLDM_a2(Cond cond, bool p, bool u, bool D, bool for (size_t i = 0; i < regs; i++) { auto word = ir.ReadMemory32(address); address = ir.Add(address, ir.Imm32(4)); - ir.SetExtendedRegister(d + i, ir.TransferToFP32(word)); + ir.SetExtendedRegister(d + i, word); } } return true; diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index df3f574d..5166100f 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -604,144 +604,128 @@ U32 IREmitter::PackedSelect(const U32& ge, const U32& a, const U32& b) { return Inst(Opcode::PackedSelect, ge, a, b); } -F32 IREmitter::TransferToFP32(const U32& a) { - return Inst(Opcode::TransferToFP32, a); +U32 IREmitter::FPAbs32(const U32& a) { + return Inst(Opcode::FPAbs32, a); } -F64 IREmitter::TransferToFP64(const U64& a) { - return Inst(Opcode::TransferToFP64, a); +U64 IREmitter::FPAbs64(const U64& a) { + return Inst(Opcode::FPAbs64, a); } -U32 IREmitter::TransferFromFP32(const F32& a) { - return Inst(Opcode::TransferFromFP32, a); -} - -U64 IREmitter::TransferFromFP64(const F64& a) { - return Inst(Opcode::TransferFromFP64, a); -} - -F32 IREmitter::FPAbs32(const F32& a) { - return Inst(Opcode::FPAbs32, a); -} - -F64 IREmitter::FPAbs64(const F64& a) { - return Inst(Opcode::FPAbs64, a); -} - -F32 IREmitter::FPAdd32(const F32& a, const F32& b, bool fpscr_controlled) { +U32 IREmitter::FPAdd32(const U32& a, const U32& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPAdd32, a, b); + return Inst(Opcode::FPAdd32, a, b); } -F64 IREmitter::FPAdd64(const F64& a, const F64& b, bool fpscr_controlled) { +U64 IREmitter::FPAdd64(const U64& a, const U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPAdd64, a, b); + return Inst(Opcode::FPAdd64, a, b); } -void IREmitter::FPCompare32(const F32& a, const F32& b, bool exc_on_qnan, bool fpscr_controlled) { +void IREmitter::FPCompare32(const U32& a, const U32& b, bool exc_on_qnan, bool fpscr_controlled) { ASSERT(fpscr_controlled); Inst(Opcode::FPCompare32, a, b, Imm1(exc_on_qnan)); } -void IREmitter::FPCompare64(const F64& a, const F64& b, bool exc_on_qnan, bool fpscr_controlled) { +void IREmitter::FPCompare64(const U64& a, const U64& b, bool exc_on_qnan, bool fpscr_controlled) { ASSERT(fpscr_controlled); Inst(Opcode::FPCompare64, a, b, Imm1(exc_on_qnan)); } -F32 IREmitter::FPDiv32(const F32& a, const F32& b, bool fpscr_controlled) { +U32 IREmitter::FPDiv32(const U32& a, const U32& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPDiv32, a, b); + return Inst(Opcode::FPDiv32, a, b); } -F64 IREmitter::FPDiv64(const F64& a, const F64& b, bool fpscr_controlled) { +U64 IREmitter::FPDiv64(const U64& a, const U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPDiv64, a, b); + return Inst(Opcode::FPDiv64, a, b); } -F32 IREmitter::FPMul32(const F32& a, const F32& b, bool fpscr_controlled) { +U32 IREmitter::FPMul32(const U32& a, const U32& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPMul32, a, b); + return Inst(Opcode::FPMul32, a, b); } -F64 IREmitter::FPMul64(const F64& a, const F64& b, bool fpscr_controlled) { +U64 IREmitter::FPMul64(const U64& a, const U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPMul64, a, b); + return Inst(Opcode::FPMul64, a, b); } -F32 IREmitter::FPNeg32(const F32& a) { - return Inst(Opcode::FPNeg32, a); +U32 IREmitter::FPNeg32(const U32& a) { + return Inst(Opcode::FPNeg32, a); } -F64 IREmitter::FPNeg64(const F64& a) { - return Inst(Opcode::FPNeg64, a); +U64 IREmitter::FPNeg64(const U64& a) { + return Inst(Opcode::FPNeg64, a); } -F32 IREmitter::FPSqrt32(const F32& a) { - return Inst(Opcode::FPSqrt32, a); +U32 IREmitter::FPSqrt32(const U32& a) { + return Inst(Opcode::FPSqrt32, a); } -F64 IREmitter::FPSqrt64(const F64& a) { - return Inst(Opcode::FPSqrt64, a); +U64 IREmitter::FPSqrt64(const U64& a) { + return Inst(Opcode::FPSqrt64, a); } -F32 IREmitter::FPSub32(const F32& a, const F32& b, bool fpscr_controlled) { +U32 IREmitter::FPSub32(const U32& a, const U32& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPSub32, a, b); + return Inst(Opcode::FPSub32, a, b); } -F64 IREmitter::FPSub64(const F64& a, const F64& b, bool fpscr_controlled) { +U64 IREmitter::FPSub64(const U64& a, const U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPSub64, a, b); + return Inst(Opcode::FPSub64, a, b); } -F32 IREmitter::FPDoubleToSingle(const F64& a, bool fpscr_controlled) { +U32 IREmitter::FPDoubleToSingle(const U64& a, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPDoubleToSingle, a); + return Inst(Opcode::FPDoubleToSingle, a); } -F64 IREmitter::FPSingleToDouble(const F32& a, bool fpscr_controlled) { +U64 IREmitter::FPSingleToDouble(const U32& a, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPSingleToDouble, a); + return Inst(Opcode::FPSingleToDouble, a); } -F32 IREmitter::FPSingleToS32(const F32& a, bool round_towards_zero, bool fpscr_controlled) { +U32 IREmitter::FPSingleToS32(const U32& a, bool round_towards_zero, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPSingleToS32, a, Imm1(round_towards_zero)); + return Inst(Opcode::FPSingleToS32, a, Imm1(round_towards_zero)); } -F32 IREmitter::FPSingleToU32(const F32& a, bool round_towards_zero, bool fpscr_controlled) { +U32 IREmitter::FPSingleToU32(const U32& a, bool round_towards_zero, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPSingleToU32, a, Imm1(round_towards_zero)); + return Inst(Opcode::FPSingleToU32, a, Imm1(round_towards_zero)); } -F32 IREmitter::FPDoubleToS32(const F32& a, bool round_towards_zero, bool fpscr_controlled) { +U32 IREmitter::FPDoubleToS32(const U32& a, bool round_towards_zero, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPDoubleToS32, a, Imm1(round_towards_zero)); + return Inst(Opcode::FPDoubleToS32, a, Imm1(round_towards_zero)); } -F32 IREmitter::FPDoubleToU32(const F32& a, bool round_towards_zero, bool fpscr_controlled) { +U32 IREmitter::FPDoubleToU32(const U32& a, bool round_towards_zero, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPDoubleToU32, a, Imm1(round_towards_zero)); + return Inst(Opcode::FPDoubleToU32, a, Imm1(round_towards_zero)); } -F32 IREmitter::FPS32ToSingle(const F32& a, bool round_to_nearest, bool fpscr_controlled) { +U32 IREmitter::FPS32ToSingle(const U32& a, bool round_to_nearest, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPS32ToSingle, a, Imm1(round_to_nearest)); + return Inst(Opcode::FPS32ToSingle, a, Imm1(round_to_nearest)); } -F32 IREmitter::FPU32ToSingle(const F32& a, bool round_to_nearest, bool fpscr_controlled) { +U32 IREmitter::FPU32ToSingle(const U32& a, bool round_to_nearest, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPU32ToSingle, a, Imm1(round_to_nearest)); + return Inst(Opcode::FPU32ToSingle, a, Imm1(round_to_nearest)); } -F64 IREmitter::FPS32ToDouble(const F32& a, bool round_to_nearest, bool fpscr_controlled) { +U64 IREmitter::FPS32ToDouble(const U32& a, bool round_to_nearest, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPS32ToDouble, a, Imm1(round_to_nearest)); + return Inst(Opcode::FPS32ToDouble, a, Imm1(round_to_nearest)); } -F64 IREmitter::FPU32ToDouble(const F32& a, bool round_to_nearest, bool fpscr_controlled) { +U64 IREmitter::FPU32ToDouble(const U32& a, bool round_to_nearest, bool fpscr_controlled) { ASSERT(fpscr_controlled); - return Inst(Opcode::FPU32ToDouble, a, Imm1(round_to_nearest)); + return Inst(Opcode::FPU32ToDouble, a, Imm1(round_to_nearest)); } void IREmitter::Breakpoint() { diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index dbb20e51..1362924f 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -177,36 +177,32 @@ public: U32 PackedAbsDiffSumS8(const U32& a, const U32& b); U32 PackedSelect(const U32& ge, const U32& a, const U32& b); - F32 TransferToFP32(const U32& a); - F64 TransferToFP64(const U64& a); - U32 TransferFromFP32(const F32& a); - U64 TransferFromFP64(const F64& a); - F32 FPAbs32(const F32& a); - F64 FPAbs64(const F64& a); - F32 FPAdd32(const F32& a, const F32& b, bool fpscr_controlled); - F64 FPAdd64(const F64& a, const F64& b, bool fpscr_controlled); - void FPCompare32(const F32& a, const F32& b, bool exc_on_qnan, bool fpscr_controlled); - void FPCompare64(const F64& a, const F64& b, bool exc_on_qnan, bool fpscr_controlled); - F32 FPDiv32(const F32& a, const F32& b, bool fpscr_controlled); - F64 FPDiv64(const F64& a, const F64& b, bool fpscr_controlled); - F32 FPMul32(const F32& a, const F32& b, bool fpscr_controlled); - F64 FPMul64(const F64& a, const F64& b, bool fpscr_controlled); - F32 FPNeg32(const F32& a); - F64 FPNeg64(const F64& a); - F32 FPSqrt32(const F32& a); - F64 FPSqrt64(const F64& a); - F32 FPSub32(const F32& a, const F32& b, bool fpscr_controlled); - F64 FPSub64(const F64& a, const F64& b, bool fpscr_controlled); - F32 FPDoubleToSingle(const F64& a, bool fpscr_controlled); - F64 FPSingleToDouble(const F32& a, bool fpscr_controlled); - F32 FPSingleToS32(const F32& a, bool round_towards_zero, bool fpscr_controlled); - F32 FPSingleToU32(const F32& a, bool round_towards_zero, bool fpscr_controlled); - F32 FPDoubleToS32(const F32& a, bool round_towards_zero, bool fpscr_controlled); - F32 FPDoubleToU32(const F32& a, bool round_towards_zero, bool fpscr_controlled); - F32 FPS32ToSingle(const F32& a, bool round_to_nearest, bool fpscr_controlled); - F32 FPU32ToSingle(const F32& a, bool round_to_nearest, bool fpscr_controlled); - F64 FPS32ToDouble(const F32& a, bool round_to_nearest, bool fpscr_controlled); - F64 FPU32ToDouble(const F32& a, bool round_to_nearest, bool fpscr_controlled); + U32 FPAbs32(const U32& a); + U64 FPAbs64(const U64& a); + U32 FPAdd32(const U32& a, const U32& b, bool fpscr_controlled); + U64 FPAdd64(const U64& a, const U64& b, bool fpscr_controlled); + void FPCompare32(const U32& a, const U32& b, bool exc_on_qnan, bool fpscr_controlled); + void FPCompare64(const U64& a, const U64& b, bool exc_on_qnan, bool fpscr_controlled); + U32 FPDiv32(const U32& a, const U32& b, bool fpscr_controlled); + U64 FPDiv64(const U64& a, const U64& b, bool fpscr_controlled); + U32 FPMul32(const U32& a, const U32& b, bool fpscr_controlled); + U64 FPMul64(const U64& a, const U64& b, bool fpscr_controlled); + U32 FPNeg32(const U32& a); + U64 FPNeg64(const U64& a); + U32 FPSqrt32(const U32& a); + U64 FPSqrt64(const U64& a); + U32 FPSub32(const U32& a, const U32& b, bool fpscr_controlled); + U64 FPSub64(const U64& a, const U64& b, bool fpscr_controlled); + U32 FPDoubleToSingle(const U64& a, bool fpscr_controlled); + U64 FPSingleToDouble(const U32& a, bool fpscr_controlled); + U32 FPSingleToS32(const U32& a, bool round_towards_zero, bool fpscr_controlled); + U32 FPSingleToU32(const U32& a, bool round_towards_zero, bool fpscr_controlled); + U32 FPDoubleToS32(const U32& a, bool round_towards_zero, bool fpscr_controlled); + U32 FPDoubleToU32(const U32& a, bool round_towards_zero, bool fpscr_controlled); + U32 FPS32ToSingle(const U32& a, bool round_to_nearest, bool fpscr_controlled); + U32 FPU32ToSingle(const U32& a, bool round_to_nearest, bool fpscr_controlled); + U64 FPS32ToDouble(const U32& a, bool round_to_nearest, bool fpscr_controlled); + U64 FPU32ToDouble(const U32& a, bool round_to_nearest, bool fpscr_controlled); void Breakpoint(); diff --git a/src/frontend/ir/opcodes.h b/src/frontend/ir/opcodes.h index 71f49995..eb083925 100644 --- a/src/frontend/ir/opcodes.h +++ b/src/frontend/ir/opcodes.h @@ -43,12 +43,10 @@ enum class Type { U16 = 1 << 7, U32 = 1 << 8, U64 = 1 << 9, - F32 = 1 << 10, - F64 = 1 << 11, - F128 = 1 << 12, - CoprocInfo = 1 << 13, - NZCVFlags = 1 << 14, - Cond = 1 << 15, + U128 = 1 << 10, + CoprocInfo = 1 << 11, + NZCVFlags = 1 << 12, + Cond = 1 << 13, }; constexpr Type operator|(Type a, Type b) { diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index f8a59eb7..fd0e1ee6 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -6,11 +6,11 @@ OPCODE(Breakpoint, T::Void, // A32 Context getters/setters A32OPC(GetRegister, T::U32, T::A32Reg ) -A32OPC(GetExtendedRegister32, T::F32, T::A32ExtReg ) -A32OPC(GetExtendedRegister64, T::F64, T::A32ExtReg ) +A32OPC(GetExtendedRegister32, T::U32, T::A32ExtReg ) +A32OPC(GetExtendedRegister64, T::U64, T::A32ExtReg ) A32OPC(SetRegister, T::Void, T::A32Reg, T::U32 ) -A32OPC(SetExtendedRegister32, T::Void, T::A32ExtReg, T::F32 ) -A32OPC(SetExtendedRegister64, T::Void, T::A32ExtReg, T::F64 ) +A32OPC(SetExtendedRegister32, T::Void, T::A32ExtReg, T::U32 ) +A32OPC(SetExtendedRegister64, T::Void, T::A32ExtReg, T::U64 ) A32OPC(GetCpsr, T::U32, ) A32OPC(SetCpsr, T::Void, T::U32 ) A32OPC(SetCpsrNZCV, T::Void, T::U32 ) @@ -150,38 +150,34 @@ OPCODE(PackedAbsDiffSumS8, T::U32, T::U32, T::U32 OPCODE(PackedSelect, T::U32, T::U32, T::U32, T::U32 ) // Floating-point operations -OPCODE(TransferToFP32, T::F32, T::U32 ) -OPCODE(TransferToFP64, T::F64, T::U64 ) -OPCODE(TransferFromFP32, T::U32, T::F32 ) -OPCODE(TransferFromFP64, T::U64, T::F64 ) -OPCODE(FPAbs32, T::F32, T::F32 ) -OPCODE(FPAbs64, T::F64, T::F64 ) -OPCODE(FPAdd32, T::F32, T::F32, T::F32 ) -OPCODE(FPAdd64, T::F64, T::F64, T::F64 ) -OPCODE(FPCompare32, T::Void, T::F32, T::F32, T::U1 ) -OPCODE(FPCompare64, T::Void, T::F64, T::F64, T::U1 ) -OPCODE(FPDiv32, T::F32, T::F32, T::F32 ) -OPCODE(FPDiv64, T::F64, T::F64, T::F64 ) -OPCODE(FPMul32, T::F32, T::F32, T::F32 ) -OPCODE(FPMul64, T::F64, T::F64, T::F64 ) -OPCODE(FPNeg32, T::F32, T::F32 ) -OPCODE(FPNeg64, T::F64, T::F64 ) -OPCODE(FPSqrt32, T::F32, T::F32 ) -OPCODE(FPSqrt64, T::F64, T::F64 ) -OPCODE(FPSub32, T::F32, T::F32, T::F32 ) -OPCODE(FPSub64, T::F64, T::F64, T::F64 ) +OPCODE(FPAbs32, T::U32, T::U32 ) +OPCODE(FPAbs64, T::U64, T::U64 ) +OPCODE(FPAdd32, T::U32, T::U32, T::U32 ) +OPCODE(FPAdd64, T::U64, T::U64, T::U64 ) +OPCODE(FPCompare32, T::Void, T::U32, T::U32, T::U1 ) +OPCODE(FPCompare64, T::Void, T::U64, T::U64, T::U1 ) +OPCODE(FPDiv32, T::U32, T::U32, T::U32 ) +OPCODE(FPDiv64, T::U64, T::U64, T::U64 ) +OPCODE(FPMul32, T::U32, T::U32, T::U32 ) +OPCODE(FPMul64, T::U64, T::U64, T::U64 ) +OPCODE(FPNeg32, T::U32, T::U32 ) +OPCODE(FPNeg64, T::U64, T::U64 ) +OPCODE(FPSqrt32, T::U32, T::U32 ) +OPCODE(FPSqrt64, T::U64, T::U64 ) +OPCODE(FPSub32, T::U32, T::U32, T::U32 ) +OPCODE(FPSub64, T::U64, T::U64, T::U64 ) // Floating-point conversions -OPCODE(FPSingleToDouble, T::F64, T::F32 ) -OPCODE(FPDoubleToSingle, T::F32, T::F64 ) -OPCODE(FPSingleToU32, T::F32, T::F32, T::U1 ) -OPCODE(FPSingleToS32, T::F32, T::F32, T::U1 ) -OPCODE(FPDoubleToU32, T::F32, T::F64, T::U1 ) -OPCODE(FPDoubleToS32, T::F32, T::F64, T::U1 ) -OPCODE(FPU32ToSingle, T::F32, T::F32, T::U1 ) -OPCODE(FPS32ToSingle, T::F32, T::F32, T::U1 ) -OPCODE(FPU32ToDouble, T::F64, T::F32, T::U1 ) -OPCODE(FPS32ToDouble, T::F64, T::F32, T::U1 ) +OPCODE(FPSingleToDouble, T::U64, T::U32 ) +OPCODE(FPDoubleToSingle, T::U32, T::U64 ) +OPCODE(FPSingleToU32, T::U32, T::U32, T::U1 ) +OPCODE(FPSingleToS32, T::U32, T::U32, T::U1 ) +OPCODE(FPDoubleToU32, T::U32, T::U64, T::U1 ) +OPCODE(FPDoubleToS32, T::U32, T::U64, T::U1 ) +OPCODE(FPU32ToSingle, T::U32, T::U32, T::U1 ) +OPCODE(FPS32ToSingle, T::U32, T::U32, T::U1 ) +OPCODE(FPU32ToDouble, T::U64, T::U32, T::U1 ) +OPCODE(FPS32ToDouble, T::U64, T::U32, T::U1 ) // A32 Memory access A32OPC(ClearExclusive, T::Void, ) diff --git a/src/frontend/ir/value.h b/src/frontend/ir/value.h index b27d69a0..d6108a87 100644 --- a/src/frontend/ir/value.h +++ b/src/frontend/ir/value.h @@ -97,12 +97,9 @@ using U8 = TypedValue; using U16 = TypedValue; using U32 = TypedValue; using U64 = TypedValue; +using U128 = TypedValue; using U32U64 = TypedValue; using UAny = TypedValue; -using F32 = TypedValue; -using F64 = TypedValue; -using F128 = TypedValue; -using F32F64 = TypedValue; using NZCV = TypedValue; } // namespace IR