This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC 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]

[PATCH][ARM] Use proper output modifier for DImode register in store exclusive patterns


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")])

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