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