annotate gcc/config/rs6000/sync.md @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 ;; Machine description for PowerPC synchronization instructions.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 ;; Copyright (C) 2005-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3 ;; Contributed by Geoffrey Keating.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 ;; This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 ;; GCC is free software; you can redistribute it and/or modify it
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 ;; under the terms of the GNU General Public License as published
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 ;; by the Free Software Foundation; either version 3, or (at your
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 ;; option) any later version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 ;; GCC is distributed in the hope that it will be useful, but WITHOUT
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 ;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 ;; License for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 ;; You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 ;; along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 ;; <http://www.gnu.org/licenses/>.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
111
kono
parents: 55
diff changeset
21 (define_mode_attr larx [(QI "lbarx")
kono
parents: 55
diff changeset
22 (HI "lharx")
kono
parents: 55
diff changeset
23 (SI "lwarx")
kono
parents: 55
diff changeset
24 (DI "ldarx")
kono
parents: 55
diff changeset
25 (TI "lqarx")])
kono
parents: 55
diff changeset
26
kono
parents: 55
diff changeset
27 (define_mode_attr stcx [(QI "stbcx.")
kono
parents: 55
diff changeset
28 (HI "sthcx.")
kono
parents: 55
diff changeset
29 (SI "stwcx.")
kono
parents: 55
diff changeset
30 (DI "stdcx.")
kono
parents: 55
diff changeset
31 (TI "stqcx.")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 (define_code_iterator FETCHOP [plus minus ior xor and])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34 (define_code_attr fetchop_name
111
kono
parents: 55
diff changeset
35 [(plus "add") (minus "sub") (ior "or") (xor "xor") (and "and")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 (define_code_attr fetchop_pred
111
kono
parents: 55
diff changeset
37 [(plus "add_operand") (minus "int_reg_operand")
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 (ior "logical_operand") (xor "logical_operand") (and "and_operand")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
111
kono
parents: 55
diff changeset
40 (define_expand "mem_thread_fence"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
41 [(match_operand:SI 0 "const_int_operand")] ;; model
111
kono
parents: 55
diff changeset
42 ""
kono
parents: 55
diff changeset
43 {
kono
parents: 55
diff changeset
44 enum memmodel model = memmodel_base (INTVAL (operands[0]));
kono
parents: 55
diff changeset
45 switch (model)
kono
parents: 55
diff changeset
46 {
kono
parents: 55
diff changeset
47 case MEMMODEL_RELAXED:
kono
parents: 55
diff changeset
48 break;
kono
parents: 55
diff changeset
49 case MEMMODEL_CONSUME:
kono
parents: 55
diff changeset
50 case MEMMODEL_ACQUIRE:
kono
parents: 55
diff changeset
51 case MEMMODEL_RELEASE:
kono
parents: 55
diff changeset
52 case MEMMODEL_ACQ_REL:
kono
parents: 55
diff changeset
53 emit_insn (gen_lwsync ());
kono
parents: 55
diff changeset
54 break;
kono
parents: 55
diff changeset
55 case MEMMODEL_SEQ_CST:
kono
parents: 55
diff changeset
56 emit_insn (gen_hwsync ());
kono
parents: 55
diff changeset
57 break;
kono
parents: 55
diff changeset
58 default:
kono
parents: 55
diff changeset
59 gcc_unreachable ();
kono
parents: 55
diff changeset
60 }
kono
parents: 55
diff changeset
61 DONE;
kono
parents: 55
diff changeset
62 })
kono
parents: 55
diff changeset
63
kono
parents: 55
diff changeset
64 (define_expand "hwsync"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 [(set (match_dup 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 ""
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 MEM_VOLATILE_P (operands[0]) = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72
111
kono
parents: 55
diff changeset
73 (define_insn "*hwsync"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 [(set (match_operand:BLK 0 "" "")
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 (unspec:BLK [(match_dup 0)] UNSPEC_SYNC))]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 ""
111
kono
parents: 55
diff changeset
77 "sync"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 [(set_attr "type" "sync")])
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79
111
kono
parents: 55
diff changeset
80 (define_expand "lwsync"
kono
parents: 55
diff changeset
81 [(set (match_dup 0)
kono
parents: 55
diff changeset
82 (unspec:BLK [(match_dup 0)] UNSPEC_LWSYNC))]
kono
parents: 55
diff changeset
83 ""
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 {
111
kono
parents: 55
diff changeset
85 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
kono
parents: 55
diff changeset
86 MEM_VOLATILE_P (operands[0]) = 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
111
kono
parents: 55
diff changeset
89 (define_insn "*lwsync"
kono
parents: 55
diff changeset
90 [(set (match_operand:BLK 0 "" "")
kono
parents: 55
diff changeset
91 (unspec:BLK [(match_dup 0)] UNSPEC_LWSYNC))]
kono
parents: 55
diff changeset
92 ""
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 {
111
kono
parents: 55
diff changeset
94 if (TARGET_NO_LWSYNC)
kono
parents: 55
diff changeset
95 return "sync";
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
96 else
111
kono
parents: 55
diff changeset
97 return "lwsync";
kono
parents: 55
diff changeset
98 }
kono
parents: 55
diff changeset
99 [(set_attr "type" "sync")])
kono
parents: 55
diff changeset
100
kono
parents: 55
diff changeset
101 (define_insn "isync"
kono
parents: 55
diff changeset
102 [(unspec_volatile:BLK [(const_int 0)] UNSPECV_ISYNC)]
kono
parents: 55
diff changeset
103 ""
kono
parents: 55
diff changeset
104 "isync"
kono
parents: 55
diff changeset
105 [(set_attr "type" "isync")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106
111
kono
parents: 55
diff changeset
107 ;; Types that we should provide atomic instructions for.
kono
parents: 55
diff changeset
108 (define_mode_iterator AINT [QI
kono
parents: 55
diff changeset
109 HI
kono
parents: 55
diff changeset
110 SI
kono
parents: 55
diff changeset
111 (DI "TARGET_POWERPC64")
kono
parents: 55
diff changeset
112 (TI "TARGET_SYNC_TI")])
kono
parents: 55
diff changeset
113
kono
parents: 55
diff changeset
114 ;; The control dependency used for load dependency described
kono
parents: 55
diff changeset
115 ;; in B.2.3 of the Power ISA 2.06B.
kono
parents: 55
diff changeset
116 (define_insn "loadsync_<mode>"
kono
parents: 55
diff changeset
117 [(unspec_volatile:BLK [(match_operand:AINT 0 "register_operand" "r")]
kono
parents: 55
diff changeset
118 UNSPECV_ISYNC)
kono
parents: 55
diff changeset
119 (clobber (match_scratch:CC 1 "=y"))]
kono
parents: 55
diff changeset
120 ""
kono
parents: 55
diff changeset
121 "cmpw %1,%0,%0\;bne- %1,$+4\;isync"
kono
parents: 55
diff changeset
122 [(set_attr "type" "isync")
kono
parents: 55
diff changeset
123 (set_attr "length" "12")])
kono
parents: 55
diff changeset
124
kono
parents: 55
diff changeset
125 (define_insn "load_quadpti"
kono
parents: 55
diff changeset
126 [(set (match_operand:PTI 0 "quad_int_reg_operand" "=&r")
kono
parents: 55
diff changeset
127 (unspec:PTI
kono
parents: 55
diff changeset
128 [(match_operand:TI 1 "quad_memory_operand" "wQ")] UNSPEC_LSQ))]
kono
parents: 55
diff changeset
129 "TARGET_SYNC_TI
kono
parents: 55
diff changeset
130 && !reg_mentioned_p (operands[0], operands[1])"
kono
parents: 55
diff changeset
131 "lq %0,%1"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
132 [(set_attr "type" "load")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133
111
kono
parents: 55
diff changeset
134 (define_expand "atomic_load<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
135 [(set (match_operand:AINT 0 "register_operand") ;; output
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
136 (match_operand:AINT 1 "memory_operand")) ;; memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
137 (use (match_operand:SI 2 "const_int_operand"))] ;; model
111
kono
parents: 55
diff changeset
138 ""
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 {
111
kono
parents: 55
diff changeset
140 if (<MODE>mode == TImode && !TARGET_SYNC_TI)
kono
parents: 55
diff changeset
141 FAIL;
kono
parents: 55
diff changeset
142
kono
parents: 55
diff changeset
143 enum memmodel model = memmodel_base (INTVAL (operands[2]));
kono
parents: 55
diff changeset
144
kono
parents: 55
diff changeset
145 if (is_mm_seq_cst (model))
kono
parents: 55
diff changeset
146 emit_insn (gen_hwsync ());
kono
parents: 55
diff changeset
147
kono
parents: 55
diff changeset
148 if (<MODE>mode != TImode)
kono
parents: 55
diff changeset
149 emit_move_insn (operands[0], operands[1]);
kono
parents: 55
diff changeset
150 else
kono
parents: 55
diff changeset
151 {
kono
parents: 55
diff changeset
152 rtx op0 = operands[0];
kono
parents: 55
diff changeset
153 rtx op1 = operands[1];
kono
parents: 55
diff changeset
154 rtx pti_reg = gen_reg_rtx (PTImode);
kono
parents: 55
diff changeset
155
kono
parents: 55
diff changeset
156 if (!quad_address_p (XEXP (op1, 0), TImode, false))
kono
parents: 55
diff changeset
157 {
kono
parents: 55
diff changeset
158 rtx old_addr = XEXP (op1, 0);
kono
parents: 55
diff changeset
159 rtx new_addr = force_reg (Pmode, old_addr);
kono
parents: 55
diff changeset
160 operands[1] = op1 = replace_equiv_address (op1, new_addr);
kono
parents: 55
diff changeset
161 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162
111
kono
parents: 55
diff changeset
163 emit_insn (gen_load_quadpti (pti_reg, op1));
kono
parents: 55
diff changeset
164
kono
parents: 55
diff changeset
165 if (WORDS_BIG_ENDIAN)
kono
parents: 55
diff changeset
166 emit_move_insn (op0, gen_lowpart (TImode, pti_reg));
kono
parents: 55
diff changeset
167 else
kono
parents: 55
diff changeset
168 {
kono
parents: 55
diff changeset
169 emit_move_insn (gen_lowpart (DImode, op0), gen_highpart (DImode, pti_reg));
kono
parents: 55
diff changeset
170 emit_move_insn (gen_highpart (DImode, op0), gen_lowpart (DImode, pti_reg));
kono
parents: 55
diff changeset
171 }
kono
parents: 55
diff changeset
172 }
kono
parents: 55
diff changeset
173
kono
parents: 55
diff changeset
174 switch (model)
kono
parents: 55
diff changeset
175 {
kono
parents: 55
diff changeset
176 case MEMMODEL_RELAXED:
kono
parents: 55
diff changeset
177 break;
kono
parents: 55
diff changeset
178 case MEMMODEL_CONSUME:
kono
parents: 55
diff changeset
179 case MEMMODEL_ACQUIRE:
kono
parents: 55
diff changeset
180 case MEMMODEL_SEQ_CST:
kono
parents: 55
diff changeset
181 emit_insn (gen_loadsync_<mode> (operands[0]));
kono
parents: 55
diff changeset
182 break;
kono
parents: 55
diff changeset
183 default:
kono
parents: 55
diff changeset
184 gcc_unreachable ();
kono
parents: 55
diff changeset
185 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
186 DONE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
187 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
188
111
kono
parents: 55
diff changeset
189 (define_insn "store_quadpti"
kono
parents: 55
diff changeset
190 [(set (match_operand:PTI 0 "quad_memory_operand" "=wQ")
kono
parents: 55
diff changeset
191 (unspec:PTI
kono
parents: 55
diff changeset
192 [(match_operand:PTI 1 "quad_int_reg_operand" "r")] UNSPEC_LSQ))]
kono
parents: 55
diff changeset
193 "TARGET_SYNC_TI"
kono
parents: 55
diff changeset
194 "stq %1,%0"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
195 [(set_attr "type" "store")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196
111
kono
parents: 55
diff changeset
197 (define_expand "atomic_store<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
198 [(set (match_operand:AINT 0 "memory_operand") ;; memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
199 (match_operand:AINT 1 "register_operand")) ;; input
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
200 (use (match_operand:SI 2 "const_int_operand"))] ;; model
111
kono
parents: 55
diff changeset
201 ""
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 {
111
kono
parents: 55
diff changeset
203 if (<MODE>mode == TImode && !TARGET_SYNC_TI)
kono
parents: 55
diff changeset
204 FAIL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205
111
kono
parents: 55
diff changeset
206 enum memmodel model = memmodel_base (INTVAL (operands[2]));
kono
parents: 55
diff changeset
207 switch (model)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208 {
111
kono
parents: 55
diff changeset
209 case MEMMODEL_RELAXED:
kono
parents: 55
diff changeset
210 break;
kono
parents: 55
diff changeset
211 case MEMMODEL_RELEASE:
kono
parents: 55
diff changeset
212 emit_insn (gen_lwsync ());
kono
parents: 55
diff changeset
213 break;
kono
parents: 55
diff changeset
214 case MEMMODEL_SEQ_CST:
kono
parents: 55
diff changeset
215 emit_insn (gen_hwsync ());
kono
parents: 55
diff changeset
216 break;
kono
parents: 55
diff changeset
217 default:
kono
parents: 55
diff changeset
218 gcc_unreachable ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
219 }
111
kono
parents: 55
diff changeset
220 if (<MODE>mode != TImode)
kono
parents: 55
diff changeset
221 emit_move_insn (operands[0], operands[1]);
kono
parents: 55
diff changeset
222 else
kono
parents: 55
diff changeset
223 {
kono
parents: 55
diff changeset
224 rtx op0 = operands[0];
kono
parents: 55
diff changeset
225 rtx op1 = operands[1];
kono
parents: 55
diff changeset
226 rtx pti_reg = gen_reg_rtx (PTImode);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227
111
kono
parents: 55
diff changeset
228 if (!quad_address_p (XEXP (op0, 0), TImode, false))
kono
parents: 55
diff changeset
229 {
kono
parents: 55
diff changeset
230 rtx old_addr = XEXP (op0, 0);
kono
parents: 55
diff changeset
231 rtx new_addr = force_reg (Pmode, old_addr);
kono
parents: 55
diff changeset
232 operands[0] = op0 = replace_equiv_address (op0, new_addr);
kono
parents: 55
diff changeset
233 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234
111
kono
parents: 55
diff changeset
235 if (WORDS_BIG_ENDIAN)
kono
parents: 55
diff changeset
236 emit_move_insn (pti_reg, gen_lowpart (PTImode, op1));
kono
parents: 55
diff changeset
237 else
kono
parents: 55
diff changeset
238 {
kono
parents: 55
diff changeset
239 emit_move_insn (gen_lowpart (DImode, pti_reg), gen_highpart (DImode, op1));
kono
parents: 55
diff changeset
240 emit_move_insn (gen_highpart (DImode, pti_reg), gen_lowpart (DImode, op1));
kono
parents: 55
diff changeset
241 }
kono
parents: 55
diff changeset
242
kono
parents: 55
diff changeset
243 emit_insn (gen_store_quadpti (gen_lowpart (PTImode, op0), pti_reg));
kono
parents: 55
diff changeset
244 }
kono
parents: 55
diff changeset
245
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246 DONE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
248
111
kono
parents: 55
diff changeset
249 ;; Any supported integer mode that has atomic l<x>arx/st<x>cx. instrucitons
kono
parents: 55
diff changeset
250 ;; other than the quad memory operations, which have special restrictions.
kono
parents: 55
diff changeset
251 ;; Byte/halfword atomic instructions were added in ISA 2.06B, but were phased
kono
parents: 55
diff changeset
252 ;; in and did not show up until power8. TImode atomic lqarx/stqcx. require
kono
parents: 55
diff changeset
253 ;; special handling due to even/odd register requirements.
kono
parents: 55
diff changeset
254 (define_mode_iterator ATOMIC [(QI "TARGET_SYNC_HI_QI")
kono
parents: 55
diff changeset
255 (HI "TARGET_SYNC_HI_QI")
kono
parents: 55
diff changeset
256 SI
kono
parents: 55
diff changeset
257 (DI "TARGET_POWERPC64")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258
111
kono
parents: 55
diff changeset
259 (define_insn "load_locked<mode>"
kono
parents: 55
diff changeset
260 [(set (match_operand:ATOMIC 0 "int_reg_operand" "=r")
kono
parents: 55
diff changeset
261 (unspec_volatile:ATOMIC
kono
parents: 55
diff changeset
262 [(match_operand:ATOMIC 1 "memory_operand" "Z")] UNSPECV_LL))]
kono
parents: 55
diff changeset
263 ""
kono
parents: 55
diff changeset
264 "<larx> %0,%y1"
kono
parents: 55
diff changeset
265 [(set_attr "type" "load_l")])
kono
parents: 55
diff changeset
266
kono
parents: 55
diff changeset
267 (define_insn "load_locked<QHI:mode>_si"
kono
parents: 55
diff changeset
268 [(set (match_operand:SI 0 "int_reg_operand" "=r")
kono
parents: 55
diff changeset
269 (unspec_volatile:SI
kono
parents: 55
diff changeset
270 [(match_operand:QHI 1 "memory_operand" "Z")] UNSPECV_LL))]
kono
parents: 55
diff changeset
271 "TARGET_SYNC_HI_QI"
kono
parents: 55
diff changeset
272 "<QHI:larx> %0,%y1"
kono
parents: 55
diff changeset
273 [(set_attr "type" "load_l")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
274
111
kono
parents: 55
diff changeset
275 ;; Use PTImode to get even/odd register pairs.
kono
parents: 55
diff changeset
276 ;; Use a temporary register to force getting an even register for the
kono
parents: 55
diff changeset
277 ;; lqarx/stqcrx. instructions. Normal optimizations will eliminate this extra
kono
parents: 55
diff changeset
278 ;; copy on big endian systems.
kono
parents: 55
diff changeset
279
kono
parents: 55
diff changeset
280 ;; On little endian systems where non-atomic quad word load/store instructions
kono
parents: 55
diff changeset
281 ;; are not used, the address can be register+offset, so make sure the address
kono
parents: 55
diff changeset
282 ;; is indexed or indirect before register allocation.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
283
111
kono
parents: 55
diff changeset
284 (define_expand "load_lockedti"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
285 [(use (match_operand:TI 0 "quad_int_reg_operand"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
286 (use (match_operand:TI 1 "memory_operand"))]
111
kono
parents: 55
diff changeset
287 "TARGET_SYNC_TI"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
288 {
111
kono
parents: 55
diff changeset
289 rtx op0 = operands[0];
kono
parents: 55
diff changeset
290 rtx op1 = operands[1];
kono
parents: 55
diff changeset
291 rtx pti = gen_reg_rtx (PTImode);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
292
111
kono
parents: 55
diff changeset
293 if (!indexed_or_indirect_operand (op1, TImode))
kono
parents: 55
diff changeset
294 {
kono
parents: 55
diff changeset
295 rtx old_addr = XEXP (op1, 0);
kono
parents: 55
diff changeset
296 rtx new_addr = force_reg (Pmode, old_addr);
kono
parents: 55
diff changeset
297 operands[1] = op1 = change_address (op1, TImode, new_addr);
kono
parents: 55
diff changeset
298 }
kono
parents: 55
diff changeset
299
kono
parents: 55
diff changeset
300 emit_insn (gen_load_lockedpti (pti, op1));
kono
parents: 55
diff changeset
301 if (WORDS_BIG_ENDIAN)
kono
parents: 55
diff changeset
302 emit_move_insn (op0, gen_lowpart (TImode, pti));
kono
parents: 55
diff changeset
303 else
kono
parents: 55
diff changeset
304 {
kono
parents: 55
diff changeset
305 emit_move_insn (gen_lowpart (DImode, op0), gen_highpart (DImode, pti));
kono
parents: 55
diff changeset
306 emit_move_insn (gen_highpart (DImode, op0), gen_lowpart (DImode, pti));
kono
parents: 55
diff changeset
307 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 DONE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310
111
kono
parents: 55
diff changeset
311 (define_insn "load_lockedpti"
kono
parents: 55
diff changeset
312 [(set (match_operand:PTI 0 "quad_int_reg_operand" "=&r")
kono
parents: 55
diff changeset
313 (unspec_volatile:PTI
kono
parents: 55
diff changeset
314 [(match_operand:TI 1 "indexed_or_indirect_operand" "Z")] UNSPECV_LL))]
kono
parents: 55
diff changeset
315 "TARGET_SYNC_TI
kono
parents: 55
diff changeset
316 && !reg_mentioned_p (operands[0], operands[1])
kono
parents: 55
diff changeset
317 && quad_int_reg_operand (operands[0], PTImode)"
kono
parents: 55
diff changeset
318 "lqarx %0,%y1"
kono
parents: 55
diff changeset
319 [(set_attr "type" "load_l")])
kono
parents: 55
diff changeset
320
kono
parents: 55
diff changeset
321 (define_insn "store_conditional<mode>"
kono
parents: 55
diff changeset
322 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
kono
parents: 55
diff changeset
323 (unspec_volatile:CC [(const_int 0)] UNSPECV_SC))
kono
parents: 55
diff changeset
324 (set (match_operand:ATOMIC 1 "memory_operand" "=Z")
kono
parents: 55
diff changeset
325 (match_operand:ATOMIC 2 "int_reg_operand" "r"))]
kono
parents: 55
diff changeset
326 ""
kono
parents: 55
diff changeset
327 "<stcx> %2,%y1"
kono
parents: 55
diff changeset
328 [(set_attr "type" "store_c")])
kono
parents: 55
diff changeset
329
kono
parents: 55
diff changeset
330 ;; Use a temporary register to force getting an even register for the
kono
parents: 55
diff changeset
331 ;; lqarx/stqcrx. instructions. Normal optimizations will eliminate this extra
kono
parents: 55
diff changeset
332 ;; copy on big endian systems.
kono
parents: 55
diff changeset
333
kono
parents: 55
diff changeset
334 ;; On little endian systems where non-atomic quad word load/store instructions
kono
parents: 55
diff changeset
335 ;; are not used, the address can be register+offset, so make sure the address
kono
parents: 55
diff changeset
336 ;; is indexed or indirect before register allocation.
kono
parents: 55
diff changeset
337
kono
parents: 55
diff changeset
338 (define_expand "store_conditionalti"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
339 [(use (match_operand:CC 0 "cc_reg_operand"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
340 (use (match_operand:TI 1 "memory_operand"))
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
341 (use (match_operand:TI 2 "quad_int_reg_operand"))]
111
kono
parents: 55
diff changeset
342 "TARGET_SYNC_TI"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 {
111
kono
parents: 55
diff changeset
344 rtx op0 = operands[0];
kono
parents: 55
diff changeset
345 rtx op1 = operands[1];
kono
parents: 55
diff changeset
346 rtx op2 = operands[2];
kono
parents: 55
diff changeset
347 rtx addr = XEXP (op1, 0);
kono
parents: 55
diff changeset
348 rtx pti_mem;
kono
parents: 55
diff changeset
349 rtx pti_reg;
kono
parents: 55
diff changeset
350
kono
parents: 55
diff changeset
351 if (!indexed_or_indirect_operand (op1, TImode))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
352 {
111
kono
parents: 55
diff changeset
353 rtx new_addr = force_reg (Pmode, addr);
kono
parents: 55
diff changeset
354 operands[1] = op1 = change_address (op1, TImode, new_addr);
kono
parents: 55
diff changeset
355 addr = new_addr;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 }
111
kono
parents: 55
diff changeset
357
kono
parents: 55
diff changeset
358 pti_mem = change_address (op1, PTImode, addr);
kono
parents: 55
diff changeset
359 pti_reg = gen_reg_rtx (PTImode);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360
111
kono
parents: 55
diff changeset
361 if (WORDS_BIG_ENDIAN)
kono
parents: 55
diff changeset
362 emit_move_insn (pti_reg, gen_lowpart (PTImode, op2));
kono
parents: 55
diff changeset
363 else
kono
parents: 55
diff changeset
364 {
kono
parents: 55
diff changeset
365 emit_move_insn (gen_lowpart (DImode, pti_reg), gen_highpart (DImode, op2));
kono
parents: 55
diff changeset
366 emit_move_insn (gen_highpart (DImode, pti_reg), gen_lowpart (DImode, op2));
kono
parents: 55
diff changeset
367 }
kono
parents: 55
diff changeset
368
kono
parents: 55
diff changeset
369 emit_insn (gen_store_conditionalpti (op0, pti_mem, pti_reg));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
370 DONE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
371 })
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
372
111
kono
parents: 55
diff changeset
373 (define_insn "store_conditionalpti"
kono
parents: 55
diff changeset
374 [(set (match_operand:CC 0 "cc_reg_operand" "=x")
kono
parents: 55
diff changeset
375 (unspec_volatile:CC [(const_int 0)] UNSPECV_SC))
kono
parents: 55
diff changeset
376 (set (match_operand:PTI 1 "indexed_or_indirect_operand" "=Z")
kono
parents: 55
diff changeset
377 (match_operand:PTI 2 "quad_int_reg_operand" "r"))]
kono
parents: 55
diff changeset
378 "TARGET_SYNC_TI && quad_int_reg_operand (operands[2], PTImode)"
kono
parents: 55
diff changeset
379 "stqcx. %2,%y1"
kono
parents: 55
diff changeset
380 [(set_attr "type" "store_c")])
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381
111
kono
parents: 55
diff changeset
382 (define_expand "atomic_compare_and_swap<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
383 [(match_operand:SI 0 "int_reg_operand") ;; bool out
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
384 (match_operand:AINT 1 "int_reg_operand") ;; val out
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
385 (match_operand:AINT 2 "memory_operand") ;; memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
386 (match_operand:AINT 3 "reg_or_short_operand") ;; expected
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
387 (match_operand:AINT 4 "int_reg_operand") ;; desired
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
388 (match_operand:SI 5 "const_int_operand") ;; is_weak
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
389 (match_operand:SI 6 "const_int_operand") ;; model succ
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
390 (match_operand:SI 7 "const_int_operand")] ;; model fail
111
kono
parents: 55
diff changeset
391 ""
kono
parents: 55
diff changeset
392 {
kono
parents: 55
diff changeset
393 rs6000_expand_atomic_compare_and_swap (operands);
kono
parents: 55
diff changeset
394 DONE;
kono
parents: 55
diff changeset
395 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396
111
kono
parents: 55
diff changeset
397 (define_expand "atomic_exchange<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
398 [(match_operand:AINT 0 "int_reg_operand") ;; output
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
399 (match_operand:AINT 1 "memory_operand") ;; memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
400 (match_operand:AINT 2 "int_reg_operand") ;; input
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
401 (match_operand:SI 3 "const_int_operand")] ;; model
111
kono
parents: 55
diff changeset
402 ""
kono
parents: 55
diff changeset
403 {
kono
parents: 55
diff changeset
404 rs6000_expand_atomic_exchange (operands);
kono
parents: 55
diff changeset
405 DONE;
kono
parents: 55
diff changeset
406 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407
111
kono
parents: 55
diff changeset
408 (define_expand "atomic_<fetchop_name><mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
409 [(match_operand:AINT 0 "memory_operand") ;; memory
111
kono
parents: 55
diff changeset
410 (FETCHOP:AINT (match_dup 0)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
411 (match_operand:AINT 1 "<fetchop_pred>")) ;; operand
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
412 (match_operand:SI 2 "const_int_operand")] ;; model
111
kono
parents: 55
diff changeset
413 ""
kono
parents: 55
diff changeset
414 {
kono
parents: 55
diff changeset
415 rs6000_expand_atomic_op (<CODE>, operands[0], operands[1],
kono
parents: 55
diff changeset
416 NULL_RTX, NULL_RTX, operands[2]);
kono
parents: 55
diff changeset
417 DONE;
kono
parents: 55
diff changeset
418 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419
111
kono
parents: 55
diff changeset
420 (define_expand "atomic_nand<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
421 [(match_operand:AINT 0 "memory_operand") ;; memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
422 (match_operand:AINT 1 "int_reg_operand") ;; operand
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
423 (match_operand:SI 2 "const_int_operand")] ;; model
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
424 ""
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
425 {
111
kono
parents: 55
diff changeset
426 rs6000_expand_atomic_op (NOT, operands[0], operands[1],
kono
parents: 55
diff changeset
427 NULL_RTX, NULL_RTX, operands[2]);
kono
parents: 55
diff changeset
428 DONE;
kono
parents: 55
diff changeset
429 })
kono
parents: 55
diff changeset
430
kono
parents: 55
diff changeset
431 (define_expand "atomic_fetch_<fetchop_name><mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
432 [(match_operand:AINT 0 "int_reg_operand") ;; output
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
433 (match_operand:AINT 1 "memory_operand") ;; memory
111
kono
parents: 55
diff changeset
434 (FETCHOP:AINT (match_dup 1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
435 (match_operand:AINT 2 "<fetchop_pred>")) ;; operand
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
436 (match_operand:SI 3 "const_int_operand")] ;; model
111
kono
parents: 55
diff changeset
437 ""
kono
parents: 55
diff changeset
438 {
kono
parents: 55
diff changeset
439 rs6000_expand_atomic_op (<CODE>, operands[1], operands[2],
kono
parents: 55
diff changeset
440 operands[0], NULL_RTX, operands[3]);
kono
parents: 55
diff changeset
441 DONE;
kono
parents: 55
diff changeset
442 })
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443
111
kono
parents: 55
diff changeset
444 (define_expand "atomic_fetch_nand<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
445 [(match_operand:AINT 0 "int_reg_operand") ;; output
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
446 (match_operand:AINT 1 "memory_operand") ;; memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
447 (match_operand:AINT 2 "int_reg_operand") ;; operand
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
448 (match_operand:SI 3 "const_int_operand")] ;; model
111
kono
parents: 55
diff changeset
449 ""
kono
parents: 55
diff changeset
450 {
kono
parents: 55
diff changeset
451 rs6000_expand_atomic_op (NOT, operands[1], operands[2],
kono
parents: 55
diff changeset
452 operands[0], NULL_RTX, operands[3]);
kono
parents: 55
diff changeset
453 DONE;
kono
parents: 55
diff changeset
454 })
kono
parents: 55
diff changeset
455
kono
parents: 55
diff changeset
456 (define_expand "atomic_<fetchop_name>_fetch<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
457 [(match_operand:AINT 0 "int_reg_operand") ;; output
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
458 (match_operand:AINT 1 "memory_operand") ;; memory
111
kono
parents: 55
diff changeset
459 (FETCHOP:AINT (match_dup 1)
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
460 (match_operand:AINT 2 "<fetchop_pred>")) ;; operand
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
461 (match_operand:SI 3 "const_int_operand")] ;; model
111
kono
parents: 55
diff changeset
462 ""
kono
parents: 55
diff changeset
463 {
kono
parents: 55
diff changeset
464 rs6000_expand_atomic_op (<CODE>, operands[1], operands[2],
kono
parents: 55
diff changeset
465 NULL_RTX, operands[0], operands[3]);
kono
parents: 55
diff changeset
466 DONE;
kono
parents: 55
diff changeset
467 })
kono
parents: 55
diff changeset
468
kono
parents: 55
diff changeset
469 (define_expand "atomic_nand_fetch<mode>"
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
470 [(match_operand:AINT 0 "int_reg_operand") ;; output
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
471 (match_operand:AINT 1 "memory_operand") ;; memory
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
472 (match_operand:AINT 2 "int_reg_operand") ;; operand
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
473 (match_operand:SI 3 "const_int_operand")] ;; model
111
kono
parents: 55
diff changeset
474 ""
kono
parents: 55
diff changeset
475 {
kono
parents: 55
diff changeset
476 rs6000_expand_atomic_op (NOT, operands[1], operands[2],
kono
parents: 55
diff changeset
477 NULL_RTX, operands[0], operands[3]);
kono
parents: 55
diff changeset
478 DONE;
kono
parents: 55
diff changeset
479 })