[SPARC] Fix PR target/44484

Submitted by Eric Botcazou on July 25, 2010, 9:33 p.m.

Details

Message ID 201007252333.17762.ebotcazou@adacore.com
State New
Headers show

Commit Message

Eric Botcazou July 25, 2010, 9:33 p.m.
This is a fallout of Bernd's IRA patch applied in early July.  The 'cas' 
instruction is irregular on the SPARC because it takes a memory operand with 
a specific address form, namely [REG].  The SPARC back-end isn't wired to 
deal with this irregularity and an ad-hoc predicate was added to try to 
prevent the other address forms from being used.  The effect of Bernd's patch 
is to bypass the predicate in some cases, exposing the naked constraint that 
accepts all the regular address forms.

Fixed by encoding the address form in the pattern, tested on SPARC/Solaris and 
SPARC64/Solaris, applied on the mainline.


2010-07-25  Eric Botcazou  <ebotcazou@adacore.com>

	PR target/44484
	* config/sparc/predicates.md (memory_reg_operand): Delete.
	* config/sparc/sync.md (sync_compare_and_swap): Minor tweaks.
	(*sync_compare_and_swap): Encode the address form in the pattern.
	(*sync_compare_and_swapdi_v8plus): Likewise.


--  
Eric Botcazou

Patch hide | download patch | download mbox

Index: config/sparc/predicates.md
===================================================================
--- config/sparc/predicates.md	(revision 162502)
+++ config/sparc/predicates.md	(working copy)
@@ -1,5 +1,5 @@ 
 ;; Predicate definitions for SPARC.
-;; Copyright (C) 2005, 2007, 2008 Free Software Foundation, Inc.
+;; Copyright (C) 2005, 2007, 2008, 2010 Free Software Foundation, Inc.
 ;;
 ;; This file is part of GCC.
 ;;
@@ -473,9 +473,3 @@  (define_predicate "cc_arith_operator"
 ;; and (xor ... (not ...)) to (not (xor ...)).  */
 (define_predicate "cc_arith_not_operator"
   (match_code "and,ior"))
-
-;; Return true if OP is memory operand with just [%reg] addressing mode.
-(define_predicate "memory_reg_operand"
-  (and (match_code "mem")
-       (and (match_operand 0 "memory_operand")
-	    (match_test "REG_P (XEXP (op, 0))"))))
Index: config/sparc/sync.md
===================================================================
--- config/sparc/sync.md	(revision 162502)
+++ config/sparc/sync.md	(working copy)
@@ -1,5 +1,5 @@ 
 ;; GCC machine description for SPARC synchronization instructions.
-;; Copyright (C) 2005, 2007, 2009
+;; Copyright (C) 2005, 2007, 2009, 2010
 ;; Free Software Foundation, Inc.
 ;;
 ;; This file is part of GCC.
@@ -62,7 +62,7 @@  (define_expand "sync_compare_and_swap<mo
 
 (define_expand "sync_compare_and_swap<mode>"
   [(parallel
-     [(set (match_operand:I48MODE 0 "register_operand" "=r")
+     [(set (match_operand:I48MODE 0 "register_operand" "")
 	   (match_operand:I48MODE 1 "memory_operand" ""))
       (set (match_dup 1)
 	   (unspec_volatile:I48MODE
@@ -71,7 +71,7 @@  (define_expand "sync_compare_and_swap<mo
 	     UNSPECV_CAS))])]
   "TARGET_V9"
 {
-  if (! REG_P (XEXP (operands[1], 0)))
+  if (!REG_P (XEXP (operands[1], 0)))
     {
       rtx addr = force_reg (Pmode, XEXP (operands[1], 0));
       operands[1] = replace_equiv_address (operands[1], addr);
@@ -81,20 +81,20 @@  (define_expand "sync_compare_and_swap<mo
 
 (define_insn "*sync_compare_and_swap<mode>"
   [(set (match_operand:I48MODE 0 "register_operand" "=r")
-	(match_operand:I48MODE 1 "memory_reg_operand" "+m"))
-   (set (match_dup 1)
+	(mem:I48MODE (match_operand 1 "register_operand" "r")))
+   (set (mem:I48MODE (match_dup 1))
 	(unspec_volatile:I48MODE
 	  [(match_operand:I48MODE 2 "register_operand" "r")
 	   (match_operand:I48MODE 3 "register_operand" "0")]
 	  UNSPECV_CAS))]
   "TARGET_V9 && (<MODE>mode == SImode || TARGET_ARCH64)"
-  "cas<modesuffix>\t%1, %2, %0"
+  "cas<modesuffix>\t[%1], %2, %0"
   [(set_attr "type" "multi")])
 
 (define_insn "*sync_compare_and_swapdi_v8plus"
   [(set (match_operand:DI 0 "register_operand" "=h")
-	(match_operand:DI 1 "memory_reg_operand" "+m"))
-   (set (match_dup 1)
+	(mem:DI (match_operand 1 "register_operand" "r")))
+   (set (mem:DI (match_dup 1))
 	(unspec_volatile:DI
 	  [(match_operand:DI 2 "register_operand" "h")
 	   (match_operand:DI 3 "register_operand" "0")]
@@ -109,7 +109,7 @@  (define_insn "*sync_compare_and_swapdi_v
     output_asm_insn ("srl\t%L2, 0, %L2", operands);
   output_asm_insn ("sllx\t%H2, 32, %H3", operands);
   output_asm_insn ("or\t%L2, %H3, %H3", operands);
-  output_asm_insn ("casx\t%1, %H3, %L3", operands);
+  output_asm_insn ("casx\t[%1], %H3, %L3", operands);
   return "srlx\t%L3, 32, %H3";
 }
   [(set_attr "type" "multi")