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] s390: support for __sync_lock_test_and_set


Hi,

this patch enables support for __sync_lock_test_and_set for all integer
modes.

Bootstrapped and regtested on s390 and s390x. The patch introduces two testcase failures:
gcc.dg/ia64-sync-1.c
gcc.dg/ia64-sync-2.c

These testcases check the memory location for the value 1 after invoking __sync_lock_test_and_set.
However, the test_and_set instruction on s390(x) stores 0xff into the
memory location, which should be ok since the documentation states that
'the true contents of the memory are implementation defined'.

As discussed with rth, the best solution should be to just check that the
memory is non-null. I'll post that patch as well.

bye,
Adrian

2005-09-30  Adrian Straetling  <straetling@de.ibm.com>

	* config/s390/s390.md: ("UNSPEC_TS") New constant.
	("movstrictsi"): Add "ipm".
	("*sne"): Rename into "*snesi".
	("*snedi","sync_lock_test_and_set<mode>", 
	"sync_lock_test_and_setqi"): New patterns.
	* config/s390/s390.c: (s390_canonicalize_comparison): Allow
	more modes for EQ/NE simplification.


Index: gcc/config/s390/s390.md
===================================================================
*** gcc/config/s390/s390.md.orig	2005-08-29 19:38:01.000000000 +0200
--- gcc/config/s390/s390.md	2005-08-30 22:29:36.613160285 +0200
***************
*** 162,167 ****
--- 162,168 ----
     ; Atomic Support
     (UNSPECV_MB			700)
     (UNSPECV_CAS			701)
+    (UNSPECV_TS			702)
    ])
  
  ;;
***************
*** 1453,1468 ****
  ;
  
  (define_insn "movstrictsi"
!   [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d"))
!                          (match_operand:SI 1 "general_operand" "d,R,T,t"))]
    "TARGET_64BIT"
    "@
     lr\t%0,%1
     l\t%0,%1
     ly\t%0,%1
!    ear\t%0,%1"
!   [(set_attr "op_type" "RR,RX,RXY,RRE")
!    (set_attr "type" "lr,load,load,*")])
  
  ;
  ; movdf instruction pattern(s).
--- 1454,1470 ----
  ;
  
  (define_insn "movstrictsi"
!   [(set (strict_low_part (match_operand:SI 0 "register_operand" "+d,d,d,d,d"))
!                          (match_operand:SI 1 "general_operand" "d,R,T,t,c"))]
    "TARGET_64BIT"
    "@
     lr\t%0,%1
     l\t%0,%1
     ly\t%0,%1
!    ear\t%0,%1
!    ipm\t%0"
!   [(set_attr "op_type" "RR,RX,RXY,RRE,RRE")
!    (set_attr "type" "lr,load,load,*,*")])
  
  ;
  ; movdf instruction pattern(s).
***************
*** 4200,4206 ****
    PUT_MODE (operands[1], SImode);
  })
  
! (define_insn_and_split "*sne"
    [(set (match_operand:SI 0 "register_operand" "=d")
  	(ne:SI (match_operand:CCZ1 1 "register_operand" "0") 
  	       (const_int 0)))
--- 4202,4223 ----
    PUT_MODE (operands[1], SImode);
  })
  
! (define_insn_and_split "*snedi"
!   [(set (match_operand:DI 0 "register_operand" "=d")
! 	(ne:DI (reg:CCZ1 CC_REGNUM)
! 	       (const_int 0)))
!    (clobber (reg:CC CC_REGNUM))]
!   "TARGET_64BIT"
!   "#"
!   "reload_completed"
!   [(set (match_dup 0) (const_int 0))
!    (set (strict_low_part (match_dup 1)) (reg:SI CC_REGNUM))
!    (parallel
!     [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 28)))
!      (clobber (reg:CC CC_REGNUM))])]
!   "operands[1] = gen_lowpart (SImode, operands[0]);")
! 
! (define_insn_and_split "*snesi"
    [(set (match_operand:SI 0 "register_operand" "=d")
  	(ne:SI (match_operand:CCZ1 1 "register_operand" "0") 
  	       (const_int 0)))
***************
*** 7174,7179 ****
--- 7191,7241 ----
     (set_attr "type"   "sem")])
  
  
+ ;
+ ; test and set pattern.
+ ;
+ 
+ (define_expand "sync_lock_test_and_set<mode>"
+   [(parallel
+     [(set (match_dup 1)
+   	  (unspec_volatile:QI
+ 	    [(match_operand:QI 1 "memory_operand" "")
+ 	     (match_operand:QI 2 "const_int_operand" "")]
+ 	    UNSPECV_TS))
+      (set (reg:CCZ1 CC_REGNUM)
+ 	  (compare:CCZ1 (match_dup 1)
+ 		        (const_int 0)))])
+    (parallel
+     [(set (match_operand:INT 0 "register_operand" "")
+ 	  (match_dup 3))
+      (clobber (reg:CC CC_REGNUM))])]
+   ""
+ {
+   if (INTVAL (operands[2]) != 1)
+     FAIL;
+ 
+   if (<MODE>mode != DImode)
+     operands[0] = gen_lowpart (SImode, operands[0]);
+   /* Adjust address to the least significant byte.  */
+   operands[1] = adjust_address (operands[1], QImode, GET_MODE_SIZE(<MODE>mode)
+ 					             - GET_MODE_SIZE (QImode));
+   /* Emit comparison with CC.  */
+   operands[3] = gen_rtx_fmt_ee (NE, (<MODE>mode == DImode) ? DImode : SImode, 
+ 				gen_rtx_REG (CCZ1mode, CC_REGNUM), const0_rtx);
+ })
+ 
+ (define_insn "*sync_lock_test_and_setqi"
+   [(set (match_operand:QI 0 "memory_operand" "+Q")
+ 	(unspec_volatile:QI [(match_dup 0) (const_int 1)] UNSPECV_TS))
+    (set (reg:CCZ1 CC_REGNUM)
+ 	(compare:CCZ1 (match_dup 0)
+ 		      (const_int 0)))]
+   ""
+   "ts\t%S0"
+   [(set_attr "op_type" "S")
+    (set_attr "type" "sem")])
+ 
+ 
  ;;
  ;;- Miscellaneous instructions.
  ;;
Index: gcc/config/s390/s390.c
===================================================================
*** gcc/config/s390/s390.c.orig	2005-08-29 19:38:01.000000000 +0200
--- gcc/config/s390/s390.c	2005-08-30 22:31:45.493160285 +0200
*************** s390_canonicalize_comparison (enum rtx_c
*** 696,702 ****
    /* Simplify cascaded EQ, NE with const0_rtx.  */
    if ((*code == NE || *code == EQ)
        && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
!       && GET_MODE (*op0) == SImode
        && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
        && REG_P (XEXP (*op0, 0))
        && XEXP (*op0, 1) == const0_rtx
--- 696,702 ----
    /* Simplify cascaded EQ, NE with const0_rtx.  */
    if ((*code == NE || *code == EQ)
        && (GET_CODE (*op0) == EQ || GET_CODE (*op0) == NE)
!       && INTEGRAL_MODE_P (GET_MODE (*op0))
        && GET_MODE (XEXP (*op0, 0)) == CCZ1mode
        && REG_P (XEXP (*op0, 0))
        && XEXP (*op0, 1) == const0_rtx


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