A64: Implement SHA256H and SHA256H2
This commit is contained in:
parent
e4237c44eb
commit
ca903c1585
2 changed files with 75 additions and 2 deletions
|
@ -326,8 +326,8 @@ INST(SHA1C, "SHA1C", "01011
|
||||||
INST(SHA1P, "SHA1P", "01011110000mmmmm000100nnnnnddddd")
|
INST(SHA1P, "SHA1P", "01011110000mmmmm000100nnnnnddddd")
|
||||||
INST(SHA1M, "SHA1M", "01011110000mmmmm001000nnnnnddddd")
|
INST(SHA1M, "SHA1M", "01011110000mmmmm001000nnnnnddddd")
|
||||||
INST(SHA1SU0, "SHA1SU0", "01011110000mmmmm001100nnnnnddddd")
|
INST(SHA1SU0, "SHA1SU0", "01011110000mmmmm001100nnnnnddddd")
|
||||||
//INST(SHA256H, "SHA256H", "01011110000mmmmm010000nnnnnddddd")
|
INST(SHA256H, "SHA256H", "01011110000mmmmm010000nnnnnddddd")
|
||||||
//INST(SHA256H2, "SHA256H2", "01011110000mmmmm010100nnnnnddddd")
|
INST(SHA256H2, "SHA256H2", "01011110000mmmmm010100nnnnnddddd")
|
||||||
INST(SHA256SU1, "SHA256SU1", "01011110000mmmmm011000nnnnnddddd")
|
INST(SHA256SU1, "SHA256SU1", "01011110000mmmmm011000nnnnnddddd")
|
||||||
INST(SHA1H, "SHA1H", "0101111000101000000010nnnnnddddd")
|
INST(SHA1H, "SHA1H", "0101111000101000000010nnnnnddddd")
|
||||||
INST(SHA1SU1, "SHA1SU1", "0101111000101000000110nnnnnddddd")
|
INST(SHA1SU1, "SHA1SU1", "0101111000101000000110nnnnnddddd")
|
||||||
|
|
|
@ -47,6 +47,67 @@ IR::U128 SHA1HashUpdate(IREmitter& ir, Vec Vm, Vec Vn, Vec Vd, SHA1HashUpdateFun
|
||||||
|
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IR::U32 SHAhashSIGMA0(IREmitter& ir, IR::U32 x) {
|
||||||
|
const IR::U32 tmp1 = ir.RotateRight(x, ir.Imm8(2));
|
||||||
|
const IR::U32 tmp2 = ir.RotateRight(x, ir.Imm8(13));
|
||||||
|
const IR::U32 tmp3 = ir.RotateRight(x, ir.Imm8(22));
|
||||||
|
|
||||||
|
return ir.Eor(tmp1, ir.Eor(tmp2, tmp3));
|
||||||
|
}
|
||||||
|
|
||||||
|
IR::U32 SHAhashSIGMA1(IREmitter& ir, IR::U32 x) {
|
||||||
|
const IR::U32 tmp1 = ir.RotateRight(x, ir.Imm8(6));
|
||||||
|
const IR::U32 tmp2 = ir.RotateRight(x, ir.Imm8(11));
|
||||||
|
const IR::U32 tmp3 = ir.RotateRight(x, ir.Imm8(25));
|
||||||
|
|
||||||
|
return ir.Eor(tmp1, ir.Eor(tmp2, tmp3));
|
||||||
|
}
|
||||||
|
|
||||||
|
enum class SHA256HashPart {
|
||||||
|
Part1,
|
||||||
|
Part2
|
||||||
|
};
|
||||||
|
|
||||||
|
IR::U128 SHA256hash(IREmitter& ir, IR::U128 x, IR::U128 y, IR::U128 w, SHA256HashPart part) {
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
const IR::U32 low_x = ir.VectorGetElement(32, x, 0);
|
||||||
|
const IR::U32 after_low_x = ir.VectorGetElement(32, x, 1);
|
||||||
|
const IR::U32 before_high_x = ir.VectorGetElement(32, x, 2);
|
||||||
|
const IR::U32 high_x = ir.VectorGetElement(32, x, 3);
|
||||||
|
|
||||||
|
const IR::U32 low_y = ir.VectorGetElement(32, y, 0);
|
||||||
|
const IR::U32 after_low_y = ir.VectorGetElement(32, y, 1);
|
||||||
|
const IR::U32 before_high_y = ir.VectorGetElement(32, y, 2);
|
||||||
|
const IR::U32 high_y = ir.VectorGetElement(32, y, 3);
|
||||||
|
|
||||||
|
const IR::U32 choice = SHAchoose(ir, low_y, after_low_y, before_high_y);
|
||||||
|
const IR::U32 majority = SHAmajority(ir, low_x, after_low_x, before_high_x);
|
||||||
|
|
||||||
|
const IR::U32 t = [&] {
|
||||||
|
const IR::U32 w_element = ir.VectorGetElement(32, w, i);
|
||||||
|
const IR::U32 sig = SHAhashSIGMA1(ir, low_y);
|
||||||
|
|
||||||
|
return ir.Add(high_y, ir.Add(sig, ir.Add(choice, w_element)));
|
||||||
|
}();
|
||||||
|
|
||||||
|
const IR::U32 new_low_x = ir.Add(t, ir.Add(SHAhashSIGMA0(ir, low_x), majority));
|
||||||
|
const IR::U32 new_low_y = ir.Add(t, high_x);
|
||||||
|
|
||||||
|
// Shuffle all words left by 1 element: [3, 2, 1, 0] -> [2, 1, 0, 3]
|
||||||
|
const IR::U128 shuffled_x = ir.VectorShuffleWords(x, 0b10010011);
|
||||||
|
const IR::U128 shuffled_y = ir.VectorShuffleWords(y, 0b10010011);
|
||||||
|
|
||||||
|
x = ir.VectorSetElement(32, shuffled_x, 0, new_low_x);
|
||||||
|
y = ir.VectorSetElement(32, shuffled_y, 0, new_low_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (part == SHA256HashPart::Part1) {
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
} // Anonymous namespace
|
} // Anonymous namespace
|
||||||
|
|
||||||
bool TranslatorVisitor::SHA1C(Vec Vm, Vec Vn, Vec Vd) {
|
bool TranslatorVisitor::SHA1C(Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
@ -186,4 +247,16 @@ bool TranslatorVisitor::SHA256SU1(Vec Vm, Vec Vn, Vec Vd) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::SHA256H(Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
const IR::U128 result = SHA256hash(ir, ir.GetQ(Vd), ir.GetQ(Vn), ir.GetQ(Vm), SHA256HashPart::Part1);
|
||||||
|
ir.SetQ(Vd, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TranslatorVisitor::SHA256H2(Vec Vm, Vec Vn, Vec Vd) {
|
||||||
|
const IR::U128 result = SHA256hash(ir, ir.GetQ(Vn), ir.GetQ(Vd), ir.GetQ(Vm), SHA256HashPart::Part2);
|
||||||
|
ir.SetQ(Vd, result);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Dynarmic::A64
|
} // namespace Dynarmic::A64
|
||||||
|
|
Loading…
Reference in a new issue