diff --git a/src/frontend/A64/decoder/a64.inc b/src/frontend/A64/decoder/a64.inc index d7460c37..8f6411cb 100644 --- a/src/frontend/A64/decoder/a64.inc +++ b/src/frontend/A64/decoder/a64.inc @@ -862,7 +862,7 @@ INST(SM3TT2B, "SM3TT2B", "11001 //INST(SHA512H2, "SHA512H2", "11001110011mmmmm100001nnnnnddddd") //INST(SHA512SU1, "SHA512SU1", "11001110011mmmmm100010nnnnnddddd") INST(RAX1, "RAX1", "11001110011mmmmm100011nnnnnddddd") -//INST(SM3PARTW1, "SM3PARTW1", "11001110011mmmmm110000nnnnnddddd") +INST(SM3PARTW1, "SM3PARTW1", "11001110011mmmmm110000nnnnnddddd") INST(SM3PARTW2, "SM3PARTW2", "11001110011mmmmm110001nnnnnddddd") //INST(SM4EKEY, "SM4EKEY", "11001110011mmmmm110010nnnnnddddd") diff --git a/src/frontend/A64/translate/impl/simd_sha512.cpp b/src/frontend/A64/translate/impl/simd_sha512.cpp index 1b87a176..463f3043 100644 --- a/src/frontend/A64/translate/impl/simd_sha512.cpp +++ b/src/frontend/A64/translate/impl/simd_sha512.cpp @@ -19,6 +19,44 @@ bool TranslatorVisitor::RAX1(Vec Vm, Vec Vn, Vec Vd) { return true; } +bool TranslatorVisitor::SM3PARTW1(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 eor_d_n = ir.VectorEor(d, n); + + const IR::U128 result_low_three_words = [&] { + // Move the top-most 3 words down one element (i.e. [3, 2, 1, 0] -> [0, 3, 2, 1]) + const IR::U128 shuffled_m = ir.VectorShuffleWords(m, 0b00111001); + + // We treat the uppermost word as junk data and don't touch/use it explicitly for now. + // Given we don't do anything with it yet, the fact we EOR into it doesn't matter. + return ir.VectorEor(eor_d_n, ir.VectorRotateLeft(32, shuffled_m, 15)); + }(); + + IR::U128 result = result_low_three_words; + for (size_t i = 0; i < 4; i++) { + if (i == 3) { + const IR::U32 top_eor_d_n = ir.VectorGetElement(32, eor_d_n, 3); + const IR::U32 low_result_word = ir.VectorGetElement(32, result, 0); + const IR::U32 top_result_word = ir.Eor(top_eor_d_n, ir.RotateRight(low_result_word, ir.Imm8(17))); + + // Now the uppermost word is well-defined data. + result = ir.VectorSetElement(32, result, 3, top_result_word); + } + + const IR::U32 word = ir.VectorGetElement(32, result, i); + const IR::U32 modified = ir.Eor(word, ir.Eor(ir.RotateRight(word, ir.Imm8(17)), + ir.RotateRight(word, ir.Imm8(9)))); + + result = ir.VectorSetElement(32, result, i, modified); + } + + ir.SetQ(Vd, result); + 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);