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_ZBRCCMask : SDTypeProfile<0, 3, 19 [SDTCisVT<0, i8>, 20 SDTCisVT<1, i8>, 21 SDTCisVT<2, OtherVT>]>; 22def SDT_ZSelectCCMask : SDTypeProfile<1, 4, 23 [SDTCisSameAs<0, 1>, 24 SDTCisSameAs<1, 2>, 25 SDTCisVT<3, i8>, 26 SDTCisVT<4, i8>]>; 27def SDT_ZWrapPtr : SDTypeProfile<1, 1, 28 [SDTCisSameAs<0, 1>, 29 SDTCisPtrTy<0>]>; 30def SDT_ZAdjDynAlloc : SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>; 31def SDT_ZExtractAccess : SDTypeProfile<1, 1, 32 [SDTCisVT<0, i32>, 33 SDTCisVT<1, i8>]>; 34def SDT_ZGR128Binary32 : SDTypeProfile<1, 2, 35 [SDTCisVT<0, untyped>, 36 SDTCisVT<1, untyped>, 37 SDTCisVT<2, i32>]>; 38def SDT_ZGR128Binary64 : SDTypeProfile<1, 2, 39 [SDTCisVT<0, untyped>, 40 SDTCisVT<1, untyped>, 41 SDTCisVT<2, i64>]>; 42def SDT_ZAtomicLoadBinaryW : SDTypeProfile<1, 5, 43 [SDTCisVT<0, i32>, 44 SDTCisPtrTy<1>, 45 SDTCisVT<2, i32>, 46 SDTCisVT<3, i32>, 47 SDTCisVT<4, i32>, 48 SDTCisVT<5, i32>]>; 49def SDT_ZAtomicCmpSwapW : SDTypeProfile<1, 6, 50 [SDTCisVT<0, i32>, 51 SDTCisPtrTy<1>, 52 SDTCisVT<2, i32>, 53 SDTCisVT<3, i32>, 54 SDTCisVT<4, i32>, 55 SDTCisVT<5, i32>, 56 SDTCisVT<6, i32>]>; 57def SDT_ZMemMemLength : SDTypeProfile<0, 3, 58 [SDTCisPtrTy<0>, 59 SDTCisPtrTy<1>, 60 SDTCisVT<2, i32>]>; 61def SDT_ZI32Intrinsic : SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>; 62 63//===----------------------------------------------------------------------===// 64// Node definitions 65//===----------------------------------------------------------------------===// 66 67// These are target-independent nodes, but have target-specific formats. 68def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, 69 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; 70def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, 71 [SDNPHasChain, SDNPSideEffect, SDNPOptInGlue, 72 SDNPOutGlue]>; 73 74// Nodes for SystemZISD::*. See SystemZISelLowering.h for more details. 75def z_retflag : SDNode<"SystemZISD::RET_FLAG", SDTNone, 76 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 77def z_call : SDNode<"SystemZISD::CALL", SDT_ZCall, 78 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 79 SDNPVariadic]>; 80def z_pcrel_wrapper : SDNode<"SystemZISD::PCREL_WRAPPER", SDT_ZWrapPtr, []>; 81def z_cmp : SDNode<"SystemZISD::CMP", SDT_ZCmp, [SDNPOutGlue]>; 82def z_ucmp : SDNode<"SystemZISD::UCMP", SDT_ZCmp, [SDNPOutGlue]>; 83def z_br_ccmask : SDNode<"SystemZISD::BR_CCMASK", SDT_ZBRCCMask, 84 [SDNPHasChain, SDNPInGlue]>; 85def z_select_ccmask : SDNode<"SystemZISD::SELECT_CCMASK", SDT_ZSelectCCMask, 86 [SDNPInGlue]>; 87def z_adjdynalloc : SDNode<"SystemZISD::ADJDYNALLOC", SDT_ZAdjDynAlloc>; 88def z_extract_access : SDNode<"SystemZISD::EXTRACT_ACCESS", 89 SDT_ZExtractAccess>; 90def z_umul_lohi64 : SDNode<"SystemZISD::UMUL_LOHI64", SDT_ZGR128Binary64>; 91def z_sdivrem32 : SDNode<"SystemZISD::SDIVREM32", SDT_ZGR128Binary32>; 92def z_sdivrem64 : SDNode<"SystemZISD::SDIVREM64", SDT_ZGR128Binary64>; 93def z_udivrem32 : SDNode<"SystemZISD::UDIVREM32", SDT_ZGR128Binary32>; 94def z_udivrem64 : SDNode<"SystemZISD::UDIVREM64", SDT_ZGR128Binary64>; 95 96class AtomicWOp<string name, SDTypeProfile profile = SDT_ZAtomicLoadBinaryW> 97 : SDNode<"SystemZISD::"##name, profile, 98 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 99 100def z_atomic_swapw : AtomicWOp<"ATOMIC_SWAPW">; 101def z_atomic_loadw_add : AtomicWOp<"ATOMIC_LOADW_ADD">; 102def z_atomic_loadw_sub : AtomicWOp<"ATOMIC_LOADW_SUB">; 103def z_atomic_loadw_and : AtomicWOp<"ATOMIC_LOADW_AND">; 104def z_atomic_loadw_or : AtomicWOp<"ATOMIC_LOADW_OR">; 105def z_atomic_loadw_xor : AtomicWOp<"ATOMIC_LOADW_XOR">; 106def z_atomic_loadw_nand : AtomicWOp<"ATOMIC_LOADW_NAND">; 107def z_atomic_loadw_min : AtomicWOp<"ATOMIC_LOADW_MIN">; 108def z_atomic_loadw_max : AtomicWOp<"ATOMIC_LOADW_MAX">; 109def z_atomic_loadw_umin : AtomicWOp<"ATOMIC_LOADW_UMIN">; 110def z_atomic_loadw_umax : AtomicWOp<"ATOMIC_LOADW_UMAX">; 111def z_atomic_cmp_swapw : AtomicWOp<"ATOMIC_CMP_SWAPW", SDT_ZAtomicCmpSwapW>; 112 113def z_mvc : SDNode<"SystemZISD::MVC", SDT_ZMemMemLength, 114 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 115def z_clc : SDNode<"SystemZISD::CLC", SDT_ZMemMemLength, 116 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 117def z_ipm : SDNode<"SystemZISD::IPM", SDT_ZI32Intrinsic, 118 [SDNPInGlue]>; 119 120//===----------------------------------------------------------------------===// 121// Pattern fragments 122//===----------------------------------------------------------------------===// 123 124// Register sign-extend operations. Sub-32-bit values are represented as i32s. 125def sext8 : PatFrag<(ops node:$src), (sext_inreg node:$src, i8)>; 126def sext16 : PatFrag<(ops node:$src), (sext_inreg node:$src, i16)>; 127def sext32 : PatFrag<(ops node:$src), (sext (i32 node:$src))>; 128 129// Register zero-extend operations. Sub-32-bit values are represented as i32s. 130def zext8 : PatFrag<(ops node:$src), (and node:$src, 0xff)>; 131def zext16 : PatFrag<(ops node:$src), (and node:$src, 0xffff)>; 132def zext32 : PatFrag<(ops node:$src), (zext (i32 node:$src))>; 133 134// Typed floating-point loads. 135def loadf32 : PatFrag<(ops node:$src), (f32 (load node:$src))>; 136def loadf64 : PatFrag<(ops node:$src), (f64 (load node:$src))>; 137 138// Extending loads in which the extension type doesn't matter. 139def anyextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ 140 return cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD; 141}]>; 142def anyextloadi8 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 143 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 144}]>; 145def anyextloadi16 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 146 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 147}]>; 148def anyextloadi32 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 149 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32; 150}]>; 151 152// Aligned loads. 153class AlignedLoad<SDPatternOperator load> 154 : PatFrag<(ops node:$addr), (load node:$addr), [{ 155 LoadSDNode *Load = cast<LoadSDNode>(N); 156 return Load->getAlignment() >= Load->getMemoryVT().getStoreSize(); 157}]>; 158def aligned_load : AlignedLoad<load>; 159def aligned_sextloadi16 : AlignedLoad<sextloadi16>; 160def aligned_sextloadi32 : AlignedLoad<sextloadi32>; 161def aligned_zextloadi16 : AlignedLoad<zextloadi16>; 162def aligned_zextloadi32 : AlignedLoad<zextloadi32>; 163 164// Aligned stores. 165class AlignedStore<SDPatternOperator store> 166 : PatFrag<(ops node:$src, node:$addr), (store node:$src, node:$addr), [{ 167 StoreSDNode *Store = cast<StoreSDNode>(N); 168 return Store->getAlignment() >= Store->getMemoryVT().getStoreSize(); 169}]>; 170def aligned_store : AlignedStore<store>; 171def aligned_truncstorei16 : AlignedStore<truncstorei16>; 172def aligned_truncstorei32 : AlignedStore<truncstorei32>; 173 174// Non-volatile loads. Used for instructions that might access the storage 175// location multiple times. 176class NonvolatileLoad<SDPatternOperator load> 177 : PatFrag<(ops node:$addr), (load node:$addr), [{ 178 LoadSDNode *Load = cast<LoadSDNode>(N); 179 return !Load->isVolatile(); 180}]>; 181def nonvolatile_load : NonvolatileLoad<load>; 182def nonvolatile_anyextloadi8 : NonvolatileLoad<anyextloadi8>; 183def nonvolatile_anyextloadi16 : NonvolatileLoad<anyextloadi16>; 184def nonvolatile_anyextloadi32 : NonvolatileLoad<anyextloadi32>; 185 186// Non-volatile stores. 187class NonvolatileStore<SDPatternOperator store> 188 : PatFrag<(ops node:$src, node:$addr), (store node:$src, node:$addr), [{ 189 StoreSDNode *Store = cast<StoreSDNode>(N); 190 return !Store->isVolatile(); 191}]>; 192def nonvolatile_store : NonvolatileStore<store>; 193def nonvolatile_truncstorei8 : NonvolatileStore<truncstorei8>; 194def nonvolatile_truncstorei16 : NonvolatileStore<truncstorei16>; 195def nonvolatile_truncstorei32 : NonvolatileStore<truncstorei32>; 196 197// Insertions. 198def inserti8 : PatFrag<(ops node:$src1, node:$src2), 199 (or (and node:$src1, -256), node:$src2)>; 200def insertll : PatFrag<(ops node:$src1, node:$src2), 201 (or (and node:$src1, 0xffffffffffff0000), node:$src2)>; 202def insertlh : PatFrag<(ops node:$src1, node:$src2), 203 (or (and node:$src1, 0xffffffff0000ffff), node:$src2)>; 204def inserthl : PatFrag<(ops node:$src1, node:$src2), 205 (or (and node:$src1, 0xffff0000ffffffff), node:$src2)>; 206def inserthh : PatFrag<(ops node:$src1, node:$src2), 207 (or (and node:$src1, 0x0000ffffffffffff), node:$src2)>; 208def insertlf : PatFrag<(ops node:$src1, node:$src2), 209 (or (and node:$src1, 0xffffffff00000000), node:$src2)>; 210def inserthf : PatFrag<(ops node:$src1, node:$src2), 211 (or (and node:$src1, 0x00000000ffffffff), node:$src2)>; 212 213// ORs that can be treated as insertions. 214def or_as_inserti8 : PatFrag<(ops node:$src1, node:$src2), 215 (or node:$src1, node:$src2), [{ 216 unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits(); 217 return CurDAG->MaskedValueIsZero(N->getOperand(0), 218 APInt::getLowBitsSet(BitWidth, 8)); 219}]>; 220 221// ORs that can be treated as reversed insertions. 222def or_as_revinserti8 : PatFrag<(ops node:$src1, node:$src2), 223 (or node:$src1, node:$src2), [{ 224 unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits(); 225 return CurDAG->MaskedValueIsZero(N->getOperand(1), 226 APInt::getLowBitsSet(BitWidth, 8)); 227}]>; 228 229// Fused multiply-add and multiply-subtract, but with the order of the 230// operands matching SystemZ's MA and MS instructions. 231def z_fma : PatFrag<(ops node:$src1, node:$src2, node:$src3), 232 (fma node:$src2, node:$src3, node:$src1)>; 233def z_fms : PatFrag<(ops node:$src1, node:$src2, node:$src3), 234 (fma node:$src2, node:$src3, (fneg node:$src1))>; 235 236// Floating-point negative absolute. 237def fnabs : PatFrag<(ops node:$ptr), (fneg (fabs node:$ptr))>; 238 239// Create a unary operator that loads from memory and then performs 240// the given operation on it. 241class loadu<SDPatternOperator operator, SDPatternOperator load = load> 242 : PatFrag<(ops node:$addr), (operator (load node:$addr))>; 243 244// Create a store operator that performs the given unary operation 245// on the value before storing it. 246class storeu<SDPatternOperator operator, SDPatternOperator store = store> 247 : PatFrag<(ops node:$value, node:$addr), 248 (store (operator node:$value), node:$addr)>; 249