This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[Patch, ARM, GAS] Handle PC-relative VSTR correctly.
- From: Tejas Belagod <tejas dot belagod at arm dot com>
- To: binutils at sourceware dot org
- Date: Fri, 24 Sep 2010 17:17:25 +0100
- Subject: [Patch, ARM, GAS] Handle PC-relative VSTR correctly.
Hi,
The attached patch implements 3 fixes:
1. Deprecates PC-relative VSTR in ARM mode.
2. Issues an UNPREDICTABLE error for PC-relative VSTR in thumb mode
3. Fixes the address disassembly comment for thumb mode PC-relative
VLDR.
For example, for:
.syntax unified
.text
nop
vldr d0, float
vldr d0, float
nop
nop
.align
float: .double 0.0
the disassembly was incorrectly being printed as:
0: bf00 nop
2: ed9f 0b03 vldr d0, [pc, #12] ; 12 <float+0x2>
6: ed9f 0b02 vldr d0, [pc, #8] ; 12 <float+0x2>
a: bf00 nop
c: bf00 nop
e: bf00 nop
00000010 <float>:
...
This patch fixes this:
...
2: ed9f 0b03 vldr d0, [pc, #12] ; 10 <float>
6: ed9f 0b02 vldr d0, [pc, #8] ; 10 <float>
...
e: bf00 nop
00000010 <float>:
...
OK?
--
Tejas Belagod
ARM.
ChangeLog:
gas/
2010-09-24 Tejas Belagod <tejas.belagod@arm.com>
* config/tc-arm.c (do_neon_ldr_str): Deprecate ARM-mode
PC-relative VSTR, issue an error in THUMB mode.
opcodes/
2010-09-24 Tejas Belagod <tejas.belagod@arm.com>
* arm-dis.c (print_insn_coprocessor): Apply off-by-alignment
correction to unaligned PCs while printing comment.
gas/testsuite/
2010-09-24 Tejas Belagod <tejas.belagod@arm.com>
* vldr.s: New test for pc-relative VLDR disassembly comment.
* vldr.d: Likewise.
* vstr-bad.s: New test for PC-relative VSTR.
* vstr-thumb-bad.l: Likewise.
* vstr-thumb-bad.d: Likewise.
* vstr-arm-bad.l: Likewise.
* vstr-arm-bad.d: Likewise.
diff --git a/gas/config/tc-arm.c b/gas/config/tc-arm.c
index e4bd9f1..fc3d63d 100644
--- a/gas/config/tc-arm.c
+++ b/gas/config/tc-arm.c
@@ -14885,6 +14885,18 @@ do_neon_ldr_str (void)
{
int is_ldr = (inst.instruction & (1 << 20)) != 0;
+ /* Use of PC in vstr in ARM mode is deprecated in ARMv7.
+ And is UNPREDICTABLE in thumb mode. */
+ if (!is_ldr
+ && inst.operands[1].reg == REG_PC
+ && ARM_CPU_HAS_FEATURE (selected_cpu, arm_ext_v7))
+ {
+ if (!thumb_mode && warn_on_deprecated)
+ as_warn (_("Use of PC here is deprecated"));
+ else
+ inst.error = _("Use of PC here is UNPREDICTABLE");
+ }
+
if (inst.operands[0].issingle)
{
if (is_ldr)
diff --git a/gas/testsuite/gas/arm/vldr.d b/gas/testsuite/gas/arm/vldr.d
new file mode 100644
index 0000000..d5c9331
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldr.d
@@ -0,0 +1,15 @@
+# name: VFP VLDR
+# as: -mfpu=vfp3 -mcpu=cortex-a8 -mthumb
+# source: vldr.s
+# objdump: -dr --prefix-addresses --show-raw-insn
+
+.*: +file format .*arm.*
+
+Disassembly of section .text:
+0[0-9a-f]+ <[^>]+> bf00 nop
+0[0-9a-f]+ <[^>]+> ed9f 0b03 vldr d0, \[pc, #12\] ; 00000010 <float>
+0[0-9a-f]+ <[^>]+> ed9f 0b02 vldr d0, \[pc, #8\] ; 00000010 <float>
+0[0-9a-f]+ <[^>]+> bf00 nop
+0[0-9a-f]+ <[^>]+> bf00 nop
+0[0-9a-f]+ <[^>]+> bf00 nop
+ ...
diff --git a/gas/testsuite/gas/arm/vldr.s b/gas/testsuite/gas/arm/vldr.s
new file mode 100644
index 0000000..86bc82e
--- /dev/null
+++ b/gas/testsuite/gas/arm/vldr.s
@@ -0,0 +1,10 @@
+.syntax unified
+.text
+ nop
+ vldr d0, float
+ vldr d0, float
+ nop
+ nop
+
+.align
+float: .double 0.0
diff --git a/gas/testsuite/gas/arm/vstr-arm-bad.d b/gas/testsuite/gas/arm/vstr-arm-bad.d
new file mode 100644
index 0000000..32a041f
--- /dev/null
+++ b/gas/testsuite/gas/arm/vstr-arm-bad.d
@@ -0,0 +1,4 @@
+# name: VFP PC-relative VSTR arm mode
+# as: -mfpu=vfp3 -mcpu=cortex-a8
+# source: vstr-bad.s
+# error-output: vstr-arm-bad.l
diff --git a/gas/testsuite/gas/arm/vstr-arm-bad.l b/gas/testsuite/gas/arm/vstr-arm-bad.l
new file mode 100644
index 0000000..0d48327
--- /dev/null
+++ b/gas/testsuite/gas/arm/vstr-arm-bad.l
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:6: Warning: Use of PC here is deprecated
+[^:]*:7: Warning: Use of PC here is deprecated
diff --git a/gas/testsuite/gas/arm/vstr-bad.s b/gas/testsuite/gas/arm/vstr-bad.s
new file mode 100644
index 0000000..f5a1365
--- /dev/null
+++ b/gas/testsuite/gas/arm/vstr-bad.s
@@ -0,0 +1,12 @@
+
+.syntax unified
+.text
+
+ nop
+ vstr d0, float
+ vstr d0, [pc, #4]
+ nop
+ nop
+
+.align
+float: .double 0.0
diff --git a/gas/testsuite/gas/arm/vstr-thumb-bad.d b/gas/testsuite/gas/arm/vstr-thumb-bad.d
new file mode 100644
index 0000000..798f16d
--- /dev/null
+++ b/gas/testsuite/gas/arm/vstr-thumb-bad.d
@@ -0,0 +1,4 @@
+# name: VFP PC-relative VSTR thumb mode
+# as: -mfpu=vfp3 -mthumb -mcpu=cortex-a8
+# source: vstr-bad.s
+# error-output: vstr-thumb-bad.l
diff --git a/gas/testsuite/gas/arm/vstr-thumb-bad.l b/gas/testsuite/gas/arm/vstr-thumb-bad.l
new file mode 100644
index 0000000..1660fbf
--- /dev/null
+++ b/gas/testsuite/gas/arm/vstr-thumb-bad.l
@@ -0,0 +1,3 @@
+[^:]*: Assembler messages:
+[^:]*:6: Error: Use of PC here is UNPREDICTABLE -- `vstr d0,float'
+[^:]*:7: Error: Use of PC here is UNPREDICTABLE -- `vstr d0,\[pc,#4\]'
diff --git a/opcodes/arm-dis.c b/opcodes/arm-dis.c
index 3dfbf5c..b8d02e5 100644
--- a/opcodes/arm-dis.c
+++ b/opcodes/arm-dis.c
@@ -1910,8 +1910,12 @@ print_insn_coprocessor (bfd_vma pc,
if (rn == 15 && (PRE_BIT_SET || WRITEBACK_BIT_SET))
{
func (stream, "\t; ");
- info->print_address_func (offset + pc
- + info->bytes_per_chunk * 2, info);
+ /* For unaligned PCs, apply off-by-alignment
+ correction. */
+ info->print_address_func (offset + pc
+ + info->bytes_per_chunk * 2
+ - (pc & 3),
+ info);
}
}
break;