From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 33620 invoked by alias); 1 May 2019 17:47:31 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Received: (qmail 33301 invoked by uid 89); 1 May 2019 17:47:31 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3 autolearn=ham version=3.3.1 spammy= X-HELO: foss.arm.com Received: from usa-sjc-mx-foss1.foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 01 May 2019 17:47:28 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.72.51.249]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 9DA3B80D for ; Wed, 1 May 2019 10:47:27 -0700 (PDT) Received: from [10.2.207.62] (e107157-lin.cambridge.arm.com [10.2.207.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 22C6E3F719 for ; Wed, 1 May 2019 10:47:26 -0700 (PDT) Subject: Re: [PATCH 0/57][Arm][binutils]: Add support for Armv8.1-M Mainline MVE instructions To: binutils@sourceware.org References: <19569550-4d2e-0bb3-592a-d91050d490f6@arm.com> From: "Andre Vieira (lists)" Message-ID: <1ab4a335-e804-53e0-b7e8-75dcb21bb464@arm.com> Date: Wed, 01 May 2019 17:47:00 -0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 In-Reply-To: <19569550-4d2e-0bb3-592a-d91050d490f6@arm.com> Content-Type: multipart/mixed; boundary="------------248E8853C532AD6764882C82" X-IsSubscribed: yes X-SW-Source: 2019-05/txt/msg00080.txt.bz2 This is a multi-part message in MIME format. --------------248E8853C532AD6764882C82 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 553 Hello, This patch adds support for all MVE vector shift instructions. opcodes/ChangeLog: 2019-05-01 Andre Vieira Michael Collison * arm-dis.c (enum mve_instructions): Add new instructions. (enum mve_undefined): Add new reasons. (is_mve_encoding_conflict): Handle new instructions. (is_mve_undefined): Likewise. (is_mve_unpredictable): Likewise. (print_mve_undefined): Likewise. (print_mve_size): Likewise. (print_mve_shift_n): Likewise. (print_insn_mve): Likewise. --------------248E8853C532AD6764882C82 Content-Type: text/x-patch; name="50.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="50.patch" Content-length: 13532 diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index f2e244d104cdb1938ea2a9b8066647b485aaaa1f..56255d5f61dd29b72e02469894186734ca1b4346 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -184,6 +184,30 @@ enum mve_instructions MVE_VHCADD, MVE_VCMLA_FP, MVE_VCMUL_FP, + MVE_VQRSHL_T1, + MVE_VQRSHL_T2, + MVE_VQRSHRN, + MVE_VQRSHRUN, + MVE_VQSHL_T1, + MVE_VQSHL_T2, + MVE_VQSHLU_T3, + MVE_VQSHL_T4, + MVE_VQSHRN, + MVE_VQSHRUN, + MVE_VRSHL_T1, + MVE_VRSHL_T2, + MVE_VRSHR, + MVE_VRSHRN, + MVE_VSHL_T1, + MVE_VSHL_T2, + MVE_VSHL_T3, + MVE_VSHLC, + MVE_VSHLL_T1, + MVE_VSHLL_T2, + MVE_VSHR, + MVE_VSHRN, + MVE_VSLI, + MVE_VSRI, MVE_NONE }; @@ -216,6 +240,7 @@ enum mve_unpredictable enum mve_undefined { + UNDEF_SIZE, /* undefined size. */ UNDEF_SIZE_0, /* undefined because size == 0. */ UNDEF_SIZE_2, /* undefined because size == 2. */ UNDEF_SIZE_3, /* undefined because size == 3. */ @@ -2420,6 +2445,63 @@ static const struct mopcode32 mve_opcodes[] = 0xef800050, 0xefb810f0, "vorr%v.i%8-11s\t%13-15,22Q, %E"}, + /* Vector VQSHL T2 Variant. + NOTE: MVE_VQSHL_T2 must appear in the table before + before MVE_VMOV_IMM_TO_VEC due to opcode aliasing. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQSHL_T2, + 0xef800750, 0xef801fd1, + "vqshl%v.%u%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VQSHLU T3 Variant + NOTE: MVE_VQSHL_T2 must appear in the table before + before MVE_VMOV_IMM_TO_VEC due to opcode aliasing. */ + + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQSHLU_T3, + 0xff800650, 0xff801fd1, + "vqshlu%v.s%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VRSHR + NOTE: MVE_VRSHR must appear in the table before + before MVE_VMOV_IMM_TO_VEC due to opcode aliasing. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VRSHR, + 0xef800250, 0xef801fd1, + "vrshr%v.%u%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VSHL. + NOTE: MVE_VSHL must appear in the table before + before MVE_VMOV_IMM_TO_VEC due to opcode aliasing. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSHL_T1, + 0xef800550, 0xff801fd1, + "vshl%v.i%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VSHR + NOTE: MVE_VSHR must appear in the table before + before MVE_VMOV_IMM_TO_VEC due to opcode aliasing. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSHR, + 0xef800050, 0xef801fd1, + "vshr%v.%u%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VSLI + NOTE: MVE_VSLI must appear in the table before + before MVE_VMOV_IMM_TO_VEC due to opcode aliasing. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSLI, + 0xff800550, 0xff801fd1, + "vsli%v.%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VSRI + NOTE: MVE_VSRI must appear in the table before + before MVE_VMOV_IMM_TO_VEC due to opcode aliasing. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSRI, + 0xff800450, 0xff801fd1, + "vsri%v.%19-21s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + /* Vector VMOV immediate to vector, cmode == 11x1 -> VMVN which is UNDEFINED for such a cmode. */ @@ -2462,6 +2544,13 @@ static const struct mopcode32 mve_opcodes[] = 0xee100b10, 0xff100f1f, "vmov%c.%u%5-6,21-22s\t%12-15r, %17-19,7Q[%N]"}, + /* Vector VSHLL T1 Variant. Note: VSHLL T1 must appear before MVE_VMOVL due + to instruction opcode aliasing. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSHLL_T1, + 0xeea00f40, 0xefa00fd1, + "vshll%T%v.%u%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + /* Vector VMOVL long. */ {ARM_FEATURE_COPROC (FPU_MVE), MVE_VMOVL, @@ -2612,6 +2701,54 @@ static const struct mopcode32 mve_opcodes[] = 0xfe010e60, 0xff811f70, "vqrdmulh%v.s%20-21s\t%13-15,22Q, %17-19,7Q, %0-3r"}, + /* Vector VQRSHL T1 variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQRSHL_T1, + 0xef000550, 0xef811f51, + "vqrshl%v.%u%20-21s\t%13-15,22Q, %1-3,5Q, %17-19,7Q"}, + + /* Vector VQRSHL T2 variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQRSHL_T2, + 0xee331ee0, 0xefb31ff0, + "vqrshl%v.%u%18-19s\t%13-15,22Q, %0-3r"}, + + /* Vector VQRSHRN. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQRSHRN, + 0xee800f41, 0xefa00fd1, + "vqrshrn%T%v.%u%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VQRSHRUN. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQRSHRUN, + 0xfe800fc0, 0xffa00fd1, + "vqrshrun%T%v.s%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VQSHL T1 Variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQSHL_T1, + 0xee311ee0, 0xefb31ff0, + "vqshl%v.%u%18-19s\t%13-15,22Q, %0-3r"}, + + /* Vector VQSHL T4 Variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQSHL_T4, + 0xef000450, 0xef811f51, + "vqshl%v.%u%20-21s\t%13-15,22Q, %1-3,5Q, %17-19,7Q"}, + + /* Vector VQSHRN. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQSHRN, + 0xee800f40, 0xefa00fd1, + "vqshrn%T%v.%u%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VQSHRUN. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VQSHRUN, + 0xee800fc0, 0xffa00fd1, + "vqshrun%T%v.s%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + /* Vector VRINT floating point. */ {ARM_FEATURE_COPROC (FPU_MVE_FP), MVE_VRINT_FP, @@ -2630,6 +2767,54 @@ static const struct mopcode32 mve_opcodes[] = 0xee801f00, 0xef811f51, "vrmlaldavh%5Ax%v.%u32\t%13-15l, %20-22h, %17-19,7Q, %1-3Q"}, + /* Vector VRSHL T1 Variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VRSHL_T1, + 0xef000540, 0xef811f51, + "vrshl%v.%u%20-21s\t%13-15,22Q, %1-3,5Q, %17-19,7Q"}, + + /* Vector VRSHL T2 Variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VRSHL_T2, + 0xee331e60, 0xefb31ff0, + "vrshl%v.%u%18-19s\t%13-15,22Q, %0-3r"}, + + /* Vector VRSHRN. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VRSHRN, + 0xfe800fc1, 0xffa00fd1, + "vrshrn%T%v.i%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + + /* Vector VSHL T2 Variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSHL_T2, + 0xee311e60, 0xefb31ff0, + "vshl%v.%u%18-19s\t%13-15,22Q, %0-3r"}, + + /* Vector VSHL T3 Variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSHL_T3, + 0xef000440, 0xef811f51, + "vshl%v.%u%20-21s\t%13-15,22Q, %1-3,5Q, %17-19,7Q"}, + + /* Vector VSHLC. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSHLC, + 0xeea00fc0, 0xffa01ff0, + "vshlc%v\t%13-15,22Q, %0-3r, #%16-20d"}, + + /* Vector VSHLL T2 Variant. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSHLL_T2, + 0xee310e01, 0xefb30fd1, + "vshll%T%v.%u%18-19s\t%13-15,22Q, %1-3,5Q, #%18-19d"}, + + /* Vector VSHRN. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VSHRN, + 0xee800fc1, 0xffa00fd1, + "vshrn%T%v.i%19-20s\t%13-15,22Q, %1-3,5Q, #%16-18d"}, + /* Vector VST2 no writeback. */ {ARM_FEATURE_COPROC (FPU_MVE), MVE_VST2, @@ -4734,6 +4919,10 @@ is_mve_encoding_conflict (unsigned long given, else return FALSE; + case MVE_VQRSHL_T1: + case MVE_VQSHL_T4: + case MVE_VRSHL_T1: + case MVE_VSHL_T3: case MVE_VCADD_VEC: case MVE_VHCADD: case MVE_VDDUP: @@ -4844,6 +5033,11 @@ is_mve_encoding_conflict (unsigned long given, return FALSE; } + case MVE_VQRSHL_T2: + case MVE_VQSHL_T1: + case MVE_VRSHL_T2: + case MVE_VSHL_T2: + case MVE_VSHLL_T2: case MVE_VADDV: case MVE_VMOVN: case MVE_VQMOVUN: @@ -4876,6 +5070,32 @@ is_mve_encoding_conflict (unsigned long given, else return FALSE; + + case MVE_VSHLL_T1: + if (arm_decode_field (given, 16, 18) == 0) + { + unsigned long sz = arm_decode_field (given, 19, 20); + + if ((sz == 1) || (sz == 2)) + return TRUE; + else + return FALSE; + } + else + return FALSE; + + case MVE_VQSHL_T2: + case MVE_VQSHLU_T3: + case MVE_VRSHR: + case MVE_VSHL_T1: + case MVE_VSHR: + case MVE_VSLI: + case MVE_VSRI: + if (arm_decode_field (given, 19, 21) == 0) + return TRUE; + else + return FALSE; + default: return FALSE; @@ -5231,6 +5451,7 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn, else return FALSE; + case MVE_VSHLL_T2: case MVE_VMOVN: if (arm_decode_field (given, 18, 19) == 2) { @@ -5253,6 +5474,56 @@ is_mve_undefined (unsigned long given, enum mve_instructions matched_insn, else return FALSE; + case MVE_VQSHRN: + case MVE_VQSHRUN: + case MVE_VSHLL_T1: + case MVE_VSHRN: + { + unsigned long sz = arm_decode_field (given, 19, 20); + if (sz == 1) + return FALSE; + else if ((sz & 2) == 2) + return FALSE; + else + { + *undefined_code = UNDEF_SIZE; + return TRUE; + } + } + break; + + case MVE_VQSHL_T2: + case MVE_VQSHLU_T3: + case MVE_VRSHR: + case MVE_VSHL_T1: + case MVE_VSHR: + case MVE_VSLI: + case MVE_VSRI: + { + unsigned long sz = arm_decode_field (given, 19, 21); + if ((sz & 7) == 1) + return FALSE; + else if ((sz & 6) == 2) + return FALSE; + else if ((sz & 4) == 4) + return FALSE; + else + { + *undefined_code = UNDEF_SIZE; + return TRUE; + } + } + + case MVE_VQRSHRN: + case MVE_VQRSHRUN: + if (arm_decode_field (given, 19, 20) == 0) + { + *undefined_code = UNDEF_SIZE_0; + return TRUE; + } + else + return FALSE; + default: return FALSE; } @@ -5312,6 +5583,11 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn, return FALSE; } + case MVE_VQRSHL_T2: + case MVE_VQSHL_T1: + case MVE_VRSHL_T2: + case MVE_VSHL_T2: + case MVE_VSHLC: case MVE_VQDMLAH: case MVE_VQRDMLAH: case MVE_VQDMLASH: @@ -5900,6 +6176,10 @@ print_mve_undefined (struct disassemble_info *info, switch (undefined_code) { + case UNDEF_SIZE: + func (stream, "illegal size"); + break; + case UNDEF_SIZE_0: func (stream, "size equals zero"); break; @@ -6406,8 +6686,17 @@ print_mve_size (struct disassemble_info *info, case MVE_VQRDMULH_T2: case MVE_VQDMULH_T3: case MVE_VQRDMULH_T4: + case MVE_VQRSHL_T1: + case MVE_VQRSHL_T2: + case MVE_VQSHL_T1: + case MVE_VQSHL_T4: case MVE_VRHADD: case MVE_VRINT_FP: + case MVE_VRSHL_T1: + case MVE_VRSHL_T2: + case MVE_VSHL_T2: + case MVE_VSHL_T3: + case MVE_VSHLL_T2: case MVE_VST2: case MVE_VST4: case MVE_VSTRB_SCATTER_T1: @@ -6566,11 +6855,95 @@ print_mve_size (struct disassemble_info *info, } break; + case MVE_VQSHRN: + case MVE_VQSHRUN: + case MVE_VQRSHRN: + case MVE_VQRSHRUN: + case MVE_VRSHRN: + case MVE_VSHRN: + { + switch (size) + { + case 1: + func (stream, "16"); + break; + + case 2: case 3: + func (stream, "32"); + break; + + default: + break; + } + } + break; + + case MVE_VQSHL_T2: + case MVE_VQSHLU_T3: + case MVE_VRSHR: + case MVE_VSHL_T1: + case MVE_VSHLL_T1: + case MVE_VSHR: + case MVE_VSLI: + case MVE_VSRI: + { + switch (size) + { + case 1: + func (stream, "8"); + break; + + case 2: case 3: + func (stream, "16"); + break; + + case 4: case 5: case 6: case 7: + func (stream, "32"); + break; + + default: + break; + } + } + break; + default: break; } } +static void +print_mve_shift_n (struct disassemble_info *info, long given, + enum mve_instructions matched_insn) +{ + void *stream = info->stream; + fprintf_ftype func = info->fprintf_func; + + int startAt0 + = matched_insn == MVE_VQSHL_T2 + || matched_insn == MVE_VQSHLU_T3 + || matched_insn == MVE_VSHL_T1 + || matched_insn == MVE_VSHLL_T1 + || matched_insn == MVE_VSLI; + + unsigned imm6 = (given & 0x3f0000) >> 16; + + if (matched_insn == MVE_VSHLL_T1) + imm6 &= 0x1f; + + unsigned shiftAmount = 0; + if ((imm6 & 0x20) != 0) + shiftAmount = startAt0 ? imm6 - 32 : 64 - imm6; + else if ((imm6 & 0x10) != 0) + shiftAmount = startAt0 ? imm6 - 16 : 32 - imm6; + else if ((imm6 & 0x08) != 0) + shiftAmount = startAt0 ? imm6 - 8 : 16 - imm6; + else + print_mve_undefined (info, UNDEF_SIZE_0); + + func (stream, "%u", shiftAmount); +} + static void print_vec_condition (struct disassemble_info *info, long given, enum mve_instructions matched_insn) @@ -8210,8 +8583,42 @@ print_insn_mve (struct disassemble_info *info, long given) func (stream, "%s", arm_regnames[value]); break; case 'd': - func (stream, "%ld", value); - value_in_comment = value; + if (insn->mve_op == MVE_VQSHL_T2 + || insn->mve_op == MVE_VQSHLU_T3 + || insn->mve_op == MVE_VRSHR + || insn->mve_op == MVE_VRSHRN + || insn->mve_op == MVE_VSHL_T1 + || insn->mve_op == MVE_VSHLL_T1 + || insn->mve_op == MVE_VSHR + || insn->mve_op == MVE_VSHRN + || insn->mve_op == MVE_VSLI + || insn->mve_op == MVE_VSRI) + print_mve_shift_n (info, given, insn->mve_op); + else if (insn->mve_op == MVE_VSHLL_T2) + { + switch (value) + { + case 0x00: + func (stream, "8"); + break; + case 0x01: + func (stream, "16"); + break; + case 0x10: + print_mve_undefined (info, UNDEF_SIZE_0); + break; + default: + assert (0); + break; + } + } + else + { + if (insn->mve_op == MVE_VSHLC && value == 0) + value = 32; + func (stream, "%ld", value); + value_in_comment = value; + } break; case 'F': func (stream, "s%ld", value); --------------248E8853C532AD6764882C82--