* config/rs6000/sync.md (fetchop_name): Change ior attribute to "or".
[official-gcc.git] / gcc / config / rs6000 / sync.md
blobd4848a81cc8577ce20b395931e490a9bce773cbd
1 ;; Machine description for PowerPC synchronization instructions.
2 ;; Copyright (C) 2005, 2007, 2008, 2009, 2011
3 ;; Free Software Foundation, Inc.
4 ;; Contributed by Geoffrey Keating.
6 ;; This file is part of GCC.
8 ;; GCC is free software; you can redistribute it and/or modify it
9 ;; under the terms of the GNU General Public License as published
10 ;; by the Free Software Foundation; either version 3, or (at your
11 ;; option) any later version.
13 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
14 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 ;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
16 ;; License for more details.
18 ;; You should have received a copy of the GNU General Public License
19 ;; along with GCC; see the file COPYING3.  If not see
20 ;; <http://www.gnu.org/licenses/>.
22 (define_mode_attr larx [(SI "lwarx") (DI "ldarx")])
23 (define_mode_attr stcx [(SI "stwcx.") (DI "stdcx.")])
25 (define_code_iterator FETCHOP [plus minus ior xor and])
26 (define_code_attr fetchop_name
27   [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")])
28 (define_code_attr fetchop_pred
29   [(plus "add_operand") (minus "gpc_reg_operand")
30    (ior "logical_operand") (xor "logical_operand") (and "and_operand")])
32 (define_expand "mem_thread_fence"
33   [(match_operand:SI 0 "const_int_operand" "")]         ;; model
34   ""
36   enum memmodel model = (enum memmodel) INTVAL (operands[0]);
37   switch (model)
38     {
39     case MEMMODEL_RELAXED:
40       break;
41     case MEMMODEL_CONSUME:
42     case MEMMODEL_ACQUIRE:
43     case MEMMODEL_RELEASE:
44     case MEMMODEL_ACQ_REL:
45       emit_insn (gen_lwsync ());
46       break;
47     case MEMMODEL_SEQ_CST:
48       emit_insn (gen_hwsync ());
49       break;
50     default:
51       gcc_unreachable ();
52     }
53   DONE;
56 (define_expand "hwsync"
57   [(set (match_dup 0)
58         (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
59   ""
61   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
62   MEM_VOLATILE_P (operands[0]) = 1;
65 (define_insn "*hwsync"
66   [(set (match_operand:BLK 0 "" "")
67         (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
68   ""
69   "{dcs|sync}"
70   [(set_attr "type" "sync")])
72 (define_expand "lwsync"
73   [(set (match_dup 0)
74         (unspec:BLK [(match_dup 0)] UNSPEC_LWSYNC))]
75   ""
77   operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
78   MEM_VOLATILE_P (operands[0]) = 1;
81 (define_insn "*lwsync"
82   [(set (match_operand:BLK 0 "" "")
83         (unspec:BLK [(match_dup 0)] UNSPEC_LWSYNC))]
84   ""
86   /* Some AIX assemblers don't accept lwsync, so we use a .long.  */
87   if (TARGET_NO_LWSYNC)
88     return "sync";
89   else if (TARGET_LWSYNC_INSTRUCTION)
90     return "lwsync";
91   else
92     return ".long 0x7c2004ac";
94   [(set_attr "type" "sync")])
96 (define_insn "isync"
97   [(unspec_volatile:BLK [(const_int 0)] UNSPECV_ISYNC)]
98   ""
99   "{ics|isync}"
100   [(set_attr "type" "isync")])
102 ;; The control dependency used for load dependency described
103 ;; in B.2.3 of the Power ISA 2.06B.
104 (define_insn "loadsync"
105   [(unspec_volatile:BLK [(match_operand 0 "register_operand" "r")]
106                         UNSPECV_ISYNC)
107    (clobber (match_scratch:CC 1 "=y"))]
108   ""
109   "cmpw %1,%0,%0\;bne- %1,$+4\;isync"
110   [(set_attr "type" "isync")
111    (set_attr "length" "12")])
113 (define_expand "atomic_load<mode>"
114   [(set (match_operand:INT 0 "register_operand" "")             ;; output
115         (match_operand:INT 1 "memory_operand" ""))              ;; memory
116    (use (match_operand:SI 2 "const_int_operand" ""))]           ;; model
117   ""
119   enum memmodel model = (enum memmodel) INTVAL (operands[2]);
121   if (model == MEMMODEL_SEQ_CST)
122     emit_insn (gen_hwsync ());
124   emit_move_insn (operands[0], operands[1]);
126   switch (model)
127     {
128     case MEMMODEL_RELAXED:
129       break;
130     case MEMMODEL_CONSUME:
131     case MEMMODEL_ACQUIRE:
132     case MEMMODEL_SEQ_CST:
133       emit_insn (gen_loadsync (operands[0]));
134       break;
135     default:
136       gcc_unreachable ();
137     }
138   DONE;
141 (define_expand "atomic_store<mode>"
142   [(set (match_operand:INT 0 "memory_operand" "")               ;; memory
143         (match_operand:INT 1 "register_operand" ""))            ;; input
144    (use (match_operand:SI 2 "const_int_operand" ""))]           ;; model
145   ""
147   enum memmodel model = (enum memmodel) INTVAL (operands[2]);
148   switch (model)
149     {
150     case MEMMODEL_RELAXED:
151       break;
152     case MEMMODEL_RELEASE:
153       emit_insn (gen_lwsync ());
154       break;
155     case MEMMODEL_SEQ_CST:
156       emit_insn (gen_hwsync ());
157       break;
158     default:
159       gcc_unreachable ();
160     }
161   emit_move_insn (operands[0], operands[1]);
162   DONE;
165 ;; ??? Power ISA 2.06B says that there *is* a load-{byte,half}-and-reserve
166 ;; opcode that is "phased-in".  Not implemented as of Power7, so not yet used,
167 ;; but let's prepare the macros anyway.
169 (define_mode_iterator ATOMIC    [SI (DI "TARGET_64BIT")])
171 (define_insn "load_locked<mode>"
172   [(set (match_operand:ATOMIC 0 "gpc_reg_operand" "=r")
173         (unspec_volatile:ATOMIC
174          [(match_operand:ATOMIC 1 "memory_operand" "Z")] UNSPECV_LL))]
175   "TARGET_POWERPC"
176   "<larx> %0,%y1"
177   [(set_attr "type" "load_l")])
179 (define_insn "store_conditional<mode>"
180   [(set (match_operand:CC 0 "cc_reg_operand" "=x")
181         (unspec_volatile:CC [(const_int 0)] UNSPECV_SC))
182    (set (match_operand:ATOMIC 1 "memory_operand" "=Z")
183         (match_operand:ATOMIC 2 "gpc_reg_operand" "r"))]
184   "TARGET_POWERPC"
185   "<stcx> %2,%y1"
186   [(set_attr "type" "store_c")])
188 (define_expand "atomic_compare_and_swap<mode>"
189   [(match_operand:SI 0 "gpc_reg_operand" "")            ;; bool out
190    (match_operand:INT1 1 "gpc_reg_operand" "")          ;; val out
191    (match_operand:INT1 2 "memory_operand" "")           ;; memory
192    (match_operand:INT1 3 "reg_or_short_operand" "")     ;; expected
193    (match_operand:INT1 4 "gpc_reg_operand" "")          ;; desired
194    (match_operand:SI 5 "const_int_operand" "")          ;; is_weak
195    (match_operand:SI 6 "const_int_operand" "")          ;; model succ
196    (match_operand:SI 7 "const_int_operand" "")]         ;; model fail
197   "TARGET_POWERPC"
199   rs6000_expand_atomic_compare_and_swap (operands);
200   DONE;
203 (define_expand "atomic_exchange<mode>"
204   [(match_operand:INT1 0 "gpc_reg_operand" "")          ;; output
205    (match_operand:INT1 1 "memory_operand" "")           ;; memory
206    (match_operand:INT1 2 "gpc_reg_operand" "")          ;; input
207    (match_operand:SI 3 "const_int_operand" "")]         ;; model
208   "TARGET_POWERPC"
210   rs6000_expand_atomic_exchange (operands);
211   DONE;
214 (define_expand "atomic_<fetchop_name><mode>"
215   [(match_operand:INT1 0 "memory_operand" "")           ;; memory
216    (FETCHOP:INT1 (match_dup 0)
217      (match_operand:INT1 1 "<fetchop_pred>" ""))        ;; operand
218    (match_operand:SI 2 "const_int_operand" "")]         ;; model
219   "TARGET_POWERPC"
221   rs6000_expand_atomic_op (<CODE>, operands[0], operands[1],
222                            NULL_RTX, NULL_RTX, operands[2]);
223   DONE;
226 (define_expand "atomic_nand<mode>"
227   [(match_operand:INT1 0 "memory_operand" "")           ;; memory
228    (match_operand:INT1 1 "gpc_reg_operand" "")          ;; operand
229    (match_operand:SI 2 "const_int_operand" "")]         ;; model
230   "TARGET_POWERPC"
232   rs6000_expand_atomic_op (NOT, operands[0], operands[1],
233                            NULL_RTX, NULL_RTX, operands[2]);
234   DONE;
237 (define_expand "atomic_fetch_<fetchop_name><mode>"
238   [(match_operand:INT1 0 "gpc_reg_operand" "")          ;; output
239    (match_operand:INT1 1 "memory_operand" "")           ;; memory
240    (FETCHOP:INT1 (match_dup 1)
241      (match_operand:INT1 2 "<fetchop_pred>" ""))        ;; operand
242    (match_operand:SI 3 "const_int_operand" "")]         ;; model
243   "TARGET_POWERPC"
245   rs6000_expand_atomic_op (<CODE>, operands[1], operands[2],
246                            operands[0], NULL_RTX, operands[3]);
247   DONE;
250 (define_expand "atomic_fetch_nand<mode>"
251   [(match_operand:INT1 0 "gpc_reg_operand" "")          ;; output
252    (match_operand:INT1 1 "memory_operand" "")           ;; memory
253    (match_operand:INT1 2 "gpc_reg_operand" "")          ;; operand
254    (match_operand:SI 3 "const_int_operand" "")]         ;; model
255   "TARGET_POWERPC"
257   rs6000_expand_atomic_op (NOT, operands[1], operands[2],
258                            operands[0], NULL_RTX, operands[3]);
259   DONE;
262 (define_expand "atomic_<fetchop_name>_fetch<mode>"
263   [(match_operand:INT1 0 "gpc_reg_operand" "")          ;; output
264    (match_operand:INT1 1 "memory_operand" "")           ;; memory
265    (FETCHOP:INT1 (match_dup 1)
266      (match_operand:INT1 2 "<fetchop_pred>" ""))        ;; operand
267    (match_operand:SI 3 "const_int_operand" "")]         ;; model
268   "TARGET_POWERPC"
270   rs6000_expand_atomic_op (<CODE>, operands[1], operands[2],
271                            NULL_RTX, operands[0], operands[3]);
272   DONE;
275 (define_expand "atomic_nand_fetch<mode>"
276   [(match_operand:INT1 0 "gpc_reg_operand" "")          ;; output
277    (match_operand:INT1 1 "memory_operand" "")           ;; memory
278    (match_operand:INT1 2 "gpc_reg_operand" "")          ;; operand
279    (match_operand:SI 3 "const_int_operand" "")]         ;; model
280   "TARGET_POWERPC"
282   rs6000_expand_atomic_op (NOT, operands[1], operands[2],
283                            NULL_RTX, operands[0], operands[3]);
284   DONE;