SystemZOperators.td revision aff1c6427ce22125adfa29de4145030aa3214a2e
1//===-- SystemZOperators.td - SystemZ-specific operators ------*- tblgen-*-===// 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//===----------------------------------------------------------------------===// 11// Type profiles 12//===----------------------------------------------------------------------===// 13def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i64>]>; 14def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i64>, 15 SDTCisVT<1, i64>]>; 16def SDT_ZCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 17def SDT_ZCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 18def SDT_ZICmp : SDTypeProfile<0, 3, 19 [SDTCisSameAs<0, 1>, 20 SDTCisVT<2, i32>]>; 21def SDT_ZBRCCMask : SDTypeProfile<0, 3, 22 [SDTCisVT<0, i8>, 23 SDTCisVT<1, i8>, 24 SDTCisVT<2, OtherVT>]>; 25def SDT_ZSelectCCMask : SDTypeProfile<1, 4, 26 [SDTCisSameAs<0, 1>, 27 SDTCisSameAs<1, 2>, 28 SDTCisVT<3, i8>, 29 SDTCisVT<4, i8>]>; 30def SDT_ZWrapPtr : SDTypeProfile<1, 1, 31 [SDTCisSameAs<0, 1>, 32 SDTCisPtrTy<0>]>; 33def SDT_ZAdjDynAlloc : SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>; 34def SDT_ZExtractAccess : SDTypeProfile<1, 1, 35 [SDTCisVT<0, i32>, 36 SDTCisVT<1, i8>]>; 37def SDT_ZGR128Binary32 : SDTypeProfile<1, 2, 38 [SDTCisVT<0, untyped>, 39 SDTCisVT<1, untyped>, 40 SDTCisVT<2, i32>]>; 41def SDT_ZGR128Binary64 : SDTypeProfile<1, 2, 42 [SDTCisVT<0, untyped>, 43 SDTCisVT<1, untyped>, 44 SDTCisVT<2, i64>]>; 45def SDT_ZAtomicLoadBinaryW : SDTypeProfile<1, 5, 46 [SDTCisVT<0, i32>, 47 SDTCisPtrTy<1>, 48 SDTCisVT<2, i32>, 49 SDTCisVT<3, i32>, 50 SDTCisVT<4, i32>, 51 SDTCisVT<5, i32>]>; 52def SDT_ZAtomicCmpSwapW : SDTypeProfile<1, 6, 53 [SDTCisVT<0, i32>, 54 SDTCisPtrTy<1>, 55 SDTCisVT<2, i32>, 56 SDTCisVT<3, i32>, 57 SDTCisVT<4, i32>, 58 SDTCisVT<5, i32>, 59 SDTCisVT<6, i32>]>; 60def SDT_ZMemMemLength : SDTypeProfile<0, 3, 61 [SDTCisPtrTy<0>, 62 SDTCisPtrTy<1>, 63 SDTCisVT<2, i64>]>; 64def SDT_ZMemMemLoop : SDTypeProfile<0, 4, 65 [SDTCisPtrTy<0>, 66 SDTCisPtrTy<1>, 67 SDTCisVT<2, i64>, 68 SDTCisVT<3, i64>]>; 69def SDT_ZString : SDTypeProfile<1, 3, 70 [SDTCisPtrTy<0>, 71 SDTCisPtrTy<1>, 72 SDTCisPtrTy<2>, 73 SDTCisVT<3, i32>]>; 74def SDT_ZI32Intrinsic : SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>; 75def SDT_ZPrefetch : SDTypeProfile<0, 2, 76 [SDTCisVT<0, i8>, 77 SDTCisPtrTy<1>]>; 78 79//===----------------------------------------------------------------------===// 80// Node definitions 81//===----------------------------------------------------------------------===// 82 83// These are target-independent nodes, but have target-specific formats. 84def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, 85 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; 86def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, 87 [SDNPHasChain, SDNPSideEffect, SDNPOptInGlue, 88 SDNPOutGlue]>; 89 90// Nodes for SystemZISD::*. See SystemZISelLowering.h for more details. 91def z_retflag : SDNode<"SystemZISD::RET_FLAG", SDTNone, 92 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 93def z_call : SDNode<"SystemZISD::CALL", SDT_ZCall, 94 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 95 SDNPVariadic]>; 96def z_sibcall : SDNode<"SystemZISD::SIBCALL", SDT_ZCall, 97 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 98 SDNPVariadic]>; 99def z_pcrel_wrapper : SDNode<"SystemZISD::PCREL_WRAPPER", SDT_ZWrapPtr, []>; 100def z_icmp : SDNode<"SystemZISD::ICMP", SDT_ZICmp, [SDNPOutGlue]>; 101def z_fcmp : SDNode<"SystemZISD::FCMP", SDT_ZCmp, [SDNPOutGlue]>; 102def z_tm : SDNode<"SystemZISD::TM", SDT_ZCmp, [SDNPOutGlue]>; 103def z_br_ccmask : SDNode<"SystemZISD::BR_CCMASK", SDT_ZBRCCMask, 104 [SDNPHasChain, SDNPInGlue]>; 105def z_select_ccmask : SDNode<"SystemZISD::SELECT_CCMASK", SDT_ZSelectCCMask, 106 [SDNPInGlue]>; 107def z_adjdynalloc : SDNode<"SystemZISD::ADJDYNALLOC", SDT_ZAdjDynAlloc>; 108def z_extract_access : SDNode<"SystemZISD::EXTRACT_ACCESS", 109 SDT_ZExtractAccess>; 110def z_umul_lohi64 : SDNode<"SystemZISD::UMUL_LOHI64", SDT_ZGR128Binary64>; 111def z_sdivrem32 : SDNode<"SystemZISD::SDIVREM32", SDT_ZGR128Binary32>; 112def z_sdivrem64 : SDNode<"SystemZISD::SDIVREM64", SDT_ZGR128Binary64>; 113def z_udivrem32 : SDNode<"SystemZISD::UDIVREM32", SDT_ZGR128Binary32>; 114def z_udivrem64 : SDNode<"SystemZISD::UDIVREM64", SDT_ZGR128Binary64>; 115 116class AtomicWOp<string name, SDTypeProfile profile = SDT_ZAtomicLoadBinaryW> 117 : SDNode<"SystemZISD::"##name, profile, 118 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 119 120def z_atomic_swapw : AtomicWOp<"ATOMIC_SWAPW">; 121def z_atomic_loadw_add : AtomicWOp<"ATOMIC_LOADW_ADD">; 122def z_atomic_loadw_sub : AtomicWOp<"ATOMIC_LOADW_SUB">; 123def z_atomic_loadw_and : AtomicWOp<"ATOMIC_LOADW_AND">; 124def z_atomic_loadw_or : AtomicWOp<"ATOMIC_LOADW_OR">; 125def z_atomic_loadw_xor : AtomicWOp<"ATOMIC_LOADW_XOR">; 126def z_atomic_loadw_nand : AtomicWOp<"ATOMIC_LOADW_NAND">; 127def z_atomic_loadw_min : AtomicWOp<"ATOMIC_LOADW_MIN">; 128def z_atomic_loadw_max : AtomicWOp<"ATOMIC_LOADW_MAX">; 129def z_atomic_loadw_umin : AtomicWOp<"ATOMIC_LOADW_UMIN">; 130def z_atomic_loadw_umax : AtomicWOp<"ATOMIC_LOADW_UMAX">; 131def z_atomic_cmp_swapw : AtomicWOp<"ATOMIC_CMP_SWAPW", SDT_ZAtomicCmpSwapW>; 132 133def z_mvc : SDNode<"SystemZISD::MVC", SDT_ZMemMemLength, 134 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 135def z_mvc_loop : SDNode<"SystemZISD::MVC_LOOP", SDT_ZMemMemLoop, 136 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 137def z_nc : SDNode<"SystemZISD::NC", SDT_ZMemMemLength, 138 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 139def z_nc_loop : SDNode<"SystemZISD::NC_LOOP", SDT_ZMemMemLoop, 140 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 141def z_oc : SDNode<"SystemZISD::OC", SDT_ZMemMemLength, 142 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 143def z_oc_loop : SDNode<"SystemZISD::OC_LOOP", SDT_ZMemMemLoop, 144 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 145def z_xc : SDNode<"SystemZISD::XC", SDT_ZMemMemLength, 146 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 147def z_xc_loop : SDNode<"SystemZISD::XC_LOOP", SDT_ZMemMemLoop, 148 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 149def z_clc : SDNode<"SystemZISD::CLC", SDT_ZMemMemLength, 150 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 151def z_clc_loop : SDNode<"SystemZISD::CLC_LOOP", SDT_ZMemMemLoop, 152 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 153def z_strcmp : SDNode<"SystemZISD::STRCMP", SDT_ZString, 154 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 155def z_stpcpy : SDNode<"SystemZISD::STPCPY", SDT_ZString, 156 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 157def z_search_string : SDNode<"SystemZISD::SEARCH_STRING", SDT_ZString, 158 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 159def z_ipm : SDNode<"SystemZISD::IPM", SDT_ZI32Intrinsic, 160 [SDNPInGlue]>; 161def z_prefetch : SDNode<"SystemZISD::PREFETCH", SDT_ZPrefetch, 162 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 163 SDNPMemOperand]>; 164 165//===----------------------------------------------------------------------===// 166// Pattern fragments 167//===----------------------------------------------------------------------===// 168 169// Signed and unsigned comparisons. 170def z_scmp : PatFrag<(ops node:$a, node:$b), (z_icmp node:$a, node:$b, imm), [{ 171 unsigned Type = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue(); 172 return Type != SystemZICMP::UnsignedOnly; 173}]>; 174def z_ucmp : PatFrag<(ops node:$a, node:$b), (z_icmp node:$a, node:$b, imm), [{ 175 unsigned Type = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue(); 176 return Type != SystemZICMP::SignedOnly; 177}]>; 178 179// Register sign-extend operations. Sub-32-bit values are represented as i32s. 180def sext8 : PatFrag<(ops node:$src), (sext_inreg node:$src, i8)>; 181def sext16 : PatFrag<(ops node:$src), (sext_inreg node:$src, i16)>; 182def sext32 : PatFrag<(ops node:$src), (sext (i32 node:$src))>; 183 184// Register zero-extend operations. Sub-32-bit values are represented as i32s. 185def zext8 : PatFrag<(ops node:$src), (and node:$src, 0xff)>; 186def zext16 : PatFrag<(ops node:$src), (and node:$src, 0xffff)>; 187def zext32 : PatFrag<(ops node:$src), (zext (i32 node:$src))>; 188 189// Typed floating-point loads. 190def loadf32 : PatFrag<(ops node:$src), (f32 (load node:$src))>; 191def loadf64 : PatFrag<(ops node:$src), (f64 (load node:$src))>; 192 193// Extending loads in which the extension type doesn't matter. 194def anyextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ 195 return cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD; 196}]>; 197def anyextloadi8 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 198 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 199}]>; 200def anyextloadi16 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 201 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 202}]>; 203def anyextloadi32 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 204 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32; 205}]>; 206 207// Aligned loads. 208class AlignedLoad<SDPatternOperator load> 209 : PatFrag<(ops node:$addr), (load node:$addr), [{ 210 LoadSDNode *Load = cast<LoadSDNode>(N); 211 return Load->getAlignment() >= Load->getMemoryVT().getStoreSize(); 212}]>; 213def aligned_load : AlignedLoad<load>; 214def aligned_sextloadi16 : AlignedLoad<sextloadi16>; 215def aligned_sextloadi32 : AlignedLoad<sextloadi32>; 216def aligned_zextloadi16 : AlignedLoad<zextloadi16>; 217def aligned_zextloadi32 : AlignedLoad<zextloadi32>; 218 219// Aligned stores. 220class AlignedStore<SDPatternOperator store> 221 : PatFrag<(ops node:$src, node:$addr), (store node:$src, node:$addr), [{ 222 StoreSDNode *Store = cast<StoreSDNode>(N); 223 return Store->getAlignment() >= Store->getMemoryVT().getStoreSize(); 224}]>; 225def aligned_store : AlignedStore<store>; 226def aligned_truncstorei16 : AlignedStore<truncstorei16>; 227def aligned_truncstorei32 : AlignedStore<truncstorei32>; 228 229// Non-volatile loads. Used for instructions that might access the storage 230// location multiple times. 231class NonvolatileLoad<SDPatternOperator load> 232 : PatFrag<(ops node:$addr), (load node:$addr), [{ 233 LoadSDNode *Load = cast<LoadSDNode>(N); 234 return !Load->isVolatile(); 235}]>; 236def nonvolatile_load : NonvolatileLoad<load>; 237def nonvolatile_anyextloadi8 : NonvolatileLoad<anyextloadi8>; 238def nonvolatile_anyextloadi16 : NonvolatileLoad<anyextloadi16>; 239def nonvolatile_anyextloadi32 : NonvolatileLoad<anyextloadi32>; 240 241// Non-volatile stores. 242class NonvolatileStore<SDPatternOperator store> 243 : PatFrag<(ops node:$src, node:$addr), (store node:$src, node:$addr), [{ 244 StoreSDNode *Store = cast<StoreSDNode>(N); 245 return !Store->isVolatile(); 246}]>; 247def nonvolatile_store : NonvolatileStore<store>; 248def nonvolatile_truncstorei8 : NonvolatileStore<truncstorei8>; 249def nonvolatile_truncstorei16 : NonvolatileStore<truncstorei16>; 250def nonvolatile_truncstorei32 : NonvolatileStore<truncstorei32>; 251 252// A store of a load that can be implemented using MVC. 253def mvc_store : PatFrag<(ops node:$value, node:$addr), 254 (unindexedstore node:$value, node:$addr), 255 [{ return storeLoadCanUseMVC(N); }]>; 256 257// Binary read-modify-write operations on memory in which the other 258// operand is also memory and for which block operations like NC can 259// be used. There are two patterns for each operator, depending on 260// which operand contains the "other" load. 261multiclass block_op<SDPatternOperator operator> { 262 def "1" : PatFrag<(ops node:$value, node:$addr), 263 (unindexedstore (operator node:$value, 264 (unindexedload node:$addr)), 265 node:$addr), 266 [{ return storeLoadCanUseBlockBinary(N, 0); }]>; 267 def "2" : PatFrag<(ops node:$value, node:$addr), 268 (unindexedstore (operator (unindexedload node:$addr), 269 node:$value), 270 node:$addr), 271 [{ return storeLoadCanUseBlockBinary(N, 1); }]>; 272} 273defm block_and : block_op<and>; 274defm block_or : block_op<or>; 275defm block_xor : block_op<xor>; 276 277// Insertions. 278def inserti8 : PatFrag<(ops node:$src1, node:$src2), 279 (or (and node:$src1, -256), node:$src2)>; 280def insertll : PatFrag<(ops node:$src1, node:$src2), 281 (or (and node:$src1, 0xffffffffffff0000), node:$src2)>; 282def insertlh : PatFrag<(ops node:$src1, node:$src2), 283 (or (and node:$src1, 0xffffffff0000ffff), node:$src2)>; 284def inserthl : PatFrag<(ops node:$src1, node:$src2), 285 (or (and node:$src1, 0xffff0000ffffffff), node:$src2)>; 286def inserthh : PatFrag<(ops node:$src1, node:$src2), 287 (or (and node:$src1, 0x0000ffffffffffff), node:$src2)>; 288def insertlf : PatFrag<(ops node:$src1, node:$src2), 289 (or (and node:$src1, 0xffffffff00000000), node:$src2)>; 290def inserthf : PatFrag<(ops node:$src1, node:$src2), 291 (or (and node:$src1, 0x00000000ffffffff), node:$src2)>; 292 293// ORs that can be treated as insertions. 294def or_as_inserti8 : PatFrag<(ops node:$src1, node:$src2), 295 (or node:$src1, node:$src2), [{ 296 unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits(); 297 return CurDAG->MaskedValueIsZero(N->getOperand(0), 298 APInt::getLowBitsSet(BitWidth, 8)); 299}]>; 300 301// ORs that can be treated as reversed insertions. 302def or_as_revinserti8 : PatFrag<(ops node:$src1, node:$src2), 303 (or node:$src1, node:$src2), [{ 304 unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits(); 305 return CurDAG->MaskedValueIsZero(N->getOperand(1), 306 APInt::getLowBitsSet(BitWidth, 8)); 307}]>; 308 309// Integer absolute, matching the canonical form generated by DAGCombiner. 310def z_iabs32 : PatFrag<(ops node:$src), 311 (xor (add node:$src, (sra node:$src, (i32 31))), 312 (sra node:$src, (i32 31)))>; 313def z_iabs64 : PatFrag<(ops node:$src), 314 (xor (add node:$src, (sra node:$src, (i32 63))), 315 (sra node:$src, (i32 63)))>; 316def z_inegabs32 : PatFrag<(ops node:$src), (ineg (z_iabs32 node:$src))>; 317def z_inegabs64 : PatFrag<(ops node:$src), (ineg (z_iabs64 node:$src))>; 318 319// Fused multiply-add and multiply-subtract, but with the order of the 320// operands matching SystemZ's MA and MS instructions. 321def z_fma : PatFrag<(ops node:$src1, node:$src2, node:$src3), 322 (fma node:$src2, node:$src3, node:$src1)>; 323def z_fms : PatFrag<(ops node:$src1, node:$src2, node:$src3), 324 (fma node:$src2, node:$src3, (fneg node:$src1))>; 325 326// Floating-point negative absolute. 327def fnabs : PatFrag<(ops node:$ptr), (fneg (fabs node:$ptr))>; 328 329// Create a unary operator that loads from memory and then performs 330// the given operation on it. 331class loadu<SDPatternOperator operator, SDPatternOperator load = load> 332 : PatFrag<(ops node:$addr), (operator (load node:$addr))>; 333 334// Create a store operator that performs the given unary operation 335// on the value before storing it. 336class storeu<SDPatternOperator operator, SDPatternOperator store = store> 337 : PatFrag<(ops node:$value, node:$addr), 338 (store (operator node:$value), node:$addr)>; 339