🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: gmane.comp.gcc.patches
1 messages
1 total messages Started by Pat Haugen Tue, 25 Mar 2014 11:20
[PATCH, rs6000] Improve atomic_load/store code gen for Power8 TI mode
#307983
Author: Pat Haugen
Date: Tue, 25 Mar 2014 11:20
224 lines
7134 bytes
This is a multi-part message in MIME format.
--------------000909010007070602050300
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

Power8 can use lq/stq instructions for TI mode atomic_load/store. 
Bootstrap/regtest with no new failures. Ok for trunk and 4.8 (once 
bootstrap/regtest finishes)?

-Pat


2014-03-25  Pat Haugen  <pthaugen@us.ibm.com>

         * config/rs6000/sync.md (AINT mode_iterator): Move definition.
         (loadsync_<mode>): Change mode.
         (atomic_load<mode>, atomic_store<mode>): Add support for TI mode.
         (load_quadpti, store_quadpti): New.
         * config/rs6000/rs6000.md (unspec enum): Add UNSPEC_LSQ.

gcc/testsuite:
         * gcc.target/powerpc/atomic_load_store-p8.c: New.



--------------000909010007070602050300
Content-Type: text/x-patch;
 name="atomic_quad.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
 filename="atomic_quad.diff"

Index: testsuite/gcc.target/powerpc/atomic_load_store-p8.c
===================================================================
--- testsuite/gcc.target/powerpc/atomic_load_store-p8.c	(revision 0)
+++ testsuite/gcc.target/powerpc/atomic_load_store-p8.c	(revision 0)
@@ -0,0 +1,22 @@
+/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */
+/* { dg-skip-if "" { powerpc*-*-darwin* } { "*" } { "" } } */
+/* { dg-require-effective-target powerpc_p8vector_ok } */
+/* { dg-options "-mcpu=power8 -O2" } */
+/* { dg-final { scan-assembler-times "lq" 1 } } */
+/* { dg-final { scan-assembler-times "stq" 1 } } */
+/* { dg-final { scan-assembler-not "bl __atomic" } } */
+/* { dg-final { scan-assembler-not "lqarx" } } */
+/* { dg-final { scan-assembler-not "stqcx" } } */
+
+__int128
+atomic_load_128_relaxed (__int128 *ptr)
+{
+	return __atomic_load_n (ptr, __ATOMIC_RELAXED);
+}
+
+void
+atomic_store_128_relaxed (__int128 *ptr, __int128 val)
+{
+	__atomic_store_n (ptr, val, __ATOMIC_RELAXED);
+}
+
Index: config/rs6000/sync.md
===================================================================
--- config/rs6000/sync.md	(revision 208798)
+++ config/rs6000/sync.md	(working copy)
@@ -107,10 +107,17 @@ (define_insn "isync"
   "isync"
   [(set_attr "type" "isync")])
 
+;; Types that we should provide atomic instructions for.
+(define_mode_iterator AINT [QI
+			    HI
+			    SI
+			    (DI "TARGET_POWERPC64")
+			    (TI "TARGET_SYNC_TI")])
+
 ;; The control dependency used for load dependency described
 ;; in B.2.3 of the Power ISA 2.06B.
 (define_insn "loadsync_<mode>"
-  [(unspec_volatile:BLK [(match_operand:INT1 0 "register_operand" "r")]
+  [(unspec_volatile:BLK [(match_operand:AINT 0 "register_operand" "r")]
 			UNSPECV_ISYNC)
    (clobber (match_scratch:CC 1 "=y"))]
   ""
@@ -119,17 +126,39 @@ (define_insn "loadsync_<mode>"
    (set_attr "length" "12")])
 
 (define_expand "atomic_load<mode>"
-  [(set (match_operand:INT1 0 "register_operand" "")		;; output
-	(match_operand:INT1 1 "memory_operand" ""))		;; memory
+  [(set (match_operand:AINT 0 "register_operand" "")		;; output
+	(match_operand:AINT 1 "memory_operand" ""))		;; memory
    (use (match_operand:SI 2 "const_int_operand" ""))]		;; model
   ""
 {
+  if (<MODE>mode == TImode && !TARGET_QUAD_MEMORY)
+    FAIL;
+
   enum memmodel model = (enum memmodel) INTVAL (operands[2]);
 
   if (model == MEMMODEL_SEQ_CST)
     emit_insn (gen_hwsync ());
 
-  emit_move_insn (operands[0], operands[1]);
+  if (<MODE>mode != TImode)
+    emit_move_insn (operands[0], operands[1]);
+  else
+    {
+      rtx op0 = operands[0];
+      rtx op1 = operands[1];
+      rtx pti_reg = gen_reg_rtx (PTImode);
+
+      // Can't have indexed address for 'lq'
+      if (indexed_address (XEXP (op1, 0), TImode))
+	{
+	  rtx old_addr = XEXP (op1, 0);
+	  rtx new_addr = force_reg (Pmode, old_addr);
+	  operands[1] = op1 = replace_equiv_address (op1, new_addr);
+	}
+
+      emit_insn (gen_load_quadpti (pti_reg, op1));
+
+      emit_move_insn (op0, gen_lowpart (TImode, pti_reg));
+    }
 
   switch (model)
     {
@@ -146,12 +175,25 @@ (define_expand "atomic_load<mode>"
   DONE;
 })
 
+(define_insn "load_quadpti"
+  [(set (match_operand:PTI 0 "quad_int_reg_operand" "=&r")
+	(unspec:PTI
+         [(match_operand:TI 1 "quad_memory_operand" "wQ")] UNSPEC_LSQ))]
+  "TARGET_QUAD_MEMORY
+   && !reg_mentioned_p (operands[0], operands[1])"
+  "lq %0,%1"
+  [(set_attr "type" "load")
+   (set_attr "length" "4")])
+
 (define_expand "atomic_store<mode>"
-  [(set (match_operand:INT1 0 "memory_operand" "")		;; memory
-	(match_operand:INT1 1 "register_operand" ""))		;; input
-   (use (match_operand:SI 2 "const_int_operand" ""))]		;; model
+  [(set (match_operand:AINT 0 "memory_operand" "")              ;; memory
+        (match_operand:AINT 1 "register_operand" ""))           ;; input
+   (use (match_operand:SI 2 "const_int_operand" ""))]           ;; model
   ""
 {
+  if (<MODE>mode == TImode && !TARGET_QUAD_MEMORY)
+    FAIL;
+
   enum memmodel model = (enum memmodel) INTVAL (operands[2]);
   switch (model)
     {
@@ -166,10 +208,38 @@ (define_expand "atomic_store<mode>"
     default:
       gcc_unreachable ();
     }
-  emit_move_insn (operands[0], operands[1]);
+  if (<MODE>mode != TImode)
+    emit_move_insn (operands[0], operands[1]);
+  else
+    {
+      rtx op0 = operands[0];
+      rtx op1 = operands[1];
+      rtx pti_reg = gen_reg_rtx (PTImode);
+
+      // Can't have indexed address for 'stq'
+      if (indexed_address (XEXP (op0, 0), TImode))
+        {
+          rtx old_addr = XEXP (op0, 0);
+          rtx new_addr = force_reg (Pmode, old_addr);
+          operands[0] = op0 = replace_equiv_address (op0, new_addr);
+        }
+
+      emit_move_insn (pti_reg, gen_lowpart (PTImode, op1));
+      emit_insn (gen_store_quadpti (gen_lowpart (PTImode, op0), pti_reg));
+    }
+
   DONE;
 })
 
+(define_insn "store_quadpti"
+  [(set (match_operand:PTI 0 "quad_memory_operand" "=wQ")
+	(unspec:PTI
+	 [(match_operand:PTI 1 "quad_int_reg_operand" "r")] UNSPEC_LSQ))]
+  "TARGET_QUAD_MEMORY"
+  "stq %1,%0"
+  [(set_attr "type" "store")
+   (set_attr "length" "4")])
+
 ;; Any supported integer mode that has atomic l<x>arx/st<x>cx. instrucitons
 ;; other than the quad memory operations, which have special restrictions.
 ;; Byte/halfword atomic instructions were added in ISA 2.06B, but were phased
@@ -180,14 +250,6 @@ (define_mode_iterator ATOMIC [(QI "TARGE
 			      SI
 			      (DI "TARGET_POWERPC64")])
 
-;; Types that we should provide atomic instructions for.
-
-(define_mode_iterator AINT [QI
-			    HI
-			    SI
-			    (DI "TARGET_POWERPC64")
-			    (TI "TARGET_SYNC_TI")])
-
 (define_insn "load_locked<mode>"
   [(set (match_operand:ATOMIC 0 "int_reg_operand" "=r")
 	(unspec_volatile:ATOMIC
Index: config/rs6000/rs6000.md
===================================================================
--- config/rs6000/rs6000.md	(revision 208798)
+++ config/rs6000/rs6000.md	(working copy)
@@ -125,6 +125,7 @@ (define_c_enum "unspec"
    UNSPEC_P8V_MTVSRD
    UNSPEC_P8V_XXPERMDI
    UNSPEC_P8V_RELOAD_FROM_VSX
+   UNSPEC_LSQ
   ])
 
 ;;

--------------000909010007070602050300--

Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads