1;; Hardware Transactional Memory (HTM) patterns.
2;; Copyright (C) 2013-2020 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
77(define_expand "tabort<wd>c"
78  [(parallel
79     [(set (match_operand:CC 3 "cc_reg_operand" "=x")
80	   (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
81				(match_operand:GPR 1 "gpc_reg_operand" "r")
82				(match_operand:GPR 2 "gpc_reg_operand" "r")]
83			       UNSPECV_HTM_TABORTXC))
84      (set (match_dup 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))])]
85  "TARGET_HTM"
86{
87  operands[4] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
88  MEM_VOLATILE_P (operands[4]) = 1;
89})
90
91(define_insn "*tabort<wd>c"
92  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
93	(unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
94			     (match_operand:GPR 1 "gpc_reg_operand" "r")
95			     (match_operand:GPR 2 "gpc_reg_operand" "r")]
96			    UNSPECV_HTM_TABORTXC))
97   (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))]
98  "TARGET_HTM"
99  "tabort<wd>c. %0,%1,%2"
100  [(set_attr "type" "htmsimple")])
101
102(define_expand "tabort<wd>ci"
103  [(parallel
104     [(set (match_operand:CC 3 "cc_reg_operand" "=x")
105	   (unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
106				(match_operand:GPR 1 "gpc_reg_operand" "r")
107				(match_operand 2 "s5bit_cint_operand" "n")]
108			       UNSPECV_HTM_TABORTXCI))
109      (set (match_dup 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))])]
110  "TARGET_HTM"
111{
112  operands[4] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
113  MEM_VOLATILE_P (operands[4]) = 1;
114})
115
116(define_insn "*tabort<wd>ci"
117  [(set (match_operand:CC 3 "cc_reg_operand" "=x")
118	(unspec_volatile:CC [(match_operand 0 "u5bit_cint_operand" "n")
119			     (match_operand:GPR 1 "gpc_reg_operand" "r")
120			     (match_operand 2 "s5bit_cint_operand" "n")]
121			    UNSPECV_HTM_TABORTXCI))
122   (set (match_operand:BLK 4) (unspec:BLK [(match_dup 4)] UNSPEC_HTM_FENCE))]
123  "TARGET_HTM"
124  "tabort<wd>ci. %0,%1,%2"
125  [(set_attr "type" "htmsimple")])
126
127(define_expand "tbegin"
128  [(parallel
129     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
130	   (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
131			       UNSPECV_HTM_TBEGIN))
132      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
133  "TARGET_HTM"
134{
135  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
136  MEM_VOLATILE_P (operands[2]) = 1;
137})
138
139(define_insn "*tbegin"
140  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
141	(unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
142			    UNSPECV_HTM_TBEGIN))
143   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
144  "TARGET_HTM"
145  "tbegin. %0"
146  [(set_attr "type" "htm")])
147
148(define_expand "tcheck"
149  [(parallel
150     [(set (match_operand:CC 0 "cc_reg_operand" "=y")
151	   (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK))
152      (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])]
153  "TARGET_HTM"
154{
155  operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
156  MEM_VOLATILE_P (operands[1]) = 1;
157})
158
159(define_insn "*tcheck"
160  [(set (match_operand:CC 0 "cc_reg_operand" "=y")
161	(unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TCHECK))
162   (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
163  "TARGET_HTM"
164  "tcheck %0"
165  [(set_attr "type" "htm")])
166
167(define_expand "tend"
168  [(parallel
169     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
170	   (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
171			       UNSPECV_HTM_TEND))
172      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
173  "TARGET_HTM"
174{
175  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
176  MEM_VOLATILE_P (operands[2]) = 1;
177})
178
179(define_insn "*tend"
180  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
181	(unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
182			    UNSPECV_HTM_TEND))
183   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
184  "TARGET_HTM"
185  "tend. %0"
186  [(set_attr "type" "htm")])
187
188(define_expand "trechkpt"
189  [(parallel
190     [(set (match_operand:CC 0 "cc_reg_operand" "=x")
191	   (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT))
192      (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])]
193  "TARGET_HTM"
194{
195  operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
196  MEM_VOLATILE_P (operands[1]) = 1;
197})
198
199(define_insn "*trechkpt"
200  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
201	(unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TRECHKPT))
202   (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
203  "TARGET_HTM"
204  "trechkpt."
205  [(set_attr "type" "htmsimple")])
206
207(define_expand "treclaim"
208  [(parallel
209     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
210	   (unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")]
211			       UNSPECV_HTM_TRECLAIM))
212      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
213  "TARGET_HTM"
214{
215  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
216  MEM_VOLATILE_P (operands[2]) = 1;
217})
218
219(define_insn "*treclaim"
220  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
221	(unspec_volatile:CC [(match_operand:SI 0 "gpc_reg_operand" "r")]
222			    UNSPECV_HTM_TRECLAIM))
223   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
224  "TARGET_HTM"
225  "treclaim. %0"
226  [(set_attr "type" "htmsimple")])
227
228(define_expand "tsr"
229  [(parallel
230     [(set (match_operand:CC 1 "cc_reg_operand" "=x")
231	   (unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
232			       UNSPECV_HTM_TSR))
233      (set (match_dup 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))])]
234  "TARGET_HTM"
235{
236  operands[2] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
237  MEM_VOLATILE_P (operands[2]) = 1;
238})
239
240(define_insn "*tsr"
241  [(set (match_operand:CC 1 "cc_reg_operand" "=x")
242	(unspec_volatile:CC [(match_operand 0 "const_0_to_1_operand" "n")]
243			    UNSPECV_HTM_TSR))
244   (set (match_operand:BLK 2) (unspec:BLK [(match_dup 2)] UNSPEC_HTM_FENCE))]
245  "TARGET_HTM"
246  "tsr. %0"
247  [(set_attr "type" "htmsimple")])
248
249(define_expand "ttest"
250  [(parallel
251     [(set (match_operand:CC 0 "cc_reg_operand" "=x")
252	   (unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TTEST))
253      (set (match_dup 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))])]
254  "TARGET_HTM"
255{
256  operands[1] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
257  MEM_VOLATILE_P (operands[1]) = 1;
258})
259
260(define_insn "*ttest"
261  [(set (match_operand:CC 0 "cc_reg_operand" "=x")
262	(unspec_volatile:CC [(const_int 0)] UNSPECV_HTM_TTEST))
263   (set (match_operand:BLK 1) (unspec:BLK [(match_dup 1)] UNSPEC_HTM_FENCE))]
264  "TARGET_HTM"
265  "tabortwci. 0,1,0"
266  [(set_attr "type" "htmsimple")])
267
268(define_insn "htm_mfspr_<mode>"
269  [(set (match_operand:GPR 0 "gpc_reg_operand" "=r")
270        (unspec_volatile:GPR [(match_operand 1 "u10bit_cint_operand" "n")]
271			     UNSPECV_HTM_MFSPR))]
272  "TARGET_HTM"
273  "mfspr %0,%1";
274  [(set_attr "type" "htm")])
275
276(define_insn "htm_mtspr_<mode>"
277  [(unspec_volatile [(match_operand:GPR 0 "gpc_reg_operand" "r")
278		     (match_operand 1 "u10bit_cint_operand" "n")]
279		    UNSPECV_HTM_MTSPR)]
280  "TARGET_HTM"
281  "mtspr %1,%0";
282  [(set_attr "type" "htm")])
283