mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2024-10-19 13:28:27 +02:00
target/arm: Use vector infrastructure for aa64 mov/not/neg
Backports commit 377ef731a85773788ae328e638698d27691bd77d from qemu
This commit is contained in:
parent
03b76589b4
commit
84f848d876
@ -83,6 +83,7 @@ typedef void CryptoThreeOpIntFn(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_i32);
|
|||||||
typedef void CryptoThreeOpFn(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_ptr);
|
typedef void CryptoThreeOpFn(TCGContext *, TCGv_ptr, TCGv_ptr, TCGv_ptr);
|
||||||
|
|
||||||
/* Note that the gvec expanders operate on offsets + sizes. */
|
/* Note that the gvec expanders operate on offsets + sizes. */
|
||||||
|
typedef void GVecGen2Fn(TCGContext *, unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
|
||||||
typedef void GVecGen3Fn(TCGContext *, unsigned, uint32_t, uint32_t,
|
typedef void GVecGen3Fn(TCGContext *, unsigned, uint32_t, uint32_t,
|
||||||
uint32_t, uint32_t, uint32_t);
|
uint32_t, uint32_t, uint32_t);
|
||||||
|
|
||||||
@ -664,6 +665,16 @@ static TCGv_ptr get_fpstatus_ptr(TCGContext *tcg_ctx)
|
|||||||
return statusptr;
|
return statusptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Expand a 2-operand AdvSIMD vector operation using an expander function. */
|
||||||
|
static void gen_gvec_fn2(DisasContext *s, bool is_q, int rd, int rn,
|
||||||
|
GVecGen2Fn *gvec_fn, int vece)
|
||||||
|
{
|
||||||
|
TCGContext *tcg_ctx = s->uc->tcg_ctx;
|
||||||
|
|
||||||
|
gvec_fn(tcg_ctx, vece, vec_full_reg_offset(s, rd), vec_full_reg_offset(s, rn),
|
||||||
|
is_q ? 16 : 8, vec_full_reg_size(s));
|
||||||
|
}
|
||||||
|
|
||||||
/* Expand a 3-operand AdvSIMD vector operation using an expander function. */
|
/* Expand a 3-operand AdvSIMD vector operation using an expander function. */
|
||||||
static void gen_gvec_fn3(DisasContext *s, bool is_q, int rd, int rn, int rm,
|
static void gen_gvec_fn3(DisasContext *s, bool is_q, int rd, int rn, int rm,
|
||||||
GVecGen3Fn *gvec_fn, int vece)
|
GVecGen3Fn *gvec_fn, int vece)
|
||||||
@ -4686,14 +4697,17 @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn)
|
|||||||
TCGv_i64 tcg_op;
|
TCGv_i64 tcg_op;
|
||||||
TCGv_i64 tcg_res;
|
TCGv_i64 tcg_res;
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x0: /* FMOV */
|
||||||
|
gen_gvec_fn2(s, false, rd, rn, tcg_gen_gvec_mov, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fpst = get_fpstatus_ptr(tcg_ctx);
|
fpst = get_fpstatus_ptr(tcg_ctx);
|
||||||
tcg_op = read_fp_dreg(s, rn);
|
tcg_op = read_fp_dreg(s, rn);
|
||||||
tcg_res = tcg_temp_new_i64(tcg_ctx);
|
tcg_res = tcg_temp_new_i64(tcg_ctx);
|
||||||
|
|
||||||
switch (opcode) {
|
switch (opcode) {
|
||||||
case 0x0: /* FMOV */
|
|
||||||
tcg_gen_mov_i64(tcg_ctx, tcg_res, tcg_op);
|
|
||||||
break;
|
|
||||||
case 0x1: /* FABS */
|
case 0x1: /* FABS */
|
||||||
gen_helper_vfp_absd(tcg_ctx, tcg_res, tcg_op);
|
gen_helper_vfp_absd(tcg_ctx, tcg_res, tcg_op);
|
||||||
break;
|
break;
|
||||||
@ -9320,7 +9334,11 @@ static void disas_simd_3same_logic(DisasContext *s, uint32_t insn)
|
|||||||
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_andc, 0);
|
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_andc, 0);
|
||||||
return;
|
return;
|
||||||
case 2: /* ORR */
|
case 2: /* ORR */
|
||||||
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0);
|
if (rn == rm) { /* MOV */
|
||||||
|
gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_mov, 0);
|
||||||
|
} else {
|
||||||
|
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_or, 0);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case 3: /* ORN */
|
case 3: /* ORN */
|
||||||
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0);
|
gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0);
|
||||||
@ -10202,8 +10220,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
|
|||||||
return;
|
return;
|
||||||
case 0x5: /* CNT, NOT, RBIT */
|
case 0x5: /* CNT, NOT, RBIT */
|
||||||
if (u && size == 0) {
|
if (u && size == 0) {
|
||||||
/* NOT: adjust size so we can use the 64-bits-at-a-time loop. */
|
/* NOT */
|
||||||
size = 3;
|
|
||||||
break;
|
break;
|
||||||
} else if (u && size == 1) {
|
} else if (u && size == 1) {
|
||||||
/* RBIT */
|
/* RBIT */
|
||||||
@ -10455,6 +10472,21 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn)
|
|||||||
tcg_rmode = NULL;
|
tcg_rmode = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (opcode) {
|
||||||
|
case 0x5:
|
||||||
|
if (u && size == 0) { /* NOT */
|
||||||
|
gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_not, 0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xb:
|
||||||
|
if (u) { /* NEG */
|
||||||
|
gen_gvec_fn2(s, is_q, rd, rn, tcg_gen_gvec_neg, size);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (size == 3) {
|
if (size == 3) {
|
||||||
/* All 64-bit element operations can be shared with scalar 2misc */
|
/* All 64-bit element operations can be shared with scalar 2misc */
|
||||||
int pass;
|
int pass;
|
||||||
|
Loading…
Reference in New Issue
Block a user