diff --git a/src/backend/x64/emit_x64_vector_floating_point.cpp b/src/backend/x64/emit_x64_vector_floating_point.cpp index 3be0c80d..5c34d85b 100644 --- a/src/backend/x64/emit_x64_vector_floating_point.cpp +++ b/src/backend/x64/emit_x64_vector_floating_point.cpp @@ -548,11 +548,11 @@ void EmitX64::EmitFPVectorAbs64(EmitContext& ctx, IR::Inst* inst) { } void EmitX64::EmitFPVectorAdd32(EmitContext& ctx, IR::Inst* inst) { - EmitThreeOpVectorOperation<32, DefaultIndexer>(code, ctx, inst, &Xbyak::CodeGenerator::addps); + EmitThreeOpVectorOperation<32, DefaultIndexer, FpcrControlledArgument::Present>(code, ctx, inst, &Xbyak::CodeGenerator::addps); } void EmitX64::EmitFPVectorAdd64(EmitContext& ctx, IR::Inst* inst) { - EmitThreeOpVectorOperation<64, DefaultIndexer>(code, ctx, inst, &Xbyak::CodeGenerator::addpd); + EmitThreeOpVectorOperation<64, DefaultIndexer, FpcrControlledArgument::Present>(code, ctx, inst, &Xbyak::CodeGenerator::addpd); } void EmitX64::EmitFPVectorDiv32(EmitContext& ctx, IR::Inst* inst) { diff --git a/src/frontend/A32/decoder/asimd.inc b/src/frontend/A32/decoder/asimd.inc index e034a505..a3c854ac 100644 --- a/src/frontend/A32/decoder/asimd.inc +++ b/src/frontend/A32/decoder/asimd.inc @@ -33,7 +33,7 @@ INST(asimd_VMUL, "VMUL", "1111001P0Dzznnnndddd100 //INST(asimd_VQRDMULH, "VQRDMULH", "111100110-CC--------1011---0----") // ASIMD //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)", "111100100-0C--------1101---0----") // ASIMD +INST(asimd_VADD_float, "VADD (floating-point)", "111100100D0znnnndddd1101NQM0mmmm") // ASIMD //INST(asimd_VSUB_float, "VSUB (floating-point)", "111100100-1C--------1101---0----") // 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 diff --git a/src/frontend/A32/translate/impl/asimd_three_same.cpp b/src/frontend/A32/translate/impl/asimd_three_same.cpp index c1fdc5ce..67c90a15 100644 --- a/src/frontend/A32/translate/impl/asimd_three_same.cpp +++ b/src/frontend/A32/translate/impl/asimd_three_same.cpp @@ -356,6 +356,12 @@ bool ArmTranslatorVisitor::asimd_VMUL(bool P, bool D, size_t sz, size_t Vn, size return true; } +bool ArmTranslatorVisitor::asimd_VADD_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.FPVectorAdd(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 e7beeb12..5085140a 100644 --- a/src/frontend/A32/translate/impl/translate_arm.h +++ b/src/frontend/A32/translate/impl/translate_arm.h @@ -462,6 +462,7 @@ struct ArmTranslatorVisitor final { bool asimd_VRSHL(bool U, bool D, size_t sz, size_t Vn, size_t Vd, bool N, bool Q, bool M, size_t Vm); 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_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 c3d8fcb8..faa2f312 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -2282,12 +2282,12 @@ U128 IREmitter::FPVectorAbs(size_t esize, const U128& a) { UNREACHABLE(); } -U128 IREmitter::FPVectorAdd(size_t esize, const U128& a, const U128& b) { +U128 IREmitter::FPVectorAdd(size_t esize, const U128& a, const U128& b, bool fpcr_controlled) { switch (esize) { case 32: - return Inst(Opcode::FPVectorAdd32, a, b); + return Inst(Opcode::FPVectorAdd32, a, b, Imm1(fpcr_controlled)); case 64: - return Inst(Opcode::FPVectorAdd64, a, b); + return Inst(Opcode::FPVectorAdd64, a, b, Imm1(fpcr_controlled)); } UNREACHABLE(); } diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index d9fae230..a882ac82 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -345,7 +345,7 @@ public: U64 FPUnsignedFixedToDouble(const U32U64& a, size_t fbits, FP::RoundingMode rounding); U128 FPVectorAbs(size_t esize, const U128& a); - U128 FPVectorAdd(size_t esize, const U128& a, const U128& b); + U128 FPVectorAdd(size_t esize, const U128& a, const U128& b, bool fpcr_controlled = true); U128 FPVectorDiv(size_t esize, const U128& a, const U128& b); U128 FPVectorEqual(size_t esize, const U128& a, const U128& b, bool fpcr_controlled = true); U128 FPVectorFromSignedFixed(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 fea5d9ba..89c84a86 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -580,8 +580,8 @@ OPCODE(FPFixedS64ToSingle, U32, U64, OPCODE(FPVectorAbs16, U128, U128 ) OPCODE(FPVectorAbs32, U128, U128 ) OPCODE(FPVectorAbs64, U128, U128 ) -OPCODE(FPVectorAdd32, U128, U128, U128 ) -OPCODE(FPVectorAdd64, U128, U128, U128 ) +OPCODE(FPVectorAdd32, U128, U128, U128, U1 ) +OPCODE(FPVectorAdd64, U128, U128, U128, U1 ) OPCODE(FPVectorDiv32, U128, U128, U128 ) OPCODE(FPVectorDiv64, U128, U128, U128 ) OPCODE(FPVectorEqual16, U128, U128, U128, U1 )