This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[AArch64] Don't warn on XZR/SP overlapping when it's in load/store


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]