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 18 using namespace llvm; 19 20 SystemZSelectionDAGInfo:: 21 SystemZSelectionDAGInfo(const SystemZTargetMachine &TM) 22 : TargetSelectionDAGInfo(TM) { 23 } 24 25 SystemZSelectionDAGInfo::~SystemZSelectionDAGInfo() { 26 } 27 28 SDValue SystemZSelectionDAGInfo:: 29 EmitTargetCodeForMemcpy(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. 51 static 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 63 SDValue SystemZSelectionDAGInfo:: 64 EmitTargetCodeForMemset(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