From d640045a3ede028293b83e57e9ae1ce4f81044b8 Mon Sep 17 00:00:00 2001 From: Aurelien Jarno Date: Sun, 31 Mar 2013 12:58:31 +0200 Subject: target-i386: add AES-NI instructions Reviewed-by: Edgar E. Iglesias Reviewed-by: Richard Henderson Signed-off-by: Aurelien Jarno --- target-i386/ops_sse.h | 87 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'target-i386/ops_sse.h') diff --git a/target-i386/ops_sse.h b/target-i386/ops_sse.h index 2ee5b8d9dd..eb24b5f721 100644 --- a/target-i386/ops_sse.h +++ b/target-i386/ops_sse.h @@ -2203,6 +2203,93 @@ void glue(helper_pclmulqdq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, d->Q(0) = resl; d->Q(1) = resh; } + +/* AES-NI op helpers */ +static const uint8_t aes_shifts[16] = { + 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11 +}; + +static const uint8_t aes_ishifts[16] = { + 0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3 +}; + +void glue(helper_aesdec, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) +{ + int i; + Reg st = *d; + Reg rk = *s; + + for (i = 0 ; i < 4 ; i++) { + d->L(i) = rk.L(i) ^ bswap32(AES_Td0[st.B(aes_ishifts[4*i+0])] ^ + AES_Td1[st.B(aes_ishifts[4*i+1])] ^ + AES_Td2[st.B(aes_ishifts[4*i+2])] ^ + AES_Td3[st.B(aes_ishifts[4*i+3])]); + } +} + +void glue(helper_aesdeclast, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) +{ + int i; + Reg st = *d; + Reg rk = *s; + + for (i = 0; i < 16; i++) { + d->B(i) = rk.B(i) ^ (AES_Td4[st.B(aes_ishifts[i])] & 0xff); + } +} + +void glue(helper_aesenc, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) +{ + int i; + Reg st = *d; + Reg rk = *s; + + for (i = 0 ; i < 4 ; i++) { + d->L(i) = rk.L(i) ^ bswap32(AES_Te0[st.B(aes_shifts[4*i+0])] ^ + AES_Te1[st.B(aes_shifts[4*i+1])] ^ + AES_Te2[st.B(aes_shifts[4*i+2])] ^ + AES_Te3[st.B(aes_shifts[4*i+3])]); + } +} + +void glue(helper_aesenclast, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) +{ + int i; + Reg st = *d; + Reg rk = *s; + + for (i = 0; i < 16; i++) { + d->B(i) = rk.B(i) ^ (AES_Te4[st.B(aes_shifts[i])] & 0xff); + } + +} + +void glue(helper_aesimc, SUFFIX)(CPUX86State *env, Reg *d, Reg *s) +{ + int i; + Reg tmp = *s; + + for (i = 0 ; i < 4 ; i++) { + d->L(i) = bswap32(AES_Td0[AES_Te4[tmp.B(4*i+0)] & 0xff] ^ + AES_Td1[AES_Te4[tmp.B(4*i+1)] & 0xff] ^ + AES_Td2[AES_Te4[tmp.B(4*i+2)] & 0xff] ^ + AES_Td3[AES_Te4[tmp.B(4*i+3)] & 0xff]); + } +} + +void glue(helper_aeskeygenassist, SUFFIX)(CPUX86State *env, Reg *d, Reg *s, + uint32_t ctrl) +{ + int i; + Reg tmp = *s; + + for (i = 0 ; i < 4 ; i++) { + d->B(i) = AES_Te4[tmp.B(i + 4)] & 0xff; + d->B(i + 8) = AES_Te4[tmp.B(i + 12)] & 0xff; + } + d->L(1) = (d->L(0) << 24 | d->L(0) >> 8) ^ ctrl; + d->L(3) = (d->L(2) << 24 | d->L(2) >> 8) ^ ctrl; +} #endif #undef SHIFT -- cgit v1.2.1