aboutsummaryrefslogtreecommitdiff
path: root/tcg/ppc
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2019-09-30 04:21:22 +0000
committerRichard Henderson <richard.henderson@linaro.org>2019-10-14 07:10:40 -0700
commitd7cd6a2f251c54c989fa35858beafe4a25c789af (patch)
treed88c5fa5053bff36f55c02a31af05b22beeb347d /tcg/ppc
parent7097312d37d3021cac9bb30a7f8c4660d2a25cd0 (diff)
tcg/ppc: Update vector support for v3.00 Altivec
These new instructions are conditional only on MSR.VEC and are thus part of the Altivec instruction set, and not VSX. This includes negation and compare not equal. Tested-by: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> Reviewed-by: Aleksandar Markovic <amarkovic@wavecomp.com> Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Diffstat (limited to 'tcg/ppc')
-rw-r--r--tcg/ppc/tcg-target.h2
-rw-r--r--tcg/ppc/tcg-target.inc.c23
2 files changed, 24 insertions, 1 deletions
diff --git a/tcg/ppc/tcg-target.h b/tcg/ppc/tcg-target.h
index 13197eddce..4fa21f0e71 100644
--- a/tcg/ppc/tcg-target.h
+++ b/tcg/ppc/tcg-target.h
@@ -159,7 +159,7 @@ extern bool have_vsx;
#define TCG_TARGET_HAS_andc_vec 1
#define TCG_TARGET_HAS_orc_vec have_isa_2_07
#define TCG_TARGET_HAS_not_vec 1
-#define TCG_TARGET_HAS_neg_vec 0
+#define TCG_TARGET_HAS_neg_vec have_isa_3_00
#define TCG_TARGET_HAS_abs_vec 0
#define TCG_TARGET_HAS_shi_vec 0
#define TCG_TARGET_HAS_shs_vec 0
diff --git a/tcg/ppc/tcg-target.inc.c b/tcg/ppc/tcg-target.inc.c
index 840464aab5..bd9259c60f 100644
--- a/tcg/ppc/tcg-target.inc.c
+++ b/tcg/ppc/tcg-target.inc.c
@@ -499,6 +499,9 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type,
#define VSUBUWM VX4(1152)
#define VSUBUDM VX4(1216) /* v2.07 */
+#define VNEGW (VX4(1538) | (6 << 16)) /* v3.00 */
+#define VNEGD (VX4(1538) | (7 << 16)) /* v3.00 */
+
#define VMAXSB VX4(258)
#define VMAXSH VX4(322)
#define VMAXSW VX4(386)
@@ -528,6 +531,9 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type,
#define VCMPGTUH VX4(582)
#define VCMPGTUW VX4(646)
#define VCMPGTUD VX4(711) /* v2.07 */
+#define VCMPNEB VX4(7) /* v3.00 */
+#define VCMPNEH VX4(71) /* v3.00 */
+#define VCMPNEW VX4(135) /* v3.00 */
#define VSLB VX4(260)
#define VSLH VX4(324)
@@ -2976,6 +2982,8 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
case INDEX_op_shri_vec:
case INDEX_op_sari_vec:
return vece <= MO_32 || have_isa_2_07 ? -1 : 0;
+ case INDEX_op_neg_vec:
+ return vece >= MO_32 && have_isa_3_00;
case INDEX_op_mul_vec:
switch (vece) {
case MO_8:
@@ -3090,7 +3098,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
static const uint32_t
add_op[4] = { VADDUBM, VADDUHM, VADDUWM, VADDUDM },
sub_op[4] = { VSUBUBM, VSUBUHM, VSUBUWM, VSUBUDM },
+ neg_op[4] = { 0, 0, VNEGW, VNEGD },
eq_op[4] = { VCMPEQUB, VCMPEQUH, VCMPEQUW, VCMPEQUD },
+ ne_op[4] = { VCMPNEB, VCMPNEH, VCMPNEW, 0 },
gts_op[4] = { VCMPGTSB, VCMPGTSH, VCMPGTSW, VCMPGTSD },
gtu_op[4] = { VCMPGTUB, VCMPGTUH, VCMPGTUW, VCMPGTUD },
ssadd_op[4] = { VADDSBS, VADDSHS, VADDSWS, 0 },
@@ -3132,6 +3142,11 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
case INDEX_op_sub_vec:
insn = sub_op[vece];
break;
+ case INDEX_op_neg_vec:
+ insn = neg_op[vece];
+ a2 = a1;
+ a1 = 0;
+ break;
case INDEX_op_mul_vec:
tcg_debug_assert(vece == MO_32 && have_isa_2_07);
insn = VMULUWM;
@@ -3194,6 +3209,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
case TCG_COND_EQ:
insn = eq_op[vece];
break;
+ case TCG_COND_NE:
+ insn = ne_op[vece];
+ break;
case TCG_COND_GT:
insn = gts_op[vece];
break;
@@ -3276,6 +3294,10 @@ static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
case TCG_COND_GTU:
break;
case TCG_COND_NE:
+ if (have_isa_3_00 && vece <= MO_32) {
+ break;
+ }
+ /* fall through */
case TCG_COND_LE:
case TCG_COND_LEU:
need_inv = true;
@@ -3599,6 +3621,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
case INDEX_op_dup2_vec:
return &v_v_v;
case INDEX_op_not_vec:
+ case INDEX_op_neg_vec:
case INDEX_op_dup_vec:
return &v_v;
case INDEX_op_ld_vec: