This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][ARM] Use proper output modifier for DImode register in store exclusive patterns
- From: Kyrill Tkachov <kyrylo dot tkachov at foss dot arm dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Cc: Ramana Radhakrishnan <ramana dot radhakrishnan at arm dot com>, Richard Earnshaw <Richard dot Earnshaw at arm dot com>
- Date: Wed, 09 Mar 2016 12:56:21 +0000
- Subject: [PATCH][ARM] Use proper output modifier for DImode register in store exclusive patterns
- Authentication-results: sourceware.org; auth=none
Hi all,
I notice that the output code for our store exclusive patterns accesses unallocated memory.
It wants to output an strexd instruction with a pair of consecutive registers corresponding
to a DImode value. For that it creates the SImode top half of the DImode register and puts it
into operands[3]. But the pattern only defines entries only up to operands[2], with no match_dup 3
or like that, so operands[3] should technically be out of bounds.
We already have a mechanism for printing the top half of a DImode register, that's the 'H' output modifier.
So this patch changes those patterns to use that, eliminating the out of bounds access and making
the code a bit simpler as well.
Bootstrapped and tested on arm-none-linux-gnueabihf.
Ok for trunk?
Thanks,
Kyrill
2016-03-09 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/sync.md (arm_store_exclusive<mode>):
Use 'H' output modifier on operands[2] rather than creating a new
entry in out-of-bounds memory of the operands array.
(arm_store_release_exclusivedi): Likewise.
diff --git a/gcc/config/arm/sync.md b/gcc/config/arm/sync.md
index 6dd2dc396210bc45374d13e1a20f124cc490b630..8158f53025400045569533a1e8c6583025d490c8 100644
--- a/gcc/config/arm/sync.md
+++ b/gcc/config/arm/sync.md
@@ -422,14 +422,13 @@ (define_insn "arm_store_exclusive<mode>"
{
if (<MODE>mode == DImode)
{
- rtx value = operands[2];
/* The restrictions on target registers in ARM mode are that the two
registers are consecutive and the first one is even; Thumb is
actually more flexible, but DI should give us this anyway.
- Note that the 1st register always gets the lowest word in memory. */
- gcc_assert ((REGNO (value) & 1) == 0 || TARGET_THUMB2);
- operands[3] = gen_rtx_REG (SImode, REGNO (value) + 1);
- return "strexd%?\t%0, %2, %3, %C1";
+ Note that the 1st register always gets the
+ lowest word in memory. */
+ gcc_assert ((REGNO (operands[2]) & 1) == 0 || TARGET_THUMB2);
+ return "strexd%?\t%0, %2, %H2, %C1";
}
return "strex<sync_sfx>%?\t%0, %2, %C1";
}
@@ -445,11 +444,9 @@ (define_insn "arm_store_release_exclusivedi"
VUNSPEC_SLX))]
"TARGET_HAVE_LDACQ && ARM_DOUBLEWORD_ALIGN"
{
- rtx value = operands[2];
/* See comment in arm_store_exclusive<mode> above. */
- gcc_assert ((REGNO (value) & 1) == 0 || TARGET_THUMB2);
- operands[3] = gen_rtx_REG (SImode, REGNO (value) + 1);
- return "stlexd%?\t%0, %2, %3, %C1";
+ gcc_assert ((REGNO (operands[2]) & 1) == 0 || TARGET_THUMB2);
+ return "stlexd%?\t%0, %2, %H2, %C1";
}
[(set_attr "predicable" "yes")
(set_attr "predicable_short_it" "no")])