target/arm: Convert Neon 3-reg-same SHA to decodetree
Convert the Neon SHA instructions in the 3-reg-same group to decodetree. Signed-off-by: Peter Maydell <peter.maydell@linaro.org> Reviewed-by: Richard Henderson <richard.henderson@linaro.org> Message-id: 20200512163904.10918-3-peter.maydell@linaro.org
This commit is contained in:
parent
a063569508
commit
21290edfc2
@ -99,4 +99,14 @@ VMUL_3s 1111 001 0 0 . .. .... .... 1001 . . . 1 .... @3same
|
||||
VMUL_p_3s 1111 001 1 0 . .. .... .... 1001 . . . 1 .... @3same
|
||||
|
||||
VQRDMLAH_3s 1111 001 1 0 . .. .... .... 1011 ... 1 .... @3same
|
||||
|
||||
SHA1_3s 1111 001 0 0 . optype:2 .... .... 1100 . 1 . 0 .... \
|
||||
vm=%vm_dp vn=%vn_dp vd=%vd_dp
|
||||
SHA256H_3s 1111 001 1 0 . 00 .... .... 1100 . 1 . 0 .... \
|
||||
vm=%vm_dp vn=%vn_dp vd=%vd_dp
|
||||
SHA256H2_3s 1111 001 1 0 . 01 .... .... 1100 . 1 . 0 .... \
|
||||
vm=%vm_dp vn=%vn_dp vd=%vd_dp
|
||||
SHA256SU1_3s 1111 001 1 0 . 10 .... .... 1100 . 1 . 0 .... \
|
||||
vm=%vm_dp vn=%vn_dp vd=%vd_dp
|
||||
|
||||
VQRDMLSH_3s 1111 001 1 0 . .. .... .... 1100 ... 1 .... @3same
|
||||
|
@ -686,3 +686,142 @@ static bool trans_VMUL_p_3s(DisasContext *s, arg_3same *a)
|
||||
|
||||
DO_VQRDMLAH(VQRDMLAH, gen_gvec_sqrdmlah_qc)
|
||||
DO_VQRDMLAH(VQRDMLSH, gen_gvec_sqrdmlsh_qc)
|
||||
|
||||
static bool trans_SHA1_3s(DisasContext *s, arg_SHA1_3s *a)
|
||||
{
|
||||
TCGv_ptr ptr1, ptr2, ptr3;
|
||||
TCGv_i32 tmp;
|
||||
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
|
||||
!dc_isar_feature(aa32_sha1, s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* UNDEF accesses to D16-D31 if they don't exist. */
|
||||
if (!dc_isar_feature(aa32_simd_r32, s) &&
|
||||
((a->vd | a->vn | a->vm) & 0x10)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a->vn | a->vm | a->vd) & 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vfp_access_check(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ptr1 = vfp_reg_ptr(true, a->vd);
|
||||
ptr2 = vfp_reg_ptr(true, a->vn);
|
||||
ptr3 = vfp_reg_ptr(true, a->vm);
|
||||
tmp = tcg_const_i32(a->optype);
|
||||
gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp);
|
||||
tcg_temp_free_i32(tmp);
|
||||
tcg_temp_free_ptr(ptr1);
|
||||
tcg_temp_free_ptr(ptr2);
|
||||
tcg_temp_free_ptr(ptr3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_SHA256H_3s(DisasContext *s, arg_SHA256H_3s *a)
|
||||
{
|
||||
TCGv_ptr ptr1, ptr2, ptr3;
|
||||
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
|
||||
!dc_isar_feature(aa32_sha2, s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* UNDEF accesses to D16-D31 if they don't exist. */
|
||||
if (!dc_isar_feature(aa32_simd_r32, s) &&
|
||||
((a->vd | a->vn | a->vm) & 0x10)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a->vn | a->vm | a->vd) & 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vfp_access_check(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ptr1 = vfp_reg_ptr(true, a->vd);
|
||||
ptr2 = vfp_reg_ptr(true, a->vn);
|
||||
ptr3 = vfp_reg_ptr(true, a->vm);
|
||||
gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
|
||||
tcg_temp_free_ptr(ptr1);
|
||||
tcg_temp_free_ptr(ptr2);
|
||||
tcg_temp_free_ptr(ptr3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_SHA256H2_3s(DisasContext *s, arg_SHA256H2_3s *a)
|
||||
{
|
||||
TCGv_ptr ptr1, ptr2, ptr3;
|
||||
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
|
||||
!dc_isar_feature(aa32_sha2, s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* UNDEF accesses to D16-D31 if they don't exist. */
|
||||
if (!dc_isar_feature(aa32_simd_r32, s) &&
|
||||
((a->vd | a->vn | a->vm) & 0x10)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a->vn | a->vm | a->vd) & 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vfp_access_check(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ptr1 = vfp_reg_ptr(true, a->vd);
|
||||
ptr2 = vfp_reg_ptr(true, a->vn);
|
||||
ptr3 = vfp_reg_ptr(true, a->vm);
|
||||
gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
|
||||
tcg_temp_free_ptr(ptr1);
|
||||
tcg_temp_free_ptr(ptr2);
|
||||
tcg_temp_free_ptr(ptr3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool trans_SHA256SU1_3s(DisasContext *s, arg_SHA256SU1_3s *a)
|
||||
{
|
||||
TCGv_ptr ptr1, ptr2, ptr3;
|
||||
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_NEON) ||
|
||||
!dc_isar_feature(aa32_sha2, s)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* UNDEF accesses to D16-D31 if they don't exist. */
|
||||
if (!dc_isar_feature(aa32_simd_r32, s) &&
|
||||
((a->vd | a->vn | a->vm) & 0x10)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((a->vn | a->vm | a->vd) & 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!vfp_access_check(s)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ptr1 = vfp_reg_ptr(true, a->vd);
|
||||
ptr2 = vfp_reg_ptr(true, a->vn);
|
||||
ptr3 = vfp_reg_ptr(true, a->vm);
|
||||
gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
|
||||
tcg_temp_free_ptr(ptr1);
|
||||
tcg_temp_free_ptr(ptr2);
|
||||
tcg_temp_free_ptr(ptr3);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -5359,7 +5359,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
||||
int vec_size;
|
||||
uint32_t imm;
|
||||
TCGv_i32 tmp, tmp2, tmp3, tmp4, tmp5;
|
||||
TCGv_ptr ptr1, ptr2, ptr3;
|
||||
TCGv_ptr ptr1, ptr2;
|
||||
TCGv_i64 tmp64;
|
||||
|
||||
if (!arm_dc_feature(s, ARM_FEATURE_NEON)) {
|
||||
@ -5403,49 +5403,6 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
||||
return 1;
|
||||
}
|
||||
switch (op) {
|
||||
case NEON_3R_SHA:
|
||||
/* The SHA-1/SHA-256 3-register instructions require special
|
||||
* treatment here, as their size field is overloaded as an
|
||||
* op type selector, and they all consume their input in a
|
||||
* single pass.
|
||||
*/
|
||||
if (!q) {
|
||||
return 1;
|
||||
}
|
||||
if (!u) { /* SHA-1 */
|
||||
if (!dc_isar_feature(aa32_sha1, s)) {
|
||||
return 1;
|
||||
}
|
||||
ptr1 = vfp_reg_ptr(true, rd);
|
||||
ptr2 = vfp_reg_ptr(true, rn);
|
||||
ptr3 = vfp_reg_ptr(true, rm);
|
||||
tmp4 = tcg_const_i32(size);
|
||||
gen_helper_crypto_sha1_3reg(ptr1, ptr2, ptr3, tmp4);
|
||||
tcg_temp_free_i32(tmp4);
|
||||
} else { /* SHA-256 */
|
||||
if (!dc_isar_feature(aa32_sha2, s) || size == 3) {
|
||||
return 1;
|
||||
}
|
||||
ptr1 = vfp_reg_ptr(true, rd);
|
||||
ptr2 = vfp_reg_ptr(true, rn);
|
||||
ptr3 = vfp_reg_ptr(true, rm);
|
||||
switch (size) {
|
||||
case 0:
|
||||
gen_helper_crypto_sha256h(ptr1, ptr2, ptr3);
|
||||
break;
|
||||
case 1:
|
||||
gen_helper_crypto_sha256h2(ptr1, ptr2, ptr3);
|
||||
break;
|
||||
case 2:
|
||||
gen_helper_crypto_sha256su1(ptr1, ptr2, ptr3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
tcg_temp_free_ptr(ptr1);
|
||||
tcg_temp_free_ptr(ptr2);
|
||||
tcg_temp_free_ptr(ptr3);
|
||||
return 0;
|
||||
|
||||
case NEON_3R_VPADD_VQRDMLAH:
|
||||
if (!u) {
|
||||
break; /* VPADD */
|
||||
@ -5496,6 +5453,7 @@ static int disas_neon_data_insn(DisasContext *s, uint32_t insn)
|
||||
case NEON_3R_VMUL:
|
||||
case NEON_3R_VML:
|
||||
case NEON_3R_VSHL:
|
||||
case NEON_3R_SHA:
|
||||
/* Already handled by decodetree */
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user