This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[AArch64] Don't warn on XZR/SP overlapping when it's in load/store
- From: Jiong Wang <jiong dot wang at arm dot com>
- To: "binutils at sourceware dot org" <binutils at sourceware dot org>
- Date: Fri, 13 Mar 2015 11:22:31 +0000
- Subject: [AArch64] Don't warn on XZR/SP overlapping when it's in load/store
- Authentication-results: sourceware.org; auth=none
for load/store write back, normally, we should give unpredicatable warning
when any operand register is the same as the base register.
but for register 31, they will never be the same hard register in load/store
context when one is base register and the other is not.
register 31 in base register slot always interpreated as SP, while interpreated
as XZR in read/write operand. there is no need to warn in "warn_unpredictable_ldst" thus.
This is documented on ARMARM also.
this glitch was introduced by the following commit where the tricky reg 31 haven't been
considered.
commit 54a28c4ce5b18cccee584d7a5e26df750edfafe1
Author: Jiong Wang <jiong.wang@arm.com>
Date: Wed Nov 19 09:35:23 2014 +0000
[AArch64] Warn on load pair to same register
2014-11-19 Ryan Mansfield <rmansfield@qnx.com>
* config/tc-aarch64.c (md_assemble): Call warn_unpredictable_ldst.
(warn_unpredictable_ldst): New.
ok for trunk?
Thanks.
2015-03-13 Jiong Wang <jiong.wang@arm.com>
gas/
* config/tc-aarch64.c (warn_unpredictable_ldst): Don't warn on reg number 31.
gas/testsuite/
* gas/aarch64/diagnostic.s: New testcases.
* gas/aarch64/diagnostic.l: New error match.
diff --git a/gas/config/tc-aarch64.c b/gas/config/tc-aarch64.c
index 77701c6..5031134 100644
--- a/gas/config/tc-aarch64.c
+++ b/gas/config/tc-aarch64.c
@@ -5585,6 +5585,7 @@ warn_unpredictable_ldst (aarch64_instruction *instr, char *str)
if ((aarch64_get_operand_class (opnds[0].type)
== AARCH64_OPND_CLASS_INT_REG)
&& opnds[0].reg.regno == opnds[1].addr.base_regno
+ && opnds[1].addr.base_regno != REG_SP
&& opnds[1].addr.writeback)
as_warn (_("unpredictable transfer with writeback -- `%s'"), str);
break;
@@ -5596,6 +5597,7 @@ warn_unpredictable_ldst (aarch64_instruction *instr, char *str)
== AARCH64_OPND_CLASS_INT_REG)
&& (opnds[0].reg.regno == opnds[2].addr.base_regno
|| opnds[1].reg.regno == opnds[2].addr.base_regno)
+ && opnds[2].addr.base_regno != REG_SP
&& opnds[2].addr.writeback)
as_warn (_("unpredictable transfer with writeback -- `%s'"), str);
/* Load operations must load different registers. */
diff --git a/gas/testsuite/gas/aarch64/diagnostic.l b/gas/testsuite/gas/aarch64/diagnostic.l
index 7a89f8e..2d7bd48 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.l
+++ b/gas/testsuite/gas/aarch64/diagnostic.l
@@ -116,3 +116,7 @@
[^:]*:125: Warning: unpredictable transfer with writeback -- `ldp x0,x1,\[x1\],#16'
[^:]*:126: Error: this relocation modifier is not allowed on this instruction at operand 2 -- `adr x2,:got:s1'
[^:]*:127: Error: this relocation modifier is not allowed on this instruction at operand 2 -- `ldr x0,\[x0,:got:s1\]'
+[^:]*:130: Error: integer 64-bit register expected at operand 2 -- `ldr x1,\[wsp,#8\]!'
+[^:]*:131: Error: integer 64-bit register expected at operand 3 -- `ldp x6,x29,\[w7,#8\]!'
+[^:]*:132: Error: integer 64-bit register expected at operand 2 -- `str x30,\[w11,#8\]!'
+[^:]*:133: Error: integer 64-bit register expected at operand 3 -- `stp x8,x27,\[wsp,#8\]!'
diff --git a/gas/testsuite/gas/aarch64/diagnostic.s b/gas/testsuite/gas/aarch64/diagnostic.s
index 7650b65..ececd20 100644
--- a/gas/testsuite/gas/aarch64/diagnostic.s
+++ b/gas/testsuite/gas/aarch64/diagnostic.s
@@ -125,3 +125,87 @@
ldp x0, x1, [x1], #16
adr x2, :got:s1
ldr x0, [x0, :got:s1]
+
+ # Test error of 32-bit base reg
+ ldr x1, [wsp, #8]!
+ ldp x6, x29, [w7, #8]!
+ str x30, [w11, #8]!
+ stp x8, x27, [wsp, #8]!
+
+ # Test various valid load/store reg combination.
+ # especially we shouldn't warn on xzr, although
+ # xzr is with the same encoding 31 as sp.
+ .macro ldst_pair_wb_2 op, reg1, reg2
+ .irp base x3, x6, x25, sp
+ \op \reg1, \reg2, [\base], #16
+ \op \reg1, \reg2, [\base, #32]!
+ \op \reg2, \reg1, [\base], #32
+ \op \reg2, \reg1, [\base, #16]!
+ .endr
+ .endm
+
+ .macro ldst_pair_wb_1 op, reg1, width
+ .irp reg2 0, 14, 21, 23, 29
+ ldst_pair_wb_2 \op, \reg1, \width\reg2
+ .endr
+ .endm
+
+ .macro ldst_pair_wb_64 op
+ .irp reg1 x2, x15, x16, x27, x30, xzr
+ ldst_pair_wb_1 \op, \reg1, x
+ .endr
+ .endm
+
+ .macro ldst_pair_wb_32 op
+ .irp reg1 w1, w12, w16, w19, w30, wzr
+ ldst_pair_wb_1 \op, \reg1, w
+ .endr
+ .endm
+
+ .macro ldst_single_wb_1 op, reg
+ .irp base x1, x4, x13, x26, sp
+ \op \reg, [\base], #16
+ .endr
+ .endm
+
+ .macro ldst_single_wb_32 op
+ .irp reg w0, w3, w12, w21, w28, w30, wzr
+ ldst_single_wb_1 \op, \reg
+ .endr
+ .endm
+
+ .macro ldst_single_wb_64 op
+ .irp reg x2, x5, x17, x23, x24, x30, xzr
+ ldst_single_wb_1 \op, \reg
+ .endr
+ .endm
+
+ ldst_pair_wb_32 stp
+ ldst_pair_wb_64 stp
+
+ ldst_pair_wb_32 ldp
+ ldst_pair_wb_64 ldp
+
+ ldst_pair_wb_64 ldpsw
+
+ ldst_single_wb_32 str
+ ldst_single_wb_64 str
+
+ ldst_single_wb_32 strb
+
+ ldst_single_wb_32 strh
+
+ ldst_single_wb_32 ldr
+ ldst_single_wb_64 ldr
+
+ ldst_single_wb_32 ldrb
+
+ ldst_single_wb_32 ldrh
+
+ ldst_single_wb_32 ldrsb
+ ldst_single_wb_64 ldrsb
+
+ ldst_single_wb_32 ldrsh
+ ldst_single_wb_64 ldrsh
+
+ ldst_single_wb_64 ldrsw