mirror of
https://github.com/izzy2lost/xemu.git
synced 2026-07-06 00:20:22 -07:00
Merge remote-tracking branch 'remotes/rth/tags/pull-tcg-20190513' into staging
Improve code generation for vector duplication. Add vector expansions for shifts by non-constant scalar. Add vector expansions for shifts by vector. Add integer and vector expansions for absolute value. Several patches in preparation for Altivec. Bug fix for tcg/aarch64 vs min/max. # gpg: Signature made Tue 14 May 2019 00:58:02 BST # gpg: using RSA key 7A481E78868B4DB6A85A05C064DF38E8AF7E215F # gpg: issuer "richard.henderson@linaro.org" # gpg: Good signature from "Richard Henderson <richard.henderson@linaro.org>" [full] # Primary key fingerprint: 7A48 1E78 868B 4DB6 A85A 05C0 64DF 38E8 AF7E 215F * remotes/rth/tags/pull-tcg-20190513: (31 commits) tcg/aarch64: Do not advertise minmax for MO_64 target/xtensa: Use tcg_gen_abs_i32 target/tricore: Use tcg_gen_abs_tl target/s390x: Use tcg_gen_abs_i64 target/ppc: Use tcg_gen_abs_tl target/ppc: Use tcg_gen_abs_i32 target/cris: Use tcg_gen_abs_tl target/arm: Use tcg_gen_abs_i64 and tcg_gen_gvec_abs tcg/aarch64: Support vector absolute value tcg/i386: Support vector absolute value tcg: Add support for vector absolute value tcg: Add support for integer absolute value tcg/i386: Support vector scalar shift opcodes tcg: Add gvec expanders for vector shift by scalar tcg/aarch64: Support vector variable shift opcodes tcg/i386: Support vector variable shift opcodes tcg: Add gvec expanders for variable shift tcg: Add INDEX_op_dupm_vec tcg/aarch64: Implement tcg_out_dupm_vec tcg/i386: Implement tcg_out_dupm_vec ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
@@ -398,6 +398,54 @@ void HELPER(gvec_neg64)(void *d, void *a, uint32_t desc)
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_abs8)(void *d, void *a, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(int8_t)) {
|
||||
int8_t aa = *(int8_t *)(a + i);
|
||||
*(int8_t *)(d + i) = aa < 0 ? -aa : aa;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_abs16)(void *d, void *a, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(int16_t)) {
|
||||
int16_t aa = *(int16_t *)(a + i);
|
||||
*(int16_t *)(d + i) = aa < 0 ? -aa : aa;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_abs32)(void *d, void *a, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(int32_t)) {
|
||||
int32_t aa = *(int32_t *)(a + i);
|
||||
*(int32_t *)(d + i) = aa < 0 ? -aa : aa;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_abs64)(void *d, void *a, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(int64_t)) {
|
||||
int64_t aa = *(int64_t *)(a + i);
|
||||
*(int64_t *)(d + i) = aa < 0 ? -aa : aa;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_mov)(void *d, void *a, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
@@ -725,6 +773,150 @@ void HELPER(gvec_sar64i)(void *d, void *a, uint32_t desc)
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_shl8v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
|
||||
uint8_t sh = *(uint8_t *)(b + i) & 7;
|
||||
*(uint8_t *)(d + i) = *(uint8_t *)(a + i) << sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_shl16v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
|
||||
uint8_t sh = *(uint16_t *)(b + i) & 15;
|
||||
*(uint16_t *)(d + i) = *(uint16_t *)(a + i) << sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_shl32v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
|
||||
uint8_t sh = *(uint32_t *)(b + i) & 31;
|
||||
*(uint32_t *)(d + i) = *(uint32_t *)(a + i) << sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_shl64v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
|
||||
uint8_t sh = *(uint64_t *)(b + i) & 63;
|
||||
*(uint64_t *)(d + i) = *(uint64_t *)(a + i) << sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_shr8v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(uint8_t)) {
|
||||
uint8_t sh = *(uint8_t *)(b + i) & 7;
|
||||
*(uint8_t *)(d + i) = *(uint8_t *)(a + i) >> sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_shr16v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(uint16_t)) {
|
||||
uint8_t sh = *(uint16_t *)(b + i) & 15;
|
||||
*(uint16_t *)(d + i) = *(uint16_t *)(a + i) >> sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_shr32v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(uint32_t)) {
|
||||
uint8_t sh = *(uint32_t *)(b + i) & 31;
|
||||
*(uint32_t *)(d + i) = *(uint32_t *)(a + i) >> sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_shr64v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(uint64_t)) {
|
||||
uint8_t sh = *(uint64_t *)(b + i) & 63;
|
||||
*(uint64_t *)(d + i) = *(uint64_t *)(a + i) >> sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_sar8v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(vec8)) {
|
||||
uint8_t sh = *(uint8_t *)(b + i) & 7;
|
||||
*(int8_t *)(d + i) = *(int8_t *)(a + i) >> sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_sar16v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(int16_t)) {
|
||||
uint8_t sh = *(uint16_t *)(b + i) & 15;
|
||||
*(int16_t *)(d + i) = *(int16_t *)(a + i) >> sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_sar32v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(vec32)) {
|
||||
uint8_t sh = *(uint32_t *)(b + i) & 31;
|
||||
*(int32_t *)(d + i) = *(int32_t *)(a + i) >> sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
void HELPER(gvec_sar64v)(void *d, void *a, void *b, uint32_t desc)
|
||||
{
|
||||
intptr_t oprsz = simd_oprsz(desc);
|
||||
intptr_t i;
|
||||
|
||||
for (i = 0; i < oprsz; i += sizeof(vec64)) {
|
||||
uint8_t sh = *(uint64_t *)(b + i) & 63;
|
||||
*(int64_t *)(d + i) = *(int64_t *)(a + i) >> sh;
|
||||
}
|
||||
clear_high(d, oprsz, desc);
|
||||
}
|
||||
|
||||
/* If vectors are enabled, the compiler fills in -1 for true.
|
||||
Otherwise, we must take care of this by hand. */
|
||||
#ifdef CONFIG_VECTOR16
|
||||
|
||||
@@ -225,6 +225,11 @@ DEF_HELPER_FLAGS_3(gvec_neg16, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(gvec_neg32, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(gvec_neg64, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_3(gvec_abs8, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(gvec_abs16, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(gvec_abs32, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(gvec_abs64, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_3(gvec_not, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_and, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_or, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
@@ -254,6 +259,21 @@ DEF_HELPER_FLAGS_3(gvec_sar16i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(gvec_sar32i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_3(gvec_sar64i, TCG_CALL_NO_RWG, void, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_shl8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_shl16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_shl32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_shl64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_shr8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_shr16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_shr32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_shr64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_sar8v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_sar16v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_sar32v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_sar64v, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
DEF_HELPER_FLAGS_4(gvec_eq8, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_eq16, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
DEF_HELPER_FLAGS_4(gvec_eq32, TCG_CALL_NO_RWG, void, ptr, ptr, ptr, i32)
|
||||
|
||||
@@ -352,8 +352,6 @@ DEF_HELPER_2(neon_ceq_u8, i32, i32, i32)
|
||||
DEF_HELPER_2(neon_ceq_u16, i32, i32, i32)
|
||||
DEF_HELPER_2(neon_ceq_u32, i32, i32, i32)
|
||||
|
||||
DEF_HELPER_1(neon_abs_s8, i32, i32)
|
||||
DEF_HELPER_1(neon_abs_s16, i32, i32)
|
||||
DEF_HELPER_1(neon_clz_u8, i32, i32)
|
||||
DEF_HELPER_1(neon_clz_u16, i32, i32)
|
||||
DEF_HELPER_1(neon_cls_s8, i32, i32)
|
||||
|
||||
@@ -1228,11 +1228,6 @@ NEON_VOP(ceq_u16, neon_u16, 2)
|
||||
NEON_VOP(ceq_u32, neon_u32, 1)
|
||||
#undef NEON_FN
|
||||
|
||||
#define NEON_FN(dest, src, dummy) dest = (src < 0) ? -src : src
|
||||
NEON_VOP1(abs_s8, neon_s8, 4)
|
||||
NEON_VOP1(abs_s16, neon_s16, 2)
|
||||
#undef NEON_FN
|
||||
|
||||
/* Count Leading Sign/Zero Bits. */
|
||||
static inline int do_clz8(uint8_t x)
|
||||
{
|
||||
|
||||
@@ -9468,11 +9468,7 @@ static void handle_2misc_64(DisasContext *s, int opcode, bool u,
|
||||
if (u) {
|
||||
tcg_gen_neg_i64(tcg_rd, tcg_rn);
|
||||
} else {
|
||||
TCGv_i64 tcg_zero = tcg_const_i64(0);
|
||||
tcg_gen_neg_i64(tcg_rd, tcg_rn);
|
||||
tcg_gen_movcond_i64(TCG_COND_GT, tcg_rd, tcg_rn, tcg_zero,
|
||||
tcg_rn, tcg_rd);
|
||||
tcg_temp_free_i64(tcg_zero);
|
||||
tcg_gen_abs_i64(tcg_rd, tcg_rn);
|
||||
}
|
||||
break;
|
||||
case 0x2f: /* FABS */
|
||||
@@ -12366,11 +12362,12 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
|
||||
}
|
||||
break;
|
||||
case 0xb:
|
||||
if (u) { /* NEG */
|
||||
if (u) { /* ABS, NEG */
|
||||
gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_neg, size);
|
||||
return;
|
||||
} else {
|
||||
gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_abs, size);
|
||||
}
|
||||
break;
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == 3) {
|
||||
@@ -12438,17 +12435,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
|
||||
gen_helper_neon_qabs_s32(tcg_res, cpu_env, tcg_op);
|
||||
}
|
||||
break;
|
||||
case 0xb: /* ABS, NEG */
|
||||
if (u) {
|
||||
tcg_gen_neg_i32(tcg_res, tcg_op);
|
||||
} else {
|
||||
TCGv_i32 tcg_zero = tcg_const_i32(0);
|
||||
tcg_gen_neg_i32(tcg_res, tcg_op);
|
||||
tcg_gen_movcond_i32(TCG_COND_GT, tcg_res, tcg_op,
|
||||
tcg_zero, tcg_op, tcg_res);
|
||||
tcg_temp_free_i32(tcg_zero);
|
||||
}
|
||||
break;
|
||||
case 0x2f: /* FABS */
|
||||
gen_helper_vfp_abss(tcg_res, tcg_op);
|
||||
break;
|
||||
@@ -12561,23 +12547,6 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
|
||||
tcg_temp_free_i32(tcg_zero);
|
||||
break;
|
||||
}
|
||||
case 0xb: /* ABS, NEG */
|
||||
if (u) {
|
||||
TCGv_i32 tcg_zero = tcg_const_i32(0);
|
||||
if (size) {
|
||||
gen_helper_neon_sub_u16(tcg_res, tcg_zero, tcg_op);
|
||||
} else {
|
||||
gen_helper_neon_sub_u8(tcg_res, tcg_zero, tcg_op);
|
||||
}
|
||||
tcg_temp_free_i32(tcg_zero);
|
||||
} else {
|
||||
if (size) {
|
||||
gen_helper_neon_abs_s16(tcg_res, tcg_op);
|
||||
} else {
|
||||
gen_helper_neon_abs_s8(tcg_res, tcg_op);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 0x4: /* CLS, CLZ */
|
||||
if (u) {
|
||||
if (size == 0) {
|
||||
|
||||
@@ -3302,29 +3302,30 @@ static bool trans_SUB_zzi(DisasContext *s, arg_rri_esz *a)
|
||||
|
||||
static bool trans_SUBR_zzi(DisasContext *s, arg_rri_esz *a)
|
||||
{
|
||||
static const TCGOpcode vecop_list[] = { INDEX_op_sub_vec, 0 };
|
||||
static const GVecGen2s op[4] = {
|
||||
{ .fni8 = tcg_gen_vec_sub8_i64,
|
||||
.fniv = tcg_gen_sub_vec,
|
||||
.fno = gen_helper_sve_subri_b,
|
||||
.opc = INDEX_op_sub_vec,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_8,
|
||||
.scalar_first = true },
|
||||
{ .fni8 = tcg_gen_vec_sub16_i64,
|
||||
.fniv = tcg_gen_sub_vec,
|
||||
.fno = gen_helper_sve_subri_h,
|
||||
.opc = INDEX_op_sub_vec,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_16,
|
||||
.scalar_first = true },
|
||||
{ .fni4 = tcg_gen_sub_i32,
|
||||
.fniv = tcg_gen_sub_vec,
|
||||
.fno = gen_helper_sve_subri_s,
|
||||
.opc = INDEX_op_sub_vec,
|
||||
.opt_opc = vecop_list,
|
||||
.vece = MO_32,
|
||||
.scalar_first = true },
|
||||
{ .fni8 = tcg_gen_sub_i64,
|
||||
.fniv = tcg_gen_sub_vec,
|
||||
.fno = gen_helper_sve_subri_d,
|
||||
.opc = INDEX_op_sub_vec,
|
||||
.opt_opc = vecop_list,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.vece = MO_64,
|
||||
.scalar_first = true }
|
||||
|
||||
+86
-58
@@ -604,16 +604,6 @@ static void gen_sar(TCGv_i32 dest, TCGv_i32 t0, TCGv_i32 t1)
|
||||
tcg_temp_free_i32(tmp1);
|
||||
}
|
||||
|
||||
static void tcg_gen_abs_i32(TCGv_i32 dest, TCGv_i32 src)
|
||||
{
|
||||
TCGv_i32 c0 = tcg_const_i32(0);
|
||||
TCGv_i32 tmp = tcg_temp_new_i32();
|
||||
tcg_gen_neg_i32(tmp, src);
|
||||
tcg_gen_movcond_i32(TCG_COND_GT, dest, src, c0, src, tmp);
|
||||
tcg_temp_free_i32(c0);
|
||||
tcg_temp_free_i32(tmp);
|
||||
}
|
||||
|
||||
static void shifter_out_im(TCGv_i32 var, int shift)
|
||||
{
|
||||
if (shift == 0) {
|
||||
@@ -5861,27 +5851,31 @@ static void gen_ssra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
|
||||
tcg_gen_add_vec(vece, d, d, a);
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_ssra[] = {
|
||||
INDEX_op_sari_vec, INDEX_op_add_vec, 0
|
||||
};
|
||||
|
||||
const GVecGen2i ssra_op[4] = {
|
||||
{ .fni8 = gen_ssra8_i64,
|
||||
.fniv = gen_ssra_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_sari_vec,
|
||||
.opt_opc = vecop_list_ssra,
|
||||
.vece = MO_8 },
|
||||
{ .fni8 = gen_ssra16_i64,
|
||||
.fniv = gen_ssra_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_sari_vec,
|
||||
.opt_opc = vecop_list_ssra,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_ssra32_i32,
|
||||
.fniv = gen_ssra_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_sari_vec,
|
||||
.opt_opc = vecop_list_ssra,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_ssra64_i64,
|
||||
.fniv = gen_ssra_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.opt_opc = vecop_list_ssra,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_sari_vec,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
|
||||
@@ -5915,27 +5909,31 @@ static void gen_usra_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
|
||||
tcg_gen_add_vec(vece, d, d, a);
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_usra[] = {
|
||||
INDEX_op_shri_vec, INDEX_op_add_vec, 0
|
||||
};
|
||||
|
||||
const GVecGen2i usra_op[4] = {
|
||||
{ .fni8 = gen_usra8_i64,
|
||||
.fniv = gen_usra_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shri_vec,
|
||||
.opt_opc = vecop_list_usra,
|
||||
.vece = MO_8, },
|
||||
{ .fni8 = gen_usra16_i64,
|
||||
.fniv = gen_usra_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shri_vec,
|
||||
.opt_opc = vecop_list_usra,
|
||||
.vece = MO_16, },
|
||||
{ .fni4 = gen_usra32_i32,
|
||||
.fniv = gen_usra_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shri_vec,
|
||||
.opt_opc = vecop_list_usra,
|
||||
.vece = MO_32, },
|
||||
{ .fni8 = gen_usra64_i64,
|
||||
.fniv = gen_usra_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shri_vec,
|
||||
.opt_opc = vecop_list_usra,
|
||||
.vece = MO_64, },
|
||||
};
|
||||
|
||||
@@ -5993,27 +5991,29 @@ static void gen_shr_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
|
||||
}
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_sri[] = { INDEX_op_shri_vec, 0 };
|
||||
|
||||
const GVecGen2i sri_op[4] = {
|
||||
{ .fni8 = gen_shr8_ins_i64,
|
||||
.fniv = gen_shr_ins_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shri_vec,
|
||||
.opt_opc = vecop_list_sri,
|
||||
.vece = MO_8 },
|
||||
{ .fni8 = gen_shr16_ins_i64,
|
||||
.fniv = gen_shr_ins_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shri_vec,
|
||||
.opt_opc = vecop_list_sri,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_shr32_ins_i32,
|
||||
.fniv = gen_shr_ins_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shri_vec,
|
||||
.opt_opc = vecop_list_sri,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_shr64_ins_i64,
|
||||
.fniv = gen_shr_ins_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shri_vec,
|
||||
.opt_opc = vecop_list_sri,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
|
||||
@@ -6069,27 +6069,29 @@ static void gen_shl_ins_vec(unsigned vece, TCGv_vec d, TCGv_vec a, int64_t sh)
|
||||
}
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_sli[] = { INDEX_op_shli_vec, 0 };
|
||||
|
||||
const GVecGen2i sli_op[4] = {
|
||||
{ .fni8 = gen_shl8_ins_i64,
|
||||
.fniv = gen_shl_ins_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shli_vec,
|
||||
.opt_opc = vecop_list_sli,
|
||||
.vece = MO_8 },
|
||||
{ .fni8 = gen_shl16_ins_i64,
|
||||
.fniv = gen_shl_ins_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shli_vec,
|
||||
.opt_opc = vecop_list_sli,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_shl32_ins_i32,
|
||||
.fniv = gen_shl_ins_vec,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shli_vec,
|
||||
.opt_opc = vecop_list_sli,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_shl64_ins_i64,
|
||||
.fniv = gen_shl_ins_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opc = INDEX_op_shli_vec,
|
||||
.opt_opc = vecop_list_sli,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
|
||||
@@ -6156,51 +6158,60 @@ static void gen_mls_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
|
||||
/* Note that while NEON does not support VMLA and VMLS as 64-bit ops,
|
||||
* these tables are shared with AArch64 which does support them.
|
||||
*/
|
||||
|
||||
static const TCGOpcode vecop_list_mla[] = {
|
||||
INDEX_op_mul_vec, INDEX_op_add_vec, 0
|
||||
};
|
||||
|
||||
static const TCGOpcode vecop_list_mls[] = {
|
||||
INDEX_op_mul_vec, INDEX_op_sub_vec, 0
|
||||
};
|
||||
|
||||
const GVecGen3 mla_op[4] = {
|
||||
{ .fni4 = gen_mla8_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.opc = INDEX_op_mul_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mla,
|
||||
.vece = MO_8 },
|
||||
{ .fni4 = gen_mla16_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.opc = INDEX_op_mul_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mla,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_mla32_i32,
|
||||
.fniv = gen_mla_vec,
|
||||
.opc = INDEX_op_mul_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mla,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_mla64_i64,
|
||||
.fniv = gen_mla_vec,
|
||||
.opc = INDEX_op_mul_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mla,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
|
||||
const GVecGen3 mls_op[4] = {
|
||||
{ .fni4 = gen_mls8_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.opc = INDEX_op_mul_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mls,
|
||||
.vece = MO_8 },
|
||||
{ .fni4 = gen_mls16_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.opc = INDEX_op_mul_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mls,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_mls32_i32,
|
||||
.fniv = gen_mls_vec,
|
||||
.opc = INDEX_op_mul_vec,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mls,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_mls64_i64,
|
||||
.fniv = gen_mls_vec,
|
||||
.opc = INDEX_op_mul_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.load_dest = true,
|
||||
.opt_opc = vecop_list_mls,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
|
||||
@@ -6226,19 +6237,25 @@ static void gen_cmtst_vec(unsigned vece, TCGv_vec d, TCGv_vec a, TCGv_vec b)
|
||||
tcg_gen_cmp_vec(TCG_COND_NE, vece, d, d, a);
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_cmtst[] = { INDEX_op_cmp_vec, 0 };
|
||||
|
||||
const GVecGen3 cmtst_op[4] = {
|
||||
{ .fni4 = gen_helper_neon_tst_u8,
|
||||
.fniv = gen_cmtst_vec,
|
||||
.opt_opc = vecop_list_cmtst,
|
||||
.vece = MO_8 },
|
||||
{ .fni4 = gen_helper_neon_tst_u16,
|
||||
.fniv = gen_cmtst_vec,
|
||||
.opt_opc = vecop_list_cmtst,
|
||||
.vece = MO_16 },
|
||||
{ .fni4 = gen_cmtst_i32,
|
||||
.fniv = gen_cmtst_vec,
|
||||
.opt_opc = vecop_list_cmtst,
|
||||
.vece = MO_32 },
|
||||
{ .fni8 = gen_cmtst_i64,
|
||||
.fniv = gen_cmtst_vec,
|
||||
.prefer_i64 = TCG_TARGET_REG_BITS == 64,
|
||||
.opt_opc = vecop_list_cmtst,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
|
||||
@@ -6253,26 +6270,30 @@ static void gen_uqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
|
||||
tcg_temp_free_vec(x);
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_uqadd[] = {
|
||||
INDEX_op_usadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
|
||||
};
|
||||
|
||||
const GVecGen4 uqadd_op[4] = {
|
||||
{ .fniv = gen_uqadd_vec,
|
||||
.fno = gen_helper_gvec_uqadd_b,
|
||||
.opc = INDEX_op_usadd_vec,
|
||||
.write_aofs = true,
|
||||
.opt_opc = vecop_list_uqadd,
|
||||
.vece = MO_8 },
|
||||
{ .fniv = gen_uqadd_vec,
|
||||
.fno = gen_helper_gvec_uqadd_h,
|
||||
.opc = INDEX_op_usadd_vec,
|
||||
.write_aofs = true,
|
||||
.opt_opc = vecop_list_uqadd,
|
||||
.vece = MO_16 },
|
||||
{ .fniv = gen_uqadd_vec,
|
||||
.fno = gen_helper_gvec_uqadd_s,
|
||||
.opc = INDEX_op_usadd_vec,
|
||||
.write_aofs = true,
|
||||
.opt_opc = vecop_list_uqadd,
|
||||
.vece = MO_32 },
|
||||
{ .fniv = gen_uqadd_vec,
|
||||
.fno = gen_helper_gvec_uqadd_d,
|
||||
.opc = INDEX_op_usadd_vec,
|
||||
.write_aofs = true,
|
||||
.opt_opc = vecop_list_uqadd,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
|
||||
@@ -6287,25 +6308,29 @@ static void gen_sqadd_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
|
||||
tcg_temp_free_vec(x);
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_sqadd[] = {
|
||||
INDEX_op_ssadd_vec, INDEX_op_cmp_vec, INDEX_op_add_vec, 0
|
||||
};
|
||||
|
||||
const GVecGen4 sqadd_op[4] = {
|
||||
{ .fniv = gen_sqadd_vec,
|
||||
.fno = gen_helper_gvec_sqadd_b,
|
||||
.opc = INDEX_op_ssadd_vec,
|
||||
.opt_opc = vecop_list_sqadd,
|
||||
.write_aofs = true,
|
||||
.vece = MO_8 },
|
||||
{ .fniv = gen_sqadd_vec,
|
||||
.fno = gen_helper_gvec_sqadd_h,
|
||||
.opc = INDEX_op_ssadd_vec,
|
||||
.opt_opc = vecop_list_sqadd,
|
||||
.write_aofs = true,
|
||||
.vece = MO_16 },
|
||||
{ .fniv = gen_sqadd_vec,
|
||||
.fno = gen_helper_gvec_sqadd_s,
|
||||
.opc = INDEX_op_ssadd_vec,
|
||||
.opt_opc = vecop_list_sqadd,
|
||||
.write_aofs = true,
|
||||
.vece = MO_32 },
|
||||
{ .fniv = gen_sqadd_vec,
|
||||
.fno = gen_helper_gvec_sqadd_d,
|
||||
.opc = INDEX_op_ssadd_vec,
|
||||
.opt_opc = vecop_list_sqadd,
|
||||
.write_aofs = true,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
@@ -6321,25 +6346,29 @@ static void gen_uqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
|
||||
tcg_temp_free_vec(x);
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_uqsub[] = {
|
||||
INDEX_op_ussub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
|
||||
};
|
||||
|
||||
const GVecGen4 uqsub_op[4] = {
|
||||
{ .fniv = gen_uqsub_vec,
|
||||
.fno = gen_helper_gvec_uqsub_b,
|
||||
.opc = INDEX_op_ussub_vec,
|
||||
.opt_opc = vecop_list_uqsub,
|
||||
.write_aofs = true,
|
||||
.vece = MO_8 },
|
||||
{ .fniv = gen_uqsub_vec,
|
||||
.fno = gen_helper_gvec_uqsub_h,
|
||||
.opc = INDEX_op_ussub_vec,
|
||||
.opt_opc = vecop_list_uqsub,
|
||||
.write_aofs = true,
|
||||
.vece = MO_16 },
|
||||
{ .fniv = gen_uqsub_vec,
|
||||
.fno = gen_helper_gvec_uqsub_s,
|
||||
.opc = INDEX_op_ussub_vec,
|
||||
.opt_opc = vecop_list_uqsub,
|
||||
.write_aofs = true,
|
||||
.vece = MO_32 },
|
||||
{ .fniv = gen_uqsub_vec,
|
||||
.fno = gen_helper_gvec_uqsub_d,
|
||||
.opc = INDEX_op_ussub_vec,
|
||||
.opt_opc = vecop_list_uqsub,
|
||||
.write_aofs = true,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
@@ -6355,25 +6384,29 @@ static void gen_sqsub_vec(unsigned vece, TCGv_vec t, TCGv_vec sat,
|
||||
tcg_temp_free_vec(x);
|
||||
}
|
||||
|
||||
static const TCGOpcode vecop_list_sqsub[] = {
|
||||
INDEX_op_sssub_vec, INDEX_op_cmp_vec, INDEX_op_sub_vec, 0
|
||||
};
|
||||
|
||||
const GVecGen4 sqsub_op[4] = {
|
||||
{ .fniv = gen_sqsub_vec,
|
||||
.fno = gen_helper_gvec_sqsub_b,
|
||||
.opc = INDEX_op_sssub_vec,
|
||||
.opt_opc = vecop_list_sqsub,
|
||||
.write_aofs = true,
|
||||
.vece = MO_8 },
|
||||
{ .fniv = gen_sqsub_vec,
|
||||
.fno = gen_helper_gvec_sqsub_h,
|
||||
.opc = INDEX_op_sssub_vec,
|
||||
.opt_opc = vecop_list_sqsub,
|
||||
.write_aofs = true,
|
||||
.vece = MO_16 },
|
||||
{ .fniv = gen_sqsub_vec,
|
||||
.fno = gen_helper_gvec_sqsub_s,
|
||||
.opc = INDEX_op_sssub_vec,
|
||||
.opt_opc = vecop_list_sqsub,
|
||||
.write_aofs = true,
|
||||
.vece = MO_32 },
|
||||
{ .fniv = gen_sqsub_vec,
|
||||
.fno = gen_helper_gvec_sqsub_d,
|
||||
.opc = INDEX_op_sssub_vec,
|
||||
.opt_opc = vecop_list_sqsub,
|
||||
.write_aofs = true,
|
||||
.vece = MO_64 },
|
||||
};
|
||||
@@ -8087,6 +8120,9 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
||||
case NEON_2RM_VNEG:
|
||||
tcg_gen_gvec_neg(size, rd_ofs, rm_ofs, vec_size, vec_size);
|
||||
break;
|
||||
case NEON_2RM_VABS:
|
||||
tcg_gen_gvec_abs(size, rd_ofs, rm_ofs, vec_size, vec_size);
|
||||
break;
|
||||
|
||||
default:
|
||||
elementwise:
|
||||
@@ -8192,14 +8228,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
||||
}
|
||||
tcg_temp_free_i32(tmp2);
|
||||
break;
|
||||
case NEON_2RM_VABS:
|
||||
switch(size) {
|
||||
case 0: gen_helper_neon_abs_s8(tmp, tmp); break;
|
||||
case 1: gen_helper_neon_abs_s16(tmp, tmp); break;
|
||||
case 2: tcg_gen_abs_i32(tmp, tmp); break;
|
||||
default: abort();
|
||||
}
|
||||
break;
|
||||
case NEON_2RM_VCGT0_F:
|
||||
{
|
||||
TCGv_ptr fpstatus = get_fpstatus_ptr(1);
|
||||
|
||||
@@ -1686,18 +1686,11 @@ static int dec_cmp_r(CPUCRISState *env, DisasContext *dc)
|
||||
|
||||
static int dec_abs_r(CPUCRISState *env, DisasContext *dc)
|
||||
{
|
||||
TCGv t0;
|
||||
|
||||
LOG_DIS("abs $r%u, $r%u\n",
|
||||
dc->op1, dc->op2);
|
||||
cris_cc_mask(dc, CC_MASK_NZ);
|
||||
|
||||
t0 = tcg_temp_new();
|
||||
tcg_gen_sari_tl(t0, cpu_R[dc->op1], 31);
|
||||
tcg_gen_xor_tl(cpu_R[dc->op2], cpu_R[dc->op1], t0);
|
||||
tcg_gen_sub_tl(cpu_R[dc->op2], cpu_R[dc->op2], t0);
|
||||
tcg_temp_free(t0);
|
||||
|
||||
tcg_gen_abs_tl(cpu_R[dc->op2], cpu_R[dc->op1]);
|
||||
cris_alu(dc, CC_OP_MOVE,
|
||||
cpu_R[dc->op2], cpu_R[dc->op2], cpu_R[dc->op2], 4);
|
||||
return 2;
|
||||
|
||||
+24
-44
@@ -5075,40 +5075,26 @@ static void gen_ecowx(DisasContext *ctx)
|
||||
/* abs - abs. */
|
||||
static void gen_abs(DisasContext *ctx)
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l1);
|
||||
tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||
gen_set_label(l2);
|
||||
TCGv d = cpu_gpr[rD(ctx->opcode)];
|
||||
TCGv a = cpu_gpr[rA(ctx->opcode)];
|
||||
|
||||
tcg_gen_abs_tl(d, a);
|
||||
if (unlikely(Rc(ctx->opcode) != 0)) {
|
||||
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
|
||||
gen_set_Rc0(ctx, d);
|
||||
}
|
||||
}
|
||||
|
||||
/* abso - abso. */
|
||||
static void gen_abso(DisasContext *ctx)
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
TCGLabel *l3 = gen_new_label();
|
||||
/* Start with XER OV disabled, the most likely case */
|
||||
tcg_gen_movi_tl(cpu_ov, 0);
|
||||
tcg_gen_brcondi_tl(TCG_COND_GE, cpu_gpr[rA(ctx->opcode)], 0, l2);
|
||||
tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rA(ctx->opcode)], 0x80000000, l1);
|
||||
tcg_gen_movi_tl(cpu_ov, 1);
|
||||
tcg_gen_movi_tl(cpu_so, 1);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||
tcg_gen_br(l3);
|
||||
gen_set_label(l2);
|
||||
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||
gen_set_label(l3);
|
||||
TCGv d = cpu_gpr[rD(ctx->opcode)];
|
||||
TCGv a = cpu_gpr[rA(ctx->opcode)];
|
||||
|
||||
tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_ov, a, 0x80000000);
|
||||
tcg_gen_abs_tl(d, a);
|
||||
tcg_gen_or_tl(cpu_so, cpu_so, cpu_ov);
|
||||
if (unlikely(Rc(ctx->opcode) != 0)) {
|
||||
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
|
||||
gen_set_Rc0(ctx, d);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5344,34 +5330,28 @@ static void gen_mulo(DisasContext *ctx)
|
||||
/* nabs - nabs. */
|
||||
static void gen_nabs(DisasContext *ctx)
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
|
||||
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||
gen_set_label(l2);
|
||||
TCGv d = cpu_gpr[rD(ctx->opcode)];
|
||||
TCGv a = cpu_gpr[rA(ctx->opcode)];
|
||||
|
||||
tcg_gen_abs_tl(d, a);
|
||||
tcg_gen_neg_tl(d, d);
|
||||
if (unlikely(Rc(ctx->opcode) != 0)) {
|
||||
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
|
||||
gen_set_Rc0(ctx, d);
|
||||
}
|
||||
}
|
||||
|
||||
/* nabso - nabso. */
|
||||
static void gen_nabso(DisasContext *ctx)
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
tcg_gen_brcondi_tl(TCG_COND_GT, cpu_gpr[rA(ctx->opcode)], 0, l1);
|
||||
tcg_gen_mov_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_neg_tl(cpu_gpr[rD(ctx->opcode)], cpu_gpr[rA(ctx->opcode)]);
|
||||
gen_set_label(l2);
|
||||
TCGv d = cpu_gpr[rD(ctx->opcode)];
|
||||
TCGv a = cpu_gpr[rA(ctx->opcode)];
|
||||
|
||||
tcg_gen_abs_tl(d, a);
|
||||
tcg_gen_neg_tl(d, d);
|
||||
/* nabs never overflows */
|
||||
tcg_gen_movi_tl(cpu_ov, 0);
|
||||
if (unlikely(Rc(ctx->opcode) != 0)) {
|
||||
gen_set_Rc0(ctx, cpu_gpr[rD(ctx->opcode)]);
|
||||
gen_set_Rc0(ctx, d);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -126,19 +126,7 @@ static inline void gen_##name(DisasContext *ctx) \
|
||||
tcg_temp_free_i32(t0); \
|
||||
}
|
||||
|
||||
static inline void gen_op_evabs(TCGv_i32 ret, TCGv_i32 arg1)
|
||||
{
|
||||
TCGLabel *l1 = gen_new_label();
|
||||
TCGLabel *l2 = gen_new_label();
|
||||
|
||||
tcg_gen_brcondi_i32(TCG_COND_GE, arg1, 0, l1);
|
||||
tcg_gen_neg_i32(ret, arg1);
|
||||
tcg_gen_br(l2);
|
||||
gen_set_label(l1);
|
||||
tcg_gen_mov_i32(ret, arg1);
|
||||
gen_set_label(l2);
|
||||
}
|
||||
GEN_SPEOP_ARITH1(evabs, gen_op_evabs);
|
||||
GEN_SPEOP_ARITH1(evabs, tcg_gen_abs_i32);
|
||||
GEN_SPEOP_ARITH1(evneg, tcg_gen_neg_i32);
|
||||
GEN_SPEOP_ARITH1(evextsb, tcg_gen_ext8s_i32);
|
||||
GEN_SPEOP_ARITH1(evextsh, tcg_gen_ext16s_i32);
|
||||
|
||||
@@ -566,10 +566,15 @@ static void glue(glue(gen_, NAME), _vec)(unsigned vece, TCGv_vec t, \
|
||||
} \
|
||||
static void glue(gen_, NAME)(DisasContext *ctx) \
|
||||
{ \
|
||||
static const TCGOpcode vecop_list[] = { \
|
||||
glue(glue(INDEX_op_, NORM), _vec), \
|
||||
glue(glue(INDEX_op_, SAT), _vec), \
|
||||
INDEX_op_cmp_vec, 0 \
|
||||
}; \
|
||||
static const GVecGen4 g = { \
|
||||
.fniv = glue(glue(gen_, NAME), _vec), \
|
||||
.fno = glue(gen_helper_, NAME), \
|
||||
.opc = glue(glue(INDEX_op_, SAT), _vec), \
|
||||
.opt_opc = vecop_list, \
|
||||
.write_aofs = true, \
|
||||
.vece = VECE, \
|
||||
}; \
|
||||
|
||||
@@ -1407,13 +1407,7 @@ static DisasJumpType help_branch(DisasContext *s, DisasCompare *c,
|
||||
|
||||
static DisasJumpType op_abs(DisasContext *s, DisasOps *o)
|
||||
{
|
||||
TCGv_i64 z, n;
|
||||
z = tcg_const_i64(0);
|
||||
n = tcg_temp_new_i64();
|
||||
tcg_gen_neg_i64(n, o->in2);
|
||||
tcg_gen_movcond_i64(TCG_COND_LT, o->out, o->in2, z, n, o->in2);
|
||||
tcg_temp_free_i64(n);
|
||||
tcg_temp_free_i64(z);
|
||||
tcg_gen_abs_i64(o->out, o->in2);
|
||||
return DISAS_NEXT;
|
||||
}
|
||||
|
||||
|
||||
@@ -2415,11 +2415,7 @@ gen_msubadr32s_h(TCGv ret, TCGv r1, TCGv r2, TCGv r3, uint32_t n, uint32_t mode)
|
||||
|
||||
static inline void gen_abs(TCGv ret, TCGv r1)
|
||||
{
|
||||
TCGv temp = tcg_temp_new();
|
||||
TCGv t0 = tcg_const_i32(0);
|
||||
|
||||
tcg_gen_neg_tl(temp, r1);
|
||||
tcg_gen_movcond_tl(TCG_COND_GE, ret, r1, t0, r1, temp);
|
||||
tcg_gen_abs_tl(ret, r1);
|
||||
/* overflow can only happen, if r1 = 0x80000000 */
|
||||
tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, r1, 0x80000000);
|
||||
tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
|
||||
@@ -2430,9 +2426,6 @@ static inline void gen_abs(TCGv ret, TCGv r1)
|
||||
tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
|
||||
/* calc SAV bit */
|
||||
tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
|
||||
|
||||
tcg_temp_free(temp);
|
||||
tcg_temp_free(t0);
|
||||
}
|
||||
|
||||
static inline void gen_absdif(TCGv ret, TCGv r1, TCGv r2)
|
||||
@@ -6617,13 +6610,8 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
|
||||
tcg_gen_movi_tl(cpu_PSW_AV, 0);
|
||||
if (!tricore_feature(env, TRICORE_FEATURE_131)) {
|
||||
/* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
|
||||
tcg_gen_neg_tl(temp, temp3);
|
||||
/* use cpu_PSW_AV to compare against 0 */
|
||||
tcg_gen_movcond_tl(TCG_COND_LT, temp, temp3, cpu_PSW_AV,
|
||||
temp, temp3);
|
||||
tcg_gen_neg_tl(temp2, cpu_gpr_d[r2]);
|
||||
tcg_gen_movcond_tl(TCG_COND_LT, temp2, cpu_gpr_d[r2], cpu_PSW_AV,
|
||||
temp2, cpu_gpr_d[r2]);
|
||||
tcg_gen_abs_tl(temp, temp3);
|
||||
tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
|
||||
tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
|
||||
} else {
|
||||
/* overflow = (D[b] == 0) */
|
||||
@@ -6655,13 +6643,8 @@ static void decode_rr_divide(CPUTriCoreState *env, DisasContext *ctx)
|
||||
tcg_gen_movi_tl(cpu_PSW_AV, 0);
|
||||
if (!tricore_feature(env, TRICORE_FEATURE_131)) {
|
||||
/* overflow = (abs(D[r3+1]) >= abs(D[r2])) */
|
||||
tcg_gen_neg_tl(temp, temp3);
|
||||
/* use cpu_PSW_AV to compare against 0 */
|
||||
tcg_gen_movcond_tl(TCG_COND_LT, temp, temp3, cpu_PSW_AV,
|
||||
temp, temp3);
|
||||
tcg_gen_neg_tl(temp2, cpu_gpr_d[r2]);
|
||||
tcg_gen_movcond_tl(TCG_COND_LT, temp2, cpu_gpr_d[r2], cpu_PSW_AV,
|
||||
temp2, cpu_gpr_d[r2]);
|
||||
tcg_gen_abs_tl(temp, temp3);
|
||||
tcg_gen_abs_tl(temp2, cpu_gpr_d[r2]);
|
||||
tcg_gen_setcond_tl(TCG_COND_GE, cpu_PSW_V, temp, temp2);
|
||||
} else {
|
||||
/* overflow = (D[b] == 0) */
|
||||
|
||||
@@ -1709,14 +1709,7 @@ void restore_state_to_opc(CPUXtensaState *env, TranslationBlock *tb,
|
||||
static void translate_abs(DisasContext *dc, const OpcodeArg arg[],
|
||||
const uint32_t par[])
|
||||
{
|
||||
TCGv_i32 zero = tcg_const_i32(0);
|
||||
TCGv_i32 neg = tcg_temp_new_i32();
|
||||
|
||||
tcg_gen_neg_i32(neg, arg[1].in);
|
||||
tcg_gen_movcond_i32(TCG_COND_GE, arg[0].out,
|
||||
arg[1].in, zero, arg[1].in, neg);
|
||||
tcg_temp_free(neg);
|
||||
tcg_temp_free(zero);
|
||||
tcg_gen_abs_i32(arg[0].out, arg[1].in);
|
||||
}
|
||||
|
||||
static void translate_add(DisasContext *dc, const OpcodeArg arg[],
|
||||
|
||||
@@ -561,6 +561,10 @@ E.g. VECL=1 -> 64 << 1 -> v128, and VECE=2 -> 1 << 2 -> i32.
|
||||
|
||||
Similarly, v0 = -v1.
|
||||
|
||||
* abs_vec v0, v1
|
||||
|
||||
Similarly, v0 = v1 < 0 ? -v1 : v1, in elements across the vector.
|
||||
|
||||
* smin_vec:
|
||||
* umin_vec:
|
||||
|
||||
|
||||
@@ -132,9 +132,10 @@ typedef enum {
|
||||
#define TCG_TARGET_HAS_orc_vec 1
|
||||
#define TCG_TARGET_HAS_not_vec 1
|
||||
#define TCG_TARGET_HAS_neg_vec 1
|
||||
#define TCG_TARGET_HAS_abs_vec 1
|
||||
#define TCG_TARGET_HAS_shi_vec 1
|
||||
#define TCG_TARGET_HAS_shs_vec 0
|
||||
#define TCG_TARGET_HAS_shv_vec 0
|
||||
#define TCG_TARGET_HAS_shv_vec 1
|
||||
#define TCG_TARGET_HAS_cmp_vec 1
|
||||
#define TCG_TARGET_HAS_mul_vec 1
|
||||
#define TCG_TARGET_HAS_sat_vec 1
|
||||
|
||||
+110
-11
@@ -381,6 +381,9 @@ typedef enum {
|
||||
I3207_BLR = 0xd63f0000,
|
||||
I3207_RET = 0xd65f0000,
|
||||
|
||||
/* AdvSIMD load/store single structure. */
|
||||
I3303_LD1R = 0x0d40c000,
|
||||
|
||||
/* Load literal for loading the address at pc-relative offset */
|
||||
I3305_LDR = 0x58000000,
|
||||
I3305_LDR_v64 = 0x5c000000,
|
||||
@@ -533,12 +536,14 @@ typedef enum {
|
||||
I3616_CMEQ = 0x2e208c00,
|
||||
I3616_SMAX = 0x0e206400,
|
||||
I3616_SMIN = 0x0e206c00,
|
||||
I3616_SSHL = 0x0e204400,
|
||||
I3616_SQADD = 0x0e200c00,
|
||||
I3616_SQSUB = 0x0e202c00,
|
||||
I3616_UMAX = 0x2e206400,
|
||||
I3616_UMIN = 0x2e206c00,
|
||||
I3616_UQADD = 0x2e200c00,
|
||||
I3616_UQSUB = 0x2e202c00,
|
||||
I3616_USHL = 0x2e204400,
|
||||
|
||||
/* AdvSIMD two-reg misc. */
|
||||
I3617_CMGT0 = 0x0e208800,
|
||||
@@ -547,6 +552,7 @@ typedef enum {
|
||||
I3617_CMGE0 = 0x2e208800,
|
||||
I3617_CMLE0 = 0x2e20a800,
|
||||
I3617_NOT = 0x2e205800,
|
||||
I3617_ABS = 0x0e20b800,
|
||||
I3617_NEG = 0x2e20b800,
|
||||
|
||||
/* System instructions. */
|
||||
@@ -566,7 +572,14 @@ static inline uint32_t tcg_in32(TCGContext *s)
|
||||
#define tcg_out_insn(S, FMT, OP, ...) \
|
||||
glue(tcg_out_insn_,FMT)(S, glue(glue(glue(I,FMT),_),OP), ## __VA_ARGS__)
|
||||
|
||||
static void tcg_out_insn_3305(TCGContext *s, AArch64Insn insn, int imm19, TCGReg rt)
|
||||
static void tcg_out_insn_3303(TCGContext *s, AArch64Insn insn, bool q,
|
||||
TCGReg rt, TCGReg rn, unsigned size)
|
||||
{
|
||||
tcg_out32(s, insn | (rt & 0x1f) | (rn << 5) | (size << 10) | (q << 30));
|
||||
}
|
||||
|
||||
static void tcg_out_insn_3305(TCGContext *s, AArch64Insn insn,
|
||||
int imm19, TCGReg rt)
|
||||
{
|
||||
tcg_out32(s, insn | (imm19 & 0x7ffff) << 5 | rt);
|
||||
}
|
||||
@@ -799,7 +812,7 @@ static void tcg_out_logicali(TCGContext *s, AArch64Insn insn, TCGType ext,
|
||||
}
|
||||
|
||||
static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
|
||||
TCGReg rd, uint64_t v64)
|
||||
TCGReg rd, tcg_target_long v64)
|
||||
{
|
||||
int op, cmode, imm8;
|
||||
|
||||
@@ -814,6 +827,43 @@ static void tcg_out_dupi_vec(TCGContext *s, TCGType type,
|
||||
}
|
||||
}
|
||||
|
||||
static bool tcg_out_dup_vec(TCGContext *s, TCGType type, unsigned vece,
|
||||
TCGReg rd, TCGReg rs)
|
||||
{
|
||||
int is_q = type - TCG_TYPE_V64;
|
||||
tcg_out_insn(s, 3605, DUP, is_q, rd, rs, 1 << vece, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool tcg_out_dupm_vec(TCGContext *s, TCGType type, unsigned vece,
|
||||
TCGReg r, TCGReg base, intptr_t offset)
|
||||
{
|
||||
TCGReg temp = TCG_REG_TMP;
|
||||
|
||||
if (offset < -0xffffff || offset > 0xffffff) {
|
||||
tcg_out_movi(s, TCG_TYPE_PTR, temp, offset);
|
||||
tcg_out_insn(s, 3502, ADD, 1, temp, temp, base);
|
||||
base = temp;
|
||||
} else {
|
||||
AArch64Insn add_insn = I3401_ADDI;
|
||||
|
||||
if (offset < 0) {
|
||||
add_insn = I3401_SUBI;
|
||||
offset = -offset;
|
||||
}
|
||||
if (offset & 0xfff000) {
|
||||
tcg_out_insn_3401(s, add_insn, 1, temp, base, offset & 0xfff000);
|
||||
base = temp;
|
||||
}
|
||||
if (offset & 0xfff) {
|
||||
tcg_out_insn_3401(s, add_insn, 1, temp, base, offset & 0xfff);
|
||||
base = temp;
|
||||
}
|
||||
}
|
||||
tcg_out_insn(s, 3303, LD1R, type == TCG_TYPE_V128, r, base, vece);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tcg_out_movi(TCGContext *s, TCGType type, TCGReg rd,
|
||||
tcg_target_long value)
|
||||
{
|
||||
@@ -938,10 +988,10 @@ static void tcg_out_ldst(TCGContext *s, AArch64Insn insn, TCGReg rd,
|
||||
tcg_out_ldst_r(s, insn, rd, rn, TCG_TYPE_I64, TCG_REG_TMP);
|
||||
}
|
||||
|
||||
static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
|
||||
static bool tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
|
||||
{
|
||||
if (ret == arg) {
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
switch (type) {
|
||||
case TCG_TYPE_I32:
|
||||
@@ -970,6 +1020,7 @@ static void tcg_out_mov(TCGContext *s, TCGType type, TCGReg ret, TCGReg arg)
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static void tcg_out_ld(TCGContext *s, TCGType type, TCGReg ret,
|
||||
@@ -2099,10 +2150,8 @@ static void tcg_out_op(TCGContext *s, TCGOpcode opc,
|
||||
|
||||
case INDEX_op_mov_i32: /* Always emitted via tcg_out_mov. */
|
||||
case INDEX_op_mov_i64:
|
||||
case INDEX_op_mov_vec:
|
||||
case INDEX_op_movi_i32: /* Always emitted via tcg_out_movi. */
|
||||
case INDEX_op_movi_i64:
|
||||
case INDEX_op_dupi_vec:
|
||||
case INDEX_op_call: /* Always emitted via tcg_out_call. */
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
@@ -2145,6 +2194,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
||||
case INDEX_op_st_vec:
|
||||
tcg_out_st(s, type, a0, a1, a2);
|
||||
break;
|
||||
case INDEX_op_dupm_vec:
|
||||
tcg_out_dupm_vec(s, type, vece, a0, a1, a2);
|
||||
break;
|
||||
case INDEX_op_add_vec:
|
||||
tcg_out_insn(s, 3616, ADD, is_q, vece, a0, a1, a2);
|
||||
break;
|
||||
@@ -2157,6 +2209,9 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
||||
case INDEX_op_neg_vec:
|
||||
tcg_out_insn(s, 3617, NEG, is_q, vece, a0, a1);
|
||||
break;
|
||||
case INDEX_op_abs_vec:
|
||||
tcg_out_insn(s, 3617, ABS, is_q, vece, a0, a1);
|
||||
break;
|
||||
case INDEX_op_and_vec:
|
||||
tcg_out_insn(s, 3616, AND, is_q, 0, a0, a1, a2);
|
||||
break;
|
||||
@@ -2199,9 +2254,6 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
||||
case INDEX_op_not_vec:
|
||||
tcg_out_insn(s, 3617, NOT, is_q, 0, a0, a1);
|
||||
break;
|
||||
case INDEX_op_dup_vec:
|
||||
tcg_out_insn(s, 3605, DUP, is_q, a0, a1, 1 << vece, 0);
|
||||
break;
|
||||
case INDEX_op_shli_vec:
|
||||
tcg_out_insn(s, 3614, SHL, is_q, a0, a1, a2 + (8 << vece));
|
||||
break;
|
||||
@@ -2211,6 +2263,12 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
||||
case INDEX_op_sari_vec:
|
||||
tcg_out_insn(s, 3614, SSHR, is_q, a0, a1, (16 << vece) - a2);
|
||||
break;
|
||||
case INDEX_op_shlv_vec:
|
||||
tcg_out_insn(s, 3616, USHL, is_q, vece, a0, a1, a2);
|
||||
break;
|
||||
case INDEX_op_aa64_sshl_vec:
|
||||
tcg_out_insn(s, 3616, SSHL, is_q, vece, a0, a1, a2);
|
||||
break;
|
||||
case INDEX_op_cmp_vec:
|
||||
{
|
||||
TCGCond cond = args[3];
|
||||
@@ -2245,6 +2303,10 @@ static void tcg_out_vec_op(TCGContext *s, TCGOpcode opc,
|
||||
}
|
||||
}
|
||||
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. */
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
@@ -2261,6 +2323,7 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
|
||||
case INDEX_op_andc_vec:
|
||||
case INDEX_op_orc_vec:
|
||||
case INDEX_op_neg_vec:
|
||||
case INDEX_op_abs_vec:
|
||||
case INDEX_op_not_vec:
|
||||
case INDEX_op_cmp_vec:
|
||||
case INDEX_op_shli_vec:
|
||||
@@ -2270,12 +2333,16 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
|
||||
case INDEX_op_sssub_vec:
|
||||
case INDEX_op_usadd_vec:
|
||||
case INDEX_op_ussub_vec:
|
||||
case INDEX_op_shlv_vec:
|
||||
return 1;
|
||||
case INDEX_op_shrv_vec:
|
||||
case INDEX_op_sarv_vec:
|
||||
return -1;
|
||||
case INDEX_op_mul_vec:
|
||||
case INDEX_op_smax_vec:
|
||||
case INDEX_op_smin_vec:
|
||||
case INDEX_op_umax_vec:
|
||||
case INDEX_op_umin_vec:
|
||||
return 1;
|
||||
case INDEX_op_mul_vec:
|
||||
return vece < MO_64;
|
||||
|
||||
default:
|
||||
@@ -2286,6 +2353,32 @@ int tcg_can_emit_vec_op(TCGOpcode opc, TCGType type, unsigned vece)
|
||||
void tcg_expand_vec_op(TCGOpcode opc, TCGType type, unsigned vece,
|
||||
TCGArg a0, ...)
|
||||
{
|
||||
va_list va;
|
||||
TCGv_vec v0, v1, v2, t1;
|
||||
|
||||
va_start(va, a0);
|
||||
v0 = temp_tcgv_vec(arg_temp(a0));
|
||||
v1 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
|
||||
v2 = temp_tcgv_vec(arg_temp(va_arg(va, TCGArg)));
|
||||
|
||||
switch (opc) {
|
||||
case INDEX_op_shrv_vec:
|
||||
case INDEX_op_sarv_vec:
|
||||
/* Right shifts are negative left shifts for AArch64. */
|
||||
t1 = tcg_temp_new_vec(type);
|
||||
tcg_gen_neg_vec(vece, t1, v2);
|
||||
opc = (opc == INDEX_op_shrv_vec
|
||||
? INDEX_op_shlv_vec : INDEX_op_aa64_sshl_vec);
|
||||
vec_gen_3(opc, type, vece, tcgv_vec_arg(v0),
|
||||
tcgv_vec_arg(v1), tcgv_vec_arg(t1));
|
||||
tcg_temp_free_vec(t1);
|
||||
break;
|
||||
|
||||
default:
|
||||
g_assert_not_reached();
|
||||
}
|
||||
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
|
||||
@@ -2467,15 +2560,21 @@ static const TCGTargetOpDef *tcg_target_op_def(TCGOpcode op)
|
||||
case INDEX_op_smin_vec:
|
||||
case INDEX_op_umax_vec:
|
||||
case INDEX_op_umin_vec:
|
||||
case INDEX_op_shlv_vec:
|
||||
case INDEX_op_shrv_vec:
|
||||
case INDEX_op_sarv_vec:
|
||||
case INDEX_op_aa64_sshl_vec:
|
||||
return &w_w_w;
|
||||
case INDEX_op_not_vec:
|
||||
case INDEX_op_neg_vec:
|
||||
case INDEX_op_abs_vec:
|
||||
case INDEX_op_shli_vec:
|
||||
case INDEX_op_shri_vec:
|
||||
case INDEX_op_sari_vec:
|
||||
return &w_w;
|
||||
case INDEX_op_ld_vec:
|
||||
case INDEX_op_st_vec:
|
||||
case INDEX_op_dupm_vec:
|
||||
return &w_r;
|
||||
case INDEX_op_dup_vec:
|
||||
return &w_wr;
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
/* Target-specific opcodes for host vector expansion. These will be
|
||||
emitted by tcg_expand_vec_op. For those familiar with GCC internals,
|
||||
consider these to be UNSPEC with names. */
|
||||
|
||||
DEF(aa64_sshl_vec, 1, 2, 0, IMPLVEC)
|
||||
|
||||
@@ -2264,10 +2264,11 @@ static inline bool tcg_out_sti(TCGContext *s, TCGType type, TCGArg val,
|
||||
return false;
|
||||
}
|
||||
|
||||
static inline void tcg_out_mov(TCGContext *s, TCGType type,
|
||||
static inline bool tcg_out_mov(TCGContext *s, TCGType type,
|
||||
TCGReg ret, TCGReg arg)
|
||||
{
|
||||
tcg_out_dat_reg(s, COND_AL, ARITH_MOV, ret, 0, arg, SHIFT_IMM_LSL(0));
|
||||
tcg_out_mov_reg(s, COND_AL, ret, arg);
|
||||
return true;
|
||||
}
|
||||
|
||||
static inline void tcg_out_movi(TCGContext *s, TCGType type,
|
||||
|
||||
@@ -182,9 +182,10 @@ extern bool have_avx2;
|
||||
#define TCG_TARGET_HAS_orc_vec 0
|
||||
#define TCG_TARGET_HAS_not_vec 0
|
||||
#define TCG_TARGET_HAS_neg_vec 0
|
||||
#define TCG_TARGET_HAS_abs_vec 1
|
||||
#define TCG_TARGET_HAS_shi_vec 1
|
||||
#define TCG_TARGET_HAS_shs_vec 0
|
||||
#define TCG_TARGET_HAS_shv_vec 0
|
||||
#define TCG_TARGET_HAS_shs_vec 1
|
||||
#define TCG_TARGET_HAS_shv_vec have_avx2
|
||||
#define TCG_TARGET_HAS_cmp_vec 1
|
||||
#define TCG_TARGET_HAS_mul_vec 1
|
||||
#define TCG_TARGET_HAS_sat_vec 1
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user