diff options
author | Víctor Colombo <victor.colombo@eldorado.org.br> | 2022-07-15 17:54:38 -0300 |
---|---|---|
committer | Daniel Henrique Barboza <danielhb413@gmail.com> | 2022-09-20 10:54:06 -0300 |
commit | 670f1da374d9e9a7d509ef6f03d871144284f8d6 (patch) | |
tree | 12b4fa10d1c493d45c0952e73c5b2ccd46995ba8 /target | |
parent | 903f84eb88c8d43fa2e46d4c30969de30dbb5297 (diff) | |
download | qemu-670f1da374d9e9a7d509ef6f03d871144284f8d6.zip qemu-670f1da374d9e9a7d509ef6f03d871144284f8d6.tar.gz qemu-670f1da374d9e9a7d509ef6f03d871144284f8d6.tar.bz2 |
target/ppc: Implement hashst and hashchk
Implementation for instructions hashst and hashchk, which were added
in Power ISA 3.1B.
It was decided to implement the hash algorithm from ground up in this
patch exactly as described in Power ISA.
Signed-off-by: Víctor Colombo <victor.colombo@eldorado.org.br>
Reviewed-by: Lucas Mateus Castro <lucas.araujo@eldorado.org.br>
Message-Id: <20220715205439.161110-3-victor.colombo@eldorado.org.br>
[danielhb: fix block comment in excp_helper.c]
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
Diffstat (limited to 'target')
-rw-r--r-- | target/ppc/excp_helper.c | 81 | ||||
-rw-r--r-- | target/ppc/helper.h | 2 | ||||
-rw-r--r-- | target/ppc/insn32.decode | 8 | ||||
-rw-r--r-- | target/ppc/translate.c | 5 | ||||
-rw-r--r-- | target/ppc/translate/fixedpoint-impl.c.inc | 32 |
5 files changed, 128 insertions, 0 deletions
diff --git a/target/ppc/excp_helper.c b/target/ppc/excp_helper.c index 7550aaf..7a16991 100644 --- a/target/ppc/excp_helper.c +++ b/target/ppc/excp_helper.c @@ -2173,6 +2173,87 @@ void helper_td(CPUPPCState *env, target_ulong arg1, target_ulong arg2, #endif #endif +static uint32_t helper_SIMON_LIKE_32_64(uint32_t x, uint64_t key, uint32_t lane) +{ + const uint16_t c = 0xfffc; + const uint64_t z0 = 0xfa2561cdf44ac398ULL; + uint16_t z = 0, temp; + uint16_t k[32], eff_k[32], xleft[33], xright[33], fxleft[32]; + + for (int i = 3; i >= 0; i--) { + k[i] = key & 0xffff; + key >>= 16; + } + xleft[0] = x & 0xffff; + xright[0] = (x >> 16) & 0xffff; + + for (int i = 0; i < 28; i++) { + z = (z0 >> (63 - i)) & 1; + temp = ror16(k[i + 3], 3) ^ k[i + 1]; + k[i + 4] = c ^ z ^ k[i] ^ temp ^ ror16(temp, 1); + } + + for (int i = 0; i < 8; i++) { + eff_k[4 * i + 0] = k[4 * i + ((0 + lane) % 4)]; + eff_k[4 * i + 1] = k[4 * i + ((1 + lane) % 4)]; + eff_k[4 * i + 2] = k[4 * i + ((2 + lane) % 4)]; + eff_k[4 * i + 3] = k[4 * i + ((3 + lane) % 4)]; + } + + for (int i = 0; i < 32; i++) { + fxleft[i] = (rol16(xleft[i], 1) & + rol16(xleft[i], 8)) ^ rol16(xleft[i], 2); + xleft[i + 1] = xright[i] ^ fxleft[i] ^ eff_k[i]; + xright[i + 1] = xleft[i]; + } + + return (((uint32_t)xright[32]) << 16) | xleft[32]; +} + +static uint64_t hash_digest(uint64_t ra, uint64_t rb, uint64_t key) +{ + uint64_t stage0_h = 0ULL, stage0_l = 0ULL; + uint64_t stage1_h, stage1_l; + + for (int i = 0; i < 4; i++) { + stage0_h |= ror64(rb & 0xff, 8 * (2 * i + 1)); + stage0_h |= ((ra >> 32) & 0xff) << (8 * 2 * i); + stage0_l |= ror64((rb >> 32) & 0xff, 8 * (2 * i + 1)); + stage0_l |= (ra & 0xff) << (8 * 2 * i); + rb >>= 8; + ra >>= 8; + } + + stage1_h = (uint64_t)helper_SIMON_LIKE_32_64(stage0_h >> 32, key, 0) << 32; + stage1_h |= helper_SIMON_LIKE_32_64(stage0_h, key, 1); + stage1_l = (uint64_t)helper_SIMON_LIKE_32_64(stage0_l >> 32, key, 2) << 32; + stage1_l |= helper_SIMON_LIKE_32_64(stage0_l, key, 3); + + return stage1_h ^ stage1_l; +} + +#include "qemu/guest-random.h" + +#define HELPER_HASH(op, key, store) \ +void helper_##op(CPUPPCState *env, target_ulong ea, target_ulong ra, \ + target_ulong rb) \ +{ \ + uint64_t calculated_hash = hash_digest(ra, rb, key), loaded_hash; \ + \ + if (store) { \ + cpu_stq_data_ra(env, ea, calculated_hash, GETPC()); \ + } else { \ + loaded_hash = cpu_ldq_data_ra(env, ea, GETPC()); \ + if (loaded_hash != calculated_hash) { \ + raise_exception_err_ra(env, POWERPC_EXCP_PROGRAM, \ + POWERPC_EXCP_TRAP, GETPC()); \ + } \ + } \ +} + +HELPER_HASH(HASHST, env->spr[SPR_HASHKEYR], true) +HELPER_HASH(HASHCHK, env->spr[SPR_HASHKEYR], false) + #if !defined(CONFIG_USER_ONLY) #ifdef CONFIG_TCG diff --git a/target/ppc/helper.h b/target/ppc/helper.h index 159b352..5817af6 100644 --- a/target/ppc/helper.h +++ b/target/ppc/helper.h @@ -4,6 +4,8 @@ DEF_HELPER_FLAGS_4(tw, TCG_CALL_NO_WG, void, env, tl, tl, i32) #if defined(TARGET_PPC64) DEF_HELPER_FLAGS_4(td, TCG_CALL_NO_WG, void, env, tl, tl, i32) #endif +DEF_HELPER_4(HASHST, void, env, tl, tl, tl) +DEF_HELPER_4(HASHCHK, void, env, tl, tl, tl) #if !defined(CONFIG_USER_ONLY) DEF_HELPER_2(store_msr, void, env, tl) DEF_HELPER_1(rfi, void, env) diff --git a/target/ppc/insn32.decode b/target/ppc/insn32.decode index eb41efc..5445145 100644 --- a/target/ppc/insn32.decode +++ b/target/ppc/insn32.decode @@ -172,6 +172,9 @@ @X_TSX ...... ..... ra:5 rb:5 .......... . &X rt=%x_rt_tsx @X_TSXP ...... ..... ra:5 rb:5 .......... . &X rt=%rt_tsxp +%x_dw 0:1 21:5 !function=dw_compose_ea +@X_DW ...... ..... ra:5 rb:5 .......... . &X rt=%x_dw + &X_frtp_vrb frtp vrb @X_frtp_vrb ...... ....0 ..... vrb:5 .......... . &X_frtp_vrb frtp=%x_frtp @@ -323,6 +326,11 @@ CNTTZDM 011111 ..... ..... ..... 1000111011 - @X PDEPD 011111 ..... ..... ..... 0010011100 - @X PEXTD 011111 ..... ..... ..... 0010111100 - @X +# Fixed-Point Hash Instructions + +HASHST 011111 ..... ..... ..... 1011010010 . @X_DW +HASHCHK 011111 ..... ..... ..... 1011110010 . @X_DW + ## BCD Assist ADDG6S 011111 ..... ..... ..... - 001001010 - @X diff --git a/target/ppc/translate.c b/target/ppc/translate.c index 000b1e5..29939bd 100644 --- a/target/ppc/translate.c +++ b/target/ppc/translate.c @@ -6473,6 +6473,11 @@ static int times_16(DisasContext *ctx, int x) return x * 16; } +static int64_t dw_compose_ea(DisasContext *ctx, int x) +{ + return deposit64(0xfffffffffffffe00, 3, 6, x); +} + /* * Helpers for trans_* functions to check for specific insns flags. * Use token pasting to ensure that we use the proper flag with the diff --git a/target/ppc/translate/fixedpoint-impl.c.inc b/target/ppc/translate/fixedpoint-impl.c.inc index db14d3b..41c06de 100644 --- a/target/ppc/translate/fixedpoint-impl.c.inc +++ b/target/ppc/translate/fixedpoint-impl.c.inc @@ -540,3 +540,35 @@ static bool trans_CBCDTD(DisasContext *ctx, arg_X_sa *a) gen_helper_CBCDTD(cpu_gpr[a->ra], cpu_gpr[a->rs]); return true; } + +static bool do_hash(DisasContext *ctx, arg_X *a, bool priv, + void (*helper)(TCGv_ptr, TCGv, TCGv, TCGv)) +{ + TCGv ea; + + if (!(ctx->insns_flags2 & PPC2_ISA310)) { + /* if version is before v3.1, this operation is a nop */ + return true; + } + + if (priv) { + /* if instruction is privileged but the context is in user space */ + REQUIRE_SV(ctx); + } + + if (unlikely(a->ra == 0)) { + /* if RA=0, the instruction form is invalid */ + gen_invalid(ctx); + return true; + } + + ea = do_ea_calc(ctx, a->ra, tcg_constant_tl(a->rt)); + helper(cpu_env, ea, cpu_gpr[a->ra], cpu_gpr[a->rb]); + + tcg_temp_free(ea); + + return true; +} + +TRANS(HASHST, do_hash, false, gen_helper_HASHST) +TRANS(HASHCHK, do_hash, false, gen_helper_HASHCHK) |