From 9cf3c25811f3114aad771b356d0e98281adcb4bb Mon Sep 17 00:00:00 2001 From: Lioncash Date: Sat, 2 Mar 2019 20:18:59 -0500 Subject: [PATCH] frontend/ir/ir_emitter: Add opcodes for floating point reciprocal exponents --- src/backend/x64/emit_x64_floating_point.cpp | 17 +++++++++++++++++ src/frontend/ir/ir_emitter.cpp | 7 +++++++ src/frontend/ir/ir_emitter.h | 1 + src/frontend/ir/opcodes.inc | 2 ++ 4 files changed, 27 insertions(+) diff --git a/src/backend/x64/emit_x64_floating_point.cpp b/src/backend/x64/emit_x64_floating_point.cpp index b6f8a06c..c499e20f 100644 --- a/src/backend/x64/emit_x64_floating_point.cpp +++ b/src/backend/x64/emit_x64_floating_point.cpp @@ -719,6 +719,23 @@ void EmitX64::EmitFPRecipEstimate64(EmitContext& ctx, IR::Inst* inst) { EmitFPRecipEstimate(code, ctx, inst); } +template +static void EmitFPRecipExponent(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { + auto args = ctx.reg_alloc.GetArgumentInfo(inst); + ctx.reg_alloc.HostCall(inst, args[0]); + code.mov(code.ABI_PARAM2.cvt32(), ctx.FPCR()); + code.lea(code.ABI_PARAM3, code.ptr[code.r15 + code.GetJitStateInfo().offsetof_fpsr_exc]); + code.CallFunction(&FP::FPRecipExponent); +} + +void EmitX64::EmitFPRecipExponent32(EmitContext& ctx, IR::Inst* inst) { + EmitFPRecipExponent(code, ctx, inst); +} + +void EmitX64::EmitFPRecipExponent64(EmitContext& ctx, IR::Inst* inst) { + EmitFPRecipExponent(code, ctx, inst); +} + template static void EmitFPRecipStepFused(BlockOfCode& code, EmitContext& ctx, IR::Inst* inst) { using FPT = mp::unsigned_integer_of_size; diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index 46b27c0c..6452e7f7 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -1895,6 +1895,13 @@ U32U64 IREmitter::FPRecipEstimate(const U32U64& a) { return Inst(Opcode::FPRecipEstimate64, a); } +U32U64 IREmitter::FPRecipExponent(const U32U64& a) { + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPRecipExponent32, a); + } + return Inst(Opcode::FPRecipExponent64, a); +} + U32U64 IREmitter::FPRecipStepFused(const U32U64& a, const U32U64& b) { if (a.GetType() == Type::U32) { return Inst(Opcode::FPRecipStepFused32, a, b); diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index 5bfb7484..f58c6efa 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -305,6 +305,7 @@ public: U32U64 FPMulX(const U32U64& a, const U32U64& b); U32U64 FPNeg(const U32U64& a); U32U64 FPRecipEstimate(const U32U64& a); + U32U64 FPRecipExponent(const U32U64& a); U32U64 FPRecipStepFused(const U32U64& a, const U32U64& b); U32U64 FPRoundInt(const U32U64& a, FP::RoundingMode rounding, bool exact); U32U64 FPRSqrtEstimate(const U32U64& a); diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 54ea8504..7306e3d0 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -484,6 +484,8 @@ OPCODE(FPNeg32, U32, U32 OPCODE(FPNeg64, U64, U64 ) OPCODE(FPRecipEstimate32, U32, U32 ) OPCODE(FPRecipEstimate64, U64, U64 ) +OPCODE(FPRecipExponent32, U32, U32 ) +OPCODE(FPRecipExponent64, U64, U64 ) OPCODE(FPRecipStepFused32, U32, U32, U32 ) OPCODE(FPRecipStepFused64, U64, U64, U64 ) OPCODE(FPRoundInt32, U32, U32, U8, U1 )