From 14925797f833c9f4eedab98c7c50961d180aa03f Mon Sep 17 00:00:00 2001 From: Andre Vieira Date: Thu, 16 May 2019 14:30:38 +0100 Subject: [PATCH] [PATCH 46/57][Arm][OBJDUMP] Add support for MVE instructions: vmovl, vmull, vqdmull, vqmovn, vqmovun and vmovn opcodes/ChangeLog: 2019-05-16 Andre Vieira Michael Collison * arm-dis.c (enum mve_instructions): Add new instructions. (is_mve_encoding_conflict): Handle new instructions. (is_mve_undefined): Likewise. (is_mve_unpredictable): Likewise. (print_mve_size): Likewise. (print_insn_mve): Likewise. --- opcodes/ChangeLog | 10 +++ opcodes/arm-dis.c | 196 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 206 insertions(+) diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 571dd3de3e..88304d59c6 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,13 @@ +2019-05-16 Andre Vieira + Michael Collison + + * arm-dis.c (enum mve_instructions): Add new instructions. + (is_mve_encoding_conflict): Handle new instructions. + (is_mve_undefined): Likewise. + (is_mve_unpredictable): Likewise. + (print_mve_size): Likewise. + (print_insn_mve): Likewise. + 2019-05-16 Andre Vieira Michael Collison diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index a779138db0..16bf0b9178 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -144,6 +144,14 @@ enum mve_instructions MVE_VBIC_IMM, MVE_VBIC_REG, MVE_VMOVX, + MVE_VMOVL, + MVE_VMOVN, + MVE_VMULL_INT, + MVE_VMULL_POLY, + MVE_VQDMULL_T1, + MVE_VQDMULL_T2, + MVE_VQMOVN, + MVE_VQMOVUN, MVE_NONE }; @@ -1913,6 +1921,7 @@ static const struct opcode32 neon_opcodes[] = %B print v{st,ld}[24] any one operands %E print vmov, vmvn, vorr, vbic encoded constant %N print generic index for vmov + %T print bottom ('b') or top ('t') of source register %r print as an ARM register %d print the bitfield in decimal @@ -2280,12 +2289,36 @@ static const struct mopcode32 mve_opcodes[] = 0xee100b10, 0xff100f1f, "vmov%c.%u%5-6,21-22s\t%12-15r, %17-19,7Q[%N]"}, + /* Vector VMOVL long. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VMOVL, + 0xeea00f40, 0xefa70fd1, + "vmovl%T%v.%u%19-20s\t%13-15,22Q, %1-3,5Q"}, + + /* Vector VMOV and narrow. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VMOVN, + 0xfe310e81, 0xffb30fd1, + "vmovn%T%v.i%18-19s\t%13-15,22Q, %1-3,5Q"}, + /* Floating point move extract. */ {ARM_FEATURE_COPROC (FPU_MVE_FP), MVE_VMOVX, 0xfeb00a40, 0xffbf0fd0, "vmovx.f16\t%22,12-15F, %5,0-3F"}, + /* Vector VMULL integer. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VMULL_INT, + 0xee010e00, 0xef810f51, + "vmull%T%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"}, + + /* Vector VMULL polynomial. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VMULL_POLY, + 0xee310e00, 0xefb10f51, + "vmull%T%v.%28s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"}, + /* Vector VMVN immediate to vector. */ {ARM_FEATURE_COPROC (FPU_MVE), MVE_VMVN_IMM, @@ -2310,6 +2343,30 @@ static const struct mopcode32 mve_opcodes[] = 0xef200150, 0xffb11f51, "vorr%v\t%13-15,22Q, %17-19,7Q, %1-3,5Q"}, + /* Vector VQDMULL T1 variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQDMULL_T1, + 0xee300f01, 0xefb10f51, + "vqdmull%T%v.s%28s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"}, + + /* Vector VQDMULL T2 variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQDMULL_T2, + 0xee300f60, 0xefb10f70, + "vqdmull%T%v.s%28s\t%13-15,22Q, %17-19,7Q, %0-3r"}, + + /* Vector VQMOVN. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQMOVN, + 0xee330e01, 0xefb30fd1, + "vqmovn%T%v.%u%18-19s\t%13-15,22Q, %1-3,5Q"}, + + /* Vector VQMOVUN. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQMOVUN, + 0xee310e81, 0xffb30fd1, + "vqmovun%T%v.s%18-19s\t%13-15,22Q, %1-3,5Q"}, + /* Vector VRINT floating point. */ {ARM_FEATURE_COPROC (FPU_MVE_FP), MVE_VRINT_FP, @@ -4420,6 +4477,7 @@ is_mve_encoding_conflict (unsigned long given, else return FALSE; + case MVE_VMULL_INT: case MVE_VHADD_T2: case MVE_VHSUB_T2: case MVE_VCMP_VEC_T1: @@ -4502,6 +4560,23 @@ is_mve_encoding_conflict (unsigned long given, else return FALSE; + case MVE_VMOVL: + { + unsigned long size = arm_decode_field (given, 19, 20); + if ((size == 0) || (size == 3)) + return TRUE; + else + return FALSE; + } + + case MVE_VMOVN: + case MVE_VQMOVUN: + case MVE_VQMOVN: + if (arm_decode_field (given, 18, 19) == 3) + return TRUE; + else + return FALSE; + default: return FALSE; @@ -4855,6 +4930,15 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn, else return FALSE; + case MVE_VMOVN: + if (arm_decode_field (given, 18, 19) == 2) + { + *undefined_code = UNDEF_SIZE_2; + return TRUE; + } + else + return FALSE; + default: return FALSE; } @@ -5126,6 +5210,86 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn, return FALSE; } + case MVE_VMULL_INT: + { + unsigned long Qd; + unsigned long Qm; + unsigned long Qn; + + if (arm_decode_field (given, 20, 21) == 2) + { + Qd = arm_decode_field_multiple (given, 13, 15, 22, 22); + Qm = arm_decode_field_multiple (given, 1, 3, 5, 5); + Qn = arm_decode_field_multiple (given, 17, 19, 7, 7); + + if ((Qd == Qn) || (Qd == Qm)) + { + *unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_2; + return TRUE; + } + else + return FALSE; + } + else + return FALSE; + } + + case MVE_VQDMULL_T1: + { + unsigned long Qd; + unsigned long Qm; + unsigned long Qn; + + if (arm_decode_field (given, 28, 28) == 1) + { + Qd = arm_decode_field_multiple (given, 13, 15, 22, 22); + Qm = arm_decode_field_multiple (given, 1, 3, 5, 5); + Qn = arm_decode_field_multiple (given, 17, 19, 7, 7); + + if ((Qd == Qn) || (Qd == Qm)) + { + *unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_1; + return TRUE; + } + else + return FALSE; + } + else + return FALSE; + } + + case MVE_VQDMULL_T2: + { + unsigned long gpr = arm_decode_field (given, 0, 3); + if (gpr == 0xd) + { + *unpredictable_code = UNPRED_R13; + return TRUE; + } + else if (gpr == 0xf) + { + *unpredictable_code = UNPRED_R15; + return TRUE; + } + + if (arm_decode_field (given, 28, 28) == 1) + { + unsigned long Qd + = arm_decode_field_multiple (given, 13, 15, 22, 22); + unsigned long Qn = arm_decode_field_multiple (given, 17, 19, 7, 7); + + if ((Qd == Qn)) + { + *unpredictable_code = UNPRED_Q_REGS_EQ_AND_SIZE_1; + return TRUE; + } + else + return FALSE; + } + + return FALSE; + } + default: return FALSE; } @@ -5804,6 +5968,24 @@ print_mve_size (struct disassemble_info *info, func (stream, "16"); break; + case MVE_VMOVN: + case MVE_VQDMULL_T1: + case MVE_VQDMULL_T2: + case MVE_VQMOVN: + case MVE_VQMOVUN: + if (size == 0) + func (stream, "16"); + else if (size == 1) + func (stream, "32"); + break; + + case MVE_VMOVL: + if (size == 1) + func (stream, "8"); + else if (size == 2) + func (stream, "16"); + break; + case MVE_VDUP: switch (size) { @@ -5868,6 +6050,13 @@ print_mve_size (struct disassemble_info *info, } break; + case MVE_VMULL_POLY: + if (size == 0) + func (stream, "p8"); + else if (size == 1) + func (stream, "p16"); + break; + case MVE_VMVN_IMM: switch (size) { @@ -7443,6 +7632,13 @@ print_insn_mve (struct disassemble_info *info, long given) print_mve_vmov_index (info, given); break; + case 'T': + if (arm_decode_field (given, 12, 12) == 0) + func (stream, "b"); + else + func (stream, "t"); + break; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { -- 2.34.1