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>
This commit is contained in:
parent
7097312d37
commit
d7cd6a2f25
|
@ -159,7 +159,7 @@ extern bool have_vsx;
|
||||||
#define TCG_TARGET_HAS_andc_vec 1
|
#define TCG_TARGET_HAS_andc_vec 1
|
||||||
#define TCG_TARGET_HAS_orc_vec have_isa_2_07
|
#define TCG_TARGET_HAS_orc_vec have_isa_2_07
|
||||||
#define TCG_TARGET_HAS_not_vec 1
|
#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_abs_vec 0
|
||||||
#define TCG_TARGET_HAS_shi_vec 0
|
#define TCG_TARGET_HAS_shi_vec 0
|
||||||
#define TCG_TARGET_HAS_shs_vec 0
|
#define TCG_TARGET_HAS_shs_vec 0
|
||||||
|
|
|
@ -499,6 +499,9 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type,
|
||||||
#define VSUBUWM VX4(1152)
|
#define VSUBUWM VX4(1152)
|
||||||
#define VSUBUDM VX4(1216) /* v2.07 */
|
#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 VMAXSB VX4(258)
|
||||||
#define VMAXSH VX4(322)
|
#define VMAXSH VX4(322)
|
||||||
#define VMAXSW VX4(386)
|
#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 VCMPGTUH VX4(582)
|
||||||
#define VCMPGTUW VX4(646)
|
#define VCMPGTUW VX4(646)
|
||||||
#define VCMPGTUD VX4(711) /* v2.07 */
|
#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 VSLB VX4(260)
|
||||||
#define VSLH VX4(324)
|
#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_shri_vec:
|
||||||
case INDEX_op_sari_vec:
|
case INDEX_op_sari_vec:
|
||||||
return vece <= MO_32 || have_isa_2_07 ? -1 : 0;
|
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:
|
case INDEX_op_mul_vec:
|
||||||
switch (vece) {
|
switch (vece) {
|
||||||
case MO_8:
|
case MO_8:
|
||||||
|
@ -3090,7 +3098,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
||||||
static const uint32_t
|
static const uint32_t
|
||||||
add_op[4] = { VADDUBM, VADDUHM, VADDUWM, VADDUDM },
|
add_op[4] = { VADDUBM, VADDUHM, VADDUWM, VADDUDM },
|
||||||
sub_op[4] = { VSUBUBM, VSUBUHM, VSUBUWM, VSUBUDM },
|
sub_op[4] = { VSUBUBM, VSUBUHM, VSUBUWM, VSUBUDM },
|
||||||
|
neg_op[4] = { 0, 0, VNEGW, VNEGD },
|
||||||
eq_op[4] = { VCMPEQUB, VCMPEQUH, VCMPEQUW, VCMPEQUD },
|
eq_op[4] = { VCMPEQUB, VCMPEQUH, VCMPEQUW, VCMPEQUD },
|
||||||
|
ne_op[4] = { VCMPNEB, VCMPNEH, VCMPNEW, 0 },
|
||||||
gts_op[4] = { VCMPGTSB, VCMPGTSH, VCMPGTSW, VCMPGTSD },
|
gts_op[4] = { VCMPGTSB, VCMPGTSH, VCMPGTSW, VCMPGTSD },
|
||||||
gtu_op[4] = { VCMPGTUB, VCMPGTUH, VCMPGTUW, VCMPGTUD },
|
gtu_op[4] = { VCMPGTUB, VCMPGTUH, VCMPGTUW, VCMPGTUD },
|
||||||
ssadd_op[4] = { VADDSBS, VADDSHS, VADDSWS, 0 },
|
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:
|
case INDEX_op_sub_vec:
|
||||||
insn = sub_op[vece];
|
insn = sub_op[vece];
|
||||||
break;
|
break;
|
||||||
|
case INDEX_op_neg_vec:
|
||||||
|
insn = neg_op[vece];
|
||||||
|
a2 = a1;
|
||||||
|
a1 = 0;
|
||||||
|
break;
|
||||||
case INDEX_op_mul_vec:
|
case INDEX_op_mul_vec:
|
||||||
tcg_debug_assert(vece == MO_32 && have_isa_2_07);
|
tcg_debug_assert(vece == MO_32 && have_isa_2_07);
|
||||||
insn = VMULUWM;
|
insn = VMULUWM;
|
||||||
|
@ -3194,6 +3209,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
||||||
case TCG_COND_EQ:
|
case TCG_COND_EQ:
|
||||||
insn = eq_op[vece];
|
insn = eq_op[vece];
|
||||||
break;
|
break;
|
||||||
|
case TCG_COND_NE:
|
||||||
|
insn = ne_op[vece];
|
||||||
|
break;
|
||||||
case TCG_COND_GT:
|
case TCG_COND_GT:
|
||||||
insn = gts_op[vece];
|
insn = gts_op[vece];
|
||||||
break;
|
break;
|
||||||
|
@ -3276,6 +3294,10 @@ static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
|
||||||
case TCG_COND_GTU:
|
case TCG_COND_GTU:
|
||||||
break;
|
break;
|
||||||
case TCG_COND_NE:
|
case TCG_COND_NE:
|
||||||
|
if (have_isa_3_00 && vece <= MO_32) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
/* fall through */
|
||||||
case TCG_COND_LE:
|
case TCG_COND_LE:
|
||||||
case TCG_COND_LEU:
|
case TCG_COND_LEU:
|
||||||
need_inv = true;
|
need_inv = true;
|
||||||
|
@ -3599,6 +3621,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
|
||||||
case INDEX_op_dup2_vec:
|
case INDEX_op_dup2_vec:
|
||||||
return &v_v_v;
|
return &v_v_v;
|
||||||
case INDEX_op_not_vec:
|
case INDEX_op_not_vec:
|
||||||
|
case INDEX_op_neg_vec:
|
||||||
case INDEX_op_dup_vec:
|
case INDEX_op_dup_vec:
|
||||||
return &v_v;
|
return &v_v;
|
||||||
case INDEX_op_ld_vec:
|
case INDEX_op_ld_vec:
|
||||||
|
|
Loading…
Reference in a new issue