Skip to content

Commit

Permalink
tcg/aarch64: Allow immediates for vector ORR and BIC
Browse files Browse the repository at this point in the history
The allows immediates to be used for ORR and BIC,
as well as the trivial inversions, ORC and AND.

Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
  • Loading branch information
rth7680 committed May 22, 2019
1 parent 02f3a5b commit 9e27f58
Showing 1 changed file with 83 additions and 7 deletions.
90 changes: 83 additions & 7 deletions tcg/aarch64/tcg-target.inc.c
Expand Up @@ -119,6 +119,8 @@ static inline bool patch_reloc(tcg_insn_unit *code_ptr, int type,
#define TCG_CT_CONST_LIMM 0x200
#define TCG_CT_CONST_ZERO 0x400
#define TCG_CT_CONST_MONE 0x800
#define TCG_CT_CONST_ORRI 0x1000
#define TCG_CT_CONST_ANDI 0x2000

/* parse target specific constraints */
static const char *target_parse_constraint(TCGArgConstraint *ct,
Expand Down Expand Up @@ -154,6 +156,12 @@ static const char *target_parse_constraint(TCGArgConstraint *ct,
case 'M': /* minus one */
ct->ct |= TCG_CT_CONST_MONE;
break;
case 'O': /* vector orr/bic immediate */
ct->ct |= TCG_CT_CONST_ORRI;
break;
case 'N': /* vector orr/bic immediate, inverted */
ct->ct |= TCG_CT_CONST_ANDI;
break;
case 'Z': /* zero */
ct->ct |= TCG_CT_CONST_ZERO;
break;
Expand Down Expand Up @@ -293,6 +301,16 @@ static int is_shimm32_pair(uint32_t v32, int *cmode, int *imm8)
return i;
}

/* Return true if V is a valid 16-bit or 32-bit shifted immediate. */
static bool is_shimm1632(uint32_t v32, int *cmode, int *imm8)
{
if (v32 == deposit32(v32, 16, 16, v32)) {
return is_shimm16(v32, cmode, imm8);
} else {
return is_shimm32(v32, cmode, imm8);
}
}

static int tcg_target_const_match(tcg_target_long val, TCGType type,
const TCGArgConstraint *arg_ct)
{
Expand All @@ -317,6 +335,23 @@ static int tcg_target_const_match(tcg_target_long val, TCGType type,
return 1;
}

switch (ct & (TCG_CT_CONST_ORRI | TCG_CT_CONST_ANDI)) {
case 0:
break;
case TCG_CT_CONST_ANDI:
val = ~val;
/* fallthru */
case TCG_CT_CONST_ORRI:
if (val == deposit64(val, 32, 32, val)) {
int cmode, imm8;
return is_shimm1632(val, &cmode, &imm8);
}
break;
default:
/* Both bits should not be set for the same insn. */
g_assert_not_reached();
}

return 0;
}

Expand Down Expand Up @@ -2278,6 +2313,7 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
TCGType type = vecl + TCG_TYPE_V64;
unsigned is_q = vecl;
TCGArg a0, a1, a2, a3;
int cmode, imm8;

a0 = args[0];
a1 = args[1];
Expand Down Expand Up @@ -2309,20 +2345,56 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
tcg_out_insn(s, 3617, ABS, is_q, vece, a0, a1);
break;
case INDEX_op_and_vec:
if (const_args[2]) {
is_shimm1632(~a2, &cmode, &imm8);
if (a0 == a1) {
tcg_out_insn(s, 3606, BIC, is_q, a0, 0, cmode, imm8);
return;
}
tcg_out_insn(s, 3606, MVNI, is_q, a0, 0, cmode, imm8);
a2 = a0;
}
tcg_out_insn(s, 3616, AND, is_q, 0, a0, a1, a2);
break;
case INDEX_op_or_vec:
if (const_args[2]) {
is_shimm1632(a2, &cmode, &imm8);
if (a0 == a1) {
tcg_out_insn(s, 3606, ORR, is_q, a0, 0, cmode, imm8);
return;
}
tcg_out_insn(s, 3606, MOVI, is_q, a0, 0, cmode, imm8);
a2 = a0;
}
tcg_out_insn(s, 3616, ORR, is_q, 0, a0, a1, a2);
break;
case INDEX_op_xor_vec:
tcg_out_insn(s, 3616, EOR, is_q, 0, a0, a1, a2);
break;
case INDEX_op_andc_vec:
if (const_args[2]) {
is_shimm1632(a2, &cmode, &imm8);
if (a0 == a1) {
tcg_out_insn(s, 3606, BIC, is_q, a0, 0, cmode, imm8);
return;
}
tcg_out_insn(s, 3606, MOVI, is_q, a0, 0, cmode, imm8);
a2 = a0;
}
tcg_out_insn(s, 3616, BIC, is_q, 0, a0, a1, a2);
break;
case INDEX_op_orc_vec:
if (const_args[2]) {
is_shimm1632(~a2, &cmode, &imm8);
if (a0 == a1) {
tcg_out_insn(s, 3606, ORR, is_q, a0, 0, cmode, imm8);
return;
}
tcg_out_insn(s, 3606, MVNI, is_q, a0, 0, cmode, imm8);
a2 = a0;
}
tcg_out_insn(s, 3616, ORN, is_q, 0, a0, a1, a2);
break;
case INDEX_op_xor_vec:
tcg_out_insn(s, 3616, EOR, is_q, 0, a0, a1, a2);
break;
case INDEX_op_ssadd_vec:
tcg_out_insn(s, 3616, SQADD, is_q, vece, a0, a1, a2);
break;
Expand Down Expand Up @@ -2505,6 +2577,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
static const TCGTargetOpDef lZ_l = { .args_ct_str = { "lZ", "l" } };
static const TCGTargetOpDef r_r_r = { .args_ct_str = { "r", "r", "r" } };
static const TCGTargetOpDef w_w_w = { .args_ct_str = { "w", "w", "w" } };
static const TCGTargetOpDef w_w_wO = { .args_ct_str = { "w", "w", "wO" } };
static const TCGTargetOpDef w_w_wN = { .args_ct_str = { "w", "w", "wN" } };
static const TCGTargetOpDef w_w_wZ = { .args_ct_str = { "w", "w", "wZ" } };
static const TCGTargetOpDef r_r_ri = { .args_ct_str = { "r", "r", "ri" } };
static const TCGTargetOpDef r_r_rA = { .args_ct_str = { "r", "r", "rA" } };
Expand Down Expand Up @@ -2660,11 +2734,7 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
case INDEX_op_add_vec:
case INDEX_op_sub_vec:
case INDEX_op_mul_vec:
case INDEX_op_and_vec:
case INDEX_op_or_vec:
case INDEX_op_xor_vec:
case INDEX_op_andc_vec:
case INDEX_op_orc_vec:
case INDEX_op_ssadd_vec:
case INDEX_op_sssub_vec:
case INDEX_op_usadd_vec:
Expand All @@ -2691,6 +2761,12 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
return &w_r;
case INDEX_op_dup_vec:
return &w_wr;
case INDEX_op_or_vec:
case INDEX_op_andc_vec:
return &w_w_wO;
case INDEX_op_and_vec:
case INDEX_op_orc_vec:
return &w_w_wN;
case INDEX_op_cmp_vec:
return &w_w_wZ;
case INDEX_op_bitsel_vec:
Expand Down

0 comments on commit 9e27f58

Please sign in to comment.