Loading target/arm/translate-a64.c +36 −6 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32); typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr); /* 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, uint32_t, uint32_t, uint32_t); Loading Loading @@ -631,6 +632,14 @@ static TCGv_ptr get_fpstatus_ptr(void) 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. */ static void gen_gvec_fn3(DisasContext *s, bool is_q, int rd, int rn, int rm, GVecGen3Fn *gvec_fn, int vece) Loading Loading @@ -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_res; switch (opcode) { case 0x0: /* FMOV */ gen_gvec_fn2(s, false, rd, rn, tcg_gen_gvec_mov, 0); return; } fpst = get_fpstatus_ptr(); tcg_op = read_fp_dreg(s, rn); tcg_res = tcg_temp_new_i64(); switch (opcode) { case 0x0: /* FMOV */ tcg_gen_mov_i64(tcg_res, tcg_op); break; case 0x1: /* FABS */ gen_helper_vfp_absd(tcg_res, tcg_op); break; Loading Loading @@ -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); return; case 2: /* ORR */ 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; case 3: /* ORN */ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0); Loading Loading @@ -10059,8 +10075,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) return; case 0x5: /* CNT, NOT, RBIT */ if (u && size == 0) { /* NOT: adjust size so we can use the 64-bits-at-a-time loop. */ size = 3; /* NOT */ break; } else if (u && size == 1) { /* RBIT */ Loading Loading @@ -10312,6 +10327,21 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) 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) { /* All 64-bit element operations can be shared with scalar 2misc */ int pass; Loading Loading
target/arm/translate-a64.c +36 −6 Original line number Diff line number Diff line Loading @@ -86,6 +86,7 @@ typedef void CryptoThreeOpIntFn(TCGv_ptr, TCGv_ptr, TCGv_i32); typedef void CryptoThreeOpFn(TCGv_ptr, TCGv_ptr, TCGv_ptr); /* 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, uint32_t, uint32_t, uint32_t); Loading Loading @@ -631,6 +632,14 @@ static TCGv_ptr get_fpstatus_ptr(void) 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. */ static void gen_gvec_fn3(DisasContext *s, bool is_q, int rd, int rn, int rm, GVecGen3Fn *gvec_fn, int vece) Loading Loading @@ -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_res; switch (opcode) { case 0x0: /* FMOV */ gen_gvec_fn2(s, false, rd, rn, tcg_gen_gvec_mov, 0); return; } fpst = get_fpstatus_ptr(); tcg_op = read_fp_dreg(s, rn); tcg_res = tcg_temp_new_i64(); switch (opcode) { case 0x0: /* FMOV */ tcg_gen_mov_i64(tcg_res, tcg_op); break; case 0x1: /* FABS */ gen_helper_vfp_absd(tcg_res, tcg_op); break; Loading Loading @@ -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); return; case 2: /* ORR */ 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; case 3: /* ORN */ gen_gvec_fn3(s, is_q, rd, rn, rm, tcg_gen_gvec_orc, 0); Loading Loading @@ -10059,8 +10075,7 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) return; case 0x5: /* CNT, NOT, RBIT */ if (u && size == 0) { /* NOT: adjust size so we can use the 64-bits-at-a-time loop. */ size = 3; /* NOT */ break; } else if (u && size == 1) { /* RBIT */ Loading Loading @@ -10312,6 +10327,21 @@ static void disas_simd_two_reg_misc(DisasContext *s, uint32_t insn) 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) { /* All 64-bit element operations can be shared with scalar 2misc */ int pass; Loading