@@ -91,3 +91,6 @@ hsv_d 0110111 ..... ..... 100 00000 1110011 @r2_s
clzw 0110000 00000 ..... 001 ..... 0011011 @r2
ctzw 0110000 00001 ..... 001 ..... 0011011 @r2
cpopw 0110000 00010 ..... 001 ..... 0011011 @r2
+
+packw 0000100 .......... 100 ..... 0111011 @r
+packuw 0100100 .......... 100 ..... 0111011 @r
@@ -602,3 +602,6 @@ cpop 011000 000010 ..... 001 ..... 0010011 @r2
andn 0100000 .......... 111 ..... 0110011 @r
orn 0100000 .......... 110 ..... 0110011 @r
xnor 0100000 .......... 100 ..... 0110011 @r
+pack 0000100 .......... 100 ..... 0110011 @r
+packu 0100100 .......... 100 ..... 0110011 @r
+packh 0000100 .......... 111 ..... 0110011 @r
@@ -53,6 +53,24 @@ static bool trans_xnor(DisasContext *ctx, arg_xnor *a)
return gen_arith(ctx, a, tcg_gen_eqv_tl);
}
+static bool trans_pack(DisasContext *ctx, arg_pack *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_pack);
+}
+
+static bool trans_packu(DisasContext *ctx, arg_packu *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_packu);
+}
+
+static bool trans_packh(DisasContext *ctx, arg_packh *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_packh);
+}
+
/* RV64-only instructions */
#ifdef TARGET_RISCV64
@@ -74,4 +92,16 @@ static bool trans_cpopw(DisasContext *ctx, arg_cpopw *a)
return gen_unary(ctx, a, gen_cpopw);
}
+static bool trans_packw(DisasContext *ctx, arg_packw *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_packw);
+}
+
+static bool trans_packuw(DisasContext *ctx, arg_packuw *a)
+{
+ REQUIRE_EXT(ctx, RVB);
+ return gen_arith(ctx, a, gen_packuw);
+}
+
#endif
@@ -711,6 +711,29 @@ static bool gen_arith_div_uw(DisasContext *ctx, arg_r *a,
#endif
+static void gen_pack(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ tcg_gen_deposit_tl(ret, arg1, arg2,
+ TARGET_LONG_BITS / 2,
+ TARGET_LONG_BITS / 2);
+}
+
+static void gen_packu(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_shri_tl(t, arg1, TARGET_LONG_BITS / 2);
+ tcg_gen_deposit_tl(ret, arg2, t, 0, TARGET_LONG_BITS / 2);
+ tcg_temp_free(t);
+}
+
+static void gen_packh(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_ext8u_tl(t, arg2);
+ tcg_gen_deposit_tl(ret, arg1, t, 8, TARGET_LONG_BITS - 8);
+ tcg_temp_free(t);
+}
+
#ifdef TARGET_RISCV64
static void gen_ctzw(TCGv ret, TCGv arg1)
@@ -732,6 +755,23 @@ static void gen_cpopw(TCGv ret, TCGv arg1)
tcg_gen_ctpop_tl(ret, arg1);
}
+static void gen_packw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_ext16s_i64(t, arg2);
+ tcg_gen_deposit_i64(ret, arg1, t, 16, 48);
+ tcg_temp_free(t);
+}
+
+static void gen_packuw(TCGv ret, TCGv arg1, TCGv arg2)
+{
+ TCGv t = tcg_temp_new();
+ tcg_gen_shri_i64(t, arg1, 16);
+ tcg_gen_deposit_i64(ret, arg2, t, 0, 16);
+ tcg_gen_ext32s_i64(ret, ret);
+ tcg_temp_free(t);
+}
+
#endif
static bool gen_arith(DisasContext *ctx, arg_r *a,