1//=----- AArch64InstrGISel.td - AArch64 GISel target pseudos -*- tablegen -*-=// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// AArch64 GlobalISel target pseudo instruction definitions. This is kept 10// separately from the other tablegen files for organizational purposes, but 11// share the same infrastructure. 12// 13//===----------------------------------------------------------------------===// 14 15 16class AArch64GenericInstruction : GenericInstruction { 17 let Namespace = "AArch64"; 18} 19 20// A pseudo to represent a relocatable add instruction as part of address 21// computation. 22def G_ADD_LOW : AArch64GenericInstruction { 23 let OutOperandList = (outs type0:$dst); 24 let InOperandList = (ins type1:$src, type2:$imm); 25 let hasSideEffects = 0; 26} 27 28// Pseudo for a rev16 instruction. Produced post-legalization from 29// G_SHUFFLE_VECTORs with appropriate masks. 30def G_REV16 : AArch64GenericInstruction { 31 let OutOperandList = (outs type0:$dst); 32 let InOperandList = (ins type0:$src); 33 let hasSideEffects = 0; 34} 35 36// Pseudo for a rev32 instruction. Produced post-legalization from 37// G_SHUFFLE_VECTORs with appropriate masks. 38def G_REV32 : AArch64GenericInstruction { 39 let OutOperandList = (outs type0:$dst); 40 let InOperandList = (ins type0:$src); 41 let hasSideEffects = 0; 42} 43 44// Pseudo for a rev64 instruction. Produced post-legalization from 45// G_SHUFFLE_VECTORs with appropriate masks. 46def G_REV64 : AArch64GenericInstruction { 47 let OutOperandList = (outs type0:$dst); 48 let InOperandList = (ins type0:$src); 49 let hasSideEffects = 0; 50} 51 52// Represents an uzp1 instruction. Produced post-legalization from 53// G_SHUFFLE_VECTORs with appropriate masks. 54def G_UZP1 : AArch64GenericInstruction { 55 let OutOperandList = (outs type0:$dst); 56 let InOperandList = (ins type0:$v1, type0:$v2); 57 let hasSideEffects = 0; 58} 59 60// Represents an uzp2 instruction. Produced post-legalization from 61// G_SHUFFLE_VECTORs with appropriate masks. 62def G_UZP2 : AArch64GenericInstruction { 63 let OutOperandList = (outs type0:$dst); 64 let InOperandList = (ins type0:$v1, type0:$v2); 65 let hasSideEffects = 0; 66} 67 68// Represents a zip1 instruction. Produced post-legalization from 69// G_SHUFFLE_VECTORs with appropriate masks. 70def G_ZIP1 : AArch64GenericInstruction { 71 let OutOperandList = (outs type0:$dst); 72 let InOperandList = (ins type0:$v1, type0:$v2); 73 let hasSideEffects = 0; 74} 75 76// Represents a zip2 instruction. Produced post-legalization from 77// G_SHUFFLE_VECTORs with appropriate masks. 78def G_ZIP2 : AArch64GenericInstruction { 79 let OutOperandList = (outs type0:$dst); 80 let InOperandList = (ins type0:$v1, type0:$v2); 81 let hasSideEffects = 0; 82} 83 84// Represents a dup instruction. Produced post-legalization from 85// G_SHUFFLE_VECTORs with appropriate masks. 86def G_DUP: AArch64GenericInstruction { 87 let OutOperandList = (outs type0:$dst); 88 let InOperandList = (ins type1:$lane); 89 let hasSideEffects = 0; 90} 91 92// Represents a lane duplicate operation. 93def G_DUPLANE8 : AArch64GenericInstruction { 94 let OutOperandList = (outs type0:$dst); 95 let InOperandList = (ins type0:$src, type1:$lane); 96 let hasSideEffects = 0; 97} 98def G_DUPLANE16 : AArch64GenericInstruction { 99 let OutOperandList = (outs type0:$dst); 100 let InOperandList = (ins type0:$src, type1:$lane); 101 let hasSideEffects = 0; 102} 103def G_DUPLANE32 : AArch64GenericInstruction { 104 let OutOperandList = (outs type0:$dst); 105 let InOperandList = (ins type0:$src, type1:$lane); 106 let hasSideEffects = 0; 107} 108def G_DUPLANE64 : AArch64GenericInstruction { 109 let OutOperandList = (outs type0:$dst); 110 let InOperandList = (ins type0:$src, type1:$lane); 111 let hasSideEffects = 0; 112} 113 114// Represents a trn1 instruction. Produced post-legalization from 115// G_SHUFFLE_VECTORs with appropriate masks. 116def G_TRN1 : AArch64GenericInstruction { 117 let OutOperandList = (outs type0:$dst); 118 let InOperandList = (ins type0:$v1, type0:$v2); 119 let hasSideEffects = 0; 120} 121 122// Represents a trn2 instruction. Produced post-legalization from 123// G_SHUFFLE_VECTORs with appropriate masks. 124def G_TRN2 : AArch64GenericInstruction { 125 let OutOperandList = (outs type0:$dst); 126 let InOperandList = (ins type0:$v1, type0:$v2); 127 let hasSideEffects = 0; 128} 129 130// Represents an ext instruction. Produced post-legalization from 131// G_SHUFFLE_VECTORs with appropriate masks. 132def G_EXT: AArch64GenericInstruction { 133 let OutOperandList = (outs type0:$dst); 134 let InOperandList = (ins type0:$v1, type0:$v2, untyped_imm_0:$imm); 135 let hasSideEffects = 0; 136} 137 138// Represents a vector G_ASHR with an immediate. 139def G_VASHR : AArch64GenericInstruction { 140 let OutOperandList = (outs type0:$dst); 141 let InOperandList = (ins type0:$src1, untyped_imm_0:$imm); 142 let hasSideEffects = 0; 143} 144 145// Represents a vector G_LSHR with an immediate. 146def G_VLSHR : AArch64GenericInstruction { 147 let OutOperandList = (outs type0:$dst); 148 let InOperandList = (ins type0:$src1, untyped_imm_0:$imm); 149 let hasSideEffects = 0; 150} 151 152// Represents an integer to FP conversion on the FPR bank. 153def G_SITOF : AArch64GenericInstruction { 154 let OutOperandList = (outs type0:$dst); 155 let InOperandList = (ins type0:$src); 156 let hasSideEffects = 0; 157} 158def G_UITOF : AArch64GenericInstruction { 159 let OutOperandList = (outs type0:$dst); 160 let InOperandList = (ins type0:$src); 161 let hasSideEffects = 0; 162} 163 164def G_FCMEQ : AArch64GenericInstruction { 165 let OutOperandList = (outs type0:$dst); 166 let InOperandList = (ins type0:$src1, type1:$src2); 167 let hasSideEffects = 0; 168} 169 170def G_FCMGE : AArch64GenericInstruction { 171 let OutOperandList = (outs type0:$dst); 172 let InOperandList = (ins type0:$src1, type1:$src2); 173 let hasSideEffects = 0; 174} 175 176def G_FCMGT : AArch64GenericInstruction { 177 let OutOperandList = (outs type0:$dst); 178 let InOperandList = (ins type0:$src1, type1:$src2); 179 let hasSideEffects = 0; 180} 181 182def G_FCMEQZ : AArch64GenericInstruction { 183 let OutOperandList = (outs type0:$dst); 184 let InOperandList = (ins type0:$src); 185 let hasSideEffects = 0; 186} 187 188def G_FCMGEZ : AArch64GenericInstruction { 189 let OutOperandList = (outs type0:$dst); 190 let InOperandList = (ins type0:$src); 191 let hasSideEffects = 0; 192} 193 194def G_FCMGTZ : AArch64GenericInstruction { 195 let OutOperandList = (outs type0:$dst); 196 let InOperandList = (ins type0:$src); 197 let hasSideEffects = 0; 198} 199 200def G_FCMLEZ : AArch64GenericInstruction { 201 let OutOperandList = (outs type0:$dst); 202 let InOperandList = (ins type0:$src); 203 let hasSideEffects = 0; 204} 205 206def G_FCMLTZ : AArch64GenericInstruction { 207 let OutOperandList = (outs type0:$dst); 208 let InOperandList = (ins type0:$src); 209 let hasSideEffects = 0; 210} 211 212def : GINodeEquiv<G_REV16, AArch64rev16>; 213def : GINodeEquiv<G_REV32, AArch64rev32>; 214def : GINodeEquiv<G_REV64, AArch64rev64>; 215def : GINodeEquiv<G_UZP1, AArch64uzp1>; 216def : GINodeEquiv<G_UZP2, AArch64uzp2>; 217def : GINodeEquiv<G_ZIP1, AArch64zip1>; 218def : GINodeEquiv<G_ZIP2, AArch64zip2>; 219def : GINodeEquiv<G_DUP, AArch64dup>; 220def : GINodeEquiv<G_DUPLANE8, AArch64duplane8>; 221def : GINodeEquiv<G_DUPLANE16, AArch64duplane16>; 222def : GINodeEquiv<G_DUPLANE32, AArch64duplane32>; 223def : GINodeEquiv<G_DUPLANE64, AArch64duplane64>; 224def : GINodeEquiv<G_TRN1, AArch64trn1>; 225def : GINodeEquiv<G_TRN2, AArch64trn2>; 226def : GINodeEquiv<G_EXT, AArch64ext>; 227def : GINodeEquiv<G_VASHR, AArch64vashr>; 228def : GINodeEquiv<G_VLSHR, AArch64vlshr>; 229def : GINodeEquiv<G_SITOF, AArch64sitof>; 230def : GINodeEquiv<G_UITOF, AArch64uitof>; 231 232def : GINodeEquiv<G_FCMEQ, AArch64fcmeq>; 233def : GINodeEquiv<G_FCMGE, AArch64fcmge>; 234def : GINodeEquiv<G_FCMGT, AArch64fcmgt>; 235 236def : GINodeEquiv<G_FCMEQZ, AArch64fcmeqz>; 237def : GINodeEquiv<G_FCMGEZ, AArch64fcmgez>; 238def : GINodeEquiv<G_FCMGTZ, AArch64fcmgtz>; 239def : GINodeEquiv<G_FCMLEZ, AArch64fcmlez>; 240def : GINodeEquiv<G_FCMLTZ, AArch64fcmltz>; 241 242def : GINodeEquiv<G_EXTRACT_VECTOR_ELT, vector_extract>; 243 244// These are patterns that we only use for GlobalISel via the importer. 245def : Pat<(f32 (fadd (vector_extract (v2f32 FPR64:$Rn), (i64 0)), 246 (vector_extract (v2f32 FPR64:$Rn), (i64 1)))), 247 (f32 (FADDPv2i32p (v2f32 FPR64:$Rn)))>; 248 249let Predicates = [HasNEON] in { 250 def : Pat<(v2f64 (sint_to_fp v2i32:$src)), 251 (SCVTFv2f64 (SSHLLv2i32_shift V64:$src, 0))>; 252 def : Pat<(v2f64 (uint_to_fp v2i32:$src)), 253 (UCVTFv2f64 (USHLLv2i32_shift V64:$src, 0))>; 254 def : Pat<(v2f32 (sint_to_fp v2i64:$src)), 255 (FCVTNv2i32 (SCVTFv2f64 V128:$src))>; 256 def : Pat<(v2f32 (uint_to_fp v2i64:$src)), 257 (FCVTNv2i32 (UCVTFv2f64 V128:$src))>; 258 259 def : Pat<(v2i64 (fp_to_sint v2f32:$src)), 260 (FCVTZSv2f64 (FCVTLv2i32 V64:$src))>; 261 def : Pat<(v2i64 (fp_to_uint v2f32:$src)), 262 (FCVTZUv2f64 (FCVTLv2i32 V64:$src))>; 263 def : Pat<(v2i32 (fp_to_sint v2f64:$src)), 264 (XTNv2i32 (FCVTZSv2f64 V128:$src))>; 265 def : Pat<(v2i32 (fp_to_uint v2f64:$src)), 266 (XTNv2i32 (FCVTZUv2f64 V128:$src))>; 267 268} 269 270let Predicates = [HasNoLSE] in { 271def : Pat<(atomic_cmp_swap_8 GPR64:$addr, GPR32:$desired, GPR32:$new), 272 (CMP_SWAP_8 GPR64:$addr, GPR32:$desired, GPR32:$new)>; 273 274def : Pat<(atomic_cmp_swap_16 GPR64:$addr, GPR32:$desired, GPR32:$new), 275 (CMP_SWAP_16 GPR64:$addr, GPR32:$desired, GPR32:$new)>; 276 277def : Pat<(atomic_cmp_swap_32 GPR64:$addr, GPR32:$desired, GPR32:$new), 278 (CMP_SWAP_32 GPR64:$addr, GPR32:$desired, GPR32:$new)>; 279 280def : Pat<(atomic_cmp_swap_64 GPR64:$addr, GPR64:$desired, GPR64:$new), 281 (CMP_SWAP_64 GPR64:$addr, GPR64:$desired, GPR64:$new)>; 282} 283 284def : Pat<(int_aarch64_stlxp GPR64:$lo, GPR64:$hi, GPR64:$addr), 285 (STLXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>; 286def : Pat<(int_aarch64_stxp GPR64:$lo, GPR64:$hi, GPR64:$addr), 287 (STXPX GPR64:$lo, GPR64:$hi, GPR64:$addr)>; 288