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