summaryrefslogtreecommitdiffstats
path: root/tcg/ppc/tcg-target.c.inc
diff options
context:
space:
mode:
Diffstat (limited to 'tcg/ppc/tcg-target.c.inc')
-rw-r--r--tcg/ppc/tcg-target.c.inc90
1 files changed, 51 insertions, 39 deletions
diff --git a/tcg/ppc/tcg-target.c.inc b/tcg/ppc/tcg-target.c.inc
index 19a4a12f15..cf64892295 100644
--- a/tcg/ppc/tcg-target.c.inc
+++ b/tcg/ppc/tcg-target.c.inc
@@ -912,31 +912,41 @@ static void tcg_out_movi_int(TCGContext *s, TCGType type, TCGReg ret,
}
}
-static void tcg_out_dupi_vec(TCGContext *s, TCGType type, TCGReg ret,
- tcg_target_long val)
+static void tcg_out_dupi_vec(TCGContext *s, TCGType type, unsigned vece,
+ TCGReg ret, int64_t val)
{
uint32_t load_insn;
int rel, low;
intptr_t add;
- low = (int8_t)val;
- if (low >= -16 && low < 16) {
- if (val == (tcg_target_long)dup_const(MO_8, low)) {
+ switch (vece) {
+ case MO_8:
+ low = (int8_t)val;
+ if (low >= -16 && low < 16) {
tcg_out32(s, VSPLTISB | VRT(ret) | ((val & 31) << 16));
return;
}
- if (val == (tcg_target_long)dup_const(MO_16, low)) {
+ if (have_isa_3_00) {
+ tcg_out32(s, XXSPLTIB | VRT(ret) | ((val & 0xff) << 11));
+ return;
+ }
+ break;
+
+ case MO_16:
+ low = (int16_t)val;
+ if (low >= -16 && low < 16) {
tcg_out32(s, VSPLTISH | VRT(ret) | ((val & 31) << 16));
return;
}
- if (val == (tcg_target_long)dup_const(MO_32, low)) {
+ break;
+
+ case MO_32:
+ low = (int32_t)val;
+ if (low >= -16 && low < 16) {
tcg_out32(s, VSPLTISW | VRT(ret) | ((val & 31) << 16));
return;
}
- }
- if (have_isa_3_00 && val == (tcg_target_long)dup_const(MO_8, val)) {
- tcg_out32(s, XXSPLTIB | VRT(ret) | ((val & 0xff) << 11));
- return;
+ break;
}
/*
@@ -956,14 +966,15 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type, TCGReg ret,
if (TCG_TARGET_REG_BITS == 64) {
new_pool_label(s, val, rel, s->code_ptr, add);
} else {
- new_pool_l2(s, rel, s->code_ptr, add, val, val);
+ new_pool_l2(s, rel, s->code_ptr, add, val >> 32, val);
}
} else {
load_insn = LVX | VRT(ret) | RB(TCG_REG_TMP1);
if (TCG_TARGET_REG_BITS == 64) {
new_pool_l2(s, rel, s->code_ptr, add, val, val);
} else {
- new_pool_l4(s, rel, s->code_ptr, add, val, val, val, val);
+ new_pool_l4(s, rel, s->code_ptr, add,
+ val >> 32, val, val >> 32, val);
}
}
@@ -987,12 +998,6 @@ static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg ret,
tcg_out_movi_int(s, type, ret, arg, false);
break;
- case TCG_TYPE_V64:
- case TCG_TYPE_V128:
- tcg_debug_assert(ret >= TCG_REG_V0);
- tcg_out_dupi_vec(s, type, ret, arg);
- break;
-
default:
g_assert_not_reached();
}
@@ -2972,8 +2977,6 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc, const TCGArg *args,
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
case INDEX_op_mov_i64:
- case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
- case INDEX_op_movi_i64:
case INDEX_op_call: /* Always emitted via tcg_out_call. */
default:
tcg_abort();
@@ -3321,7 +3324,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
return;
case INDEX_op_mov_vec: /* Always emitted via tcg_out_mov. */
- case INDEX_op_dupi_vec: /* Always emitted via tcg_out_movi. */
case INDEX_op_dup_vec: /* Always emitted via tcg_out_dup_vec. */
default:
g_assert_not_reached();
@@ -3334,13 +3336,22 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
static void expand_vec_shi(TCGType type, unsigned vece, TCGv_vec v0,
TCGv_vec v1, TCGArg imm, TCGOpcode opci)
{
- TCGv_vec t1 = tcg_temp_new_vec(type);
+ TCGv_vec t1;
- /* Splat w/bytes for xxspltib. */
- tcg_gen_dupi_vec(MO_8, t1, imm & ((8 << vece) - 1));
+ if (vece == MO_32) {
+ /*
+ * Only 5 bits are significant, and VSPLTISB can represent -16..15.
+ * So using negative numbers gets us the 4th bit easily.
+ */
+ imm = sextract32(imm, 0, 5);
+ } else {
+ imm &= (8 << vece) - 1;
+ }
+
+ /* Splat w/bytes for xxspltib when 2.07 allows MO_64. */
+ t1 = tcg_constant_vec(type, MO_8, imm);
vec_gen_3(opci, type, vece, tcgv_vec_arg(v0),
tcgv_vec_arg(v1), tcgv_vec_arg(t1));
- tcg_temp_free_vec(t1);
}
static void expand_vec_cmp(TCGType type, unsigned vece, TCGv_vec v0,
@@ -3398,7 +3409,7 @@ static void expand_vec_mul(TCGType type, unsigned vece, TCGv_vec v0,
{
TCGv_vec t1 = tcg_temp_new_vec(type);
TCGv_vec t2 = tcg_temp_new_vec(type);
- TCGv_vec t3, t4;
+ TCGv_vec c0, c16;
switch (vece) {
case MO_8:
@@ -3417,21 +3428,22 @@ static void expand_vec_mul(TCGType type, unsigned vece, TCGv_vec v0,
case MO_32:
tcg_debug_assert(!have_isa_2_07);
- t3 = tcg_temp_new_vec(type);
- t4 = tcg_temp_new_vec(type);
- tcg_gen_dupi_vec(MO_8, t4, -16);
+ /*
+ * Only 5 bits are significant, and VSPLTISB can represent -16..15.
+ * So using -16 is a quick way to represent 16.
+ */
+ c16 = tcg_constant_vec(type, MO_8, -16);
+ c0 = tcg_constant_vec(type, MO_8, 0);
+
vec_gen_3(INDEX_op_rotlv_vec, type, MO_32, tcgv_vec_arg(t1),
- tcgv_vec_arg(v2), tcgv_vec_arg(t4));
+ tcgv_vec_arg(v2), tcgv_vec_arg(c16));
vec_gen_3(INDEX_op_ppc_mulou_vec, type, MO_16, tcgv_vec_arg(t2),
tcgv_vec_arg(v1), tcgv_vec_arg(v2));
- tcg_gen_dupi_vec(MO_8, t3, 0);
- vec_gen_4(INDEX_op_ppc_msum_vec, type, MO_16, tcgv_vec_arg(t3),
- tcgv_vec_arg(v1), tcgv_vec_arg(t1), tcgv_vec_arg(t3));
- vec_gen_3(INDEX_op_shlv_vec, type, MO_32, tcgv_vec_arg(t3),
- tcgv_vec_arg(t3), tcgv_vec_arg(t4));
- tcg_gen_add_vec(MO_32, v0, t2, t3);
- tcg_temp_free_vec(t3);
- tcg_temp_free_vec(t4);
+ vec_gen_4(INDEX_op_ppc_msum_vec, type, MO_16, tcgv_vec_arg(t1),
+ tcgv_vec_arg(v1), tcgv_vec_arg(t1), tcgv_vec_arg(c0));
+ vec_gen_3(INDEX_op_shlv_vec, type, MO_32, tcgv_vec_arg(t1),
+ tcgv_vec_arg(t1), tcgv_vec_arg(c16));
+ tcg_gen_add_vec(MO_32, v0, t1, t2);
break;
default: