diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index a9e1b00c..d7460c37 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -863,7 +863,7 @@ INST(SM3TT2B, "SM3TT2B", "11001 //INST(SHA512SU1, "SHA512SU1", "11001110011mmmmm100010nnnnnddddd") INST(RAX1, "RAX1", "11001110011mmmmm100011nnnnnddddd") //INST(SM3PARTW1, "SM3PARTW1", "11001110011mmmmm110000nnnnnddddd") -//INST(SM3PARTW2, "SM3PARTW2", "11001110011mmmmm110001nnnnnddddd") +INST(SM3PARTW2, "SM3PARTW2", "11001110011mmmmm110001nnnnnddddd") //INST(SM4EKEY, "SM4EKEY", "11001110011mmmmm110010nnnnnddddd") // Data Processing - FP and SIMD - Cryptographic four register diff --git a/src/frontend/A64/translate/impl/simd_sha512.cpp b/src/frontend/A64/translate/impl/simd_sha512.cpp index 4ccb86c7..acfbb3d0 100644 --- a/src/frontend/A64/translate/impl/simd_sha512.cpp +++ b/src/frontend/A64/translate/impl/simd_sha512.cpp @@ -20,4 +20,27 @@ bool TranslatorVisitor::RAX1(Vec Vm, Vec Vn, Vec Vd) { return true; } +bool TranslatorVisitor::SM3PARTW2(Vec Vm, Vec Vn, Vec Vd) { + const IR::U128 d = ir.GetQ(Vd); + const IR::U128 m = ir.GetQ(Vm); + const IR::U128 n = ir.GetQ(Vn); + + const IR::U128 temp = ir.VectorEor(n, ir.VectorRotateLeft(32, m, 7)); + const IR::U128 temp_result = ir.VectorEor(d, temp); + const IR::U32 temp2 = [&] { + const IR::U32 rotate1 = ir.RotateRight(ir.VectorGetElement(32, temp, 0), ir.Imm8(17)); + const IR::U32 rotate2 = ir.RotateRight(rotate1, ir.Imm8(17)); + const IR::U32 rotate3 = ir.RotateRight(rotate1, ir.Imm8(9)); + + return ir.Eor(rotate1, ir.Eor(rotate2, rotate3)); + }(); + + const IR::U32 high_temp_result = ir.VectorGetElement(32, temp_result, 3); + const IR::U32 replacement = ir.Eor(high_temp_result, temp2); + const IR::U128 result = ir.VectorSetElement(32, temp_result, 3, replacement); + + ir.SetQ(Vd, result); + return true; +} + } // namespace Dynarmic::A64