diff --git a/src/backend_x64/emit_x64_floating_point.cpp b/src/backend_x64/emit_x64_floating_point.cpp index c890c625..bd3c489c 100644 --- a/src/backend_x64/emit_x64_floating_point.cpp +++ b/src/backend_x64/emit_x64_floating_point.cpp @@ -257,6 +257,22 @@ void EmitX64::EmitFPDiv64(EmitContext& ctx, IR::Inst* inst) { FPThreeOp64(code, ctx, inst, &Xbyak::CodeGenerator::divsd); } +void EmitX64::EmitFPMax32(EmitContext& ctx, IR::Inst* inst) { + FPThreeOp32(code, ctx, inst, &Xbyak::CodeGenerator::maxss); +} + +void EmitX64::EmitFPMax64(EmitContext& ctx, IR::Inst* inst) { + FPThreeOp64(code, ctx, inst, &Xbyak::CodeGenerator::maxsd); +} + +void EmitX64::EmitFPMin32(EmitContext& ctx, IR::Inst* inst) { + FPThreeOp32(code, ctx, inst, &Xbyak::CodeGenerator::minss); +} + +void EmitX64::EmitFPMin64(EmitContext& ctx, IR::Inst* inst) { + FPThreeOp64(code, ctx, inst, &Xbyak::CodeGenerator::minsd); +} + void EmitX64::EmitFPMul32(EmitContext& ctx, IR::Inst* inst) { FPThreeOp32(code, ctx, inst, &Xbyak::CodeGenerator::mulss); } diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index 734d240d..4d33f33a 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -1068,6 +1068,26 @@ U32U64 IREmitter::FPDiv(const U32U64& a, const U32U64& b, bool fpscr_controlled) } } +U32U64 IREmitter::FPMax(const U32U64& a, const U32U64& b, bool fpscr_controlled) { + ASSERT(fpscr_controlled); + ASSERT(a.GetType() == b.GetType()); + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPMax32, a, b); + } else { + return Inst(Opcode::FPMax64, a, b); + } +} + +U32U64 IREmitter::FPMin(const U32U64& a, const U32U64& b, bool fpscr_controlled) { + ASSERT(fpscr_controlled); + ASSERT(a.GetType() == b.GetType()); + if (a.GetType() == Type::U32) { + return Inst(Opcode::FPMin32, a, b); + } else { + return Inst(Opcode::FPMin64, a, b); + } +} + U32U64 IREmitter::FPMul(const U32U64& a, const U32U64& b, bool fpscr_controlled) { ASSERT(fpscr_controlled); ASSERT(a.GetType() == b.GetType()); diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index b9f9241b..3fd1f569 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -233,6 +233,8 @@ public: U32U64 FPAdd(const U32U64& a, const U32U64& b, bool fpscr_controlled); NZCV FPCompare(const U32U64& a, const U32U64& b, bool exc_on_qnan, bool fpscr_controlled); U32U64 FPDiv(const U32U64& a, const U32U64& b, bool fpscr_controlled); + U32U64 FPMax(const U32U64& a, const U32U64& b, bool fpscr_controlled); + U32U64 FPMin(const U32U64& a, const U32U64& b, bool fpscr_controlled); U32U64 FPMul(const U32U64& a, const U32U64& b, bool fpscr_controlled); U32U64 FPNeg(const U32U64& a); U32U64 FPSqrt(const U32U64& a); diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index d7daa9d8..b6ee5703 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -272,6 +272,10 @@ OPCODE(FPCompare32, T::NZCVFlags, T::U32, T::U32, OPCODE(FPCompare64, T::NZCVFlags, T::U64, T::U64, T::U1 ) OPCODE(FPDiv32, T::U32, T::U32, T::U32 ) OPCODE(FPDiv64, T::U64, T::U64, T::U64 ) +OPCODE(FPMax32, T::U32, T::U32, T::U32 ) +OPCODE(FPMax64, T::U64, T::U64, T::U64 ) +OPCODE(FPMin32, T::U32, T::U32, T::U32 ) +OPCODE(FPMin64, 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 )