This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[SPARC] Fix PR target/44484
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sun, 25 Jul 2010 23:33:17 +0200
- Subject: [SPARC] Fix PR target/44484
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
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")