mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-01-12 22:45:38 +00:00
tcg/aarch64: Support vector bitwise select value
The instruction set has 3 insns that perform the same operation, only varying in which operand must overlap the destination. We can represent the operation without overlap and choose based on the operands seen. Backports commit a9e434a5dc16f71ee156428619fc3c3765b68f26 from qemu
This commit is contained in:
parent
c79510378f
commit
0ea4c05dc3
qemu/tcg/aarch64
|
@ -140,7 +140,7 @@ typedef enum {
|
|||
#define TCG_TARGET_HAS_mul_vec 1
|
||||
#define TCG_TARGET_HAS_sat_vec 1
|
||||
#define TCG_TARGET_HAS_minmax_vec 1
|
||||
#define TCG_TARGET_HAS_bitsel_vec 0
|
||||
#define TCG_TARGET_HAS_bitsel_vec 1
|
||||
#define TCG_TARGET_HAS_cmpsel_vec 0
|
||||
|
||||
#define TCG_TARGET_DEFAULT_MO (0)
|
||||
|
|
|
@ -520,6 +520,9 @@ typedef enum {
|
|||
I3616_ADD = 0x0e208400,
|
||||
I3616_AND = 0x0e201c00,
|
||||
I3616_BIC = 0x0e601c00,
|
||||
I3616_BIF = 0x2ee01c00,
|
||||
I3616_BIT = 0x2ea01c00,
|
||||
I3616_BSL = 0x2e601c00,
|
||||
I3616_EOR = 0x2e201c00,
|
||||
I3616_MUL = 0x0e209c00,
|
||||
I3616_ORR = 0x0ea01c00,
|
||||
|
@ -2163,7 +2166,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;
|
||||
TCGArg a0, a1, a2, a3;
|
||||
|
||||
a0 = args[0];
|
||||
a1 = args[1];
|
||||
|
@ -2286,6 +2289,20 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
|||
}
|
||||
break;
|
||||
|
||||
case INDEX_op_bitsel_vec:
|
||||
a3 = args[3];
|
||||
if (a0 == a3) {
|
||||
tcg_out_insn(s, 3616, BIT, is_q, 0, a0, a2, a1);
|
||||
} else if (a0 == a2) {
|
||||
tcg_out_insn(s, 3616, BIF, is_q, 0, a0, a3, a1);
|
||||
} else {
|
||||
if (a0 != a1) {
|
||||
tcg_out_mov(s, type, a0, a1);
|
||||
}
|
||||
tcg_out_insn(s, 3616, BSL, is_q, 0, a0, a2, a3);
|
||||
}
|
||||
break;
|
||||
|
||||
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. */
|
||||
|
@ -2316,6 +2333,7 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
|
|||
case INDEX_op_usadd_vec:
|
||||
case INDEX_op_ussub_vec:
|
||||
case INDEX_op_shlv_vec:
|
||||
case INDEX_op_bitsel_vec:
|
||||
return 1;
|
||||
case INDEX_op_shrv_vec:
|
||||
case INDEX_op_sarv_vec:
|
||||
|
@ -2390,6 +2408,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
|
|||
= { .args_ct_str = { "r", "r", "rA", "rZ", "rZ" } };
|
||||
static const TCGTargetOpDef add2
|
||||
= { .args_ct_str = { "r", "r", "rZ", "rZ", "rA", "rMZ" } };
|
||||
static const TCGTargetOpDef w_w_w_w
|
||||
= { .args_ct_str = { "w", "w", "w", "w" } };
|
||||
|
||||
switch (op) {
|
||||
case INDEX_op_goto_ptr:
|
||||
|
@ -2562,6 +2582,8 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
|
|||
return &w_wr;
|
||||
case INDEX_op_cmp_vec:
|
||||
return &w_w_wZ;
|
||||
case INDEX_op_bitsel_vec:
|
||||
return &w_w_w_w;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
|
|
Loading…
Reference in a new issue