diff --git a/src/backend_x64/emit_x64.cpp b/src/backend_x64/emit_x64.cpp index d9987b12..4a2bbb00 100644 --- a/src/backend_x64/emit_x64.cpp +++ b/src/backend_x64/emit_x64.cpp @@ -2199,6 +2199,11 @@ void EmitX64::EmitVectorAdd64(EmitContext& ctx, IR::Inst* inst) { EmitVectorOperation(code, ctx, inst, &Xbyak::CodeGenerator::paddq); } +template +void EmitX64::EmitVectorAnd(EmitContext& ctx, IR::Inst* inst) { + EmitVectorOperation(code, ctx, inst, &Xbyak::CodeGenerator::pand); +} + template static void DenormalsAreZero32(BlockOfCode* code, Xbyak::Xmm xmm_value, Xbyak::Reg32 gpr_scratch) { Xbyak::Label end; diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index 6bf98af3..80f76a79 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -832,7 +832,7 @@ INST(ADD_vector, "ADD (vector)", "0Q001 //INST(ADDP_vec, "ADDP (vector)", "0Q001110zz1mmmmm101111nnnnnddddd") //INST(FMLAL_vec_1, "FMLAL, FMLAL2 (vector)", "0Q0011100z1mmmmm111011nnnnnddddd") //INST(FMLAL_vec_2, "FMLAL, FMLAL2 (vector)", "0Q1011100z1mmmmm110011nnnnnddddd") -//INST(AND_asimd, "AND (vector)", "0Q001110001mmmmm000111nnnnnddddd") +INST(AND_asimd, "AND (vector)", "0Q001110001mmmmm000111nnnnnddddd") //INST(BIC_asimd_reg, "BIC (vector, register)", "0Q001110011mmmmm000111nnnnnddddd") //INST(FMLSL_vec_1, "FMLSL, FMLSL2 (vector)", "0Q0011101z1mmmmm111011nnnnnddddd") //INST(FMLSL_vec_2, "FMLSL, FMLSL2 (vector)", "0Q1011101z1mmmmm110011nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_three_same.cpp b/src/frontend/A64/translate/impl/simd_three_same.cpp index 09f23ce9..2fa6506c 100644 --- a/src/frontend/A64/translate/impl/simd_three_same.cpp +++ b/src/frontend/A64/translate/impl/simd_three_same.cpp @@ -35,5 +35,18 @@ bool TranslatorVisitor::ADD_vector(bool Q, Imm<2> size, Vec Vm, Vec Vn, Vec Vd) return true; } +bool TranslatorVisitor::AND_asimd(bool Q, Vec Vm, Vec Vn, Vec Vd) { + const size_t datasize = Q ? 128 : 64; + + auto operand1 = V(datasize, Vn); + auto operand2 = V(datasize, Vm); + + auto result = ir.VectorAnd(operand1, operand2); + + V(datasize, Vd, result); + + return true; +} + } // namespace A64 } // namespace Dynarmic diff --git a/src/frontend/ir/ir_emitter.cpp b/src/frontend/ir/ir_emitter.cpp index 5d28143f..d32af660 100644 --- a/src/frontend/ir/ir_emitter.cpp +++ b/src/frontend/ir/ir_emitter.cpp @@ -620,6 +620,10 @@ U128 IREmitter::VectorAdd64(const U128& a, const U128& b) { return Inst(Opcode::VectorAdd64, a, b); } +U128 IREmitter::VectorAnd(const U128& a, const U128& b) { + return Inst(Opcode::VectorAnd, a, b); +} + U32 IREmitter::FPAbs32(const U32& a) { return Inst(Opcode::FPAbs32, a); } diff --git a/src/frontend/ir/ir_emitter.h b/src/frontend/ir/ir_emitter.h index 0c8549b4..e02c169e 100644 --- a/src/frontend/ir/ir_emitter.h +++ b/src/frontend/ir/ir_emitter.h @@ -181,6 +181,7 @@ public: U128 VectorAdd16(const U128& a, const U128& b); U128 VectorAdd32(const U128& a, const U128& b); U128 VectorAdd64(const U128& a, const U128& b); + U128 VectorAnd(const U128& a, const U128& b); U32 FPAbs32(const U32& a); U64 FPAbs64(const U64& a); diff --git a/src/frontend/ir/opcodes.inc b/src/frontend/ir/opcodes.inc index 690b70f0..ef46afec 100644 --- a/src/frontend/ir/opcodes.inc +++ b/src/frontend/ir/opcodes.inc @@ -164,6 +164,7 @@ OPCODE(VectorAdd8, T::U128, T::U128, T::U128 OPCODE(VectorAdd16, T::U128, T::U128, T::U128 ) OPCODE(VectorAdd32, T::U128, T::U128, T::U128 ) OPCODE(VectorAdd64, T::U128, T::U128, T::U128 ) +OPCODE(VectorAnd, T::U128, T::U128, T::U128 ) // Floating-point operations OPCODE(FPAbs32, T::U32, T::U32 )