1 ;; GCC machine description for SH synchronization instructions.
3 ;; Free Software Foundation, Inc.
5 ;; This file is part of GCC.
7 ;; GCC is free software; you can redistribute it and/or modify
8 ;; it under the terms of the GNU General Public License as published by
9 ;; the Free Software Foundation; either version 3, or (at your option)
12 ;; GCC is distributed in the hope that it will be useful,
13 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 ;; GNU General Public License for more details.
17 ;; You should have received a copy of the GNU General Public License
18 ;; along with GCC; see the file COPYING3. If not see
19 ;; <http://www.gnu.org/licenses/>.
21 (define_c_enum "unspec" [
25 (define_c_enum "unspecv" [
31 (define_mode_iterator I124 [QI HI SI])
33 (define_mode_attr i124suffix [(QI "b") (HI "w") (SI "l")])
34 (define_mode_attr i124extend_insn [(QI "exts.b") (HI "exts.w") (SI "mov")])
36 (define_code_iterator FETCHOP [plus minus ior xor and])
37 (define_code_attr fetchop_name
38 [(plus "add") (minus "sub") (ior "ior") (xor "xor") (and "and")])
39 (define_code_attr fetchop_insn
40 [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")])
42 ;; Linux specific atomic patterns for the Renesas / SuperH SH CPUs.
43 ;; Linux kernel for SH3/4 has implemented the support for software
46 (define_expand "atomic_compare_and_swap<mode>"
47 [(match_operand:QI 0 "register_operand" "") ;; bool success output
48 (match_operand:I124 1 "register_operand" "") ;; oldval output
49 (match_operand:I124 2 "memory_operand" "") ;; memory
50 (match_operand:I124 3 "register_operand" "") ;; expected input
51 (match_operand:I124 4 "register_operand" "") ;; newval input
52 (match_operand:SI 5 "const_int_operand" "") ;; is_weak
53 (match_operand:SI 6 "const_int_operand" "") ;; success model
54 (match_operand:SI 7 "const_int_operand" "")] ;; failure model
55 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
59 addr = force_reg (Pmode, XEXP (operands[2], 0));
60 emit_insn (gen_atomic_compare_and_swap<mode>_soft
61 (gen_lowpart (SImode, operands[1]), addr, operands[3],
63 if (<MODE>mode == QImode)
64 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[1]),
66 else if (<MODE>mode == HImode)
67 emit_insn (gen_zero_extendhisi2 (gen_lowpart (SImode, operands[1]),
69 emit_insn (gen_movqi (operands[0], gen_rtx_REG (QImode, T_REG)));
73 (define_insn "atomic_compare_and_swap<mode>_soft"
74 [(set (match_operand:SI 0 "register_operand" "=&u")
76 [(mem:I124 (match_operand:SI 1 "register_operand" "u"))
77 (match_operand:I124 2 "register_operand" "u")
78 (match_operand:I124 3 "register_operand" "u")]
80 (set (mem:I124 (match_dup 1))
81 (unspec_volatile:I124 [(const_int 0)] UNSPECV_CMPXCHG_2))
83 (unspec_volatile:QI [(const_int 0)] UNSPECV_CMPXCHG_3))
84 (clobber (match_scratch:SI 4 "=&u"))
85 (clobber (reg:SI R0_REG))
86 (clobber (reg:SI R1_REG))]
87 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
92 \\t<i124extend_insn>\\t%2, %4\\n\\
94 \\tmov\\t#(0f-1f), r15\\n\\
95 0:\\tmov.<i124suffix>\\t@%1, %0\\n\\
96 \\tcmp/eq\\t%0, %4\\n\\
98 \\tmov.<i124suffix>\\t%3, @%1\\n\\
102 [(set_attr "length" "20")])
104 (define_expand "atomic_fetch_<fetchop_name><mode>"
105 [(set (match_operand:I124 0 "register_operand" "")
106 (match_operand:I124 1 "memory_operand" ""))
109 [(FETCHOP:I124 (match_dup 1)
110 (match_operand:I124 2 "register_operand" ""))]
112 (match_operand:SI 3 "const_int_operand" "")]
113 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
117 addr = force_reg (Pmode, XEXP (operands[1], 0));
118 emit_insn (gen_atomic_fetch_<fetchop_name><mode>_soft
119 (operands[0], addr, operands[2]));
120 if (<MODE>mode == QImode)
121 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
123 else if (<MODE>mode == HImode)
124 emit_insn (gen_zero_extendhisi2 (gen_lowpart (SImode, operands[0]),
129 (define_insn "atomic_fetch_<fetchop_name><mode>_soft"
130 [(set (match_operand:I124 0 "register_operand" "=&u")
131 (mem:I124 (match_operand:SI 1 "register_operand" "u")))
132 (set (mem:I124 (match_dup 1))
134 [(FETCHOP:I124 (mem:I124 (match_dup 1))
135 (match_operand:I124 2 "register_operand" "u"))]
137 (clobber (match_scratch:I124 3 "=&u"))
138 (clobber (reg:SI R0_REG))
139 (clobber (reg:SI R1_REG))]
140 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
145 \\tmov\\tr15, r1\\n\\
146 \\tmov\\t#(0f-1f), r15\\n\\
147 0:\\tmov.<i124suffix>\\t@%1, %0\\n\\
149 \\t<fetchop_insn>\\t%2, %3\\n\\
150 \\tmov.<i124suffix>\\t%3, @%1\\n\\
154 [(set_attr "length" "18")])
156 (define_expand "atomic_fetch_nand<mode>"
157 [(set (match_operand:I124 0 "register_operand" "")
158 (match_operand:I124 1 "memory_operand" ""))
161 [(not:I124 (and:I124 (match_dup 1)
162 (match_operand:I124 2 "register_operand" "")))]
164 (match_operand:SI 3 "const_int_operand" "")]
165 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
169 addr = force_reg (Pmode, XEXP (operands[1], 0));
170 emit_insn (gen_atomic_fetch_nand<mode>_soft
171 (operands[0], addr, operands[2]));
172 if (<MODE>mode == QImode)
173 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
175 else if (<MODE>mode == HImode)
176 emit_insn (gen_zero_extendhisi2 (gen_lowpart (SImode, operands[0]),
181 (define_insn "atomic_fetch_nand<mode>_soft"
182 [(set (match_operand:I124 0 "register_operand" "=&u")
183 (mem:I124 (match_operand:SI 1 "register_operand" "u")))
184 (set (mem:I124 (match_dup 1))
186 [(not:I124 (and:I124 (mem:I124 (match_dup 1))
187 (match_operand:I124 2 "register_operand" "u")))]
189 (clobber (match_scratch:I124 3 "=&u"))
190 (clobber (reg:SI R0_REG))
191 (clobber (reg:SI R1_REG))]
192 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
197 \\tmov\\tr15, r1\\n\\
198 \\tmov\\t#(0f-1f), r15\\n\\
199 0:\\tmov.<i124suffix>\\t@%1, %0\\n\\
203 \\tmov.<i124suffix>\\t%3, @%1\\n\\
207 [(set_attr "length" "20")])
209 (define_expand "atomic_<fetchop_name>_fetch<mode>"
210 [(set (match_operand:I124 0 "register_operand" "")
212 (match_operand:I124 1 "memory_operand" "")
213 (match_operand:I124 2 "register_operand" "")))
216 [(FETCHOP:I124 (match_dup 1) (match_dup 2))]
218 (match_operand:SI 3 "const_int_operand" "")]
219 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
223 addr = force_reg (Pmode, XEXP (operands[1], 0));
224 emit_insn (gen_atomic_<fetchop_name>_fetch<mode>_soft
225 (operands[0], addr, operands[2]));
226 if (<MODE>mode == QImode)
227 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
229 else if (<MODE>mode == HImode)
230 emit_insn (gen_zero_extendhisi2 (gen_lowpart (SImode, operands[0]),
235 (define_insn "atomic_<fetchop_name>_fetch<mode>_soft"
236 [(set (match_operand:I124 0 "register_operand" "=&u")
238 (mem:I124 (match_operand:SI 1 "register_operand" "u"))
239 (match_operand:I124 2 "register_operand" "u")))
240 (set (mem:I124 (match_dup 1))
242 [(FETCHOP:I124 (mem:I124 (match_dup 1)) (match_dup 2))]
244 (clobber (reg:SI R0_REG))
245 (clobber (reg:SI R1_REG))]
246 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
251 \\tmov\\tr15, r1\\n\\
252 \\tmov\\t#(0f-1f), r15\\n\\
253 0:\\tmov.<i124suffix>\\t@%1, %0\\n\\
254 \\t<fetchop_insn>\\t%2, %0\\n\\
255 \\tmov.<i124suffix>\\t%0, @%1\\n\\
259 [(set_attr "length" "16")])
261 (define_expand "atomic_nand_fetch<mode>"
262 [(set (match_operand:I124 0 "register_operand" "")
264 (match_operand:I124 1 "memory_operand" "")
265 (match_operand:I124 2 "register_operand" ""))))
268 [(not:I124 (and:I124 (match_dup 1) (match_dup 2)))]
270 (match_operand:SI 3 "const_int_operand" "")]
271 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
275 addr = force_reg (Pmode, XEXP (operands[1], 0));
276 emit_insn (gen_atomic_nand_fetch<mode>_soft
277 (operands[0], addr, operands[2]));
278 if (<MODE>mode == QImode)
279 emit_insn (gen_zero_extendqisi2 (gen_lowpart (SImode, operands[0]),
281 else if (<MODE>mode == HImode)
282 emit_insn (gen_zero_extendhisi2 (gen_lowpart (SImode, operands[0]),
287 (define_insn "atomic_nand_fetch<mode>_soft"
288 [(set (match_operand:I124 0 "register_operand" "=&u")
290 (mem:I124 (match_operand:SI 1 "register_operand" "u"))
291 (match_operand:I124 2 "register_operand" "u"))))
292 (set (mem:I124 (match_dup 1))
294 [(not:I124 (and:I124 (mem:I124 (match_dup 1)) (match_dup 2)))]
296 (clobber (reg:SI R0_REG))
297 (clobber (reg:SI R1_REG))]
298 "TARGET_SOFT_ATOMIC && !TARGET_SHMEDIA"
303 \\tmov\\tr15, r1\\n\\
304 \\tmov\\t#(0f-1f), r15\\n\\
305 0:\\tmov.<i124suffix>\\t@%1, %0\\n\\
308 \\tmov.<i124suffix>\\t%0, @%1\\n\\
312 [(set_attr "length" "18")])