On 9/2/21 2:40 PM, Song Gao wrote:
+static void gen_clz_w(TCGv dest, TCGv src1)
+{
+ tcg_gen_clzi_tl(dest, src1, TARGET_LONG_BITS);
+ tcg_gen_subi_tl(dest, dest, TARGET_LONG_BITS - 32);
+}
+
+static void gen_clo_w(TCGv dest, TCGv src1)
+{
+ tcg_gen_not_tl(dest, src1);
+ gen_clz_w(dest, dest);
+}
This doesn't work, quite. You need
tcg_gen_not_tl(dest, src1);
tcg_gen_ext32u_tl(dest, dest);
gen_clz_w(dest, dest);
+static void gen_ctz_w(TCGv dest, TCGv src1)
+{
+ tcg_gen_ori_tl(dest, src1, (target_ulong)MAKE_64BIT_MASK(32, 32));
+ tcg_gen_ctzi_tl(dest, dest, 64);
+}
+
+static void gen_cto_w(TCGv dest, TCGv src1)
+{
+ tcg_gen_not_tl(dest, src1);
+ gen_ctz_w(dest, dest);
+}
Likewise, this needs the OR after the NOT.
Alternately, zero-extend and use
tcg_gen_ctzi_tl(dest, dest, 32);
+static void gen_revb_2w(TCGv dest, TCGv src1)
+{
+ tcg_gen_bswap64_i64(dest, src1);
+ tcg_gen_rotri_i64(dest, dest, 32);
+}
+
+static bool trans_revb_2h(DisasContext *ctx, arg_revb_2h *a)
+{
+ ctx->dst_ext = EXT_SIGN;
+ TCGv dest = gpr_dst(ctx, a->rd);
+ TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+ TCGv mask = tcg_constant_tl(0x00FF00FF);
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+
+ tcg_gen_shri_tl(t0, src1, 8);
+ tcg_gen_and_tl(t0, t0, mask);
+ tcg_gen_and_tl(t1, src1, mask);
+ tcg_gen_shli_tl(t1, t1, 8);
+ tcg_gen_or_tl(dest, t0, t1);
+ gen_set_gpr(ctx, a->rd, dest);
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ return true;
+}
Split out the center of this so you can use gen_r2.
+static bool trans_revb_4h(DisasContext *ctx, arg_revb_4h *a)
+{
+ TCGv dest = gpr_dst(ctx, a->rd);
+ TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+ TCGv mask = tcg_constant_tl(0x00FF00FF00FF00FFULL);
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+
+ tcg_gen_shri_tl(t0, src1, 8);
+ tcg_gen_and_tl(t0, t0, mask);
+ tcg_gen_and_tl(t1, src1, mask);
+ tcg_gen_shli_tl(t1, t1, 8);
+ tcg_gen_or_tl(dest, t0, t1);
+
+ tcg_temp_free(t0);
+ tcg_temp_free(t1);
+ return true;
+}
Likewise.
+static bool trans_revh_2w(DisasContext *ctx, arg_revh_2w *a)
+{
+ TCGv dest = gpr_dst(ctx, a->rd);
+ TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+ TCGv_i64 t0 = tcg_temp_new_i64();
+ TCGv_i64 t1 = tcg_temp_new_i64();
+ TCGv_i64 mask = tcg_constant_i64(0x0000ffff0000ffffull);
+
+ tcg_gen_shri_i64(t0, src1, 16);
+ tcg_gen_and_i64(t1, src1, mask);
+ tcg_gen_and_i64(t0, t0, mask);
+ tcg_gen_shli_i64(t1, t1, 16);
+ tcg_gen_or_i64(dest, t1, t0);
+
+ tcg_temp_free_i64(t0);
+ tcg_temp_free_i64(t1);
+
+ return true;
+}
Likewise.
+
+static bool trans_revh_d(DisasContext *ctx, arg_revh_d *a)
+{
+ TCGv dest = gpr_dst(ctx, a->rd);
+ TCGv src1 = gpr_src(ctx, a->rj, EXT_NONE);
+ TCGv t0 = tcg_temp_new();
+ TCGv t1 = tcg_temp_new();
+ TCGv mask = tcg_constant_tl(0x0000FFFF0000FFFFULL);
+
+ tcg_gen_shri_tl(t1, src1, 16);
+ tcg_gen_and_tl(t1, t1, mask);
+ tcg_gen_and_tl(t0, src1, mask);
+ tcg_gen_shli_tl(t0, t0, 16);
+ tcg_gen_or_tl(t0, t0, t1);
+ tcg_gen_shri_tl(t1, t0, 32);
+ tcg_gen_shli_tl(t0, t0, 32);
+ tcg_gen_or_tl(dest, t0, t1);
This last is rotate by 32.
+static void gen_maskeqz(TCGv dest, TCGv src1, TCGv src2)
+{
+ TCGv cond1 = tcg_constant_tl(0);
+
+ tcg_gen_movcond_tl(TCG_COND_EQ, dest, src2, cond1, cond1, src1);
+}
+
+static void gen_masknez(TCGv dest, TCGv src1, TCGv src2)
+{
+ TCGv cond1 = tcg_constant_tl(0);
+
+ tcg_gen_movcond_tl(TCG_COND_NE, dest, src2, cond1, cond1, src1);
+}
s/cond1/zero/g
r~