1 //=- AArch64InstrAtomics.td - AArch64 Atomic codegen support -*- tablegen -*-=// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // AArch64 Atomic operand code-gen constructs. 11 // 12 //===----------------------------------------------------------------------===// 13 14 //===---------------------------------- 15 // Atomic fences 16 //===---------------------------------- 17 def : Pat<(atomic_fence (i64 4), (imm)), (DMB (i32 0x9))>; 18 def : Pat<(atomic_fence (imm), (imm)), (DMB (i32 0xb))>; 19 20 //===---------------------------------- 21 // Atomic loads 22 //===---------------------------------- 23 24 // When they're actually atomic, only one addressing mode (GPR64sp) is 25 // supported, but when they're relaxed and anything can be used, all the 26 // standard modes would be valid and may give efficiency gains. 27 28 // A atomic load operation that actually needs acquire semantics. 29 class acquiring_load<PatFrag base> 30 : PatFrag<(ops node:$ptr), (base node:$ptr), [{ 31 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering(); 32 return isAtLeastAcquire(Ordering); 33 }]>; 34 35 // An atomic load operation that does not need either acquire or release 36 // semantics. 37 class relaxed_load<PatFrag base> 38 : PatFrag<(ops node:$ptr), (base node:$ptr), [{ 39 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering(); 40 return !isAtLeastAcquire(Ordering); 41 }]>; 42 43 // 8-bit loads 44 def : Pat<(acquiring_load<atomic_load_8> GPR64sp:$ptr), (LDARB GPR64sp:$ptr)>; 45 def : Pat<(relaxed_load<atomic_load_8> (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, 46 ro_Wextend8:$offset)), 47 (LDRBBroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$offset)>; 48 def : Pat<(relaxed_load<atomic_load_8> (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, 49 ro_Xextend8:$offset)), 50 (LDRBBroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$offset)>; 51 def : Pat<(relaxed_load<atomic_load_8> (am_indexed8 GPR64sp:$Rn, 52 uimm12s1:$offset)), 53 (LDRBBui GPR64sp:$Rn, uimm12s1:$offset)>; 54 def : Pat<(relaxed_load<atomic_load_8> 55 (am_unscaled8 GPR64sp:$Rn, simm9:$offset)), 56 (LDURBBi GPR64sp:$Rn, simm9:$offset)>; 57 58 // 16-bit loads 59 def : Pat<(acquiring_load<atomic_load_16> GPR64sp:$ptr), (LDARH GPR64sp:$ptr)>; 60 def : Pat<(relaxed_load<atomic_load_16> (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 61 ro_Wextend16:$extend)), 62 (LDRHHroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend)>; 63 def : Pat<(relaxed_load<atomic_load_16> (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 64 ro_Xextend16:$extend)), 65 (LDRHHroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend)>; 66 def : Pat<(relaxed_load<atomic_load_16> (am_indexed16 GPR64sp:$Rn, 67 uimm12s2:$offset)), 68 (LDRHHui GPR64sp:$Rn, uimm12s2:$offset)>; 69 def : Pat<(relaxed_load<atomic_load_16> 70 (am_unscaled16 GPR64sp:$Rn, simm9:$offset)), 71 (LDURHHi GPR64sp:$Rn, simm9:$offset)>; 72 73 // 32-bit loads 74 def : Pat<(acquiring_load<atomic_load_32> GPR64sp:$ptr), (LDARW GPR64sp:$ptr)>; 75 def : Pat<(relaxed_load<atomic_load_32> (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 76 ro_Wextend32:$extend)), 77 (LDRWroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend)>; 78 def : Pat<(relaxed_load<atomic_load_32> (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 79 ro_Xextend32:$extend)), 80 (LDRWroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend)>; 81 def : Pat<(relaxed_load<atomic_load_32> (am_indexed32 GPR64sp:$Rn, 82 uimm12s4:$offset)), 83 (LDRWui GPR64sp:$Rn, uimm12s4:$offset)>; 84 def : Pat<(relaxed_load<atomic_load_32> 85 (am_unscaled32 GPR64sp:$Rn, simm9:$offset)), 86 (LDURWi GPR64sp:$Rn, simm9:$offset)>; 87 88 // 64-bit loads 89 def : Pat<(acquiring_load<atomic_load_64> GPR64sp:$ptr), (LDARX GPR64sp:$ptr)>; 90 def : Pat<(relaxed_load<atomic_load_64> (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 91 ro_Wextend64:$extend)), 92 (LDRXroW GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend)>; 93 def : Pat<(relaxed_load<atomic_load_64> (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 94 ro_Xextend64:$extend)), 95 (LDRXroX GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend)>; 96 def : Pat<(relaxed_load<atomic_load_64> (am_indexed64 GPR64sp:$Rn, 97 uimm12s8:$offset)), 98 (LDRXui GPR64sp:$Rn, uimm12s8:$offset)>; 99 def : Pat<(relaxed_load<atomic_load_64> 100 (am_unscaled64 GPR64sp:$Rn, simm9:$offset)), 101 (LDURXi GPR64sp:$Rn, simm9:$offset)>; 102 103 //===---------------------------------- 104 // Atomic stores 105 //===---------------------------------- 106 107 // When they're actually atomic, only one addressing mode (GPR64sp) is 108 // supported, but when they're relaxed and anything can be used, all the 109 // standard modes would be valid and may give efficiency gains. 110 111 // A store operation that actually needs release semantics. 112 class releasing_store<PatFrag base> 113 : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{ 114 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering(); 115 assert(Ordering != AcquireRelease && "unexpected store ordering"); 116 return isAtLeastRelease(Ordering); 117 }]>; 118 119 // An atomic store operation that doesn't actually need to be atomic on AArch64. 120 class relaxed_store<PatFrag base> 121 : PatFrag<(ops node:$ptr, node:$val), (base node:$ptr, node:$val), [{ 122 AtomicOrdering Ordering = cast<AtomicSDNode>(N)->getOrdering(); 123 return !isAtLeastRelease(Ordering); 124 }]>; 125 126 // 8-bit stores 127 def : Pat<(releasing_store<atomic_store_8> GPR64sp:$ptr, GPR32:$val), 128 (STLRB GPR32:$val, GPR64sp:$ptr)>; 129 def : Pat<(relaxed_store<atomic_store_8> 130 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend), 131 GPR32:$val), 132 (STRBBroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend)>; 133 def : Pat<(relaxed_store<atomic_store_8> 134 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend), 135 GPR32:$val), 136 (STRBBroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend)>; 137 def : Pat<(relaxed_store<atomic_store_8> 138 (am_indexed8 GPR64sp:$Rn, uimm12s1:$offset), GPR32:$val), 139 (STRBBui GPR32:$val, GPR64sp:$Rn, uimm12s1:$offset)>; 140 def : Pat<(relaxed_store<atomic_store_8> 141 (am_unscaled8 GPR64sp:$Rn, simm9:$offset), GPR32:$val), 142 (STURBBi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>; 143 144 // 16-bit stores 145 def : Pat<(releasing_store<atomic_store_16> GPR64sp:$ptr, GPR32:$val), 146 (STLRH GPR32:$val, GPR64sp:$ptr)>; 147 def : Pat<(relaxed_store<atomic_store_16> (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm, 148 ro_Wextend16:$extend), 149 GPR32:$val), 150 (STRHHroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend)>; 151 def : Pat<(relaxed_store<atomic_store_16> (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm, 152 ro_Xextend16:$extend), 153 GPR32:$val), 154 (STRHHroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend)>; 155 def : Pat<(relaxed_store<atomic_store_16> 156 (am_indexed16 GPR64sp:$Rn, uimm12s2:$offset), GPR32:$val), 157 (STRHHui GPR32:$val, GPR64sp:$Rn, uimm12s2:$offset)>; 158 def : Pat<(relaxed_store<atomic_store_16> 159 (am_unscaled16 GPR64sp:$Rn, simm9:$offset), GPR32:$val), 160 (STURHHi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>; 161 162 // 32-bit stores 163 def : Pat<(releasing_store<atomic_store_32> GPR64sp:$ptr, GPR32:$val), 164 (STLRW GPR32:$val, GPR64sp:$ptr)>; 165 def : Pat<(relaxed_store<atomic_store_32> (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm, 166 ro_Wextend32:$extend), 167 GPR32:$val), 168 (STRWroW GPR32:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend)>; 169 def : Pat<(relaxed_store<atomic_store_32> (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm, 170 ro_Xextend32:$extend), 171 GPR32:$val), 172 (STRWroX GPR32:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend)>; 173 def : Pat<(relaxed_store<atomic_store_32> 174 (am_indexed32 GPR64sp:$Rn, uimm12s4:$offset), GPR32:$val), 175 (STRWui GPR32:$val, GPR64sp:$Rn, uimm12s4:$offset)>; 176 def : Pat<(relaxed_store<atomic_store_32> 177 (am_unscaled32 GPR64sp:$Rn, simm9:$offset), GPR32:$val), 178 (STURWi GPR32:$val, GPR64sp:$Rn, simm9:$offset)>; 179 180 // 64-bit stores 181 def : Pat<(releasing_store<atomic_store_64> GPR64sp:$ptr, GPR64:$val), 182 (STLRX GPR64:$val, GPR64sp:$ptr)>; 183 def : Pat<(relaxed_store<atomic_store_64> (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm, 184 ro_Wextend16:$extend), 185 GPR64:$val), 186 (STRXroW GPR64:$val, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend)>; 187 def : Pat<(relaxed_store<atomic_store_64> (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm, 188 ro_Xextend16:$extend), 189 GPR64:$val), 190 (STRXroX GPR64:$val, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend)>; 191 def : Pat<(relaxed_store<atomic_store_64> 192 (am_indexed64 GPR64sp:$Rn, uimm12s8:$offset), GPR64:$val), 193 (STRXui GPR64:$val, GPR64sp:$Rn, uimm12s8:$offset)>; 194 def : Pat<(relaxed_store<atomic_store_64> 195 (am_unscaled64 GPR64sp:$Rn, simm9:$offset), GPR64:$val), 196 (STURXi GPR64:$val, GPR64sp:$Rn, simm9:$offset)>; 197 198 //===---------------------------------- 199 // Low-level exclusive operations 200 //===---------------------------------- 201 202 // Load-exclusives. 203 204 def ldxr_1 : PatFrag<(ops node:$ptr), (int_aarch64_ldxr node:$ptr), [{ 205 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 206 }]>; 207 208 def ldxr_2 : PatFrag<(ops node:$ptr), (int_aarch64_ldxr node:$ptr), [{ 209 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 210 }]>; 211 212 def ldxr_4 : PatFrag<(ops node:$ptr), (int_aarch64_ldxr node:$ptr), [{ 213 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 214 }]>; 215 216 def ldxr_8 : PatFrag<(ops node:$ptr), (int_aarch64_ldxr node:$ptr), [{ 217 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64; 218 }]>; 219 220 def : Pat<(ldxr_1 GPR64sp:$addr), 221 (SUBREG_TO_REG (i64 0), (LDXRB GPR64sp:$addr), sub_32)>; 222 def : Pat<(ldxr_2 GPR64sp:$addr), 223 (SUBREG_TO_REG (i64 0), (LDXRH GPR64sp:$addr), sub_32)>; 224 def : Pat<(ldxr_4 GPR64sp:$addr), 225 (SUBREG_TO_REG (i64 0), (LDXRW GPR64sp:$addr), sub_32)>; 226 def : Pat<(ldxr_8 GPR64sp:$addr), (LDXRX GPR64sp:$addr)>; 227 228 def : Pat<(and (ldxr_1 GPR64sp:$addr), 0xff), 229 (SUBREG_TO_REG (i64 0), (LDXRB GPR64sp:$addr), sub_32)>; 230 def : Pat<(and (ldxr_2 GPR64sp:$addr), 0xffff), 231 (SUBREG_TO_REG (i64 0), (LDXRH GPR64sp:$addr), sub_32)>; 232 def : Pat<(and (ldxr_4 GPR64sp:$addr), 0xffffffff), 233 (SUBREG_TO_REG (i64 0), (LDXRW GPR64sp:$addr), sub_32)>; 234 235 // Load-exclusives. 236 237 def ldaxr_1 : PatFrag<(ops node:$ptr), (int_aarch64_ldaxr node:$ptr), [{ 238 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 239 }]>; 240 241 def ldaxr_2 : PatFrag<(ops node:$ptr), (int_aarch64_ldaxr node:$ptr), [{ 242 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 243 }]>; 244 245 def ldaxr_4 : PatFrag<(ops node:$ptr), (int_aarch64_ldaxr node:$ptr), [{ 246 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 247 }]>; 248 249 def ldaxr_8 : PatFrag<(ops node:$ptr), (int_aarch64_ldaxr node:$ptr), [{ 250 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64; 251 }]>; 252 253 def : Pat<(ldaxr_1 GPR64sp:$addr), 254 (SUBREG_TO_REG (i64 0), (LDAXRB GPR64sp:$addr), sub_32)>; 255 def : Pat<(ldaxr_2 GPR64sp:$addr), 256 (SUBREG_TO_REG (i64 0), (LDAXRH GPR64sp:$addr), sub_32)>; 257 def : Pat<(ldaxr_4 GPR64sp:$addr), 258 (SUBREG_TO_REG (i64 0), (LDAXRW GPR64sp:$addr), sub_32)>; 259 def : Pat<(ldaxr_8 GPR64sp:$addr), (LDAXRX GPR64sp:$addr)>; 260 261 def : Pat<(and (ldaxr_1 GPR64sp:$addr), 0xff), 262 (SUBREG_TO_REG (i64 0), (LDAXRB GPR64sp:$addr), sub_32)>; 263 def : Pat<(and (ldaxr_2 GPR64sp:$addr), 0xffff), 264 (SUBREG_TO_REG (i64 0), (LDAXRH GPR64sp:$addr), sub_32)>; 265 def : Pat<(and (ldaxr_4 GPR64sp:$addr), 0xffffffff), 266 (SUBREG_TO_REG (i64 0), (LDAXRW GPR64sp:$addr), sub_32)>; 267 268 // Store-exclusives. 269 270 def stxr_1 : PatFrag<(ops node:$val, node:$ptr), 271 (int_aarch64_stxr node:$val, node:$ptr), [{ 272 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 273 }]>; 274 275 def stxr_2 : PatFrag<(ops node:$val, node:$ptr), 276 (int_aarch64_stxr node:$val, node:$ptr), [{ 277 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 278 }]>; 279 280 def stxr_4 : PatFrag<(ops node:$val, node:$ptr), 281 (int_aarch64_stxr node:$val, node:$ptr), [{ 282 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 283 }]>; 284 285 def stxr_8 : PatFrag<(ops node:$val, node:$ptr), 286 (int_aarch64_stxr node:$val, node:$ptr), [{ 287 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64; 288 }]>; 289 290 291 def : Pat<(stxr_1 GPR64:$val, GPR64sp:$addr), 292 (STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 293 def : Pat<(stxr_2 GPR64:$val, GPR64sp:$addr), 294 (STXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 295 def : Pat<(stxr_4 GPR64:$val, GPR64sp:$addr), 296 (STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 297 def : Pat<(stxr_8 GPR64:$val, GPR64sp:$addr), 298 (STXRX GPR64:$val, GPR64sp:$addr)>; 299 300 def : Pat<(stxr_1 (zext (and GPR32:$val, 0xff)), GPR64sp:$addr), 301 (STXRB GPR32:$val, GPR64sp:$addr)>; 302 def : Pat<(stxr_2 (zext (and GPR32:$val, 0xffff)), GPR64sp:$addr), 303 (STXRH GPR32:$val, GPR64sp:$addr)>; 304 def : Pat<(stxr_4 (zext GPR32:$val), GPR64sp:$addr), 305 (STXRW GPR32:$val, GPR64sp:$addr)>; 306 307 def : Pat<(stxr_1 (and GPR64:$val, 0xff), GPR64sp:$addr), 308 (STXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 309 def : Pat<(stxr_2 (and GPR64:$val, 0xffff), GPR64sp:$addr), 310 (STXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 311 def : Pat<(stxr_4 (and GPR64:$val, 0xffffffff), GPR64sp:$addr), 312 (STXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 313 314 // Store-release-exclusives. 315 316 def stlxr_1 : PatFrag<(ops node:$val, node:$ptr), 317 (int_aarch64_stlxr node:$val, node:$ptr), [{ 318 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i8; 319 }]>; 320 321 def stlxr_2 : PatFrag<(ops node:$val, node:$ptr), 322 (int_aarch64_stlxr node:$val, node:$ptr), [{ 323 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i16; 324 }]>; 325 326 def stlxr_4 : PatFrag<(ops node:$val, node:$ptr), 327 (int_aarch64_stlxr node:$val, node:$ptr), [{ 328 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i32; 329 }]>; 330 331 def stlxr_8 : PatFrag<(ops node:$val, node:$ptr), 332 (int_aarch64_stlxr node:$val, node:$ptr), [{ 333 return cast<MemIntrinsicSDNode>(N)->getMemoryVT() == MVT::i64; 334 }]>; 335 336 337 def : Pat<(stlxr_1 GPR64:$val, GPR64sp:$addr), 338 (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 339 def : Pat<(stlxr_2 GPR64:$val, GPR64sp:$addr), 340 (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 341 def : Pat<(stlxr_4 GPR64:$val, GPR64sp:$addr), 342 (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 343 def : Pat<(stlxr_8 GPR64:$val, GPR64sp:$addr), 344 (STLXRX GPR64:$val, GPR64sp:$addr)>; 345 346 def : Pat<(stlxr_1 (zext (and GPR32:$val, 0xff)), GPR64sp:$addr), 347 (STLXRB GPR32:$val, GPR64sp:$addr)>; 348 def : Pat<(stlxr_2 (zext (and GPR32:$val, 0xffff)), GPR64sp:$addr), 349 (STLXRH GPR32:$val, GPR64sp:$addr)>; 350 def : Pat<(stlxr_4 (zext GPR32:$val), GPR64sp:$addr), 351 (STLXRW GPR32:$val, GPR64sp:$addr)>; 352 353 def : Pat<(stlxr_1 (and GPR64:$val, 0xff), GPR64sp:$addr), 354 (STLXRB (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 355 def : Pat<(stlxr_2 (and GPR64:$val, 0xffff), GPR64sp:$addr), 356 (STLXRH (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 357 def : Pat<(stlxr_4 (and GPR64:$val, 0xffffffff), GPR64sp:$addr), 358 (STLXRW (EXTRACT_SUBREG GPR64:$val, sub_32), GPR64sp:$addr)>; 359 360 361 // And clear exclusive. 362 363 def : Pat<(int_aarch64_clrex), (CLREX 0xf)>; 364