SystemZSelectionDAGInfo.cpp revision f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92
1dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford//===-- SystemZSelectionDAGInfo.cpp - SystemZ SelectionDAG Info -----------===// 2dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// 3dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// The LLVM Compiler Infrastructure 4dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// 5dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// This file is distributed under the University of Illinois Open Source 6dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// License. See LICENSE.TXT for details. 7dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// 8dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford//===----------------------------------------------------------------------===// 9dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// 10dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// This file implements the SystemZSelectionDAGInfo class. 11dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford// 12dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford//===----------------------------------------------------------------------===// 13dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 14dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford#define DEBUG_TYPE "systemz-selectiondag-info" 15dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford#include "SystemZTargetMachine.h" 16dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford#include "llvm/CodeGen/SelectionDAG.h" 17dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 18dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandifordusing namespace llvm; 19dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 20dff0009d0ced62b92cb5900bc2203ec40142ba15Richard SandifordSystemZSelectionDAGInfo:: 21dff0009d0ced62b92cb5900bc2203ec40142ba15Richard SandifordSystemZSelectionDAGInfo(const SystemZTargetMachine &TM) 22dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford : TargetSelectionDAGInfo(TM) { 23dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford} 24dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 25dff0009d0ced62b92cb5900bc2203ec40142ba15Richard SandifordSystemZSelectionDAGInfo::~SystemZSelectionDAGInfo() { 26dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford} 27dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 28dff0009d0ced62b92cb5900bc2203ec40142ba15Richard SandifordSDValue SystemZSelectionDAGInfo:: 29dff0009d0ced62b92cb5900bc2203ec40142ba15Richard SandifordEmitTargetCodeForMemcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 30dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford SDValue Dst, SDValue Src, SDValue Size, unsigned Align, 31dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford bool IsVolatile, bool AlwaysInline, 32dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford MachinePointerInfo DstPtrInfo, 33dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford MachinePointerInfo SrcPtrInfo) const { 34dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford if (IsVolatile) 35dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford return SDValue(); 36dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford 37dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford if (ConstantSDNode *CSize = dyn_cast<ConstantSDNode>(Size)) { 38dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford uint64_t Bytes = CSize->getZExtValue(); 39dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford if (Bytes >= 1 && Bytes <= 0x100) { 40dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford // A single MVC. 41dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford return DAG.getNode(SystemZISD::MVC, DL, MVT::Other, 42dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford Chain, Dst, Src, Size); 43dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford } 44dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford } 45dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford return SDValue(); 46dff0009d0ced62b92cb5900bc2203ec40142ba15Richard Sandiford} 47f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford 48f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford// Handle a memset of 1, 2, 4 or 8 bytes with the operands given by 49f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford// Chain, Dst, ByteVal and Size. These cases are expected to use 50f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford// MVI, MVHHI, MVHI and MVGHI respectively. 51f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandifordstatic SDValue memsetStore(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 52f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford SDValue Dst, uint64_t ByteVal, uint64_t Size, 53f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford unsigned Align, 54f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford MachinePointerInfo DstPtrInfo) { 55f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford uint64_t StoreVal = ByteVal; 56f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford for (unsigned I = 1; I < Size; ++I) 57f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford StoreVal |= ByteVal << (I * 8); 58f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return DAG.getStore(Chain, DL, 59f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford DAG.getConstant(StoreVal, MVT::getIntegerVT(Size * 8)), 60f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford Dst, DstPtrInfo, false, false, Align); 61f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford} 62f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford 63f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard SandifordSDValue SystemZSelectionDAGInfo:: 64f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard SandifordEmitTargetCodeForMemset(SelectionDAG &DAG, SDLoc DL, SDValue Chain, 65f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford SDValue Dst, SDValue Byte, SDValue Size, 66f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford unsigned Align, bool IsVolatile, 67f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford MachinePointerInfo DstPtrInfo) const { 68f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford EVT DstVT = Dst.getValueType(); 69f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford 70f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (IsVolatile) 71f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return SDValue(); 72f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford 73f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (ConstantSDNode *CSize = dyn_cast<ConstantSDNode>(Size)) { 74f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford uint64_t Bytes = CSize->getZExtValue(); 75f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (Bytes == 0) 76f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return SDValue(); 77f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (ConstantSDNode *CByte = dyn_cast<ConstantSDNode>(Byte)) { 78f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // Handle cases that can be done using at most two of 79f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // MVI, MVHI, MVHHI and MVGHI. The latter two can only be 80f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // used if ByteVal is all zeros or all ones; in other casees, 81f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // we can move at most 2 halfwords. 82f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford uint64_t ByteVal = CByte->getZExtValue(); 83f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (ByteVal == 0 || ByteVal == 255 ? 84f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford Bytes <= 16 && CountPopulation_64(Bytes) <= 2 : 85f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford Bytes <= 4) { 86f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford unsigned Size1 = Bytes == 16 ? 8 : 1 << findLastSet(Bytes); 87f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford unsigned Size2 = Bytes - Size1; 88f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford SDValue Chain1 = memsetStore(DAG, DL, Chain, Dst, ByteVal, Size1, 89f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford Align, DstPtrInfo); 90f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (Size2 == 0) 91f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return Chain1; 92f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford Dst = DAG.getNode(ISD::ADD, DL, DstVT, Dst, 93f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford DAG.getConstant(Size1, DstVT)); 94f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford DstPtrInfo = DstPtrInfo.getWithOffset(Size1); 95f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford SDValue Chain2 = memsetStore(DAG, DL, Chain, Dst, ByteVal, Size2, 96f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford std::min(Align, Size1), DstPtrInfo); 97f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chain1, Chain2); 98f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford } 99f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford } else { 100f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // Handle one and two bytes using STC. 101f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (Bytes <= 2) { 102f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford SDValue Chain1 = DAG.getStore(Chain, DL, Byte, Dst, DstPtrInfo, 103f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford false, false, Align); 104f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (Bytes == 1) 105f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return Chain1; 106f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford SDValue Dst2 = DAG.getNode(ISD::ADD, DL, DstVT, Dst, 107f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford DAG.getConstant(1, DstVT)); 108f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford SDValue Chain2 = DAG.getStore(Chain, DL, Byte, Dst2, 109f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford DstPtrInfo.getWithOffset(1), 110f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford false, false, 1); 111f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return DAG.getNode(ISD::TokenFactor, DL, MVT::Other, Chain1, Chain2); 112f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford } 113f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford } 114f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford assert(Bytes >= 2 && "Should have dealt with 0- and 1-byte cases already"); 115f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford if (Bytes <= 0x101) { 116f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // Copy the byte to the first location and then use MVC to copy 117f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford // it to the rest. 118f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford Chain = DAG.getStore(Chain, DL, Byte, Dst, DstPtrInfo, 119f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford false, false, Align); 120f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford SDValue Dst2 = DAG.getNode(ISD::ADD, DL, DstVT, Dst, 121f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford DAG.getConstant(1, DstVT)); 122f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return DAG.getNode(SystemZISD::MVC, DL, MVT::Other, Chain, Dst2, Dst, 123f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford DAG.getConstant(Bytes - 1, MVT::i32)); 124f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford } 125f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford } 126f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford return SDValue(); 127f6ea5e0d8007234fc74c1ff6ac2c3ca316c41d92Richard Sandiford} 128