aboutsummaryrefslogtreecommitdiff
path: root/gas
diff options
context:
space:
mode:
authorJiong Wang <jiong.wang@arm.com>2016-11-03 12:00:53 +0000
committerJiong Wang <jiong.wang@arm.com>2016-11-03 12:00:53 +0000
commitbada43421274615d0d5f629a61a60b7daa71bc15 (patch)
tree9c1be5a6a202d2d65d8f1d5baabe37be2d1b43fe /gas
parent225b362d1036121a611f3dd17fdb6780070ba51f (diff)
downloadfsf-binutils-gdb-bada43421274615d0d5f629a61a60b7daa71bc15.zip
fsf-binutils-gdb-bada43421274615d0d5f629a61a60b7daa71bc15.tar.gz
fsf-binutils-gdb-bada43421274615d0d5f629a61a60b7daa71bc15.tar.bz2
[ARM] Allow MOV/MOV.W to accept all possible immediates
gas/ * 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.
Diffstat (limited to 'gas')
-rw-r--r--gas/ChangeLog16
-rw-r--r--gas/config/tc-arm.c85
-rw-r--r--gas/testsuite/gas/arm/archv6t2-bad.l1
-rw-r--r--gas/testsuite/gas/arm/archv6t2-bad.s5
-rw-r--r--gas/testsuite/gas/arm/archv6t2.d1
-rw-r--r--gas/testsuite/gas/arm/archv6t2.s3
-rw-r--r--gas/testsuite/gas/arm/archv8m-base.d2
-rw-r--r--gas/testsuite/gas/arm/archv8m-main-dsp-1.d2
-rw-r--r--gas/testsuite/gas/arm/archv8m-main.d2
-rw-r--r--gas/testsuite/gas/arm/archv8m.s8
10 files changed, 108 insertions, 17 deletions
diff --git a/gas/ChangeLog b/gas/ChangeLog
index 98aa7499..0030ab3 100644
--- a/gas/ChangeLog
+++ b/gas/ChangeLog
@@ -1,3 +1,19 @@
+2016-11-02 Jiong Wang <jiong.wang@arm.com>
+
+ * 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.
+
2016-11-02 Igor Tsimbalist <igor.v.tsimbalist@intel.com>
* config/tc-i386.c: (cpu_arch) Add .avx512_4vnniw.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index 73f8396..f28bf52 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 0f00db3..89c28ec 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 af13972..008088d 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 eb76a32..8769b3f 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 81ff501..8d74359 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 6a2ee87..6075ee0 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 c8f9d7b..8c2c12d 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 a0c40e9..0b76db1 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 5f8aafe..a82582e 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