From patchwork Tue Nov 1 12:21:19 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jiong Wang X-Patchwork-Id: 80337 Delivered-To: patch@linaro.org Received: by 10.140.97.247 with SMTP id m110csp599591qge; Tue, 1 Nov 2016 05:21:50 -0700 (PDT) X-Received: by 10.99.156.10 with SMTP id f10mr49559181pge.123.1478002910704; Tue, 01 Nov 2016 05:21:50 -0700 (PDT) Return-Path: Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id tc3si25132527pab.207.2016.11.01.05.21.50 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 01 Nov 2016 05:21:50 -0700 (PDT) Received-SPF: pass (google.com: domain of binutils-return-94279-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Authentication-Results: mx.google.com; dkim=pass header.i=@sourceware.org; spf=pass (google.com: domain of binutils-return-94279-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) smtp.mailfrom=binutils-return-94279-patch=linaro.org@sourceware.org DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:from:subject:message-id:date:mime-version :content-type; q=dns; s=default; b=yqSfsJjTDJV4Vl0izC6chxPMXWVdz D0fCf4eCKwT37QSoA12XeNR5CvHaSHy00q9lh+YNQQ2VogH9NZGCOFCoRADwwyqF 2LPUklqOVBc4ofLZX5vcIIBkxqNzuR9lDYP/17L1xFP10TEHnfP81PaCxqYcEyVp I9wqDJYX8xQbZ0= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:to:from:subject:message-id:date:mime-version :content-type; s=default; bh=s5mkiZIZd9eHweNYEit1sGQRato=; b=USf A6qIffKZ52phLcVn6b/6lRKlzKjOU98J8cWFMrzEv+cSBRsSZJKr7D8/afFWQnUc 3oM9/i+TupFXFK50Ya4mwzVtL/UfCWwdOnq3n9FTuFgcdJ7XmT+pK6MUqPAErz7D KIj4LGmOcj/neuFD6Svt1dCXNlEVu1NT3EJ57yO0= Received: (qmail 70364 invoked by alias); 1 Nov 2016 12:21:34 -0000 Mailing-List: contact binutils-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: binutils-owner@sourceware.org Delivered-To: mailing list binutils@sourceware.org Received: (qmail 70337 invoked by uid 89); 1 Nov 2016 12:21:32 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=BAYES_00, KAM_LAZY_DOMAIN_SECURITY, KAM_LOTSOFHASH, RP_MATCHES_RCVD autolearn=ham version=3.3.2 spammy=GAS, MOV, Turn, movs X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.101.70) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 01 Nov 2016 12:21:22 +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 D56B514D1; Tue, 1 Nov 2016 05:21:20 -0700 (PDT) Received: from [10.2.206.198] (e104437-lin.cambridge.arm.com [10.2.206.198]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 862B53F318 for ; Tue, 1 Nov 2016 05:21:20 -0700 (PDT) To: Binutils From: Jiong Wang Subject: [ARM] Allow MOV/MOV.W to accept all possible immediates Message-ID: <27959ba0-3b6f-185d-1c8b-55a28d7e286c@foss.arm.com> Date: Tue, 1 Nov 2016 12:21:19 +0000 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:45.0) Gecko/20100101 Thunderbird/45.4.0 MIME-Version: 1.0 X-IsSubscribed: yes Hi, AArch32 MOV Rd, #imm should accept all immediates which can be encoded into available encoding, A1/A2 for ARM, T1/T2/T3 for Thumb/Thumb2, and MOV is the preferred disassembly syntax. See latest ARM Architecture Reference Manual for ARMv8-A, section F6.1.108 and for ARMv8-M, section C2.4.89. The same for MOV.W under Thumb mode. It should try all possible 32-bit Thumb encoding instead of T2 only. This patch let MOV/MOV.W accept more immediate formats while their currently supported immediate formats are not affected, so there is no backward compatibility issue, also this patch haven't touched the disassembler. I think this patch brings GAS closer to ARM Architecture Reference Manual. OK for master? gas/ 2016-11-01 Jiong Wang * config/tc-arm.c (SBIT_SHIFT): New. (T2_SBIT_SHIFT): Likewise. (t32_insn_ok): Return TRUE for MOV in ARMv8-M Baseline. (md_apply_fix): Try UINT16 encoding when ARM/Thumb modified immediate encoding failed. * testsuite/gas/arm/archv6t2-bad.s: New error case. * testsuite/gas/arm/archv6t2-bad.l: New error match. * testsuite/gas/arm/archv6t2.s: New testcase. * testsuite/gas/arm/archv6t2.d: New expected result. * testsuite/gas/arm/archv8m.s: New testcase * testsuite/gas/arm/archv8m-base.d: New expected result. * testsuite/gas/arm/archv8m-main.d: Likewise. * testsuite/gas/arm/archv8m-main-dsp-1.d: Likewise. diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c index 73f8396396ff85276dc5bc92f79764d6d194b3d3..f28bf5297f33d69fd93961aaff51554434ab4223 100644 --- a/gas/config/tc-arm.c +++ b/gas/config/tc-arm.c @@ -685,9 +685,11 @@ struct asm_opcode #define T2_SUBS_PC_LR 0xf3de8f00 #define DATA_OP_SHIFT 21 +#define SBIT_SHIFT 20 #define T2_OPCODE_MASK 0xfe1fffff #define T2_DATA_OP_SHIFT 21 +#define T2_SBIT_SHIFT 20 #define A_COND_MASK 0xf0000000 #define A_PUSH_POP_OP_MASK 0x0fff0000 @@ -18270,6 +18272,13 @@ t32_insn_ok (arm_feature_set arch, const struct asm_opcode *opcode) && opcode->tencode == do_t_branch) return TRUE; + /* MOV accepts T1/T3 encodings under Baseline, T3 encoding is 32bit. */ + if (ARM_CPU_HAS_FEATURE (arch, arm_ext_v8m) + && opcode->tencode == do_t_mov_cmp + /* Make sure CMP instruction is not affected. */ + && opcode->aencode == do_mov) + return TRUE; + /* Wide instruction variants of all instructions with narrow *and* wide variants become available with ARMv6t2. Other opcodes are either narrow-only or wide-only and are thus available if OPCODE is valid. */ @@ -22773,6 +22782,23 @@ md_apply_fix (fixS * fixP, changing the opcode. */ if (newimm == (unsigned int) FAIL) newimm = negate_data_op (&temp, value); + /* MOV accepts both ARM modified immediate (A1 encoding) and + UINT16 (A2 encoding) when possible, MOVW only accepts UINT16. + When disassembling, MOV is preferred when there is no encoding + overlap. */ + if (newimm == (unsigned int) FAIL + && ((temp >> DATA_OP_SHIFT) & 0xf) == OPCODE_MOV + && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2) + && !((temp >> SBIT_SHIFT) & 0x1) + && value >= 0 && value <= 0xffff) + { + /* Clear bits[23:20] to change encoding from A1 to A2. */ + temp &= 0xff0fffff; + /* Encoding high 4bits imm. Code below will encode the remaining + low 12bits. */ + temp |= (value & 0x0000f000) << 4; + newimm = value & 0x00000fff; + } } if (newimm == (unsigned int) FAIL) @@ -23089,32 +23115,59 @@ md_apply_fix (fixS * fixP, newval |= md_chars_to_number (buf+2, THUMB_SIZE); newimm = FAIL; - if (fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE + if ((fixP->fx_r_type == BFD_RELOC_ARM_T32_IMMEDIATE + /* ARMv8-M Baseline MOV will reach here, but it doesn't support + Thumb2 modified immediate encoding (T2). */ + && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2)) || fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM) { newimm = encode_thumb32_immediate (value); if (newimm == (unsigned int) FAIL) newimm = thumb32_negate_data_op (&newval, value); } - if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE - && newimm == (unsigned int) FAIL) + if (newimm == (unsigned int) FAIL) { - /* Turn add/sum into addw/subw. */ - if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM) - newval = (newval & 0xfeffffff) | 0x02000000; - /* No flat 12-bit imm encoding for addsw/subsw. */ - if ((newval & 0x00100000) == 0) + if (fixP->fx_r_type != BFD_RELOC_ARM_T32_IMMEDIATE) { - /* 12 bit immediate for addw/subw. */ - if (value < 0) + /* Turn add/sum into addw/subw. */ + if (fixP->fx_r_type == BFD_RELOC_ARM_T32_ADD_IMM) + newval = (newval & 0xfeffffff) | 0x02000000; + /* No flat 12-bit imm encoding for addsw/subsw. */ + if ((newval & 0x00100000) == 0) { - value = -value; - newval ^= 0x00a00000; + /* 12 bit immediate for addw/subw. */ + if (value < 0) + { + value = -value; + newval ^= 0x00a00000; + } + if (value > 0xfff) + newimm = (unsigned int) FAIL; + else + newimm = value; + } + } + else + { + /* MOV accepts both Thumb2 modified immediate (T2 encoding) and + UINT16 (T3 encoding), MOVW only accepts UINT16. When + disassembling, MOV is preferred when there is no encoding + overlap. + NOTE: MOV is using ORR opcode under Thumb 2 mode. */ + if (((newval >> T2_DATA_OP_SHIFT) & 0xf) == T2_OPCODE_ORR + && ARM_CPU_HAS_FEATURE (cpu_variant, arm_ext_v6t2_v8m) + && !((newval >> T2_SBIT_SHIFT) & 0x1) + && value >= 0 && value <=0xffff) + { + /* Toggle bit[25] to change encoding from T2 to T3. */ + newval ^= 1 << 25; + /* Clear bits[19:16]. */ + newval &= 0xfff0ffff; + /* Encoding high 4bits imm. Code below will encode the + remaining low 12bits. */ + newval |= (value & 0x0000f000) << 4; + newimm = value & 0x00000fff; } - if (value > 0xfff) - newimm = (unsigned int) FAIL; - else - newimm = value; } } diff --git a/gas/testsuite/gas/arm/archv6t2-bad.l b/gas/testsuite/gas/arm/archv6t2-bad.l index 0f00db37b2b826c1a55f194d16b455c7c7421a26..89c28ecd2314c6405eb646f8b29ceeb30f066896 100644 --- a/gas/testsuite/gas/arm/archv6t2-bad.l +++ b/gas/testsuite/gas/arm/archv6t2-bad.l @@ -38,3 +38,4 @@ [^:]*:53: Warning: source register same as write-back base [^:]*:59: Error: instruction does not accept this addressing mode -- `ldrex r0,r2' [^:]*:60: Error: instruction does not accept this addressing mode -- `strex r1,r0,r2' +[^:]*:64: Error: invalid constant \(999\) after fixup diff --git a/gas/testsuite/gas/arm/archv6t2-bad.s b/gas/testsuite/gas/arm/archv6t2-bad.s index af1397271b629b0293d728ba1ebd6e5d656b767d..008088d923b6bb29bce440f04c6720735fabedd5 100644 --- a/gas/testsuite/gas/arm/archv6t2-bad.s +++ b/gas/testsuite/gas/arm/archv6t2-bad.s @@ -58,4 +58,7 @@ x: @ to a label called "r2". ldrex r0, r2 strex r1, r0, r2 - \ No newline at end of file + + @ movs shouldn't be extened to accept UINT16 can't fit into ARM modified + @ immediate format. + movs r0, #0x0999 diff --git a/gas/testsuite/gas/arm/archv6t2.d b/gas/testsuite/gas/arm/archv6t2.d index eb76a321a8edfee66b8676cb7b909ac0b3cf4b12..8769b3f3a180f7bb256950b12fc11f0d9e7c2a92 100644 --- a/gas/testsuite/gas/arm/archv6t2.d +++ b/gas/testsuite/gas/arm/archv6t2.d @@ -61,3 +61,4 @@ Disassembly of section .text: 0+d4 <[^>]+> e06100b2 strht r0, \[r1\], #-2 0+d8 <[^>]+> 10e100b2 strhtne r0, \[r1\], #2 0+dc <[^>]+> 106100b2 strhtne r0, \[r1\], #-2 +0+e0 <[^>]+> e3009999 movw r9, #2457 ; 0x999 diff --git a/gas/testsuite/gas/arm/archv6t2.s b/gas/testsuite/gas/arm/archv6t2.s index 81ff5012f5dec6f01cb657ea9e212e9ee07cf1b6..8d74359ad7b430d97af9f7c298198a416033f6b8 100644 --- a/gas/testsuite/gas/arm/archv6t2.s +++ b/gas/testsuite/gas/arm/archv6t2.s @@ -65,3 +65,6 @@ x: strht r0, [r1], #-2 strneht r0, [r1], #2 strneht r0, [r1], #-2 + + @ mov accept A2 encoding as well. + mov r9, #0x0999 diff --git a/gas/testsuite/gas/arm/archv8m-base.d b/gas/testsuite/gas/arm/archv8m-base.d index 6a2ee87f3b6eb90754c91c78788276b2bfd92880..6075ee048a077d0a6127607ad7d05fcccaa03cff 100644 --- a/gas/testsuite/gas/arm/archv8m-base.d +++ b/gas/testsuite/gas/arm/archv8m-base.d @@ -16,6 +16,8 @@ Disassembly of section .text: 0+.* <[^>]*> e849 f840 ttt r8, r9 0+.* <[^>]*> f24f 1023 movw r0, #61731 ; 0xf123 0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 +0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 +0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 0+.* <[^>]*> f2cf 1023 movt r0, #61731 ; 0xf123 0+.* <[^>]*> f2cf 1823 movt r8, #61731 ; 0xf123 0+.* <[^>]*> b154 cbz r4, 0+.* <[^>]*> diff --git a/gas/testsuite/gas/arm/archv8m-main-dsp-1.d b/gas/testsuite/gas/arm/archv8m-main-dsp-1.d index c8f9d7b81bf1af3949afffa7d4d3df7f3065f4bc..8c2c12d0d1cac7ca1b2f8de9abe92aa0802efc81 100644 --- a/gas/testsuite/gas/arm/archv8m-main-dsp-1.d +++ b/gas/testsuite/gas/arm/archv8m-main-dsp-1.d @@ -16,6 +16,8 @@ Disassembly of section .text: 0+.* <[^>]*> e849 f840 ttt r8, r9 0+.* <[^>]*> f24f 1023 movw r0, #61731 ; 0xf123 0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 +0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 +0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 0+.* <[^>]*> f2cf 1023 movt r0, #61731 ; 0xf123 0+.* <[^>]*> f2cf 1823 movt r8, #61731 ; 0xf123 0+.* <[^>]*> b154 cbz r4, 0+.* <[^>]*> diff --git a/gas/testsuite/gas/arm/archv8m-main.d b/gas/testsuite/gas/arm/archv8m-main.d index a0c40e99c89cef9aaef41c252bc37806d776f278..0b76db10fbda6c972007bb62ff303401f12e506a 100644 --- a/gas/testsuite/gas/arm/archv8m-main.d +++ b/gas/testsuite/gas/arm/archv8m-main.d @@ -16,6 +16,8 @@ Disassembly of section .text: 0+.* <[^>]*> e849 f840 ttt r8, r9 0+.* <[^>]*> f24f 1023 movw r0, #61731 ; 0xf123 0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 +0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 +0+.* <[^>]*> f24f 1823 movw r8, #61731 ; 0xf123 0+.* <[^>]*> f2cf 1023 movt r0, #61731 ; 0xf123 0+.* <[^>]*> f2cf 1823 movt r8, #61731 ; 0xf123 0+.* <[^>]*> b154 cbz r4, 0+.* <[^>]*> diff --git a/gas/testsuite/gas/arm/archv8m.s b/gas/testsuite/gas/arm/archv8m.s index 5f8aafed48746e19056a33405104a9768ed9feab..a82582eb889420177c5ab2afa0e4b555ec6b2047 100644 --- a/gas/testsuite/gas/arm/archv8m.s +++ b/gas/testsuite/gas/arm/archv8m.s @@ -11,6 +11,14 @@ tt r8, r9 ttt r0, r1 ttt r8, r9 movw r0, #0xF123 +@ mov accept all immediate formats, including T3. It's also the suggested +@ assembly to use. +mov r8, #0xF123 +@ .w means wide, specifies that the assembler must select a 32-bit encoding for +@ the instruction if it is possible, it should accept both T2 (Thumb modified +@ immediate) and T3 (UINT16) encoding. See the section "Standard assembler +@ syntax fields" on latest ARM-ARM. +mov.w r8, #0xF123 movw r8, #0xF123 movt r0, #0xF123 movt r8, #0xF123