SystemZSelectionDAGInfo.cpp revision 19262ee0725a09b7c621a3d2eb66ba1513ae932a
1//===-- SystemZSelectionDAGInfo.cpp - SystemZ SelectionDAG Info -----------===// 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// This file implements the SystemZSelectionDAGInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#define DEBUG_TYPE "systemz-selectiondag-info" 15#include "SystemZTargetMachine.h" 16#include "llvm/CodeGen/SelectionDAG.h" 17 18using namespace llvm; 19 20SystemZSelectionDAGInfo:: 21SystemZSelectionDAGInfo(const SystemZTargetMachine &TM) 22 : TargetSelectionDAGInfo(TM) { 23} 24 25SystemZSelectionDAGInfo::~SystemZSelectionDAGInfo() { 26} 27 28SDValue SystemZSelectionDAGInfo:: 29EmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 30 SDValue Dst, SDValue Src, SDValue Size, unsigned Align, 31 bool IsVolatile, bool AlwaysInline, 32 MachinePointerInfo DstPtrInfo, 33 MachinePointerInfo SrcPtrInfo) const { 34 if (IsVolatile) 35 return SDValue(); 36 37 if (ConstantSDNode *CSize = dyn_cast<ConstantSDNode>(Size)) { 38 uint64_t Bytes = CSize->getZExtValue(); 39 if (Bytes >= 1 && Bytes <= 0x100) { 40 // A single MVC. 41 return DAG.getNode(SystemZISD::MVC, DL, MVT::Other, 42 Chain, Dst, Src, Size); 43 } 44 } 45 return SDValue(); 46} 47 48// Handle a memset of 1, 2, 4 or 8 bytes with the operands given by 49// Chain, Dst, ByteVal and Size. These cases are expected to use 50// MVI, MVHHI, MVHI and MVGHI respectively. 51static SDValue memsetStore(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 52 SDValue Dst, uint64_t ByteVal, uint64_t Size, 53 unsigned Align, 54 MachinePointerInfo DstPtrInfo) { 55 uint64_t StoreVal = ByteVal; 56 for (unsigned I = 1; I < Size; ++I) 57 StoreVal |= ByteVal << (I * 8); 58 return DAG.getStore(Chain, DL, 59 DAG.getConstant(StoreVal, MVT::getIntegerVT(Size * 8)), 60 Dst, DstPtrInfo, false, false, Align); 61} 62 63SDValue SystemZSelectionDAGInfo:: 64EmitTargetCodeForMemset(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 65 SDValue Dst, SDValue Byte, SDValue Size, 66 unsigned Align, bool IsVolatile, 67 MachinePointerInfo DstPtrInfo) const { 68 EVT DstVT = Dst.getValueType(); 69 70 if (IsVolatile) 71 return SDValue(); 72 73 if (ConstantSDNode *CSize = dyn_cast<ConstantSDNode>(Size)) { 74 uint64_t Bytes = CSize->getZExtValue(); 75 if (Bytes == 0) 76 return SDValue(); 77 if (ConstantSDNode *CByte = dyn_cast<ConstantSDNode>(Byte)) { 78 // Handle cases that can be done using at most two of 79 // MVI, MVHI, MVHHI and MVGHI. The latter two can only be 80 // used if ByteVal is all zeros or all ones; in other casees, 81 // we can move at most 2 halfwords. 82 uint64_t ByteVal = CByte->getZExtValue(); 83 if (ByteVal == 0 || ByteVal == 255 ? 84 Bytes <= 16 && CountPopulation_64(Bytes) <= 2 : 85 Bytes <= 4) { 86 unsigned Size1 = Bytes == 16 ? 8 : 1 << findLastSet(Bytes); 87 unsigned Size2 = Bytes - Size1; 88 SDValue Chain1 = memsetStore(DAG, DL, Chain, Dst, ByteVal, Size1, 89 Align, DstPtrInfo); 90 if (Size2 == 0) 91 return Chain1; 92 Dst = DAG.getNode(ISD::ADD, DL, DstVT, Dst, 93 DAG.getConstant(Size1, DstVT)); 94 DstPtrInfo = DstPtrInfo.getWithOffset(Size1); 95 SDValue Chain2 = memsetStore(DAG, DL, Chain, Dst, ByteVal, Size2, 96 std::min(Align, Size1), DstPtrInfo); 97 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chain1, Chain2); 98 } 99 } else { 100 // Handle one and two bytes using STC. 101 if (Bytes <= 2) { 102 SDValue Chain1 = DAG.getStore(Chain, DL, Byte, Dst, DstPtrInfo, 103 false, false, Align); 104 if (Bytes == 1) 105 return Chain1; 106 SDValue Dst2 = DAG.getNode(ISD::ADD, DL, DstVT, Dst, 107 DAG.getConstant(1, DstVT)); 108 SDValue Chain2 = DAG.getStore(Chain, DL, Byte, Dst2, 109 DstPtrInfo.getWithOffset(1), 110 false, false, 1); 111 return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chain1, Chain2); 112 } 113 } 114 assert(Bytes >= 2 && "Should have dealt with 0- and 1-byte cases already"); 115 if (Bytes <= 0x101) { 116 // Copy the byte to the first location and then use MVC to copy 117 // it to the rest. 118 Chain = DAG.getStore(Chain, DL, Byte, Dst, DstPtrInfo, 119 false, false, Align); 120 SDValue Dst2 = DAG.getNode(ISD::ADD, DL, DstVT, Dst, 121 DAG.getConstant(1, DstVT)); 122 return DAG.getNode(SystemZISD::MVC, DL, MVT::Other, Chain, Dst2, Dst, 123 DAG.getConstant(Bytes - 1, MVT::i32)); 124 } 125 } 126 return SDValue(); 127} 128 129// Convert the current CC value into an integer that is 0 if CC == 0, 130// less than zero if CC == 1 and greater than zero if CC >= 2. 131// The sequence starts with IPM, which puts CC into bits 29 and 28 132// of an integer and clears bits 30 and 31. 133static SDValue addIPMSequence(SDLoc DL, SDValue Glue, SelectionDAG &DAG) { 134 SDValue IPM = DAG.getNode(SystemZISD::IPM, DL, MVT::i32, Glue); 135 SDValue SRL = DAG.getNode(ISD::SRL, DL, MVT::i32, IPM, 136 DAG.getConstant(28, MVT::i32)); 137 SDValue ROTL = DAG.getNode(ISD::ROTL, DL, MVT::i32, SRL, 138 DAG.getConstant(31, MVT::i32)); 139 return ROTL; 140} 141 142std::pair<SDValue, SDValue> SystemZSelectionDAGInfo:: 143EmitTargetCodeForMemcmp(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 144 SDValue Src1, SDValue Src2, SDValue Size, 145 MachinePointerInfo Op1PtrInfo, 146 MachinePointerInfo Op2PtrInfo) const { 147 if (ConstantSDNode *CSize = dyn_cast<ConstantSDNode>(Size)) { 148 uint64_t Bytes = CSize->getZExtValue(); 149 if (Bytes >= 1 && Bytes <= 0x100) { 150 // A single CLC. 151 SDVTList VTs = DAG.getVTList(MVT::Other, MVT::Glue); 152 Chain = DAG.getNode(SystemZISD::CLC, DL, VTs, Chain, 153 Src1, Src2, Size); 154 SDValue Glue = Chain.getValue(1); 155 return std::make_pair(addIPMSequence(DL, Glue, DAG), Chain); 156 } 157 } 158 return std::make_pair(SDValue(), SDValue()); 159} 160 161std::pair<SDValue, SDValue> SystemZSelectionDAGInfo:: 162EmitTargetCodeForStrcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 163 SDValue Dest, SDValue Src, 164 MachinePointerInfo DestPtrInfo, 165 MachinePointerInfo SrcPtrInfo, bool isStpcpy) const { 166 SDVTList VTs = DAG.getVTList(Dest.getValueType(), MVT::Other); 167 SDValue EndDest = DAG.getNode(SystemZISD::STPCPY, DL, VTs, Chain, Dest, Src, 168 DAG.getConstant(0, MVT::i32)); 169 return std::make_pair(isStpcpy ? EndDest : Dest, EndDest.getValue(1)); 170} 171 172std::pair<SDValue, SDValue> SystemZSelectionDAGInfo:: 173EmitTargetCodeForStrcmp(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 174 SDValue Src1, SDValue Src2, 175 MachinePointerInfo Op1PtrInfo, 176 MachinePointerInfo Op2PtrInfo) const { 177 SDVTList VTs = DAG.getVTList(Src1.getValueType(), MVT::Other, MVT::Glue); 178 SDValue Unused = DAG.getNode(SystemZISD::STRCMP, DL, VTs, Chain, Src1, Src2, 179 DAG.getConstant(0, MVT::i32)); 180 Chain = Unused.getValue(1); 181 SDValue Glue = Chain.getValue(2); 182 return std::make_pair(addIPMSequence(DL, Glue, DAG), Chain); 183} 184 185// Search from Src for a null character, stopping once Src reaches Limit. 186// Return a pair of values, the first being the number of nonnull characters 187// and the second being the out chain. 188// 189// This can be used for strlen by setting Limit to 0. 190static std::pair<SDValue, SDValue> getBoundedStrlen(SelectionDAG &DAG, SDLoc DL, 191 SDValue Chain, SDValue Src, 192 SDValue Limit) { 193 EVT PtrVT = Src.getValueType(); 194 SDVTList VTs = DAG.getVTList(PtrVT, MVT::Other, MVT::Glue); 195 SDValue End = DAG.getNode(SystemZISD::SEARCH_STRING, DL, VTs, Chain, 196 Limit, Src, DAG.getConstant(0, MVT::i32)); 197 Chain = End.getValue(1); 198 SDValue Len = DAG.getNode(ISD::SUB, DL, PtrVT, End, Src); 199 return std::make_pair(Len, Chain); 200} 201 202std::pair<SDValue, SDValue> SystemZSelectionDAGInfo:: 203EmitTargetCodeForStrlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 204 SDValue Src, MachinePointerInfo SrcPtrInfo) const { 205 EVT PtrVT = Src.getValueType(); 206 return getBoundedStrlen(DAG, DL, Chain, Src, DAG.getConstant(0, PtrVT)); 207} 208 209std::pair<SDValue, SDValue> SystemZSelectionDAGInfo:: 210EmitTargetCodeForStrnlen(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 211 SDValue Src, SDValue MaxLength, 212 MachinePointerInfo SrcPtrInfo) const { 213 EVT PtrVT = Src.getValueType(); 214 MaxLength = DAG.getZExtOrTrunc(MaxLength, DL, PtrVT); 215 SDValue Limit = DAG.getNode(ISD::ADD, DL, PtrVT, Src, MaxLength); 216 return getBoundedStrlen(DAG, DL, Chain, Src, Limit); 217} 218