Loading target/arm/neon-dp.decode +3 −0 Original line number Diff line number Diff line Loading @@ -485,5 +485,8 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm VMUL_2sc 1111 001 . 1 . .. .... .... 1000 . 1 . 0 .... @2scalar VMUL_F_2sc 1111 001 . 1 . .. .... .... 1001 . 1 . 0 .... @2scalar VQDMULH_2sc 1111 001 . 1 . .. .... .... 1100 . 1 . 0 .... @2scalar VQRDMULH_2sc 1111 001 . 1 . .. .... .... 1101 . 1 . 0 .... @2scalar ] } target/arm/translate-neon.inc.c +29 −0 Original line number Diff line number Diff line Loading @@ -2546,3 +2546,32 @@ static bool trans_VMLS_F_2sc(DisasContext *s, arg_2scalar *a) return do_2scalar(s, a, opfn[a->size], accfn[a->size]); } WRAP_ENV_FN(gen_VQDMULH_16, gen_helper_neon_qdmulh_s16) WRAP_ENV_FN(gen_VQDMULH_32, gen_helper_neon_qdmulh_s32) WRAP_ENV_FN(gen_VQRDMULH_16, gen_helper_neon_qrdmulh_s16) WRAP_ENV_FN(gen_VQRDMULH_32, gen_helper_neon_qrdmulh_s32) static bool trans_VQDMULH_2sc(DisasContext *s, arg_2scalar *a) { static NeonGenTwoOpFn * const opfn[] = { NULL, gen_VQDMULH_16, gen_VQDMULH_32, NULL, }; return do_2scalar(s, a, opfn[a->size], NULL); } static bool trans_VQRDMULH_2sc(DisasContext *s, arg_2scalar *a) { static NeonGenTwoOpFn * const opfn[] = { NULL, gen_VQRDMULH_16, gen_VQRDMULH_32, NULL, }; return do_2scalar(s, a, opfn[a->size], NULL); } target/arm/translate.c +2 −40 Original line number Diff line number Diff line Loading @@ -2973,19 +2973,6 @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc) #define CPU_V001 cpu_V0, cpu_V0, cpu_V1 static TCGv_i32 neon_load_scratch(int scratch) { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); return tmp; } static void neon_store_scratch(int scratch, TCGv_i32 var) { tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); tcg_temp_free_i32(var); } static int gen_neon_unzip(int rd, int rm, int size, int q) { TCGv_ptr pd, pm; Loading Loading @@ -5190,35 +5177,10 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) case 1: /* Float VMLA scalar */ case 5: /* Floating point VMLS scalar */ case 9: /* Floating point VMUL scalar */ return 1; /* handled by decodetree */ case 12: /* VQDMULH scalar */ case 13: /* VQRDMULH scalar */ if (u && ((rd | rn) & 1)) { return 1; } tmp = neon_get_scalar(size, rm); neon_store_scratch(0, tmp); for (pass = 0; pass < (u ? 4 : 2); pass++) { tmp = neon_load_scratch(0); tmp2 = neon_load_reg(rn, pass); if (op == 12) { if (size == 1) { gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); } else { gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); } } else { if (size == 1) { gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); } else { gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); } } tcg_temp_free_i32(tmp2); neon_store_reg(rd, pass, tmp); } break; return 1; /* handled by decodetree */ case 3: /* VQDMLAL scalar */ case 7: /* VQDMLSL scalar */ case 11: /* VQDMULL scalar */ Loading Loading
target/arm/neon-dp.decode +3 −0 Original line number Diff line number Diff line Loading @@ -485,5 +485,8 @@ Vimm_1r 1111 001 . 1 . 000 ... .... cmode:4 0 . op:1 1 .... @1reg_imm VMUL_2sc 1111 001 . 1 . .. .... .... 1000 . 1 . 0 .... @2scalar VMUL_F_2sc 1111 001 . 1 . .. .... .... 1001 . 1 . 0 .... @2scalar VQDMULH_2sc 1111 001 . 1 . .. .... .... 1100 . 1 . 0 .... @2scalar VQRDMULH_2sc 1111 001 . 1 . .. .... .... 1101 . 1 . 0 .... @2scalar ] }
target/arm/translate-neon.inc.c +29 −0 Original line number Diff line number Diff line Loading @@ -2546,3 +2546,32 @@ static bool trans_VMLS_F_2sc(DisasContext *s, arg_2scalar *a) return do_2scalar(s, a, opfn[a->size], accfn[a->size]); } WRAP_ENV_FN(gen_VQDMULH_16, gen_helper_neon_qdmulh_s16) WRAP_ENV_FN(gen_VQDMULH_32, gen_helper_neon_qdmulh_s32) WRAP_ENV_FN(gen_VQRDMULH_16, gen_helper_neon_qrdmulh_s16) WRAP_ENV_FN(gen_VQRDMULH_32, gen_helper_neon_qrdmulh_s32) static bool trans_VQDMULH_2sc(DisasContext *s, arg_2scalar *a) { static NeonGenTwoOpFn * const opfn[] = { NULL, gen_VQDMULH_16, gen_VQDMULH_32, NULL, }; return do_2scalar(s, a, opfn[a->size], NULL); } static bool trans_VQRDMULH_2sc(DisasContext *s, arg_2scalar *a) { static NeonGenTwoOpFn * const opfn[] = { NULL, gen_VQRDMULH_16, gen_VQRDMULH_32, NULL, }; return do_2scalar(s, a, opfn[a->size], NULL); }
target/arm/translate.c +2 −40 Original line number Diff line number Diff line Loading @@ -2973,19 +2973,6 @@ static void gen_exception_return(DisasContext *s, TCGv_i32 pc) #define CPU_V001 cpu_V0, cpu_V0, cpu_V1 static TCGv_i32 neon_load_scratch(int scratch) { TCGv_i32 tmp = tcg_temp_new_i32(); tcg_gen_ld_i32(tmp, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); return tmp; } static void neon_store_scratch(int scratch, TCGv_i32 var) { tcg_gen_st_i32(var, cpu_env, offsetof(CPUARMState, vfp.scratch[scratch])); tcg_temp_free_i32(var); } static int gen_neon_unzip(int rd, int rm, int size, int q) { TCGv_ptr pd, pm; Loading Loading @@ -5190,35 +5177,10 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn) case 1: /* Float VMLA scalar */ case 5: /* Floating point VMLS scalar */ case 9: /* Floating point VMUL scalar */ return 1; /* handled by decodetree */ case 12: /* VQDMULH scalar */ case 13: /* VQRDMULH scalar */ if (u && ((rd | rn) & 1)) { return 1; } tmp = neon_get_scalar(size, rm); neon_store_scratch(0, tmp); for (pass = 0; pass < (u ? 4 : 2); pass++) { tmp = neon_load_scratch(0); tmp2 = neon_load_reg(rn, pass); if (op == 12) { if (size == 1) { gen_helper_neon_qdmulh_s16(tmp, cpu_env, tmp, tmp2); } else { gen_helper_neon_qdmulh_s32(tmp, cpu_env, tmp, tmp2); } } else { if (size == 1) { gen_helper_neon_qrdmulh_s16(tmp, cpu_env, tmp, tmp2); } else { gen_helper_neon_qrdmulh_s32(tmp, cpu_env, tmp, tmp2); } } tcg_temp_free_i32(tmp2); neon_store_reg(rd, pass, tmp); } break; return 1; /* handled by decodetree */ case 3: /* VQDMLAL scalar */ case 7: /* VQDMLSL scalar */ case 11: /* VQDMULL scalar */ Loading