2011-06-09 James Greenhalgh <james.greenhalgh@arm.com>

* config/tc-arm.c (do_ldrd): Warn in unpredictable cases.

2011-06-09  James Greenhalgh  <james.greenhalgh@arm.com>

	* gas/arm/ldrd-unpredicatble.d: New testcase.
	* gas/arm/ldrd-unpredicatble.s: Likewise.
	* gas/arm/ldrd-unpredicatble.l: Likewise.
This commit is contained in:
Richard Earnshaw 2011-06-09 09:59:34 +00:00
parent 2ddcd4af49
commit c56791bbad
6 changed files with 50 additions and 18 deletions

View File

@ -1,3 +1,7 @@
2011-06-09 James Greenhalgh <james.greenhalgh@arm.com>
* config/tc-arm.c (do_ldrd): Warn in unpredictable cases.
2011-06-03 Arnaud Patard <arnaud.patard@rtp-net.org>
PR gas/12698

View File

@ -7798,35 +7798,34 @@ static void
do_ldrd (void)
{
constraint (inst.operands[0].reg % 2 != 0,
_("first destination register must be even"));
_("first transfer register must be even"));
constraint (inst.operands[1].present
&& inst.operands[1].reg != inst.operands[0].reg + 1,
_("can only load two consecutive registers"));
_("can only transfer two consecutive registers"));
constraint (inst.operands[0].reg == REG_LR, _("r14 not allowed here"));
constraint (!inst.operands[2].isreg, _("'[' expected"));
if (!inst.operands[1].present)
inst.operands[1].reg = inst.operands[0].reg + 1;
if (inst.instruction & LOAD_BIT)
/* encode_arm_addr_mode_3 will diagnose overlap between the base
register and the first register written; we have to diagnose
overlap between the base and the second register written here. */
if (inst.operands[2].reg == inst.operands[1].reg
&& (inst.operands[2].writeback || inst.operands[2].postind))
as_warn (_("base register written back, and overlaps "
"second transfer register"));
if (!(inst.instruction & V4_STR_BIT))
{
/* encode_arm_addr_mode_3 will diagnose overlap between the base
register and the first register written; we have to diagnose
overlap between the base and the second register written here. */
if (inst.operands[2].reg == inst.operands[1].reg
&& (inst.operands[2].writeback || inst.operands[2].postind))
as_warn (_("base register written back, and overlaps "
"second destination register"));
/* For an index-register load, the index register must not overlap the
destination (even if not write-back). */
else if (inst.operands[2].immisreg
&& ((unsigned) inst.operands[2].imm == inst.operands[0].reg
|| (unsigned) inst.operands[2].imm == inst.operands[1].reg))
as_warn (_("index register overlaps destination register"));
destination (even if not write-back). */
if (inst.operands[2].immisreg
&& ((unsigned) inst.operands[2].imm == inst.operands[0].reg
|| (unsigned) inst.operands[2].imm == inst.operands[1].reg))
as_warn (_("index register overlaps transfer register"));
}
inst.instruction |= inst.operands[0].reg << 12;
encode_arm_addr_mode_3 (2, /*is_t=*/FALSE);
}

View File

@ -1,3 +1,9 @@
2011-06-09 James Greenhalgh <james.greenhalgh@arm.com>
* gas/arm/ldrd-unpredicatble.d: New testcase.
* gas/arm/ldrd-unpredicatble.s: Likewise.
* gas/arm/ldrd-unpredicatble.l: Likewise.
2011-06-02 Jie Zhang <jie@codesourcery.com>
Nathan Sidwell <nathan@codesourcery.com>

View File

@ -0,0 +1,2 @@
# name: Unpredictable LDRD and STRD instructions. - ARM
# error-output: ldrd-unpredictable.l

View File

@ -0,0 +1,7 @@
[^:]*: Assembler messages:
[^:]*:6: Warning: index register overlaps transfer register
[^:]*:7: Warning: index register overlaps transfer register
[^:]*:8: Warning: source register same as write-back base
[^:]*:9: Warning: base register written back, and overlaps second transfer register
[^:]*:13: Warning: source register same as write-back base
[^:]*:14: Warning: base register written back, and overlaps second transfer register

View File

@ -0,0 +1,14 @@
.syntax unified
.arm
@ LDRD
ldrd r0,r1,[r0,r1] @ unpredictable
ldrd r0,r1,[r1,r0] @ ditto
ldrd r0,r1,[r0,r2]! @ ditto
ldrd r0,r1,[r1,r2]! @ ditto
@ STRD
strd r0,r1,[r0,r2]! @ ditto
strd r0,r1,[r1,r2]! @ ditto