1 ;; Hardware Transactional Memory (HTM) patterns. 2 ;; Copyright (C) 2013-2022 Free Software Foundation, Inc. 3 ;; Contributed by Peter Bergner <bergner (a] 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