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]

[SH] Add atomic_exchange patterns


Hello,

The attached patch adds atomic_exchange patterns to the SH target.
This results in slightly better generated code compared to the default
compare_and_swap loop that is generated if atomic_exchange patterns are
absent.

Tested against rev 184582 with

make -k check RUNTESTFLAGS="--target_board=sh-sim
\{-m2/-ml/-msoft-atomic,
-m2/-mb/-msoft-atomic,
-m2a-single/-mb/-msoft-atomic,
-m4-single/-ml/-msoft-atomic,
-m4-single/-mb/-msoft-atomic,
-m4a-single/-ml/-msoft-atomic,
-m4a-single/-mb/-msoft-atomic}"

and no new failures.

Cheers,
Oleg

2012-02-27  Oleg Endo  <olegendo@gcc.gnu.org>

	* config/sh/sync.md (atomic_exchange<mode>): New expander.
	(atomic_exchange<mode>_soft): New insn.
Index: gcc/config/sh/sync.md
===================================================================
--- gcc/config/sh/sync.md	(revision 184582)
+++ gcc/config/sh/sync.md	(working copy)
@@ -164,6 +164,45 @@
 }
   [(set_attr "length" "20")])
 
+(define_expand "atomic_exchange<mode>"
+  [(match_operand:I124 0 "register_operand" "")		;; oldval output
+   (match_operand:I124 1 "memory_operand" "")		;; memory
+   (match_operand:I124 2 "register_operand" "")		;; newval input
+   (match_operand:SI 3 "const_int_operand" "")]		;; memory model
+  "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+{
+  rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
+  emit_insn (gen_atomic_exchange<mode>_soft
+	     (operands[0], addr, operands[2]));
+  if (<MODE>mode == QImode)
+    emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
+				     operands[0]));
+  else if (<MODE>mode == HImode)
+    emit_insn (gen_zero_extendhisi2 (gen_lowpart (SImode, operands[0]),
+				     operands[0]));
+  DONE;
+})
+
+(define_insn "atomic_exchange<mode>_soft"
+  [(set (match_operand:I124 0 "register_operand" "=&u")
+	(mem:I124 (match_operand:SI 1 "register_operand" "u")))
+   (set (mem:I124 (match_dup 1))
+	(unspec:I124
+	  [(match_operand:I124 2 "register_operand" "u")] UNSPEC_ATOMIC))
+   (clobber (reg:SI R0_REG))
+   (clobber (reg:SI R1_REG))]
+  "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
+{
+  return "mova	1f,r0"				"\n"
+	 "	.align 2"			"\n"
+	 "	mov	r15,r1"			"\n"
+	 "	mov	#(0f-1f),r15"		"\n"
+	 "0:	mov.<i124suffix>	@%1,%0"	"\n"
+	 "	mov.<i124suffix>	%2,@%1"	"\n"
+	 "1:	mov	r1,r15";
+}
+  [(set_attr "length" "14")])
+
 (define_expand "atomic_fetch_<fetchop_name><mode>"
   [(set (match_operand:I124 0 "register_operand" "")
 	(match_operand:I124 1 "memory_operand" ""))

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