提交 377ef731 编写于 作者: R Richard Henderson

target/arm: Use vector infrastructure for aa64 mov/not/neg

Reviewed-by: NAlex Bennée <alex.bennee@linaro.org>
Reviewed-by: NPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: NRichard Henderson <richard.henderson@linaro.org>
上级 bc48092f
...@@ -86,6 +86,7 @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32); ...@@ -86,6 +86,7 @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32);
typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr); typedef void CryptoThreeOpFn(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(unsigned, uint32_t, uint32_t, uint32_t, uint32_t);
typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t, typedef void GVecGen3Fn(unsigned, uint32_t, uint32_t,
uint32_t, uint32_t, uint32_t); uint32_t, uint32_t, uint32_t);
...@@ -631,6 +632,14 @@ static TCGv_ptr get_fpstatus_ptr(void) ...@@ -631,6 +632,14 @@ static TCGv_ptr get_fpstatus_ptr(void)
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)
{
gvec_fn(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)
...@@ -4596,14 +4605,17 @@ static void handle_fp_1src_double(DisasContext *s, int opcode, int rd, int rn) ...@@ -4596,14 +4605,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(); fpst = get_fpstatus_ptr();
tcg_op = read_fp_dreg(s, rn); tcg_op = read_fp_dreg(s, rn);
tcg_res = tcg_temp_new_i64(); tcg_res = tcg_temp_new_i64();
switch (opcode) { switch (opcode) {
case 0x0: /* FMOV */
tcg_gen_mov_i64(tcg_res, tcg_op);
break;
case 0x1: /* FABS */ case 0x1: /* FABS */
gen_helper_vfp_absd(tcg_res, tcg_op); gen_helper_vfp_absd(tcg_res, tcg_op);
break; break;
...@@ -9185,7 +9197,11 @@ static void disas_simd_3same_logic(DisasContext *s, uint32_t insn) ...@@ -9185,7 +9197,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);
...@@ -10059,8 +10075,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) ...@@ -10059,8 +10075,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 */
...@@ -10312,6 +10327,21 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) ...@@ -10312,6 +10327,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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册