1;; Hardware Transactional Memory (HTM) patterns.
2;; Copyright (C) 2013-2018 Free Software Foundation, Inc.
3;; Contributed by Peter Bergner <bergner@vnet.ibm.com>.
4
5;; This file is part of GCC.
6
7;; GCC is free software; you can redistribute it and/or modify it
8;; under the terms of the GNU General Public License as published
9;; by the Free Software Foundation; either version 3, or (at your
10;; option) any later version.
11
12;; GCC is distributed in the hope that it will be useful, but WITHOUT
13;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14;; or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
15;; License for more details.
16
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/>.
20
21(define_constants
22  [(TFHAR_SPR		128)
23   (TFIAR_SPR		129)
24   (TEXASR_SPR		130)
25   (TEXASRU_SPR		131)
26   (MAX_HTM_OPERANDS	4)
27  ])
28
29;;
30;; UNSPEC usage
31;;
32
33(define_c_enum "unspec"
34  [UNSPEC_HTM_FENCE
35  ])
36
37;;
38;; UNSPEC_VOLATILE usage
39;;
40
41(define_c_enum "unspecv"
42  [UNSPECV_HTM_TABORT
43   UNSPECV_HTM_TABORTXC
44   UNSPECV_HTM_TABORTXCI
45   UNSPECV_HTM_TBEGIN
46   UNSPECV_HTM_TCHECK
47   UNSPECV_HTM_TEND
48   UNSPECV_HTM_TRECHKPT
49   UNSPECV_HTM_TRECLAIM
50   UNSPECV_HTM_TSR
51   UNSPECV_HTM_TTEST
52   UNSPECV_HTM_MFSPR
53   UNSPECV_HTM_MTSPR
54  ])
55
56(define_expand "tabort"
57  [(parallel
58     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
59	   (unspec_volatile:CC [(match_operand:SI 0 "base_reg_operand" "b")]
60			       UNSPECV_HTM_TABORT))
61      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
62  "TARGET_HTM"
63{
64  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
65  MEM_VOLATILE_P (operands[2]) = 1;
66})
67
68(define_insn "*tabort"
69  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
70	(unspec_volatile:CC [(match_operand:SI 0 "base_reg_operand" "b")]
71			    UNSPECV_HTM_TABORT))
72   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
73  "TARGET_HTM"
74  "tabort. %0"
75  [(set_attr "type" "htmsimple")
76   (set_attr "length" "4")])
77
78(define_expand "tabort<wd>c"
79  [(parallel
80     [(set (match_operand:CC 3 "cc_reg_operand" "=x")
81	   (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
82				(match_operand:GPR 1 "gpc_reg_operand" "r")
83				(match_operand:GPR 2 "gpc_reg_operand" "r")]
84			       UNSPECV_HTM_TABORTXC))
85      (set (match_dup 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))])]
86  "TARGET_HTM"
87{
88  operands[4] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
89  MEM_VOLATILE_P (operands[4]) = 1;
90})
91
92(define_insn "*tabort<wd>c"
93  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
94	(unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
95			     (match_operand:GPR 1 "gpc_reg_operand" "r")
96			     (match_operand:GPR 2 "gpc_reg_operand" "r")]
97			    UNSPECV_HTM_TABORTXC))
98   (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))]
99  "TARGET_HTM"
100  "tabort<wd>c. %0,%1,%2"
101  [(set_attr "type" "htmsimple")
102   (set_attr "length" "4")])
103
104(define_expand "tabort<wd>ci"
105  [(parallel
106     [(set (match_operand:CC 3 "cc_reg_operand" "=x")
107	   (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
108				(match_operand:GPR 1 "gpc_reg_operand" "r")
109				(match_operand 2 "s5bit_cint_operand" "n")]
110			       UNSPECV_HTM_TABORTXCI))
111      (set (match_dup 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))])]
112  "TARGET_HTM"
113{
114  operands[4] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
115  MEM_VOLATILE_P (operands[4]) = 1;
116})
117
118(define_insn "*tabort<wd>ci"
119  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
120	(unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
121			     (match_operand:GPR 1 "gpc_reg_operand" "r")
122			     (match_operand 2 "s5bit_cint_operand" "n")]
123			    UNSPECV_HTM_TABORTXCI))
124   (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))]
125  "TARGET_HTM"
126  "tabort<wd>ci. %0,%1,%2"
127  [(set_attr "type" "htmsimple")
128   (set_attr "length" "4")])
129
130(define_expand "tbegin"
131  [(parallel
132     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
133	   (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
134			       UNSPECV_HTM_TBEGIN))
135      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
136  "TARGET_HTM"
137{
138  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
139  MEM_VOLATILE_P (operands[2]) = 1;
140})
141
142(define_insn "*tbegin"
143  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
144	(unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
145			    UNSPECV_HTM_TBEGIN))
146   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
147  "TARGET_HTM"
148  "tbegin. %0"
149  [(set_attr "type" "htm")
150   (set_attr "length" "4")])
151
152(define_expand "tcheck"
153  [(parallel
154     [(set (match_operand:CC 0 "cc_reg_operand" "=y")
155	   (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK))
156      (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])]
157  "TARGET_HTM"
158{
159  operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
160  MEM_VOLATILE_P (operands[1]) = 1;
161})
162
163(define_insn "*tcheck"
164  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
165	(unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK))
166   (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
167  "TARGET_HTM"
168  "tcheck %0"
169  [(set_attr "type" "htm")
170   (set_attr "length" "4")])
171
172(define_expand "tend"
173  [(parallel
174     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
175	   (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
176			       UNSPECV_HTM_TEND))
177      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
178  "TARGET_HTM"
179{
180  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
181  MEM_VOLATILE_P (operands[2]) = 1;
182})
183
184(define_insn "*tend"
185  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
186	(unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
187			    UNSPECV_HTM_TEND))
188   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
189  "TARGET_HTM"
190  "tend. %0"
191  [(set_attr "type" "htm")
192   (set_attr "length" "4")])
193
194(define_expand "trechkpt"
195  [(parallel
196     [(set (match_operand:CC 0 "cc_reg_operand" "=x")
197	   (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT))
198      (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])]
199  "TARGET_HTM"
200{
201  operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
202  MEM_VOLATILE_P (operands[1]) = 1;
203})
204
205(define_insn "*trechkpt"
206  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
207	(unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT))
208   (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
209  "TARGET_HTM"
210  "trechkpt."
211  [(set_attr "type" "htmsimple")
212   (set_attr "length" "4")])
213
214(define_expand "treclaim"
215  [(parallel
216     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
217	   (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")]
218			       UNSPECV_HTM_TRECLAIM))
219      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
220  "TARGET_HTM"
221{
222  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
223  MEM_VOLATILE_P (operands[2]) = 1;
224})
225
226(define_insn "*treclaim"
227  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
228	(unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")]
229			    UNSPECV_HTM_TRECLAIM))
230   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
231  "TARGET_HTM"
232  "treclaim. %0"
233  [(set_attr "type" "htmsimple")
234   (set_attr "length" "4")])
235
236(define_expand "tsr"
237  [(parallel
238     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
239	   (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
240			       UNSPECV_HTM_TSR))
241      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
242  "TARGET_HTM"
243{
244  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
245  MEM_VOLATILE_P (operands[2]) = 1;
246})
247
248(define_insn "*tsr"
249  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
250	(unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
251			    UNSPECV_HTM_TSR))
252   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
253  "TARGET_HTM"
254  "tsr. %0"
255  [(set_attr "type" "htmsimple")
256   (set_attr "length" "4")])
257
258(define_expand "ttest"
259  [(parallel
260     [(set (match_operand:CC 0 "cc_reg_operand" "=x")
261	   (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TTEST))
262      (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])]
263  "TARGET_HTM"
264{
265  operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
266  MEM_VOLATILE_P (operands[1]) = 1;
267})
268
269(define_insn "*ttest"
270  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
271	(unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TTEST))
272   (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
273  "TARGET_HTM"
274  "tabortwci. 0,1,0"
275  [(set_attr "type" "htmsimple")
276   (set_attr "length" "4")])
277
278(define_insn "htm_mfspr_<mode>"
279  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
280        (unspec_volatile:GPR [(match_operand 1 "u10bit_cint_operand" "n")
281			      (match_operand:GPR 2 "htm_spr_reg_operand" "")]
282			     UNSPECV_HTM_MFSPR))]
283  "TARGET_HTM"
284  "mfspr %0,%1";
285  [(set_attr "type" "htm")
286   (set_attr "length" "4")])
287
288(define_insn "htm_mtspr_<mode>"
289  [(set (match_operand:GPR 2 "htm_spr_reg_operand" "")
290        (unspec_volatile:GPR [(match_operand:GPR 0 "gpc_reg_operand" "r")
291			      (match_operand 1 "u10bit_cint_operand" "n")]
292			     UNSPECV_HTM_MTSPR))]
293  "TARGET_HTM"
294  "mtspr %1,%0";
295  [(set_attr "type" "htm")
296   (set_attr "length" "4")])
297