summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authordje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-07 14:30:14 +0000
committerdje <dje@138bc75d-0d04-0410-961f-82ee72b054a4>2005-07-07 14:30:14 +0000
commitdda067b9b5ccf4b56314d719820288e9789e3885 (patch)
tree955cd40d8715a07dc2818bb9bbd6b997d6646a4f /gcc
parentaceb72d385a46da9c11219b802b83fb374f61bce (diff)
downloadgcc-dda067b9b5ccf4b56314d719820288e9789e3885.tar.gz
* config/rs6000/rs6000.md (UNSPEC_SYNC, UNSPEC_SYNC_OP,
UNSPEC_SYNC_SWAP, UNSPEC_LWSYNC, UNSPEC_ISYNC): Delete. (UNSPECV_LL, UNSPECV_SC, UNSPECV_ATOMIC, UNSPECV_SYNC, UNSPECV_SYNC_OP, UNSPECV_CMPXCHG, UNSPECV_LWSYNC, UNSPECV_ISYNC): New. (define_attr "type"): Add isync, sync, load_l, store_c. * config/rs6000/sync.md (memory_barrier): Change to define_expand. Create scratch volatile MEM. (sync_internal): New. POWER mnemonic is dcs, not ics. Attribute sync. (load_locked_<mode>): New. (store_conditional_<mode>): New. (sync_compare_and_swap<mode>): Replace with splitter. (sync_lock_test_and_set<mode>): Replace with splitter. (sync_<fetchop><mode>): Change to unspec_volatile UNSPECV_SYNC_OP and UNSPECV_ISYNC. (isync): Change to unspec_volatile UNSPECV_ISYNC. POWER mnemonic is ics. Attribute isync. (lwsync): Change to unspec_volatile UNSPECV_LWSYNC. Attribute lwsync. * config/rs6000/rs6000.c (rs6000_emit_sync): Use UNSPEC_VOLATILE and UNSPECV_SYNC_OP. (emit_unlikely_jump): New. (emit_load_locked): New. (emit_store_conditional): New. (rs6000_split_compare_and_swap): New. (rs6000_split_lock_test_and_set): New. (is_dispatch_slot_restricted): Return 4 for TYPE_LOAD_L, TYPE_STORE_C, TYPE_ISYNC, TYPE_SYNC. * config/rs6000/rs6000-protos.h (rs6000_split_compare_and_swap, rs6000_split_lock_test_and_set): Declare. * config/rs6000/{40x.md,440.md,603.md,6xx.md,7450.md,7xx.md,8540.md, mpc.md,power4.md,power5.md,rios1.md,rios2.md,rs64.md): Add load_l, store_c, isync, sync. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@101712 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog36
-rw-r--r--gcc/config/rs6000/40x.md8
-rw-r--r--gcc/config/rs6000/440.md5
-rw-r--r--gcc/config/rs6000/603.md11
-rw-r--r--gcc/config/rs6000/6xx.md30
-rw-r--r--gcc/config/rs6000/7450.md12
-rw-r--r--gcc/config/rs6000/7xx.md16
-rw-r--r--gcc/config/rs6000/8540.md7
-rw-r--r--gcc/config/rs6000/mpc.md5
-rw-r--r--gcc/config/rs6000/power4.md12
-rw-r--r--gcc/config/rs6000/power5.md12
-rw-r--r--gcc/config/rs6000/rios1.md5
-rw-r--r--gcc/config/rs6000/rios2.md5
-rw-r--r--gcc/config/rs6000/rs6000-protos.h2
-rw-r--r--gcc/config/rs6000/rs6000.c117
-rw-r--r--gcc/config/rs6000/rs6000.md15
-rw-r--r--gcc/config/rs6000/rs64.md15
-rw-r--r--gcc/config/rs6000/sync.md166
18 files changed, 372 insertions, 107 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index ad5f7c926fb..1536408978b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,39 @@
+2005-07-07 David Edelsohn <edelsohn@gnu.org>
+
+ * config/rs6000/rs6000.md (UNSPEC_SYNC, UNSPEC_SYNC_OP,
+ UNSPEC_SYNC_SWAP, UNSPEC_LWSYNC, UNSPEC_ISYNC): Delete.
+ (UNSPECV_LL, UNSPECV_SC, UNSPECV_ATOMIC, UNSPECV_SYNC,
+ UNSPECV_SYNC_OP, UNSPECV_CMPXCHG, UNSPECV_LWSYNC, UNSPECV_ISYNC): New.
+ (define_attr "type"): Add isync, sync, load_l, store_c.
+ * config/rs6000/sync.md (memory_barrier): Change to define_expand.
+ Create scratch volatile MEM.
+ (sync_internal): New. POWER mnemonic is dcs, not ics. Attribute
+ sync.
+ (load_locked_<mode>): New.
+ (store_conditional_<mode>): New.
+ (sync_compare_and_swap<mode>): Replace with splitter.
+ (sync_lock_test_and_set<mode>): Replace with splitter.
+ (sync_<fetchop><mode>): Change to unspec_volatile UNSPECV_SYNC_OP
+ and UNSPECV_ISYNC.
+ (isync): Change to unspec_volatile UNSPECV_ISYNC. POWER mnemonic
+ is ics. Attribute isync.
+ (lwsync): Change to unspec_volatile UNSPECV_LWSYNC. Attribute
+ lwsync.
+ * config/rs6000/rs6000.c (rs6000_emit_sync): Use UNSPEC_VOLATILE
+ and UNSPECV_SYNC_OP.
+ (emit_unlikely_jump): New.
+ (emit_load_locked): New.
+ (emit_store_conditional): New.
+ (rs6000_split_compare_and_swap): New.
+ (rs6000_split_lock_test_and_set): New.
+ (is_dispatch_slot_restricted): Return 4 for TYPE_LOAD_L,
+ TYPE_STORE_C, TYPE_ISYNC, TYPE_SYNC.
+ * config/rs6000/rs6000-protos.h (rs6000_split_compare_and_swap,
+ rs6000_split_lock_test_and_set): Declare.
+ * config/rs6000/{40x.md,440.md,603.md,6xx.md,7450.md,7xx.md,8540.md,
+ mpc.md,power4.md,power5.md,rios1.md,rios2.md,rs64.md): Add load_l,
+ store_c, isync, sync.
+
2005-07-07 Kelley Cook <kcook@gcc.gnu.org>
* Makefile.in (echo_quoted_to_gtyp): New template for outputing
diff --git a/gcc/config/rs6000/40x.md b/gcc/config/rs6000/40x.md
index 9167cb5c3ec..c1fdce0fc25 100644
--- a/gcc/config/rs6000/40x.md
+++ b/gcc/config/rs6000/40x.md
@@ -27,7 +27,8 @@
;; In-order execution
;; Max issue two insns/cycle (includes one branch)
(define_insn_reservation "ppc403-load" 2
- (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
+ load_l,store_c,sync")
(eq_attr "cpu" "ppc403,ppc405"))
"iu_40x")
@@ -102,7 +103,7 @@
"iu_40x")
(define_insn_reservation "ppc403-jmpreg" 1
- (and (eq_attr "type" "jmpreg,branch")
+ (and (eq_attr "type" "jmpreg,branch,isync")
(eq_attr "cpu" "ppc403,ppc405"))
"bpu_40x")
@@ -112,6 +113,7 @@
"bpu_40x")
(define_insn_reservation "ppc405-float" 11
- (and (eq_attr "type" "fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,fpcompare,fp,dmul,sdiv,ddiv")
+ (and (eq_attr "type" "fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,\
+ fpcompare,fp,dmul,sdiv,ddiv")
(eq_attr "cpu" "ppc405"))
"fpu_405*10")
diff --git a/gcc/config/rs6000/440.md b/gcc/config/rs6000/440.md
index 31a5591c25c..6b1b4554d14 100644
--- a/gcc/config/rs6000/440.md
+++ b/gcc/config/rs6000/440.md
@@ -34,7 +34,8 @@
(define_insn_reservation "ppc440-load" 3
- (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
+ load_l,store_c,sync")
(eq_attr "cpu" "ppc440"))
"ppc440_issue,ppc440_l_pipe")
@@ -86,7 +87,7 @@
"ppc440_issue,ppc440_i_pipe*33")
(define_insn_reservation "ppc440-branch" 1
- (and (eq_attr "type" "branch,jmpreg")
+ (and (eq_attr "type" "branch,jmpreg,isync")
(eq_attr "cpu" "ppc440"))
"ppc440_issue,ppc440_i_pipe")
diff --git a/gcc/config/rs6000/603.md b/gcc/config/rs6000/603.md
index de8983f2564..b094d2a8af7 100644
--- a/gcc/config/rs6000/603.md
+++ b/gcc/config/rs6000/603.md
@@ -39,11 +39,11 @@
;; CR insns get executed in the SRU. Not modelled.
(define_insn_reservation "ppc603-load" 2
- (and (eq_attr "type" "load,load_ext,load_ux,load_u")
+ (and (eq_attr "type" "load,load_ext,load_ux,load_u,load_l")
(eq_attr "cpu" "ppc603"))
"lsu_603")
-(define_insn_reservation "ppc603-store" 1
+(define_insn_reservation "ppc603-store" 2
(and (eq_attr "type" "store,store_ux,store_u,fpstore,fpstore_ux,fpstore_u")
(eq_attr "cpu" "ppc603"))
"lsu_603")
@@ -53,6 +53,11 @@
(eq_attr "cpu" "ppc603"))
"lsu_603")
+(define_insn_reservation "ppc603-storec" 8
+ (and (eq_attr "type" "store_c")
+ (eq_attr "cpu" "ppc603"))
+ "lsu_603")
+
(define_insn_reservation "ppc603-integer" 1
(and (eq_attr "type" "integer,insert_word")
(eq_attr "cpu" "ppc603"))
@@ -126,7 +131,7 @@
"sru_603")
(define_insn_reservation "ppc603-mfjmpr" 2
- (and (eq_attr "type" "mfjmpr")
+ (and (eq_attr "type" "mfjmpr,isync,sync")
(eq_attr "cpu" "ppc603"))
"sru_603")
diff --git a/gcc/config/rs6000/6xx.md b/gcc/config/rs6000/6xx.md
index f2b1f0aa059..deb0e89c058 100644
--- a/gcc/config/rs6000/6xx.md
+++ b/gcc/config/rs6000/6xx.md
@@ -63,6 +63,16 @@
(eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
"lsu_6xx")
+(define_insn_reservation "ppc604-llsc" 3
+ (and (eq_attr "type" "load_l,store_c")
+ (eq_attr "cpu" "ppc604,ppc604e"))
+ "lsu_6xx")
+
+(define_insn_reservation "ppc630-llsc" 4
+ (and (eq_attr "type" "load_l,store_c")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "lsu_6xx")
+
(define_insn_reservation "ppc604-integer" 1
(and (eq_attr "type" "integer,insert_word")
(eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
@@ -242,3 +252,23 @@
(eq_attr "cpu" "ppc604,ppc604e,ppc620,ppc630"))
"bpu_6xx")
+(define_insn_reservation "ppc604-isync" 0
+ (and (eq_attr "type" "isync")
+ (eq_attr "cpu" "ppc604,ppc604e"))
+ "bpu_6xx")
+
+(define_insn_reservation "ppc630-isync" 6
+ (and (eq_attr "type" "isync")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "bpu_6xx")
+
+(define_insn_reservation "ppc604-sync" 35
+ (and (eq_attr "type" "sync")
+ (eq_attr "cpu" "ppc604,ppc604e"))
+ "lsu_6xx")
+
+(define_insn_reservation "ppc630-sync" 26
+ (and (eq_attr "type" "sync")
+ (eq_attr "cpu" "ppc620,ppc630"))
+ "lsu_6xx")
+
diff --git a/gcc/config/rs6000/7450.md b/gcc/config/rs6000/7450.md
index 8514b04944a..99e87125fb9 100644
--- a/gcc/config/rs6000/7450.md
+++ b/gcc/config/rs6000/7450.md
@@ -64,6 +64,16 @@
(eq_attr "cpu" "ppc7450"))
"ppc7450_du,lsu_7450*3")
+(define_insn_reservation "ppc7450-llsc" 3
+ (and (eq_attr "type" "load_l,store_c")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450")
+
+(define_insn_reservation "ppc7450-sync" 35
+ (and (eq_attr "type" "sync")
+ (eq_attr "cpu" "ppc7450"))
+ "ppc7450_du,lsu_7450")
+
(define_insn_reservation "ppc7450-integer" 1
(and (eq_attr "type" "integer,insert_word")
(eq_attr "cpu" "ppc7450"))
@@ -142,7 +152,7 @@
"nothing,mciu_7450*2")
(define_insn_reservation "ppc7450-jmpreg" 1
- (and (eq_attr "type" "jmpreg,branch")
+ (and (eq_attr "type" "jmpreg,branch,isync")
(eq_attr "cpu" "ppc7450"))
"nothing,bpu_7450")
diff --git a/gcc/config/rs6000/7xx.md b/gcc/config/rs6000/7xx.md
index 930882421fc..77e58a3cb6c 100644
--- a/gcc/config/rs6000/7xx.md
+++ b/gcc/config/rs6000/7xx.md
@@ -48,16 +48,22 @@
(define_insn_reservation "ppc750-load" 2
(and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,\
- load_ux,load_u,fpload,fpload_ux,fpload_u,vecload")
+ load_ux,load_u,fpload,fpload_ux,fpload_u,\
+ vecload,load_l")
(eq_attr "cpu" "ppc750,ppc7400"))
"ppc750_du,lsu_7xx")
-(define_insn_reservation "ppc750-store" 1
+(define_insn_reservation "ppc750-store" 2
(and (eq_attr "type" "store,store_ux,store_u,\
fpstore,fpstore_ux,fpstore_u,vecstore")
(eq_attr "cpu" "ppc750,ppc7400"))
"ppc750_du,lsu_7xx")
+(define_insn_reservation "ppc750-storec" 8
+ (and (eq_attr "type" "store_c")
+ (eq_attr "cpu" "ppc750,ppc7400"))
+ "ppc750_du,lsu_7xx")
+
(define_insn_reservation "ppc750-integer" 1
(and (eq_attr "type" "integer,insert_word")
(eq_attr "cpu" "ppc750,ppc7400"))
@@ -137,10 +143,10 @@
(define_insn_reservation "ppc750-crlogical" 3
(and (eq_attr "type" "cr_logical,delayed_cr")
(eq_attr "cpu" "ppc750,ppc7400"))
- "ppc750_du,sru_7xx*2")
+ "nothing,sru_7xx*2")
(define_insn_reservation "ppc750-mtjmpr" 2
- (and (eq_attr "type" "mtjmpr")
+ (and (eq_attr "type" "mtjmpr,isync,sync")
(eq_attr "cpu" "ppc750,ppc7400"))
"nothing,sru_7xx*2")
@@ -150,7 +156,7 @@
"nothing,sru_7xx*2")
(define_insn_reservation "ppc750-jmpreg" 1
- (and (eq_attr "type" "jmpreg,branch")
+ (and (eq_attr "type" "jmpreg,branch,isync")
(eq_attr "cpu" "ppc750,ppc7400"))
"nothing,bpu_7xx")
diff --git a/gcc/config/rs6000/8540.md b/gcc/config/rs6000/8540.md
index 4b9e7e05d82..b42e2472a41 100644
--- a/gcc/config/rs6000/8540.md
+++ b/gcc/config/rs6000/8540.md
@@ -104,7 +104,7 @@
;; Branch. Actually this latency time is not used by the scheduler.
(define_insn_reservation "ppc8540_branch" 1
- (and (eq_attr "type" "jmpreg,branch")
+ (and (eq_attr "type" "jmpreg,branch,isync")
(eq_attr "cpu" "ppc8540"))
"ppc8540_decode,ppc8540_bu,ppc8540_retire")
@@ -151,13 +151,14 @@
;; Loads
(define_insn_reservation "ppc8540_load" 3
- (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
+ load_l,sync")
(eq_attr "cpu" "ppc8540"))
"ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
;; Stores.
(define_insn_reservation "ppc8540_store" 3
- (and (eq_attr "type" "store,store_ux,store_u")
+ (and (eq_attr "type" "store,store_ux,store_u,store_c")
(eq_attr "cpu" "ppc8540"))
"ppc8540_decode,ppc8540_issue+ppc8540_lsu,nothing,ppc8540_retire")
diff --git a/gcc/config/rs6000/mpc.md b/gcc/config/rs6000/mpc.md
index 8429d4f3296..242382c0132 100644
--- a/gcc/config/rs6000/mpc.md
+++ b/gcc/config/rs6000/mpc.md
@@ -27,7 +27,8 @@
;; 505/801/821/823
(define_insn_reservation "mpccore-load" 2
- (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
+ load_l,store_c,sync")
(eq_attr "cpu" "mpccore"))
"lsu_mpc")
@@ -103,7 +104,7 @@
"bpu_mpc")
(define_insn_reservation "mpccore-jmpreg" 1
- (and (eq_attr "type" "jmpreg,branch,cr_logical,delayed_cr,mfcr,mtcr")
+ (and (eq_attr "type" "jmpreg,branch,cr_logical,delayed_cr,mfcr,mtcr,isync")
(eq_attr "cpu" "mpccore"))
"bpu_mpc")
diff --git a/gcc/config/rs6000/power4.md b/gcc/config/rs6000/power4.md
index 92f63cb32f6..53ac066d856 100644
--- a/gcc/config/rs6000/power4.md
+++ b/gcc/config/rs6000/power4.md
@@ -174,6 +174,12 @@
|(du3_power4,lsu2_power4,vec_power4)\
|(du4_power4,lsu1_power4,vec_power4)")
+(define_insn_reservation "power4-llsc" 11
+ (and (eq_attr "type" "load_l,store_c,sync")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ lsu1_power4")
+
; Integer latency is 2 cycles
(define_insn_reservation "power4-integer" 2
@@ -354,6 +360,12 @@
|(du3_power4,fpu2_power4*35)\
|(du4_power4,fpu2_power4*35)")
+(define_insn_reservation "power4-isync" 2
+ (and (eq_attr "type" "isync")
+ (eq_attr "cpu" "power4"))
+ "du1_power4+du2_power4+du3_power4+du4_power4,\
+ lsu1_power4")
+
; VMX
(define_insn_reservation "power4-vecsimple" 2
diff --git a/gcc/config/rs6000/power5.md b/gcc/config/rs6000/power5.md
index 0dc1fdc4c02..ce6892605d1 100644
--- a/gcc/config/rs6000/power5.md
+++ b/gcc/config/rs6000/power5.md
@@ -135,6 +135,12 @@
(eq_attr "cpu" "power5"))
"du1_power5+du2_power5,lsu1_power5+iu2_power5,fpu1_power5")
+(define_insn_reservation "power5-llsc" 11
+ (and (eq_attr "type" "load_l,store_c,sync")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ lsu1_power5")
+
; Integer latency is 2 cycles
(define_insn_reservation "power5-integer" 2
@@ -307,3 +313,9 @@
|(du3_power5,fpu2_power5*35)\
|(du4_power5,fpu2_power5*35)")
+(define_insn_reservation "power5-isync" 2
+ (and (eq_attr "type" "isync")
+ (eq_attr "cpu" "power5"))
+ "du1_power5+du2_power5+du3_power5+du4_power5,\
+ lsu1_power5")
+
diff --git a/gcc/config/rs6000/rios1.md b/gcc/config/rs6000/rios1.md
index 0cbca162b2d..945ee10dd06 100644
--- a/gcc/config/rs6000/rios1.md
+++ b/gcc/config/rs6000/rios1.md
@@ -26,7 +26,8 @@
;; RIOS1 32-bit IU, FPU, BPU
(define_insn_reservation "rios1-load" 2
- (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u")
+ (and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,\
+ load_l,store_c,sync")
(eq_attr "cpu" "rios1,ppc601"))
"iu_rios1")
@@ -183,7 +184,7 @@
"iu_rios1,bpu_rios1")
(define_insn_reservation "rios1-branch" 1
- (and (eq_attr "type" "jmpreg,branch")
+ (and (eq_attr "type" "jmpreg,branch,isync")
(eq_attr "cpu" "rios1,ppc601"))
"bpu_rios1")
diff --git a/gcc/config/rs6000/rios2.md b/gcc/config/rs6000/rios2.md
index 8417e354c02..6c0966ede41 100644
--- a/gcc/config/rs6000/rios2.md
+++ b/gcc/config/rs6000/rios2.md
@@ -29,7 +29,8 @@
(define_insn_reservation "rios2-load" 2
(and (eq_attr "type" "load,load_ext,load_ext_u,load_ext_ux,\
- load_ux,load_u,fpload,fpload_ux,fpload_u")
+ load_ux,load_u,fpload,fpload_ux,fpload_u,\
+ load_l,store_c,sync")
(eq_attr "cpu" "rios2"))
"iu1_rios2|iu2_rios2")
@@ -121,7 +122,7 @@
"iu1_rios2,bpu_rios2")
(define_insn_reservation "rios2-branch" 1
- (and (eq_attr "type" "jmpreg,branch")
+ (and (eq_attr "type" "jmpreg,branch,isync")
(eq_attr "cpu" "rios2"))
"bpu_rios2")
diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h
index 4aebf53d5e6..20bdded1cca 100644
--- a/gcc/config/rs6000/rs6000-protos.h
+++ b/gcc/config/rs6000/rs6000-protos.h
@@ -82,6 +82,8 @@ extern int rs6000_emit_vector_cond_expr (rtx, rtx, rtx, rtx, rtx, rtx);
extern void rs6000_emit_minmax (rtx, enum rtx_code, rtx, rtx);
extern void rs6000_emit_sync (enum rtx_code, enum machine_mode,
rtx, rtx, rtx, rtx, bool);
+extern void rs6000_split_compare_and_swap (rtx, rtx, rtx, rtx, rtx);
+extern void rs6000_split_lock_test_and_set (rtx, rtx, rtx, rtx);
extern void rs6000_emit_swdivsf (rtx, rtx, rtx);
extern void rs6000_emit_swdivdf (rtx, rtx, rtx);
extern void output_toc (FILE *, rtx, int, enum machine_mode);
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index fb5f3ae4074..921d16ff783 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -11643,8 +11643,9 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
set_after = gen_rtx_SET (VOIDmode, after, the_op);
set_before = gen_rtx_SET (VOIDmode, before, used_m);
set_atomic = gen_rtx_SET (VOIDmode, used_m,
- gen_rtx_UNSPEC (used_mode, gen_rtvec (1, the_op),
- UNSPEC_SYNC_OP));
+ gen_rtx_UNSPEC_VOLATILE (used_mode,
+ gen_rtvec (1, the_op),
+ UNSPECV_SYNC_OP));
cc_scratch = gen_rtx_CLOBBER (VOIDmode, gen_rtx_SCRATCH (CCmode));
if (code == PLUS && used_mode != mode)
@@ -11675,7 +11676,112 @@ rs6000_emit_sync (enum rtx_code code, enum machine_mode mode,
emit_insn (gen_isync ());
}
-/* Emit instructions to move SRC to DST. Called by splitters for
+/* A subroutine of the atomic operation splitters. Jump to LABEL if
+ COND is true. Mark the jump as unlikely to be taken. */
+
+static void
+emit_unlikely_jump (rtx cond, rtx label)
+{
+ rtx very_unlikely = GEN_INT (REG_BR_PROB_BASE / 100 - 1);
+ rtx x;
+
+ x = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, label, pc_rtx);
+ x = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, x));
+ REG_NOTES (x) = gen_rtx_EXPR_LIST (REG_BR_PROB, very_unlikely, NULL_RTX);
+}
+
+/* A subroutine of the atomic operation splitters. Emit a load-locked
+ instruction in MODE. */
+
+static void
+emit_load_locked (enum machine_mode mode, rtx reg, rtx mem)
+{
+ rtx (*fn) (rtx, rtx) = NULL;
+ if (mode == SImode)
+ fn = gen_load_locked_si;
+ else if (mode == DImode)
+ fn = gen_load_locked_di;
+ emit_insn (fn (reg, mem));
+}
+
+/* A subroutine of the atomic operation splitters. Emit a store-conditional
+ instruction in MODE. */
+
+static void
+emit_store_conditional (enum machine_mode mode, rtx res, rtx mem, rtx val)
+{
+ rtx (*fn) (rtx, rtx, rtx) = NULL;
+ if (mode == SImode)
+ fn = gen_store_conditional_si;
+ else if (mode == DImode)
+ fn = gen_store_conditional_di;
+
+ if (PPC405_ERRATUM77)
+ emit_insn (gen_memory_barrier ());
+
+ emit_insn (fn (res, mem, val));
+}
+
+/* Expand an atomic compare and swap operation. MEM is the memory on which
+ to operate. OLDVAL is the old value to be compared. NEWVAL is the new
+ value to be stored. SCRATCH is a scratch GPR. */
+
+void
+rs6000_split_compare_and_swap (rtx retval, rtx mem, rtx oldval, rtx newval,
+ rtx scratch)
+{
+ enum machine_mode mode = GET_MODE (mem);
+ rtx label1, label2, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
+
+ emit_insn (gen_memory_barrier ());
+
+ label1 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
+ label2 = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
+ emit_label (XEXP (label1, 0));
+
+ emit_load_locked (mode, retval, mem);
+
+ x = gen_rtx_COMPARE (CCmode, retval, oldval);
+ emit_insn (gen_rtx_SET (VOIDmode, cond, x));
+
+ x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
+ emit_unlikely_jump (x, label2);
+
+ emit_move_insn (scratch, newval);
+ emit_store_conditional (mode, cond, mem, scratch);
+
+ x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
+ emit_unlikely_jump (x, label1);
+
+ emit_insn (gen_isync ());
+ emit_label (XEXP (label2, 0));
+}
+
+/* Expand an atomic test and set operation. MEM is the memory on which
+ to operate. VAL is the value set. SCRATCH is a scratch GPR. */
+
+void
+rs6000_split_lock_test_and_set (rtx retval, rtx mem, rtx val, rtx scratch)
+{
+ enum machine_mode mode = GET_MODE (mem);
+ rtx label, x, cond = gen_rtx_REG (CCmode, CR0_REGNO);
+
+ emit_insn (gen_memory_barrier ());
+
+ label = gen_rtx_LABEL_REF (VOIDmode, gen_label_rtx ());
+ emit_label (XEXP (label, 0));
+
+ emit_load_locked (mode, retval, mem);
+ emit_move_insn (scratch, val);
+ emit_store_conditional (mode, cond, mem, scratch);
+
+ x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
+ emit_unlikely_jump (x, label);
+
+ emit_insn (gen_isync ());
+}
+
+ /* Emit instructions to move SRC to DST. Called by splitters for
multi-register moves. It will emit at most one instruction for
each register that is accessed; that is, it won't emit li/lis pairs
(or equivalent for 64-bit code). One of SRC or DST must be a hard
@@ -15795,6 +15901,11 @@ is_dispatch_slot_restricted (rtx insn)
case TYPE_IDIV:
case TYPE_LDIV:
return 2;
+ case TYPE_LOAD_L:
+ case TYPE_STORE_C:
+ case TYPE_ISYNC:
+ case TYPE_SYNC:
+ return 4;
default:
if (rs6000_cpu == PROCESSOR_POWER5
&& is_cracked_insn (insn))
diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md
index f363a96a339..1381f7d7865 100644
--- a/gcc/config/rs6000/rs6000.md
+++ b/gcc/config/rs6000/rs6000.md
@@ -52,11 +52,6 @@
(UNSPEC_FIX_TRUNC_TF 30) ; fadd, rounding towards zero
(UNSPEC_MV_CR_GT 31) ; move_from_CR_eq_bit
(UNSPEC_STFIWX 32)
- (UNSPEC_SYNC 33)
- (UNSPEC_SYNC_OP 34)
- (UNSPEC_SYNC_SWAP 35)
- (UNSPEC_LWSYNC 36)
- (UNSPEC_ISYNC 37)
(UNSPEC_POPCNTB 38)
(UNSPEC_FRES 39)
(UNSPEC_SP_SET 40)
@@ -69,12 +64,20 @@
(define_constants
[(UNSPECV_BLOCK 0)
+ (UNSPECV_LL 1) ; load-locked
+ (UNSPECV_SC 2) ; store-conditional
+ (UNSPECV_ATOMIC 3)
+ (UNSPECV_SYNC 4)
+ (UNSPECV_SYNC_OP 5)
+ (UNSPECV_CMPXCHG 6)
+ (UNSPECV_LWSYNC 7)
+ (UNSPECV_ISYNC 8)
(UNSPECV_EH_RR 9) ; eh_reg_restore
])
;; Define an insn type attribute. This is used in function unit delay
;; computations.
-(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv"
+(define_attr "type" "integer,two,three,load,load_ext,load_ext_u,load_ext_ux,load_ux,load_u,store,store_ux,store_u,fpload,fpload_ux,fpload_u,fpstore,fpstore_ux,fpstore_u,vecload,vecstore,imul,imul2,imul3,lmul,idiv,ldiv,insert_word,branch,cmp,fast_compare,compare,delayed_compare,imul_compare,lmul_compare,fpcompare,cr_logical,delayed_cr,mfcr,mfcrf,mtcr,mfjmpr,mtjmpr,fp,fpsimple,dmul,sdiv,ddiv,ssqrt,dsqrt,jmpreg,brinc,vecsimple,veccomplex,vecdiv,veccmp,veccmpsimple,vecperm,vecfloat,vecfdiv,isync,sync,load_l,store_c"
(const_string "integer"))
;; Length (in bytes).
diff --git a/gcc/config/rs6000/rs64.md b/gcc/config/rs6000/rs64.md
index 001ab79230e..503130f3326 100644
--- a/gcc/config/rs6000/rs64.md
+++ b/gcc/config/rs6000/rs64.md
@@ -41,6 +41,11 @@
(eq_attr "cpu" "rs64a"))
"lsu_rs64")
+(define_insn_reservation "rs64a-llsc" 2
+ (and (eq_attr "type" "load_l,store_c")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
(define_insn_reservation "rs64a-integer" 1
(and (eq_attr "type" "integer,insert_word")
(eq_attr "cpu" "rs64a"))
@@ -136,3 +141,13 @@
(eq_attr "cpu" "rs64a"))
"bpu_rs64")
+(define_insn_reservation "rs64a-isync" 6
+ (and (eq_attr "type" "isync")
+ (eq_attr "cpu" "rs64a"))
+ "bpu_rs64")
+
+(define_insn_reservation "rs64a-sync" 1
+ (and (eq_attr "type" "sync")
+ (eq_attr "cpu" "rs64a"))
+ "lsu_rs64")
+
diff --git a/gcc/config/rs6000/sync.md b/gcc/config/rs6000/sync.md
index ac8e64990c6..a98dc1545d3 100644
--- a/gcc/config/rs6000/sync.md
+++ b/gcc/config/rs6000/sync.md
@@ -22,51 +22,77 @@
(define_mode_attr larx [(SI "lwarx") (DI "ldarx")])
(define_mode_attr stcx [(SI "stwcx.") (DI "stdcx.")])
-(define_insn "memory_barrier"
- [(set (mem:BLK (match_scratch 0 "X"))
- (unspec:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_SYNC))]
+(define_expand "memory_barrier"
+ [(set (mem:BLK (match_dup 0))
+ (unspec_volatile:BLK [(mem:BLK (match_dup 0))] UNSPECV_SYNC))]
""
- "{ics|sync}")
-
-(define_expand "sync_compare_and_swap<mode>"
- [(parallel [(set (match_operand:GPR 1 "memory_operand" "")
- (unspec:GPR [(match_dup 1)
- (match_operand:GPR 2 "reg_or_short_operand" "")
- (match_operand:GPR 3 "gpc_reg_operand" "")]
- UNSPEC_SYNC_SWAP))
- (set (match_operand:GPR 0 "gpc_reg_operand" "") (match_dup 1))
- (set (mem:BLK (match_scratch 5 ""))
- (unspec:BLK [(mem:BLK (match_scratch 6 ""))] UNSPEC_SYNC))
- (clobber (match_scratch:CC 4 ""))])]
- "TARGET_POWERPC")
-
-(define_insn "sync_compare_and_swap<mode>_internal"
- [(set (match_operand:GPR 1 "memory_operand" "+Z")
- (unspec:GPR [(match_dup 1)
- (match_operand:GPR 2 "reg_or_short_operand" "rI")
- (match_operand:GPR 3 "gpc_reg_operand" "r")]
- UNSPEC_SYNC_SWAP))
- (set (match_operand:GPR 0 "gpc_reg_operand" "=&r") (match_dup 1))
- (set (mem:BLK (match_scratch 5 "X"))
- (unspec:BLK [(mem:BLK (match_scratch 6 "X"))] UNSPEC_SYNC))
- (clobber (match_scratch:CC 4 "=&x"))]
- "TARGET_POWERPC && !PPC405_ERRATUM77"
- "sync\n\t<larx> %0,%y1\n\tcmp<wd>%I2 %0,%2\n\tbne- $+12\n\t<stcx> %3,%y1\n\tbne- $-16\n\tisync"
- [(set_attr "length" "28")])
+{
+ operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
+ MEM_VOLATILE_P (operands[0]) = 1;
+})
+
+(define_insn "*sync_internal"
+ [(set (match_operand:BLK 0 "" "")
+ (unspec_volatile:BLK [(match_operand:BLK 1 "" "")] UNSPECV_SYNC))]
+ ""
+ "{dcs|sync}"
+ [(set_attr "type" "sync")])
+
+(define_insn "load_locked_<mode>"
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
+ (unspec_volatile:GPR
+ [(match_operand:GPR 1 "memory_operand" "m")] UNSPECV_LL))]
+ "TARGET_POWERPC"
+ "<larx> %0,%y1"
+ [(set_attr "type" "load_l")])
+
+(define_insn "store_conditional_<mode>"
+ [(set (match_operand:CC 0 "cc_reg_operand" "=x")
+ (unspec_volatile:CC [(const_int 0)] UNSPECV_SC))
+ (set (match_operand:GPR 1 "memory_operand" "=m")
+ (match_operand:GPR 2 "gpc_reg_operand" "r"))]
+ "TARGET_POWERPC"
+ "<stcx> %2,%y1"
+ [(set_attr "type" "store_c")])
+
+(define_insn_and_split "sync_compare_and_swap<mode>"
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
+ (match_operand:GPR 1 "memory_operand" "+m"))
+ (set (match_dup 1)
+ (unspec_volatile:GPR
+ [(match_operand:GPR 2 "reg_or_short_operand" "rI")
+ (match_operand:GPR 3 "gpc_reg_operand" "r")]
+ UNSPECV_CMPXCHG))
+ (clobber (match_scratch:GPR 4 "=&r"))
+ (clobber (match_scratch:CC 5 "=&x"))]
+ "TARGET_POWERPC"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rs6000_split_compare_and_swap (operands[0], operands[1], operands[2],
+ operands[3], operands[4]);
+ DONE;
+})
-(define_insn "sync_compare_and_swap<mode>_ppc405"
- [(set (match_operand:GPR 1 "memory_operand" "+Z")
- (unspec:GPR [(match_dup 1)
- (match_operand:GPR 2 "reg_or_short_operand" "rI")
- (match_operand:GPR 3 "gpc_reg_operand" "r")]
- UNSPEC_SYNC_SWAP))
- (set (match_operand:GPR 0 "gpc_reg_operand" "=&r") (match_dup 1))
- (set (mem:BLK (match_scratch 5 "X"))
- (unspec:BLK [(mem:BLK (match_scratch 6 "X"))] UNSPEC_SYNC))
+(define_insn_and_split "sync_lock_test_and_set<mode>"
+ [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
+ (match_operand:GPR 1 "memory_operand" "+m"))
+ (set (match_dup 1)
+ (unspec_volatile:GPR
+ [(match_operand:GPR 2 "reg_or_short_operand" "rL")]
+ UNSPECV_CMPXCHG))
+ (clobber (match_scratch:GPR 3 "=&r"))
(clobber (match_scratch:CC 4 "=&x"))]
- "TARGET_POWERPC && PPC405_ERRATUM77"
- "sync\n\t<larx> %0,%y1\n\tcmp<wd>%I2 %0,%2\n\tbne- $+12\n\tsync\n\t<stcx> %3,%y1\n\tbne- $-16\n\tisync"
- [(set_attr "length" "32")])
+ "TARGET_POWERPC"
+ "#"
+ "&& reload_completed"
+ [(const_int 0)]
+{
+ rs6000_split_lock_test_and_set (operands[0], operands[1], operands[2],
+ operands[3]);
+ DONE;
+})
(define_expand "sync_add<mode>"
[(use (match_operand:INT1 0 "memory_operand" ""))
@@ -296,8 +322,8 @@
(match_operand:GPR 1 "add_operand" "rI,L")))
(set (match_operand:GPR 3 "gpc_reg_operand" "=&b,&b") (match_dup 0))
(set (match_dup 0)
- (unspec:GPR [(plus:GPR (match_dup 0) (match_dup 1))]
- UNSPEC_SYNC_OP))
+ (unspec_volatile:GPR [(plus:GPR (match_dup 0) (match_dup 1))]
+ UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 4 "=&x,&x"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
"@
@@ -313,10 +339,10 @@
(and:SI (not:SI (match_dup 4)) (match_dup 0))))
(set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
(set (match_dup 0)
- (unspec:SI [(ior:SI (and:SI (plus:SI (match_dup 0) (match_dup 1))
+ (unspec_volatile:SI [(ior:SI (and:SI (plus:SI (match_dup 0) (match_dup 1))
(match_dup 4))
(and:SI (not:SI (match_dup 4)) (match_dup 0)))]
- UNSPEC_SYNC_OP))
+ UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 5 "=&x"))
(clobber (match_scratch:SI 6 "=&r"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
@@ -329,8 +355,8 @@
(match_operand:GPR 1 "gpc_reg_operand" "r")))
(set (match_operand:GPR 3 "gpc_reg_operand" "=&b") (match_dup 0))
(set (match_dup 0)
- (unspec:GPR [(minus:GPR (match_dup 0) (match_dup 1))]
- UNSPEC_SYNC_OP))
+ (unspec_volatile:GPR [(minus:GPR (match_dup 0) (match_dup 1))]
+ UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 4 "=&x"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
"<larx> %3,%y0\n\tsubf %2,%1,%3\n\t<stcx> %2,%y0\n\tbne- $-12"
@@ -342,8 +368,8 @@
(match_operand:SI 1 "and_operand" "r,T,K,L")))
(set (match_operand:SI 3 "gpc_reg_operand" "=&b,&b,&b,&b") (match_dup 0))
(set (match_dup 0)
- (unspec:SI [(and:SI (match_dup 0) (match_dup 1))]
- UNSPEC_SYNC_OP))
+ (unspec_volatile:SI [(and:SI (match_dup 0) (match_dup 1))]
+ UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 4 "=&x,&x,&x,&x"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
"@
@@ -359,8 +385,8 @@
(match_operand:DI 1 "and_operand" "r,S,T,K,J")))
(set (match_operand:DI 3 "gpc_reg_operand" "=&b,&b,&b,&b,&b") (match_dup 0))
(set (match_dup 0)
- (unspec:DI [(and:DI (match_dup 0) (match_dup 1))]
- UNSPEC_SYNC_OP))
+ (unspec_volatile:DI [(and:DI (match_dup 0) (match_dup 1))]
+ UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 4 "=&x,&x,&x,&x,&x"))]
"TARGET_POWERPC64"
"@
@@ -377,7 +403,7 @@
[(match_operand:SI 0 "memory_operand" "+Z,Z,Z")
(match_operand:SI 1 "logical_operand" "r,K,L")]))
(set (match_operand:SI 3 "gpc_reg_operand" "=&b,&b,&b") (match_dup 0))
- (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
+ (set (match_dup 0) (unspec_volatile:SI [(match_dup 4)] UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 5 "=&x,&x,&x"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
"@
@@ -392,7 +418,7 @@
[(match_operand:DI 0 "memory_operand" "+Z,Z,Z")
(match_operand:DI 1 "logical_operand" "r,K,JF")]))
(set (match_operand:DI 3 "gpc_reg_operand" "=&b,&b,&b") (match_dup 0))
- (set (match_dup 0) (unspec:DI [(match_dup 4)] UNSPEC_SYNC_OP))
+ (set (match_dup 0) (unspec_volatile:DI [(match_dup 4)] UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 5 "=&x,&x,&x"))]
"TARGET_POWERPC64"
"@
@@ -407,7 +433,7 @@
[(not:GPR (match_operand:GPR 0 "memory_operand" "+Z"))
(match_operand:GPR 1 "gpc_reg_operand" "r")]))
(set (match_operand:GPR 3 "gpc_reg_operand" "=&b") (match_dup 0))
- (set (match_dup 0) (unspec:GPR [(match_dup 4)] UNSPEC_SYNC_OP))
+ (set (match_dup 0) (unspec_volatile:GPR [(match_dup 4)] UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 5 "=&x"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
"<larx> %3,%y0\n\t%q4 %2,%1,%3\n\t<stcx> %2,%y0\n\tbne- $-12"
@@ -424,7 +450,7 @@
(match_operand:SI 5 "logical_operand" "rK"))
(match_operand:SI 1 "gpc_reg_operand" "r")]))
(set (match_operand:SI 3 "gpc_reg_operand" "=&b") (match_dup 0))
- (set (match_dup 0) (unspec:SI [(match_dup 4)] UNSPEC_SYNC_OP))
+ (set (match_dup 0) (unspec_volatile:SI [(match_dup 4)] UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 6 "=&x"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
"lwarx %3,%y0\n\txor%I2 %2,%3,%5\n\t%q4 %2,%2,%1\n\tstwcx. %2,%y0\n\tbne- $-16"
@@ -436,7 +462,7 @@
[(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))
(match_operand:GPR 0 "memory_operand" "+Z")]))
(set (match_operand:GPR 3 "gpc_reg_operand" "=&b") (match_dup 0))
- (set (match_dup 0) (unspec:GPR [(match_dup 4)] UNSPEC_SYNC_OP))
+ (set (match_dup 0) (unspec_volatile:GPR [(match_dup 4)] UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 5 "=&x"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
"<larx> %3,%y0\n\t%q4 %2,%3,%1\n\t<stcx> %2,%y0\n\tbne- $-12"
@@ -448,7 +474,7 @@
[(not:GPR (match_operand:GPR 0 "memory_operand" "+Z"))
(not:GPR (match_operand:GPR 1 "gpc_reg_operand" "r"))]))
(set (match_operand:GPR 3 "gpc_reg_operand" "=&b") (match_dup 0))
- (set (match_dup 0) (unspec:GPR [(match_dup 4)] UNSPEC_SYNC_OP))
+ (set (match_dup 0) (unspec_volatile:GPR [(match_dup 4)] UNSPECV_SYNC_OP))
(clobber (match_scratch:CC 5 "=&x"))]
"TARGET_POWERPC && !PPC405_ERRATUM77"
"<larx> %3,%y0\n\t%q4 %2,%1,%3\n\t<stcx> %2,%y0\n\tbne- $-12"
@@ -456,21 +482,10 @@
(define_insn "isync"
[(set (mem:BLK (match_scratch 0 "X"))
- (unspec:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_ISYNC))]
- "TARGET_POWERPC"
- "isync")
-
-(define_insn "sync_lock_test_and_set<mode>"
- [(set (match_operand:GPR 0 "gpc_reg_operand" "=&r")
- (match_operand:GPR 1 "memory_operand" "+Z"))
- (set (match_dup 1) (unspec:GPR [(match_operand:GPR 2 "gpc_reg_operand" "r")]
- UNSPEC_SYNC_OP))
- (clobber (match_scratch:CC 3 "=&x"))
- (set (mem:BLK (match_scratch 4 "X"))
- (unspec:BLK [(mem:BLK (match_scratch 5 "X"))] UNSPEC_ISYNC))]
- "TARGET_POWERPC && !PPC405_ERRATUM77"
- "<larx> %0,%y1\n\t<stcx> %2,%y1\n\tbne- $-8\n\tisync"
- [(set_attr "length" "16")])
+ (unspec_volatile:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPECV_ISYNC))]
+ ""
+ "{ics|isync}"
+ [(set_attr "type" "isync")])
(define_expand "sync_lock_release<mode>"
[(set (match_operand:INT 0 "memory_operand")
@@ -486,7 +501,8 @@
; Some AIX assemblers don't accept lwsync, so we use a .long.
(define_insn "lwsync"
[(set (mem:BLK (match_scratch 0 "X"))
- (unspec:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPEC_LWSYNC))]
+ (unspec_volatile:BLK [(mem:BLK (match_scratch 1 "X"))] UNSPECV_LWSYNC))]
""
- ".long 0x7c2004ac")
+ ".long 0x7c2004ac"
+ [(set_attr "type" "sync")])