diff --git a/src/backend/x64/emit_x64_vector_floating_point.cpp b/src/backend/x64/emit_x64_vector_floating_point.cpp index 5c34d85b..aa353e23 100644 --- a/src/backend/x64/emit_x64_vector_floating_point.cpp +++ b/src/backend/x64/emit_x64_vector_floating_point.cpp @@ -1401,11 +1401,11 @@ void EmitX64::EmitFPVectorSqrt64(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitFPVectorSub32(EmitContext& ctx, IR::Inst* inst) { - EmitThreeOpVectorOperation<32, DefaultIndexer>(code, ctx, inst, &Xbyak::CodeGenerator::subps); + EmitThreeOpVectorOperation<32, DefaultIndexer, FpcrControlledArgument::Present>(code, ctx, inst, &Xbyak::CodeGenerator::subps); } void EmitX64::EmitFPVectorSub64(EmitContext& ctx, IR::Inst* inst) { - EmitThreeOpVectorOperation<64, DefaultIndexer>(code, ctx, inst, &Xbyak::CodeGenerator::subpd); + EmitThreeOpVectorOperation<64, DefaultIndexer, FpcrControlledArgument::Present>(code, ctx, inst, &Xbyak::CodeGenerator::subpd); } template diff --git a/src/frontend/A32/decoder/asimd.inc b/src/frontend/A32/decoder/asimd.inc index a3c854ac..f87c4f59 100644 --- a/src/frontend/A32/decoder/asimd.inc +++ b/src/frontend/A32/decoder/asimd.inc @@ -34,7 +34,7 @@ INST(asimd_VMUL, "VMUL", "1111001P0Dzznnnndddd100 //INST(asimd_VPADD, "VPADD", "1111001U0-CC--------1011---1----") // ASIMD //INST(asimd_VFMA, "VFMA/VFMS", "111100100-CC--------1100---1----") // ASIMD INST(asimd_VADD_float, "VADD (floating-point)", "111100100D0znnnndddd1101NQM0mmmm") // ASIMD -//INST(asimd_VSUB_float, "VSUB (floating-point)", "111100100-1C--------1101---0----") // ASIMD +INST(asimd_VSUB_float, "VSUB (floating-point)", "111100100D1znnnndddd1101NQM0mmmm") // ASIMD //INST(asimd_VPADD_float, "VPADD (floating-point)", "111100110-0C--------1101---0----") // ASIMD //INST(asimd_VABD_float, "VABD (floating-point)", "111100110-1C--------1101---0----") // ASIMD //INST(asimd_VMLA_float, "VMLA (floating-point)", "111100100-CC--------1101---1----") // ASIMD diff --git a/src/frontend/A32/translate/impl/asimd_three_same.cpp b/src/frontend/A32/translate/impl/asimd_three_same.cpp index 67c90a15..75d87db3 100644 --- a/src/frontend/A32/translate/impl/asimd_three_same.cpp +++ b/src/frontend/A32/translate/impl/asimd_three_same.cpp @@ -362,6 +362,12 @@ bool ArmTranslatorVisitor::asimd_VADD_float(bool D, bool sz, size_t Vn, size_t V }); } +bool ArmTranslatorVisitor::asimd_VSUB_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { + return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { + return ir.FPVectorSub(32, reg_n, reg_m, false); + }); +} + bool ArmTranslatorVisitor::asimd_VMUL_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm) { return FloatingPointInstruction(*this, D, sz, Vn, Vd, N, Q, M, Vm, [this](const auto&, const auto& reg_n, const auto& reg_m) { return ir.FPVectorMul(32, reg_n, reg_m, false); diff --git a/src/frontend/A32/translate/impl/translate_arm.h b/src/frontend/A32/translate/impl/translate_arm.h index 5085140a..b07b3e6f 100644 --- a/src/frontend/A32/translate/impl/translate_arm.h +++ b/src/frontend/A32/translate/impl/translate_arm.h @@ -463,6 +463,7 @@ struct ArmTranslatorVisitor final { bool asimd_VTST(bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); bool asimd_VMUL(bool P, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); bool asimd_VADD_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); + bool asimd_VSUB_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); bool asimd_VMUL_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); bool asimd_VMAX_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); bool asimd_VMIN_float(bool D, bool sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index faa2f312..1eaf36b4 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -2513,12 +2513,12 @@ U128 IREmitter::FPVectorSqrt(size_t esize, const U128& a) { UNREACHABLE(); } -U128 IREmitter::FPVectorSub(size_t esize, const U128& a, const U128& b) { +U128 IREmitter::FPVectorSub(size_t esize, const U128& a, const U128& b, bool fpcr_controlled) { switch (esize) { case 32: - return Inst(Opcode::FPVectorSub32, a, b); + return Inst(Opcode::FPVectorSub32, a, b, Imm1(fpcr_controlled)); case 64: - return Inst(Opcode::FPVectorSub64, a, b); + return Inst(Opcode::FPVectorSub64, a, b, Imm1(fpcr_controlled)); } UNREACHABLE(); } diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index a882ac82..f2243688 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -366,7 +366,7 @@ public: U128 FPVectorRSqrtEstimate(size_t esize, const U128& a); U128 FPVectorRSqrtStepFused(size_t esize, const U128& a, const U128& b); U128 FPVectorSqrt(size_t esize, const U128& a); - U128 FPVectorSub(size_t esize, const U128& a, const U128& b); + U128 FPVectorSub(size_t esize, const U128& a, const U128& b, bool fpcr_controlled = true); U128 FPVectorToSignedFixed(size_t esize, const U128& a, size_t fbits, FP::RoundingMode rounding); U128 FPVectorToUnsignedFixed(size_t esize, const U128& a, size_t fbits, FP::RoundingMode rounding); diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 89c84a86..0eacd22b 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -630,8 +630,8 @@ OPCODE(FPVectorRSqrtStepFused32, U128, U128 OPCODE(FPVectorRSqrtStepFused64, U128, U128, U128 ) OPCODE(FPVectorSqrt32, U128, U128 ) OPCODE(FPVectorSqrt64, U128, U128 ) -OPCODE(FPVectorSub32, U128, U128, U128 ) -OPCODE(FPVectorSub64, U128, U128, U128 ) +OPCODE(FPVectorSub32, U128, U128, U128, U1 ) +OPCODE(FPVectorSub64, U128, U128, U128, U1 ) OPCODE(FPVectorToSignedFixed16, U128, U128, U8, U8 ) OPCODE(FPVectorToSignedFixed32, U128, U128, U8, U8 ) OPCODE(FPVectorToSignedFixed64, U128, U128, U8, U8 )