> Subject: [PATCH v2 12/33] target/mips: Implement emulation of nanoMIPS ROTX > instruction > > From: Matthew Fortune <matthew.fort...@mips.com> > > Added a helper for ROTX based on the pseudocode from the > architecture spec. This instraction was not present in previous
instraction -> instruction (this was my fault, since I wrote this commit message for v2) > MIPS instruction sets. > > Signed-off-by: Yongbok Kim <yongbok....@mips.com> > Signed-off-by: Aleksandar Markovic <amarko...@wavecomp.com> > Signed-off-by: Stefan Markovic <smarko...@wavecomp.com> > --- > target/mips/helper.h | 2 ++ > target/mips/op_helper.c | 94 > +++++++++++++++++++++++++++++++++++++++++++++++++ > target/mips/translate.c | 15 ++++++++ > 3 files changed, 111 insertions(+) > Reviewed-by: Aleksandar Markovic <amarko...@wavecomp.com> ... with a hint that, in future, an inline implementation should be considered. > diff --git a/target/mips/helper.h b/target/mips/helper.h > index 5f49234..b2a780a 100644 > --- a/target/mips/helper.h > +++ b/target/mips/helper.h > @@ -40,6 +40,8 @@ DEF_HELPER_FLAGS_1(bitswap, TCG_CALL_NO_RWG_SE, tl, tl) > DEF_HELPER_FLAGS_1(dbitswap, TCG_CALL_NO_RWG_SE, tl, tl) > #endif > > +DEF_HELPER_FLAGS_4(rotx, TCG_CALL_NO_RWG_SE, tl, tl, i32, i32, i32) > + > #ifndef CONFIG_USER_ONLY > /* CP0 helpers */ > DEF_HELPER_1(mfc0_mvpcontrol, tl, env) > diff --git a/target/mips/op_helper.c b/target/mips/op_helper.c > index 0b2663b..b3eef9f 100644 > --- a/target/mips/op_helper.c > +++ b/target/mips/op_helper.c > @@ -249,6 +249,100 @@ target_ulong helper_bitswap(target_ulong rt) > return (int32_t)bitswap(rt); > } > > +target_ulong helper_rotx(target_ulong rs, uint32_t shift, uint32_t shiftx, > + uint32_t stripe) > +{ > + int i; > + uint64_t tmp0 = ((uint64_t)rs) << 32 | ((uint64_t)rs & 0xffffffff); > + uint64_t tmp1 = tmp0; > + for (i = 0; i <= 46; i++) { > + int s; > + if (i & 0x8) { > + s = shift; > + } else { > + s = shiftx; > + } > + > + if (stripe != 0 && !(i & 0x4)) { > + s = ~s; > + } > + if (s & 0x10) { > + if (tmp0 & (1LL << (i + 16))) { > + tmp1 |= 1LL << i; > + } else { > + tmp1 &= ~(1LL << i); > + } > + } > + } > + > + uint64_t tmp2 = tmp1; > + for (i = 0; i <= 38; i++) { > + int s; > + if (i & 0x4) { > + s = shift; > + } else { > + s = shiftx; > + } > + > + if (s & 0x8) { > + if (tmp1 & (1LL << (i + 8))) { > + tmp2 |= 1LL << i; > + } else { > + tmp2 &= ~(1LL << i); > + } > + } > + } > + > + uint64_t tmp3 = tmp2; > + for (i = 0; i <= 34; i++) { > + int s; > + if (i & 0x2) { > + s = shift; > + } else { > + s = shiftx; > + } > + if (s & 0x4) { > + if (tmp2 & (1LL << (i + 4))) { > + tmp3 |= 1LL << i; > + } else { > + tmp3 &= ~(1LL << i); > + } > + } > + } > + > + uint64_t tmp4 = tmp3; > + for (i = 0; i <= 32; i++) { > + int s; > + if (i & 0x1) { > + s = shift; > + } else { > + s = shiftx; > + } > + if (s & 0x2) { > + if (tmp3 & (1LL << (i + 2))) { > + tmp4 |= 1LL << i; > + } else { > + tmp4 &= ~(1LL << i); > + } > + } > + } > + > + uint64_t tmp5 = tmp4; > + for (i = 0; i <= 31; i++) { > + int s; > + s = shift; > + if (s & 0x1) { > + if (tmp4 & (1LL << (i + 1))) { > + tmp5 |= 1LL << i; > + } else { > + tmp5 &= ~(1LL << i); > + } > + } > + } > + > + return (int64_t)(int32_t)(uint32_t)tmp5; > +} > + > #ifndef CONFIG_USER_ONLY > > static inline hwaddr do_translate_address(CPUMIPSState *env, > diff --git a/target/mips/translate.c b/target/mips/translate.c > index 0a37f5a..944b40b 100644 > --- a/target/mips/translate.c > +++ b/target/mips/translate.c > @@ -17437,6 +17437,21 @@ static int decode_nanomips_32_48_opc(CPUMIPSState > *env, > DisasContext *ctx) > } > break; > case NM_P_ROTX: > + if (rt != 0) { > + TCGv t0 = tcg_temp_new(); > + TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5)); > + TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4) > + << 1); > + TCGv_i32 stripe = tcg_const_i32((ctx->opcode >> 6) & 1); > + > + gen_load_gpr(t0, rs); > + gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe); > + tcg_temp_free(t0); > + > + tcg_temp_free_i32(shift); > + tcg_temp_free_i32(shiftx); > + tcg_temp_free_i32(stripe); > + } > break; > case NM_P_INS: > switch (((ctx->opcode >> 10) & 2) | ((ctx->opcode >> 5) & 1)) { > -- > 2.7.4 > >