summaryrefslogtreecommitdiffstats
path: root/target
diff options
context:
space:
mode:
authorStefan Brankovic2019-07-15 16:22:51 +0200
committerDavid Gibson2019-08-21 09:17:11 +0200
commitb8313f0d91b192c9415b3c678b387acb77ad112b (patch)
tree619f26167704f857e461f04d03e39810b7711c13 /target
parenttarget/ppc: Optimize emulation of vgbbd instruction (diff)
downloadqemu-b8313f0d91b192c9415b3c678b387acb77ad112b.tar.gz
qemu-b8313f0d91b192c9415b3c678b387acb77ad112b.tar.xz
qemu-b8313f0d91b192c9415b3c678b387acb77ad112b.zip
target/ppc: Optimize emulation of vclzd instruction
Optimize Altivec instruction vclzd (Vector Count Leading Zeros Doubleword). This instruction counts the number of leading zeros of each doubleword element in source register and places result in the appropriate doubleword element of destination register. Using tcg-s count leading zeros instruction two times(once for each doubleword element of source register vB) and placing result in appropriate doubleword element of destination register vD. Signed-off-by: Stefan Brankovic <stefan.brankovic@rt-rk.com> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-Id: <1563200574-11098-6-git-send-email-stefan.brankovic@rt-rk.com> Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
Diffstat (limited to 'target')
-rw-r--r--target/ppc/helper.h1
-rw-r--r--target/ppc/int_helper.c3
-rw-r--r--target/ppc/translate/vmx-impl.inc.c28
3 files changed, 27 insertions, 5 deletions
diff --git a/target/ppc/helper.h b/target/ppc/helper.h
index 9b486a0c37..e203f76bf1 100644
--- a/target/ppc/helper.h
+++ b/target/ppc/helper.h
@@ -311,7 +311,6 @@ DEF_HELPER_4(vctsxs, void, env, avr, avr, i32)
DEF_HELPER_2(vclzb, void, avr, avr)
DEF_HELPER_2(vclzh, void, avr, avr)
DEF_HELPER_2(vclzw, void, avr, avr)
-DEF_HELPER_2(vclzd, void, avr, avr)
DEF_HELPER_2(vctzb, void, avr, avr)
DEF_HELPER_2(vctzh, void, avr, avr)
DEF_HELPER_2(vctzw, void, avr, avr)
diff --git a/target/ppc/int_helper.c b/target/ppc/int_helper.c
index a265cb07c5..b82765db33 100644
--- a/target/ppc/int_helper.c
+++ b/target/ppc/int_helper.c
@@ -1820,17 +1820,14 @@ VUPK(lsw, s64, s32, UPKLO)
#define clzb(v) ((v) ? clz32((uint32_t)(v) << 24) : 8)
#define clzh(v) ((v) ? clz32((uint32_t)(v) << 16) : 16)
#define clzw(v) clz32((v))
-#define clzd(v) clz64((v))
VGENERIC_DO(clzb, u8)
VGENERIC_DO(clzh, u16)
VGENERIC_DO(clzw, u32)
-VGENERIC_DO(clzd, u64)
#undef clzb
#undef clzh
#undef clzw
-#undef clzd
#define ctzb(v) ((v) ? ctz32(v) : 8)
#define ctzh(v) ((v) ? ctz32(v) : 16)
diff --git a/target/ppc/translate/vmx-impl.inc.c b/target/ppc/translate/vmx-impl.inc.c
index 13153352e4..3372c2c3d3 100644
--- a/target/ppc/translate/vmx-impl.inc.c
+++ b/target/ppc/translate/vmx-impl.inc.c
@@ -742,6 +742,32 @@ static void trans_vgbbd(DisasContext *ctx)
tcg_temp_free_i64(avr[1]);
}
+/*
+ * vclzd VRT,VRB - Vector Count Leading Zeros Doubleword
+ *
+ * Counting the number of leading zero bits of each doubleword element in source
+ * register and placing result in appropriate doubleword element of destination
+ * register.
+ */
+static void trans_vclzd(DisasContext *ctx)
+{
+ int VT = rD(ctx->opcode);
+ int VB = rB(ctx->opcode);
+ TCGv_i64 avr = tcg_temp_new_i64();
+
+ /* high doubleword */
+ get_avr64(avr, VB, true);
+ tcg_gen_clzi_i64(avr, avr, 64);
+ set_avr64(VT, avr, true);
+
+ /* low doubleword */
+ get_avr64(avr, VB, false);
+ tcg_gen_clzi_i64(avr, avr, 64);
+ set_avr64(VT, avr, false);
+
+ tcg_temp_free_i64(avr);
+}
+
GEN_VXFORM(vmuloub, 4, 0);
GEN_VXFORM(vmulouh, 4, 1);
GEN_VXFORM(vmulouw, 4, 2);
@@ -1258,7 +1284,7 @@ GEN_VAFORM_PAIRED(vmaddfp, vnmsubfp, 23)
GEN_VXFORM_NOA(vclzb, 1, 28)
GEN_VXFORM_NOA(vclzh, 1, 29)
GEN_VXFORM_NOA(vclzw, 1, 30)
-GEN_VXFORM_NOA(vclzd, 1, 31)
+GEN_VXFORM_TRANS(vclzd, 1, 31)
GEN_VXFORM_NOA_2(vnegw, 1, 24, 6)
GEN_VXFORM_NOA_2(vnegd, 1, 24, 7)
GEN_VXFORM_NOA_2(vextsb2w, 1, 24, 16)