From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 44069 invoked by alias); 1 May 2019 17:40:47 -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 44059 invoked by uid 89); 1 May 2019 17:40:47 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.7 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.1 spammy=decimal 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:40:45 +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 51B0F80D for ; Wed, 1 May 2019 10:40:44 -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 F03E93F719 for ; Wed, 1 May 2019 10:40:43 -0700 (PDT) Subject: [PATCH 41/57][Arm][OBJDUMP] Add support for MVE instructions: vld[24] and vst[24] To: binutils@sourceware.org References: <19569550-4d2e-0bb3-592a-d91050d490f6@arm.com> From: "Andre Vieira (lists)" Message-ID: Date: Wed, 01 May 2019 17:40: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="------------DE711A355556B28325C0AC0A" X-IsSubscribed: yes X-SW-Source: 2019-05/txt/msg00071.txt.bz2 This is a multi-part message in MIME format. --------------DE711A355556B28325C0AC0A Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit Content-length: 636 Hi, This patch adds support for the MVE deinterleaving loads and interleaving stores. opcodes/ChangeLog: 2019-05-01 Andre Vieira Michael Collison * arm-dis.c (enum mve_instructions): Add new instructions. (enum mve_unpredictable): Add new reasons. (is_mve_encoding_conflict): Handle new instructions. (is_mve_unpredictable): Likewise. (mve_opcodes): Add new instructions. (print_mve_unpredictable): Handle new reasons. (print_mve_register_blocks): New print function. (print_mve_size): Handle new instructions. (print_insn_mve): Likewise. --------------DE711A355556B28325C0AC0A Content-Type: text/x-patch; name="41.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="41.patch" Content-length: 6859 diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c index 89d15893f648295ae7840217bec9b35129e67922..2b8755ab1b5042562bf4f9c69b9ea5de5ee2011a 100644 --- a/opcodes/arm-dis.c +++ b/opcodes/arm-dis.c @@ -99,6 +99,10 @@ enum mve_instructions MVE_VHSUB_T1, MVE_VHSUB_T2, MVE_VRHADD, + MVE_VLD2, + MVE_VLD4, + MVE_VST2, + MVE_VST4, MVE_NONE }; @@ -111,6 +115,12 @@ enum mve_unpredictable UNPRED_R13, /* Unpredictable because r13 (sp) or r15 (sp) used. */ UNPRED_R15, /* Unpredictable because r15 (pc) is used. */ + UNPRED_Q_GT_4, /* Unpredictable because + vec reg start > 4 (vld4/st4). */ + UNPRED_Q_GT_6, /* Unpredictable because + vec reg start > 6 (vld2/st2). */ + UNPRED_R13_AND_WB, /* Unpredictable becase gp reg = r13 + and WB bit = 1. */ UNPRED_NONE /* No unpredictable behavior. */ }; @@ -1833,7 +1843,11 @@ static const struct opcode32 neon_opcodes[] = %n print vector comparison code for predicated instruction %v print vector predicate for instruction in predicated block + %w print writeback mode for MVE v{st,ld}[24] + %B print v{st,ld}[24] any one operands + %r print as an ARM register + %d print the bitfield in decimal %Q print as a MVE Q register %Z as %<>r but r15 is ZR instead of PC and r13 is UNPREDICTABLE @@ -2007,6 +2021,42 @@ static const struct mopcode32 mve_opcodes[] = 0xef000140, 0xef811f51, "vrhadd%v.%u%20-21s\t%13-15,22Q, %17-19,7Q, %1-3,5Q"}, + /* Vector VLD2. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VLD2, + 0xfc901e00, 0xff901e5f, + "vld2%5d.%7-8s\t%B, [%16-19r]%w"}, + + /* Vector VLD4. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VLD4, + 0xfc901e01, 0xff901e1f, + "vld4%5-6d.%7-8s\t%B, [%16-19r]%w"}, + + /* Vector VST2 no writeback. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VST2, + 0xfc801e00, 0xffb01e5f, + "vst2%5d.%7-8s\t%B, [%16-19r]"}, + + /* Vector VST2 writeback. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VST2, + 0xfca01e00, 0xffb01e5f, + "vst2%5d.%7-8s\t%B, [%16-19r]!"}, + + /* Vector VST4 no writeback. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VST4, + 0xfc801e01, 0xffb01e1f, + "vst4%5-6d.%7-8s\t%B, [%16-19r]"}, + + /* Vector VST4 writeback. */ + {ARM_FEATURE_COPROC (FPU_MVE), + MVE_VST4, + 0xfca01e01, 0xffb01e1f, + "vst4%5-6d.%7-8s\t%B, [%16-19r]!"}, + {ARM_FEATURE_CORE_LOW (0), MVE_NONE, 0x00000000, 0x00000000, 0} @@ -4025,6 +4075,15 @@ is_mve_encoding_conflict (unsigned long given, else return FALSE; + case MVE_VLD2: + case MVE_VLD4: + case MVE_VST2: + case MVE_VST4: + if (arm_decode_field (given, 7, 8) == 3) + return TRUE; + else + return FALSE; + default: return FALSE; @@ -4142,6 +4201,58 @@ is_mve_unpredictable (unsigned long given, enum mve_instructions matched_insn, return FALSE; } + case MVE_VLD2: + case MVE_VST2: + { + unsigned long rn = arm_decode_field (given, 16, 19); + + if ((rn == 0xd) && (arm_decode_field (given, 21, 21) == 1)) + { + *unpredictable_code = UNPRED_R13_AND_WB; + return TRUE; + } + + if (rn == 0xf) + { + *unpredictable_code = UNPRED_R15; + return TRUE; + } + + if (arm_decode_field_multiple (given, 13, 15, 22, 22) > 6) + { + *unpredictable_code = UNPRED_Q_GT_6; + return TRUE; + } + else + return FALSE; + } + + case MVE_VLD4: + case MVE_VST4: + { + unsigned long rn = arm_decode_field (given, 16, 19); + + if ((rn == 0xd) && (arm_decode_field (given, 21, 21) == 1)) + { + *unpredictable_code = UNPRED_R13_AND_WB; + return TRUE; + } + + if (rn == 0xf) + { + *unpredictable_code = UNPRED_R15; + return TRUE; + } + + if (arm_decode_field_multiple (given, 13, 15, 22, 22) > 4) + { + *unpredictable_code = UNPRED_Q_GT_4; + return TRUE; + } + else + return FALSE; + } + default: return FALSE; } @@ -4195,11 +4306,61 @@ print_mve_unpredictable (struct disassemble_info *info, func (stream, "use of r15 (pc)"); break; + case UNPRED_Q_GT_4: + func (stream, "start register block > r4"); + break; + + case UNPRED_Q_GT_6: + func (stream, "start register block > r6"); + break; + + case UNPRED_R13_AND_WB: + func (stream, "use of r13 and write back"); + break; + case UNPRED_NONE: break; } } +/* Print register block operand for mve vld2/vld4/vst2/vld4. */ + +static void +print_mve_register_blocks (struct disassemble_info *info, + unsigned long given, + enum mve_instructions matched_insn) +{ + void *stream = info->stream; + fprintf_ftype func = info->fprintf_func; + + unsigned long q_reg_start = arm_decode_field_multiple (given, + 13, 15, + 22, 22); + switch (matched_insn) + { + case MVE_VLD2: + case MVE_VST2: + if (q_reg_start <= 6) + func (stream, "{q%ld, q%ld}", q_reg_start, q_reg_start + 1); + else + func (stream, "", q_reg_start); + break; + + case MVE_VLD4: + case MVE_VST4: + if (q_reg_start <= 4) + func (stream, "{q%ld, q%ld, q%ld, q%ld}", q_reg_start, + q_reg_start + 1, q_reg_start + 2, + q_reg_start + 3); + else + func (stream, "", q_reg_start); + break; + + default: + break; + } +} + static void print_instruction_predicate (struct disassemble_info *info) { @@ -4232,6 +4393,8 @@ print_mve_size (struct disassemble_info *info, case MVE_VHADD_T2: case MVE_VHSUB_T1: case MVE_VHSUB_T2: + case MVE_VLD2: + case MVE_VLD4: case MVE_VPT_VEC_T1: case MVE_VPT_VEC_T2: case MVE_VPT_VEC_T3: @@ -4239,6 +4402,8 @@ print_mve_size (struct disassemble_info *info, case MVE_VPT_VEC_T5: case MVE_VPT_VEC_T6: case MVE_VRHADD: + case MVE_VST2: + case MVE_VST4: if (size <= 3) func (stream, "%s", mve_vec_sizename[size]); else @@ -5752,6 +5917,15 @@ print_insn_mve (struct disassemble_info *info, long given) print_instruction_predicate (info); break; + case 'w': + if (arm_decode_field (given, 21, 21) == 1) + func (stream, "!"); + break; + + case 'B': + print_mve_register_blocks (info, given, insn->mve_op); + break; + case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { @@ -5778,6 +5952,10 @@ print_insn_mve (struct disassemble_info *info, long given) case 'r': func (stream, "%s", arm_regnames[value]); break; + case 'd': + func (stream, "%ld", value); + value_in_comment = value; + break; case 'Q': if (value & 0x8) func (stream, "", value); --------------DE711A355556B28325C0AC0A--