1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===-- LegalizeDAG.cpp - Implement SelectionDAG::Legalize ----------------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file implements the SelectionDAG::Legalize method. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Analysis/DebugInfo.h" 1519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/Analysis.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineFunction.h" 17894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineJumpTableInfo.h" 1819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/CodeGen/SelectionDAG.h" 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Target/TargetFrameLowering.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetLowering.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetData.h" 22894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Target/TargetMachine.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CallingConv.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Constants.h" 25894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/DerivedTypes.h" 26894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/LLVMContext.h" 27894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/MathExtras.h" 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/DenseMap.h" 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/SmallVector.h" 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/ADT/SmallPtrSet.h" 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// SelectionDAGLegalize - This takes an arbitrary SelectionDAG as input and 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// hacks on it until the target machine can handle it. This involves 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// eliminating value sizes the machine cannot handle (promoting small sizes to 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// large sizes or splitting up large values into small values) as well as 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// eliminating operations the machine cannot handle. 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// This code also does a small amount of optimization and recognition of idioms 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// as part of its processing. For example, if a target does not support a 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 'setcc' instruction efficiently, but does support 'brcc' instruction, this 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// will attempt merge setcc and brc instructions into brcc's. 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace { 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanclass SelectionDAGLegalize { 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetMachine &TM; 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetLowering &TLI; 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectionDAG &DAG; 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Libcall insertion helpers. 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 56894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// LastCALLSEQ_END - This keeps track of the CALLSEQ_END node that has been 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// legalized. We use this to ensure that calls are properly serialized 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// against each other, including inserted libcalls. 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LastCALLSEQ_END; 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 61894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// IsLegalizingCall - This member is used *only* for purposes of providing 62894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// helpful assertions that a libcall isn't created while another call is 63894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// being legalized (which could lead to non-serialized call sequences). 64894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool IsLegalizingCall; 65894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 66894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// LegalizedNodes - For nodes that are of legal width, and that have more 67894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// than one use, this map indicates what regularized operand to use. This 68894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// allows us to avoid legalizing the same thing more than once. 69894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DenseMap<SDValue, SDValue> LegalizedNodes; 70894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void AddLegalizedOperand(SDValue From, SDValue To) { 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizedNodes.insert(std::make_pair(From, To)); 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If someone requests legalization of the new node, return itself. 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (From != To) 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizedNodes.insert(std::make_pair(To, To)); 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 7719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Transfer SDDbgValues. 7819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.TransferDbgValues(From, To); 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 8119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanpublic: 8219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman explicit SelectionDAGLegalize(SelectionDAG &DAG); 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void LegalizeDAG(); 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanprivate: 8719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /// LegalizeOp - Return a legal replacement for the given operation, with 8819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /// all legal operands. 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LegalizeOp(SDValue O); 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue OptimizeFloatStore(StoreSDNode *ST); 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// PerformInsertVectorEltInMemory - Some target cannot handle a variable 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// is necessary to spill the vector being inserted into to memory, perform 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// the insert there, and then read the result back. 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Idx, DebugLoc dl); 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandINSERT_VECTOR_ELT(SDValue Vec, SDValue Val, 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Idx, DebugLoc dl); 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// ShuffleWithNarrowerEltType - Return a vector shuffle operation which 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// performs the same shuffe in terms of order or result bytes, but on a type 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// whose vector element type is narrower than the original shuffle type. 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3> 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ShuffleWithNarrowerEltType(EVT NVT, EVT VT, DebugLoc dl, 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N1, SDValue N2, 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<int> &Mask) const; 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest, 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallPtrSet<SDNode*, 32> &NodesLeadingTo); 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void LegalizeSetCCCondCode(EVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl); 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned); 11719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ExpandLibCall(RTLIB::Libcall LC, EVT RetVT, const SDValue *Ops, 11819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumOps, bool isSigned, DebugLoc dl); 11919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::pair<SDValue, SDValue> ExpandChainLibCall(RTLIB::Libcall LC, 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Node, bool isSigned); 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandFPLibCall(SDNode *Node, RTLIB::Libcall Call_F32, 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80, 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_PPCF128); 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandIntLibCall(SDNode *Node, bool isSigned, 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I8, 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I16, 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I32, 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I64, 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I128); 13119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman void ExpandDivRemLibCall(SDNode *Node, SmallVectorImpl<SDValue> &Results); 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue EmitStackConvert(SDValue SrcOp, EVT SlotVT, EVT DestVT, DebugLoc dl); 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandBUILD_VECTOR(SDNode *Node); 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node); 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void ExpandDYNAMIC_STACKALLOC(SDNode *Node, 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<SDValue> &Results); 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandFCOPYSIGN(SDNode *Node); 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, EVT DestVT, 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl); 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, EVT DestVT, bool isSigned, 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl); 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, EVT DestVT, bool isSigned, 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl); 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandBSWAP(SDValue Op, DebugLoc dl); 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandBitCount(unsigned Opc, SDValue Op, DebugLoc dl); 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandExtractFromVectorThroughStack(SDValue Op); 15019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ExpandInsertToVectorThroughStack(SDValue Op); 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ExpandVectorBuildThroughStack(SDNode* Node); 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::pair<SDValue, SDValue> ExpandAtomic(SDNode *Node); 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void ExpandNode(SDNode *Node, SmallVectorImpl<SDValue> &Results); 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman void PromoteNode(SDNode *Node, SmallVectorImpl<SDValue> &Results); 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman}; 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ShuffleWithNarrowerEltType - Return a vector shuffle operation which 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// performs the same shuffe in terms of order or result bytes, but on a type 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// whose vector element type is narrower than the original shuffle type. 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3> 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSelectionDAGLegalize::ShuffleWithNarrowerEltType(EVT NVT, EVT VT, DebugLoc dl, 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue N1, SDValue N2, 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<int> &Mask) const { 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumMaskElts = VT.getVectorNumElements(); 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumDestElts = NVT.getVectorNumElements(); 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumEltsGrowth = NumDestElts / NumMaskElts; 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NumEltsGrowth && "Cannot promote to vector type with fewer elts!"); 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NumEltsGrowth == 1) 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getVectorShuffle(NVT, dl, N1, N2, &Mask[0]); 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<int, 8> NewMask; 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i != NumMaskElts; ++i) { 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int Idx = Mask[i]; 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned j = 0; j != NumEltsGrowth; ++j) { 181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Idx < 0) 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewMask.push_back(-1); 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewMask.push_back(Idx * NumEltsGrowth + j); 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NewMask.size() == NumDestElts && "Non-integer NumEltsGrowth?"); 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(TLI.isShuffleMaskLegal(NewMask, NVT) && "Shuffle not legal?"); 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getVectorShuffle(NVT, dl, N1, N2, &NewMask[0]); 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 19219bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag) 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman : TM(dag.getTarget()), TLI(dag.getTargetLoweringInfo()), 19419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG(dag) { 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid SelectionDAGLegalize::LegalizeDAG() { 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastCALLSEQ_END = DAG.getEntryNode(); 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IsLegalizingCall = false; 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The legalize process is inherently a bottom-up recursive process (users 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // legalize their uses before themselves). Given infinite stack space, we 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // could just start legalizing on the root and traverse the whole graph. In 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // practice however, this causes us to run out of stack space on large basic 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // blocks. To avoid this problem, compute an ordering of the nodes where each 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // node is only legalized after all of its operands are legalized. 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.AssignTopologicalOrder(); 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman E = prior(DAG.allnodes_end()); I != llvm::next(E); ++I) 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeOp(SDValue(I, 0)); 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Finally, it's possible the root changed. Get the new root. 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue OldRoot = DAG.getRoot(); 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?"); 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.setRoot(LegalizedNodes[OldRoot]); 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizedNodes.clear(); 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Remove dead nodes now. 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.RemoveDeadNodes(); 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FindCallEndFromCallStart - Given a chained node that is part of a call 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// sequence, find the CALLSEQ_END node that terminates the call sequence. 22619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { 22719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Nested CALLSEQ_START/END constructs aren't yet legal, 22819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // but we can DTRT and handle them correctly here. 22919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Node->getOpcode() == ISD::CALLSEQ_START) 23019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman depth++; 23119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (Node->getOpcode() == ISD::CALLSEQ_END) { 23219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman depth--; 23319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (depth == 0) 23419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Node; 23519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->use_empty()) 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; // No CallSeqEnd 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The chain is usually at the end. 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TheChain(Node, Node->getNumValues()-1); 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TheChain.getValueType() != MVT::Other) { 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Sometimes it's at the beginning. 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheChain = SDValue(Node, 0); 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TheChain.getValueType() != MVT::Other) { 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, hunt for it. 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 1, e = Node->getNumValues(); i != e; ++i) 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getValueType(i) == MVT::Other) { 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TheChain = SDValue(Node, i); 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, we walked into a node without a chain. 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TheChain.getValueType() != MVT::Other) 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (SDNode::use_iterator UI = Node->use_begin(), 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman E = Node->use_end(); UI != E; ++UI) { 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make sure to only follow users of our token chain. 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *User = *UI; 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (User->getOperand(i) == TheChain) 26519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SDNode *Result = FindCallEndFromCallStart(User, depth)) 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result; 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FindCallStartFromCallEnd - Given a chained node that is part of a call 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// sequence, find the CALLSEQ_START node that initiates the call sequence. 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDNode *FindCallStartFromCallEnd(SDNode *Node) { 27419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int nested = 0; 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Node && "Didn't find callseq_start for a call??"); 27619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman while (Node->getOpcode() != ISD::CALLSEQ_START || nested) { 27719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node = Node->getOperand(0).getNode(); 27819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Node->getOperand(0).getValueType() == MVT::Other && 27919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Node doesn't have a token chain argument!"); 28019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (Node->getOpcode()) { 28119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: 28219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 28319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::CALLSEQ_START: 28419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!nested) 28519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Node; 28619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman nested--; 28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::CALLSEQ_END: 28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman nested++; 29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return 0; 294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// LegalizeAllNodesNotLeadingTo - Recursively walk the uses of N, looking to 297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// see if any uses can reach Dest. If no dest operands can get to dest, 298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// legalize them, legalize ourself, and return false, otherwise, return true. 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// Keep track of the nodes we fine that actually do lead to Dest in 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// NodesLeadingTo. This avoids retraversing them exponential number of times. 302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool SelectionDAGLegalize::LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest, 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallPtrSet<SDNode*, 32> &NodesLeadingTo) { 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (N == Dest) return true; // N certainly leads to Dest :) 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we've already processed this node and it does lead to Dest, there is no 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // need to reprocess it. 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NodesLeadingTo.count(N)) return true; 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the first result of this node has been already legalized, then it cannot 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // reach N. 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (LegalizedNodes.count(SDValue(N, 0))) return false; 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Okay, this node has not already been legalized. Check and legalize all 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // operands. If none lead to Dest, then we can legalize this node. 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool OperandsLeadToDest = false; 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OperandsLeadToDest |= // If an operand leads to Dest, so do we. 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeAllNodesNotLeadingTo(N->getOperand(i).getNode(), Dest, 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NodesLeadingTo); 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OperandsLeadToDest) { 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NodesLeadingTo.insert(N); 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Okay, this node looks safe, legalize it and return false. 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeOp(SDValue(N, 0)); 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandConstantFP - Expands the ConstantFP node to an integer constant or 334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// a load from the constant pool. 335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP, 336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SelectionDAG &DAG, const TargetLowering &TLI) { 337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool Extend = false; 338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = CFP->getDebugLoc(); 339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If a FP immediate is precise when represented as a float and if the 341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // target can do an extending load from float to double, we put it into 342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the constant pool as a float, even if it's is statically typed as a 343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // double. This shrinks FP constants and canonicalizes them for targets where 344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // an FP extending load is the same cost as a normal load (such as on the x87 345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // fp stack or PPC FP unit). 346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = CFP->getValueType(0); 347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantFP *LLVMC = const_cast<ConstantFP*>(CFP->getConstantFPValue()); 348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!UseCP) { 349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert((VT == MVT::f64 || VT == MVT::f32) && "Invalid type expansion"); 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getConstant(LLVMC->getValueAPF().bitcastToAPInt(), 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (VT == MVT::f64) ? MVT::i64 : MVT::i32); 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OrigVT = VT; 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT SVT = VT; 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (SVT != MVT::f32) { 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1); 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantFPSDNode::isValueValidForType(SVT, CFP->getValueAPF()) && 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Only do this if the target has a native EXTLOAD instruction from 360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // smaller type. 361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.isLoadExtLegal(ISD::EXTLOAD, SVT) && 362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.ShouldShrinkFPConstant(OrigVT)) { 36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *SType = SVT.getTypeForEVT(*DAG.getContext()); 364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType)); 365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VT = SVT; 366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Extend = true; 367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy()); 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Extend) 37319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getExtLoad(ISD::EXTLOAD, dl, OrigVT, 374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getEntryNode(), 37519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman CPIdx, MachinePointerInfo::getConstantPool(), 37619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VT, false, false, Alignment); 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getLoad(OrigVT, dl, DAG.getEntryNode(), CPIdx, 37819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getConstantPool(), false, false, 379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Alignment); 380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores. 383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic 384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, 385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetLowering &TLI) { 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Chain = ST->getChain(); 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ptr = ST->getBasePtr(); 388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Val = ST->getValue(); 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Val.getValueType(); 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int Alignment = ST->getAlignment(); 391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = ST->getDebugLoc(); 392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ST->getMemoryVT().isFloatingPoint() || 393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ST->getMemoryVT().isVector()) { 394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT intVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits()); 395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isTypeLegal(intVT)) { 396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand to a bitconvert of the value to the integer type of the 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // same size, then a (misaligned) int store. 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: Does not handle truncating floating point stores! 39919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Result = DAG.getNode(ISD::BITCAST, dl, intVT, Val); 40019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getStore(Chain, dl, Result, Ptr, ST->getPointerInfo(), 40119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->isVolatile(), ST->isNonTemporal(), Alignment); 40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 40319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Do a (aligned) store to a stack slot, then copy from the stack slot 40419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // to the final destination using (unaligned) integer loads and stores. 40519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT StoredVT = ST->getMemoryVT(); 40619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT RegVT = 40719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getRegisterType(*DAG.getContext(), 40819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT::getIntegerVT(*DAG.getContext(), 40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StoredVT.getSizeInBits())); 41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned StoredBytes = StoredVT.getSizeInBits() / 8; 41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned RegBytes = RegVT.getSizeInBits() / 8; 41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumRegs = (StoredBytes + RegBytes - 1) / RegBytes; 41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Make sure the stack slot is also aligned for the register type. 41519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue StackPtr = DAG.CreateStackTemporary(StoredVT, RegVT); 41619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 41719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Perform the original store, only redirected to the stack slot. 41819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Store = DAG.getTruncStore(Chain, dl, 41919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Val, StackPtr, MachinePointerInfo(), 42019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StoredVT, false, false, 0); 42119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); 42219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> Stores; 42319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Offset = 0; 42419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 42519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Do all but one copies using the full register width. 42619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 1; i < NumRegs; i++) { 42719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load one integer register's worth from the stack slot. 42819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, 42919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), 43019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 43119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Store it to the final location. Remember the store. 43219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr, 43319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo().getWithOffset(Offset), 43419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->isVolatile(), ST->isNonTemporal(), 43519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinAlign(ST->getAlignment(), Offset))); 43619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Increment the pointers. 43719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset += RegBytes; 43819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 43919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Increment); 44019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 44219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 44319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The last store may be partial. Do a truncating store. On big-endian 44419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // machines this requires an extending load from the stack slot to ensure 44519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // that the bits are in the right place. 44619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), 44719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8 * (StoredBytes - Offset)); 44819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 44919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load from the stack slot. 45019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr, 45119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), 45219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MemVT, false, false, 0); 45319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 45419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr, 45519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo() 45619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman .getWithOffset(Offset), 45719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MemVT, ST->isVolatile(), 45819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->isNonTemporal(), 45919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinAlign(ST->getAlignment(), Offset))); 46019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The order of the stores doesn't matter - say it with a TokenFactor. 46119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], 46219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Stores.size()); 463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ST->getMemoryVT().isInteger() && 465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman !ST->getMemoryVT().isVector() && 466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Unaligned store of unknown type."); 467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the half-size VT 468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NewStoredVT = ST->getMemoryVT().getHalfSizedIntegerVT(*DAG.getContext()); 469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int NumBits = NewStoredVT.getSizeInBits(); 470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int IncrementSize = NumBits / 8; 471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Divide the stored value in two parts. 47319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ShiftAmount = DAG.getConstant(NumBits, 47419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(Val.getValueType())); 475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo = Val; 476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Hi = DAG.getNode(ISD::SRL, dl, VT, Val, ShiftAmount); 477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the two parts 479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Store1, Store2; 480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr, 48119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo(), NewStoredVT, 482894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ST->isVolatile(), ST->isNonTemporal(), Alignment); 483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(IncrementSize, TLI.getPointerTy())); 485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Alignment = MinAlign(Alignment, IncrementSize); 486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr, 48719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo().getWithOffset(IncrementSize), 488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewStoredVT, ST->isVolatile(), ST->isNonTemporal(), 489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Alignment); 490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2); 492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads. 495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstatic 496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, 497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetLowering &TLI) { 498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Chain = LD->getChain(); 499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ptr = LD->getBasePtr(); 500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = LD->getValueType(0); 501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT LoadedVT = LD->getMemoryVT(); 502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = LD->getDebugLoc(); 503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT.isFloatingPoint() || VT.isVector()) { 504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT intVT = EVT::getIntegerVT(*DAG.getContext(), LoadedVT.getSizeInBits()); 505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isTypeLegal(intVT)) { 506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand to a (misaligned) integer load of the same size, 507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // then bitconvert to floating point or vector. 50819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getPointerInfo(), 50919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->isVolatile(), 510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LD->isNonTemporal(), LD->getAlignment()); 51119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Result = DAG.getNode(ISD::BITCAST, dl, LoadedVT, newLoad); 512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT.isFloatingPoint() && LoadedVT != VT) 513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result); 514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[] = { Result, Chain }; 516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getMergeValues(Ops, 2, dl); 51719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 51919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Copy the value to a (aligned) stack slot using (unaligned) integer 52019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // loads and stores, then do a (aligned) load from the stack slot. 52119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT RegVT = TLI.getRegisterType(*DAG.getContext(), intVT); 52219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned LoadedBytes = LoadedVT.getSizeInBits() / 8; 52319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned RegBytes = RegVT.getSizeInBits() / 8; 52419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumRegs = (LoadedBytes + RegBytes - 1) / RegBytes; 52519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Make sure the stack slot is also aligned for the register type. 52719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue StackBase = DAG.CreateStackTemporary(LoadedVT, RegVT); 52819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 52919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); 53019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> Stores; 53119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue StackPtr = StackBase; 53219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Offset = 0; 53319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 53419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Do all but one copies using the full register width. 53519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 1; i < NumRegs; i++) { 53619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load one integer register's worth from the original location. 53719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, 53819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo().getWithOffset(Offset), 53919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->isVolatile(), LD->isNonTemporal(), 54019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinAlign(LD->getAlignment(), Offset)); 541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Follow the load with a store to the stack slot. Remember the store. 54219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr, 54319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), false, false, 0)); 54419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Increment the pointers. 54519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Offset += RegBytes; 54619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); 54719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 54819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Increment); 549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 55019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 55119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The last copy may be partial. Do an extending load. 55219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), 55319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 8 * (LoadedBytes - Offset)); 55419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr, 55519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo().getWithOffset(Offset), 55619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MemVT, LD->isVolatile(), 55719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->isNonTemporal(), 55819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinAlign(LD->getAlignment(), Offset)); 55919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Follow the load with a store to the stack slot. Remember the store. 56019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // On big-endian machines this requires a truncating store to ensure 56119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // that the bits end up in the right place. 56219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr, 56319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), MemVT, 56419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0)); 56519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 56619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The order of the stores doesn't matter - say it with a TokenFactor. 56719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], 56819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Stores.size()); 56919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Finally, perform the original load only redirected to the stack slot. 57119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase, 57219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), LoadedVT, false, false, 0); 57319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 57419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Callers expect a MERGE_VALUES node. 57519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ops[] = { Load, TF }; 57619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getMergeValues(Ops, 2, dl); 577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(LoadedVT.isInteger() && !LoadedVT.isVector() && 579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Unaligned load of unsupported type."); 580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Compute the new VT that is half the size of the old one. This is an 582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // integer MVT. 583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumBits = LoadedVT.getSizeInBits(); 584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NewLoadedVT; 585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewLoadedVT = EVT::getIntegerVT(*DAG.getContext(), NumBits/2); 586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NumBits >>= 1; 587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = LD->getAlignment(); 589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned IncrementSize = NumBits / 8; 590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::LoadExtType HiExtType = LD->getExtensionType(); 591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD. 593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HiExtType == ISD::NON_EXTLOAD) 594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman HiExtType = ISD::ZEXTLOAD; 595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load the value in two parts 597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo, Hi; 598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isLittleEndian()) { 59919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getPointerInfo(), 60019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewLoadedVT, LD->isVolatile(), 601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LD->isNonTemporal(), Alignment); 602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(IncrementSize, TLI.getPointerTy())); 60419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, 60519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo().getWithOffset(IncrementSize), 60619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewLoadedVT, LD->isVolatile(), 607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LD->isNonTemporal(), MinAlign(Alignment,IncrementSize)); 608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 60919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getPointerInfo(), 61019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewLoadedVT, LD->isVolatile(), 611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LD->isNonTemporal(), Alignment); 612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(IncrementSize, TLI.getPointerTy())); 61419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, 61519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo().getWithOffset(IncrementSize), 61619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NewLoadedVT, LD->isVolatile(), 617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LD->isNonTemporal(), MinAlign(Alignment,IncrementSize)); 618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // aggregate the two parts 62119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ShiftAmount = DAG.getConstant(NumBits, 62219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(Hi.getValueType())); 623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Result = DAG.getNode(ISD::SHL, dl, VT, Hi, ShiftAmount); 624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = DAG.getNode(ISD::OR, dl, VT, Result, Lo); 625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi.getValue(1)); 628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ops[] = { Result, TF }; 630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getMergeValues(Ops, 2, dl); 631894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PerformInsertVectorEltInMemory - Some target cannot handle a variable 634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it 635894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// is necessary to spill the vector being inserted into to memory, perform 636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// the insert there, and then read the result back. 637894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize:: 638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanPerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx, 639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1 = Vec; 641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp2 = Val; 642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp3 = Idx; 643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the target doesn't support this, we have to spill the input vector 645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to a temporary stack slot, update the element, then reload it. This is 646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // badness. We could also load the value into a vector register (either 647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // with a "move to register" or "extload into register" instruction, then 648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // permute it into place, if the idx is a constant and if the idx is 649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // supported by the target. 650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Tmp1.getValueType(); 651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EltVT = VT.getVectorElementType(); 652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT IdxVT = Tmp3.getValueType(); 653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PtrVT = TLI.getPointerTy(); 654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue StackPtr = DAG.CreateStackTemporary(VT); 655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); 657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the vector. 659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr, 66019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getFixedStack(SPFI), 661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Truncate or zero extend offset to target pointer type. 664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; 665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(CastOpc, dl, PtrVT, Tmp3); 666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add the offset to the index. 667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EltSize = EltVT.getSizeInBits()/8; 668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ISD::MUL, dl, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT)); 669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr); 670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the scalar value. 67119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2, MachinePointerInfo(), EltVT, 672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load the updated vector. 674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getLoad(VT, dl, Ch, StackPtr, 67519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getFixedStack(SPFI), false, false, 0); 676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize:: 680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanExpandINSERT_VECTOR_ELT(SDValue Vec, SDValue Val, SDValue Idx, DebugLoc dl) { 681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantSDNode *InsertPos = dyn_cast<ConstantSDNode>(Idx)) { 682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SCALAR_TO_VECTOR requires that the type of the value being inserted 683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // match the element type of the vector being created, except for 684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // integers in which case the inserted value can be over width. 685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EltVT = Vec.getValueType().getVectorElementType(); 686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Val.getValueType() == EltVT || 687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (EltVT.isInteger() && Val.getValueType().bitsGE(EltVT))) { 688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, 689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Vec.getValueType(), Val); 690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumElts = Vec.getValueType().getVectorNumElements(); 692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We generate a shuffle of InVec and ScVec, so the shuffle mask 693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // should be 0,1,2,3,4,5... with the appropriate element replaced with 694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // elt 0 of the RHS. 695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<int, 8> ShufOps; 696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i != NumElts; ++i) 697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShufOps.push_back(i != InsertPos->getZExtValue() ? i : NumElts); 698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getVectorShuffle(Vec.getValueType(), dl, Vec, ScVec, 700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &ShufOps[0]); 701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return PerformInsertVectorEltInMemory(Vec, Val, Idx, dl); 704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) { 707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr' 708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: We shouldn't do this for TargetConstantFP's. 709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: move this to the DAG Combiner! Note that we can't regress due 710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to phase ordering between legalized code and the dag combiner. This 711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // probably means that we need to integrate dag combiner and legalizer 712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // together. 713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We generally can't do this one for long doubles. 714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1 = ST->getChain(); 715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp2 = ST->getBasePtr(); 716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp3; 717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = ST->getAlignment(); 718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isVolatile = ST->isVolatile(); 719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isNonTemporal = ST->isNonTemporal(); 720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = ST->getDebugLoc(); 721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) { 722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (CFP->getValueType(0) == MVT::f32 && 72319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.isTypeLegal(MVT::i32)) { 724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getConstant(CFP->getValueAPF(). 725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bitcastToAPInt().zextOrTrunc(32), 726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::i32); 72719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 72819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isVolatile, isNonTemporal, Alignment); 72919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 73019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 73119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (CFP->getValueType(0) == MVT::f64) { 732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this target supports 64-bit registers, do a single 64-bit store. 73319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TLI.isTypeLegal(MVT::i64)) { 734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). 735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman zextOrTrunc(64), MVT::i64); 73619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 73719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isVolatile, isNonTemporal, Alignment); 73819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 73919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 74019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TLI.isTypeLegal(MVT::i32) && !ST->isVolatile()) { 741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, if the target supports 32-bit registers, use 2 32-bit 742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // stores. If the target supports neither 32- nor 64-bits, this 743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // xform is certainly not worth it. 744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const APInt &IntVal =CFP->getValueAPF().bitcastToAPInt(); 74519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Lo = DAG.getConstant(IntVal.trunc(32), MVT::i32); 746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Hi = DAG.getConstant(IntVal.lshr(32).trunc(32), MVT::i32); 747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isBigEndian()) std::swap(Lo, Hi); 748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 74919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getPointerInfo(), isVolatile, 75019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isNonTemporal, Alignment); 751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(4)); 75319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, 75419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo().getWithOffset(4), 755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isVolatile, isNonTemporal, MinAlign(Alignment, 4U)); 756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 76119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return SDValue(0, 0); 762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 76419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// LegalizeOp - Return a legal replacement for the given operation, with 76519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// all legal operands. 766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { 767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op.getOpcode() == ISD::TargetConstant) // Allow illegal target nodes. 768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Op; 769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Node = Op.getNode(); 771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 77419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(TLI.getTypeAction(*DAG.getContext(), Node->getValueType(i)) == 77519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::TypeLegal && 776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Unexpected illegal type!"); 777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 77919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert((TLI.getTypeAction(*DAG.getContext(), 78019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(i).getValueType()) == 78119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::TypeLegal || 782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(i).getOpcode() == ISD::TargetConstant) && 783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Unexpected illegal type!"); 784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Note that LegalizeOp may be reentered even from single-use nodes, which 786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // means that we always must cache transformed nodes. 787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op); 788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I != LegalizedNodes.end()) return I->second; 789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1, Tmp2, Tmp3, Tmp4; 791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Result = Op; 792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isCustom = false; 793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Figure out the correct action; the way to query this varies by opcode 79519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::LegalizeAction Action = TargetLowering::Legal; 796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool SimpleFinishLegalizing = true; 797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Node->getOpcode()) { 798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INTRINSIC_W_CHAIN: 799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INTRINSIC_WO_CHAIN: 800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INTRINSIC_VOID: 801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VAARG: 802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::STACKSAVE: 803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getOperationAction(Node->getOpcode(), MVT::Other); 804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SINT_TO_FP: 806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UINT_TO_FP: 807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_VECTOR_ELT: 808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getOperationAction(Node->getOpcode(), 809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0).getValueType()); 810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_ROUND_INREG: 812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND_INREG: { 813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT InnerType = cast<VTSDNode>(Node->getOperand(1))->getVT(); 814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getOperationAction(Node->getOpcode(), InnerType); 815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 81719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_STORE: { 81819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Action = TLI.getOperationAction(Node->getOpcode(), 81919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(2).getValueType()); 82019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 82119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT_CC: 823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETCC: 824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BR_CC: { 825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned CCOperand = Node->getOpcode() == ISD::SELECT_CC ? 4 : 826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOpcode() == ISD::SETCC ? 2 : 1; 827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned CompareOperand = Node->getOpcode() == ISD::BR_CC ? 2 : 0; 828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpVT = Node->getOperand(CompareOperand).getValueType(); 829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode CCCode = 830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cast<CondCodeSDNode>(Node->getOperand(CCOperand))->get(); 831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getCondCodeAction(CCCode, OpVT); 832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Action == TargetLowering::Legal) { 833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getOpcode() == ISD::SELECT_CC) 834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getOperationAction(Node->getOpcode(), 835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getValueType(0)); 836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getOperationAction(Node->getOpcode(), OpVT); 838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::LOAD: 842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::STORE: 843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: Model these properly. LOAD and STORE are complicated, and 844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // STORE expects the unlegalized operand in some cases. 845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SimpleFinishLegalizing = false; 846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CALLSEQ_START: 848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CALLSEQ_END: 849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: This shouldn't be necessary. These nodes have special properties 850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // dealing with the recursive nature of legalization. Removing this 851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // special case should be done as part of making LegalizeDAG non-recursive. 852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SimpleFinishLegalizing = false; 853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_ELEMENT: 855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FLT_ROUNDS_: 856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SADDO: 857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SSUBO: 858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UADDO: 859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::USUBO: 860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SMULO: 861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UMULO: 862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FPOWI: 863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MERGE_VALUES: 86419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_RETURN: 865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FRAME_TO_ARGS_OFFSET: 86619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_SJLJ_SETJMP: 86719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_SJLJ_LONGJMP: 86819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_SJLJ_DISPATCHSETUP: 869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // These operations lie about being legal: when they claim to be legal, 870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // they should actually be expanded. 871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Action == TargetLowering::Legal) 873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TargetLowering::Expand; 874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 87519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::INIT_TRAMPOLINE: 87619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ADJUST_TRAMPOLINE: 877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FRAMEADDR: 878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::RETURNADDR: 879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // These operations lie about being legal: when they claim to be legal, 880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // they should actually be custom-lowered. 881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Action == TargetLowering::Legal) 883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TargetLowering::Custom; 884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_VECTOR: 886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // A weird case: legalization for BUILD_VECTOR never legalizes the 887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // operands! 888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: This really sucks... changing it isn't semantically incorrect, 889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // but it massively pessimizes the code for floating-point BUILD_VECTORs 890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // because ConstantFP operands get legalized into constant pool loads 891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // before the BUILD_VECTOR code can see them. It doesn't usually bite, 892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // though, because BUILD_VECTORS usually get lowered into other nodes 893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // which get legalized properly. 894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SimpleFinishLegalizing = false; 895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getOpcode() >= ISD::BUILTIN_OP_END) { 898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TargetLowering::Legal; 899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SimpleFinishLegalizing) { 906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Ops, ResultVals; 907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.push_back(LegalizeOp(Node->getOperand(i))); 909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Node->getOpcode()) { 910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: break; 911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BR: 912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BRIND: 913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BR_JT: 914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BR_CC: 915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BRCOND: 916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Branches tweak the chain to include LastCALLSEQ_END 917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ops[0], 91819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LastCALLSEQ_END); 919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[0] = LegalizeOp(Ops[0]); 920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastCALLSEQ_END = DAG.getEntryNode(); 921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL: 923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL: 924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA: 925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTL: 926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ROTR: 927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalizing shifts/rotates requires adjusting the shift amount 928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to the appropriate width. 929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Ops[1].getValueType().isVector()) 93019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops[1] = LegalizeOp(DAG.getShiftAmountOperand(Ops[0].getValueType(), 93119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops[1])); 932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRL_PARTS: 934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SRA_PARTS: 935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SHL_PARTS: 936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalizing shifts/rotates requires adjusting the shift amount 937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to the appropriate width. 938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Ops[2].getValueType().isVector()) 93919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops[2] = LegalizeOp(DAG.getShiftAmountOperand(Ops[0].getValueType(), 94019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ops[2])); 941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), Ops.data(), 945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.size()), 0); 946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Action) { 947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Legal: 948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultVals.push_back(Result.getValue(i)); 950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Custom: 952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: The handling for custom lowering with multiple results is 953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // a complete mess. 954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = TLI.LowerOperation(Result, DAG); 955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp1.getNode()) { 956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) { 957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (e == 1) 958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultVals.push_back(Tmp1); 959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultVals.push_back(Tmp1.getValue(i)); 961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FALL THROUGH 966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Expand: 967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExpandNode(Result.getNode(), ResultVals); 968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Promote: 970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman PromoteNode(Result.getNode(), ResultVals); 971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ResultVals.empty()) { 974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = ResultVals.size(); i != e; ++i) { 975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ResultVals[i] != SDValue(Node, i)) 976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ResultVals[i] = LegalizeOp(ResultVals[i]); 977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLegalizedOperand(SDValue(Node, i), ResultVals[i]); 978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ResultVals[Op.getResNo()]; 980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Node->getOpcode()) { 984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#ifndef NDEBUG 986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "NODE: "; 987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->dump( &DAG); 988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dbgs() << "\n"; 989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#endif 990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(0 && "Do not know how to legalize this operator!"); 991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 99219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::SRA: 99319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::SRL: 99419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::SHL: { 99519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Scalarize vector SRA/SRL/SHL. 99619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT VT = Node->getValueType(0); 99719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(VT.isVector() && "Unable to legalize non-vector shift"); 99819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(TLI.isTypeLegal(VT.getScalarType())&& "Element type must be legal"); 99919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElem = VT.getVectorNumElements(); 100019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 100119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> Scalars; 100219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned Idx = 0; Idx < NumElem; Idx++) { 100319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 100419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VT.getScalarType(), 100519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(0), DAG.getIntPtrConstant(Idx)); 100619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Sh = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 100719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VT.getScalarType(), 100819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(1), DAG.getIntPtrConstant(Idx)); 100919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Scalars.push_back(DAG.getNode(Node->getOpcode(), dl, 101019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VT.getScalarType(), Ex, Sh)); 101119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 101219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0), 101319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman &Scalars[0], Scalars.size()); 101419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 101519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 101619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_VECTOR: 1018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (TLI.getOperationAction(ISD::BUILD_VECTOR, Node->getValueType(0))) { 1019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "This action is not supported yet!"); 1020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Custom: 1021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = TLI.LowerOperation(Result, DAG); 1022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp3.getNode()) { 1023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = Tmp3; 1024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FALLTHROUGH 1027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Expand: 1028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = ExpandBUILD_VECTOR(Result.getNode()); 1029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CALLSEQ_START: { 1033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *CallEnd = FindCallEndFromCallStart(Node); 1034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Recursively Legalize all of the inputs of the call end that do not lead 1036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // to this call start. This ensures that any libcalls that need be inserted 1037894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // are inserted *before* the CALLSEQ_START. 1038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman {SmallPtrSet<SDNode*, 32> NodesLeadingTo; 1039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = CallEnd->getNumOperands(); i != e; ++i) 1040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeAllNodesNotLeadingTo(CallEnd->getOperand(i).getNode(), Node, 1041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NodesLeadingTo); 1042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Now that we have legalized all of the inputs (which may have inserted 1045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // libcalls), create the new CALLSEQ_START node. 1046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 1047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Merge in the last call to ensure that this call starts after the last 1049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // call ended. 1050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (LastCALLSEQ_END.getOpcode() != ISD::EntryToken) { 1051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, LastCALLSEQ_END); 1053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = LegalizeOp(Tmp1); 1054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Do not try to legalize the target-specific arguments (#1+). 1057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp1 != Node->getOperand(0)) { 1058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 1059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[0] = Tmp1; 1060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), &Ops[0], 1061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.size()), Result.getResNo()); 1062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Remember that the CALLSEQ_START is legalized. 1065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLegalizedOperand(Op.getValue(0), Result); 1066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getNumValues() == 2) // If this has a flag result, remember it. 1067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); 1068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Now that the callseq_start and all of the non-call nodes above this call 1070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // sequence have been legalized, legalize the call itself. During this 1071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // process, no libcalls can/will be inserted, guaranteeing that no calls 1072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // can overlap. 1073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!IsLegalizingCall && "Inconsistent sequentialization of calls!"); 1074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Note that we are selecting this call! 1075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastCALLSEQ_END = SDValue(CallEnd, 0); 1076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IsLegalizingCall = true; 1077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalize the call, starting from the CALLSEQ_END. 1079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeOp(LastCALLSEQ_END); 1080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!IsLegalizingCall && "CALLSEQ_END should have cleared this!"); 1081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result; 1082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CALLSEQ_END: 1084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the CALLSEQ_START node hasn't been legalized first, legalize it. This 1085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // will cause this node to be legalized as well as handling libcalls right. 1086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (LastCALLSEQ_END.getNode() != Node) { 1087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeOp(SDValue(FindCallStartFromCallEnd(Node), 0)); 1088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op); 1089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(I != LegalizedNodes.end() && 1090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Legalizing the call start should have legalized this node!"); 1091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return I->second; 1092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, the call start has been legalized and everything is going 1095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // according to plan. Just legalize ourselves normally here. 1096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 1097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Do not try to legalize the target-specific arguments (#1+), except for 1098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // an optional flag input. 109919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Node->getOperand(Node->getNumOperands()-1).getValueType() != MVT::Glue){ 1100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp1 != Node->getOperand(0)) { 1101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 1102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[0] = Tmp1; 1103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &Ops[0], Ops.size()), 1105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result.getResNo()); 1106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = LegalizeOp(Node->getOperand(Node->getNumOperands()-1)); 1109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp1 != Node->getOperand(0) || 1110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 != Node->getOperand(Node->getNumOperands()-1)) { 1111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 1112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops[0] = Tmp1; 1113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.back() = Tmp2; 1114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &Ops[0], Ops.size()), 1116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result.getResNo()); 1117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(IsLegalizingCall && "Call sequence imbalance between start/end?"); 1120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This finishes up call legalization. 1121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IsLegalizingCall = false; 1122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the CALLSEQ_END node has a flag, remember that we legalized it. 1124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0)); 1125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getNumValues() == 2) 1126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1)); 1127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result.getValue(Op.getResNo()); 1128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::LOAD: { 1129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoadSDNode *LD = cast<LoadSDNode>(Node); 1130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = LegalizeOp(LD->getChain()); // Legalize the chain. 1131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = LegalizeOp(LD->getBasePtr()); // Legalize the base pointer. 1132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::LoadExtType ExtType = LD->getExtensionType(); 1134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ExtType == ISD::NON_EXTLOAD) { 1135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 1136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, Tmp2, LD->getOffset()), 1138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result.getResNo()); 1139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = Result.getValue(0); 1140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = Result.getValue(1); 1141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 1143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "This action is not supported yet!"); 1144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Legal: 1145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is an unaligned load and the target doesn't support it, 1146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // expand it. 1147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { 114819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *Ty = LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); 1149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ABIAlignment = TLI.getTargetData()->getABITypeAlignment(Ty); 1150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (LD->getAlignment() < ABIAlignment){ 1151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = ExpandUnalignedLoad(cast<LoadSDNode>(Result.getNode()), 1152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG, TLI); 1153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = Result.getOperand(0); 1154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = Result.getOperand(1); 1155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = LegalizeOp(Tmp3); 1156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = LegalizeOp(Tmp4); 1157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Custom: 1161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = TLI.LowerOperation(Tmp3, DAG); 1162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp1.getNode()) { 1163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = LegalizeOp(Tmp1); 1164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = LegalizeOp(Tmp1.getValue(1)); 1165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Promote: { 1168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Only promote a load of vector type to another. 1169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(VT.isVector() && "Cannot promote this load!"); 1170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Change base type to a different vector type. 1171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT); 1172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 117319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getPointerInfo(), 1174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LD->isVolatile(), LD->isNonTemporal(), 1175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LD->getAlignment()); 117619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp3 = LegalizeOp(DAG.getNode(ISD::BITCAST, dl, VT, Tmp1)); 1177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = LegalizeOp(Tmp1.getValue(1)); 1178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Since loads produce two values, make sure to remember that we 1182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // legalized both of them. 1183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLegalizedOperand(SDValue(Node, 0), Tmp3); 1184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLegalizedOperand(SDValue(Node, 1), Tmp4); 1185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Op.getResNo() ? Tmp4 : Tmp3; 118619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 118819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT SrcVT = LD->getMemoryVT(); 118919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SrcWidth = SrcVT.getSizeInBits(); 119019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Alignment = LD->getAlignment(); 119119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isVolatile = LD->isVolatile(); 119219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isNonTemporal = LD->isNonTemporal(); 119319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 119419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (SrcWidth != SrcVT.getStoreSizeInBits() && 119519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Some targets pretend to have an i1 loading operation, and actually 119619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // load an i8. This trick is correct for ZEXTLOAD because the top 7 119719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // bits are guaranteed to be zero; it helps the optimizers understand 119819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // that these bits are zero. It is also useful for EXTLOAD, since it 119919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // tells the optimizers that those bits are undefined. It would be 120019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // nice to have an effective generic way of getting these benefits... 120119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Until such a way is found, don't insist on promoting i1 here. 120219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (SrcVT != MVT::i1 || 120319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getLoadExtAction(ExtType, MVT::i1) == TargetLowering::Promote)) { 120419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Promote to a byte-sized load if not loading an integral number of 120519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // bytes. For example, promote EXTLOAD:i20 -> EXTLOAD:i24. 120619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NewWidth = SrcVT.getStoreSizeInBits(); 120719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NVT = EVT::getIntegerVT(*DAG.getContext(), NewWidth); 120819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ch; 120919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 121019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The extra bits are guaranteed to be zero, since we stored them that 121119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // way. A zext load from NVT thus automatically gives zext from SrcVT. 121219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 121319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ISD::LoadExtType NewExtType = 121419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtType == ISD::ZEXTLOAD ? ISD::ZEXTLOAD : ISD::EXTLOAD; 121519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 121619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getExtLoad(NewExtType, dl, Node->getValueType(0), 121719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1, Tmp2, LD->getPointerInfo(), 121819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NVT, isVolatile, isNonTemporal, Alignment); 121919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 122019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ch = Result.getValue(1); // The chain. 122119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 122219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ExtType == ISD::SEXTLOAD) 122319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Having the top bits zero doesn't help when sign extending. 122419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, 122519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result.getValueType(), 122619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result, DAG.getValueType(SrcVT)); 122719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (ExtType == ISD::ZEXTLOAD || NVT == Result.getValueType()) 122819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // All the top bits are guaranteed to be zero - inform the optimizers. 122919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::AssertZext, dl, 123019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result.getValueType(), Result, 123119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getValueType(SrcVT)); 123219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 123319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = LegalizeOp(Result); 123419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = LegalizeOp(Ch); 123519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (SrcWidth & (SrcWidth - 1)) { 123619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If not loading a power-of-2 number of bits, expand as two loads. 123719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!SrcVT.isVector() && "Unsupported extload!"); 123819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned RoundWidth = 1 << Log2_32(SrcWidth); 123919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(RoundWidth < SrcWidth); 124019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ExtraWidth = SrcWidth - RoundWidth; 124119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(ExtraWidth < RoundWidth); 124219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(!(RoundWidth % 8) && !(ExtraWidth % 8) && 124319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "Load size not an integral number of bytes!"); 124419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT RoundVT = EVT::getIntegerVT(*DAG.getContext(), RoundWidth); 124519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ExtraVT = EVT::getIntegerVT(*DAG.getContext(), ExtraWidth); 124619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Lo, Hi, Ch; 124719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned IncrementSize; 124819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 124919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TLI.isLittleEndian()) { 125019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // EXTLOAD:i24 -> ZEXTLOAD:i16 | (shl EXTLOAD@+2:i8, 16) 125119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load the bottom RoundWidth bits. 125219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, Node->getValueType(0), 125319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1, Tmp2, 125419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo(), RoundVT, isVolatile, 125519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isNonTemporal, Alignment); 125619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 125719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load the remaining ExtraWidth bits. 125819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman IncrementSize = RoundWidth / 8; 125919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 126019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(IncrementSize)); 126119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, 126219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo().getWithOffset(IncrementSize), 126319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtraVT, isVolatile, isNonTemporal, 126419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinAlign(Alignment, IncrementSize)); 126519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 126619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Build a factor node to remember that this load is independent of 126719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the other one. 126819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 126919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi.getValue(1)); 127019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 127119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Move the top bits to the right place. 127219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, 127319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(RoundWidth, 127419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(Hi.getValueType()))); 127519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 127619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Join the hi and lo parts. 127719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); 127819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 127919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Big endian - avoid unaligned loads. 128019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // EXTLOAD:i24 -> (shl EXTLOAD:i16, 8) | ZEXTLOAD@+2:i8 128119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load the top RoundWidth bits. 128219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, 128319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo(), RoundVT, isVolatile, 128419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isNonTemporal, Alignment); 128519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 128619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Load the remaining ExtraWidth bits. 128719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman IncrementSize = RoundWidth / 8; 128819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 128919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(IncrementSize)); 129019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getExtLoad(ISD::ZEXTLOAD, 129119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman dl, Node->getValueType(0), Tmp1, Tmp2, 129219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo().getWithOffset(IncrementSize), 129319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtraVT, isVolatile, isNonTemporal, 129419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MinAlign(Alignment, IncrementSize)); 129519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 129619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Build a factor node to remember that this load is independent of 129719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the other one. 129819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 129919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi.getValue(1)); 130019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 130119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Move the top bits to the right place. 130219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, 130319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(ExtraWidth, 130419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(Hi.getValueType()))); 130519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 130619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Join the hi and lo parts. 130719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); 130819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 131019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = LegalizeOp(Result); 131119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = LegalizeOp(Ch); 131219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 131319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (TLI.getLoadExtAction(ExtType, SrcVT)) { 131419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: assert(0 && "This action is not supported yet!"); 131519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::Custom: 131619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isCustom = true; 131719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FALLTHROUGH 131819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::Legal: 131919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 132019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1, Tmp2, LD->getOffset()), 132119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result.getResNo()); 132219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = Result.getValue(0); 132319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = Result.getValue(1); 132419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 132519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isCustom) { 132619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp3 = TLI.LowerOperation(Result, DAG); 132719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Tmp3.getNode()) { 132819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = LegalizeOp(Tmp3); 132919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = LegalizeOp(Tmp3.getValue(1)); 133019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 133219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If this is an unaligned load and the target doesn't support it, 133319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // expand it. 133419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { 133519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *Ty = 133619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); 133719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ABIAlignment = 133819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getTargetData()->getABITypeAlignment(Ty); 133919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (LD->getAlignment() < ABIAlignment){ 134019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = ExpandUnalignedLoad(cast<LoadSDNode>(Result.getNode()), 134119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG, TLI); 134219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = Result.getOperand(0); 134319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = Result.getOperand(1); 134419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = LegalizeOp(Tmp1); 134519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = LegalizeOp(Tmp2); 134619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 134719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 134819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 134919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 135019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::Expand: 135119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TLI.isLoadExtLegal(ISD::EXTLOAD, SrcVT) && TLI.isTypeLegal(SrcVT)) { 135219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, 135319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getPointerInfo(), 135419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->isVolatile(), LD->isNonTemporal(), 135519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getAlignment()); 135619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ExtendOp; 135719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (ExtType) { 135819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EXTLOAD: 135919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtendOp = (SrcVT.isFloatingPoint() ? 136019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ISD::FP_EXTEND : ISD::ANY_EXTEND); 136119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 136219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::SEXTLOAD: ExtendOp = ISD::SIGN_EXTEND; break; 136319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ZEXTLOAD: ExtendOp = ISD::ZERO_EXTEND; break; 136419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: llvm_unreachable("Unexpected extend load type!"); 136519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 136619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ExtendOp, dl, Node->getValueType(0), Load); 136719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = LegalizeOp(Result); // Relegalize new nodes. 136819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = LegalizeOp(Load.getValue(1)); 136919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 1370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 137219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If this is a promoted vector load, and the vector element types are 137319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // legal, then scalarize it. 137419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ExtType == ISD::EXTLOAD && SrcVT.isVector() && 137519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.isTypeLegal(Node->getValueType(0).getScalarType())) { 137619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> LoadVals; 137719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> LoadChains; 137819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElem = SrcVT.getVectorNumElements(); 137919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Stride = SrcVT.getScalarType().getSizeInBits()/8; 138019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 138119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned Idx=0; Idx<NumElem; Idx++) { 138219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 138319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(Stride)); 138419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl, 138519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getValueType(0).getScalarType(), 138619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1, Tmp2, LD->getPointerInfo().getWithOffset(Idx * Stride), 138719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SrcVT.getScalarType(), 138819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->isVolatile(), LD->isNonTemporal(), 138919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getAlignment()); 139019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 139119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoadVals.push_back(ScalarLoad.getValue(0)); 139219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoadChains.push_back(ScalarLoad.getValue(1)); 1393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 139419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 139519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman &LoadChains[0], LoadChains.size()); 139619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ValRes = DAG.getNode(ISD::BUILD_VECTOR, dl, 139719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getValueType(0), &LoadVals[0], LoadVals.size()); 139819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 139919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes. 140019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = LegalizeOp(Result.getValue(0)); // Relegalize new nodes. 1401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 140219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 140319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 140419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If this is a promoted vector load, and the vector element types are 140519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // illegal, create the promoted vector from bitcasted segments. 140619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ExtType == ISD::EXTLOAD && SrcVT.isVector()) { 140719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT MemElemTy = Node->getValueType(0).getScalarType(); 140819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT SrcSclrTy = SrcVT.getScalarType(); 140919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeRatio = 141019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (MemElemTy.getSizeInBits() / SrcSclrTy.getSizeInBits()); 141119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 141219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> LoadVals; 141319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> LoadChains; 141419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElem = SrcVT.getVectorNumElements(); 141519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Stride = SrcVT.getScalarType().getSizeInBits()/8; 141619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 141719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned Idx=0; Idx<NumElem; Idx++) { 141819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 141919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(Stride)); 142019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl, 142119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SrcVT.getScalarType(), 142219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1, Tmp2, LD->getPointerInfo().getWithOffset(Idx * Stride), 142319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SrcVT.getScalarType(), 142419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->isVolatile(), LD->isNonTemporal(), 142519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getAlignment()); 142619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TLI.isBigEndian()) { 142719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // MSB (which is garbage, comes first) 142819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoadVals.push_back(ScalarLoad.getValue(0)); 142919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i<SizeRatio-1; ++i) 143019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoadVals.push_back(DAG.getUNDEF(SrcVT.getScalarType())); 143119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 143219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // LSB (which is data, comes first) 143319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i<SizeRatio-1; ++i) 143419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoadVals.push_back(DAG.getUNDEF(SrcVT.getScalarType())); 143519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoadVals.push_back(ScalarLoad.getValue(0)); 143619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 143719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LoadChains.push_back(ScalarLoad.getValue(1)); 1438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 143919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 144019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 144119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman &LoadChains[0], LoadChains.size()); 144219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT TempWideVector = EVT::getVectorVT(*DAG.getContext(), 144319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SrcVT.getScalarType(), NumElem*SizeRatio); 144419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ValRes = DAG.getNode(ISD::BUILD_VECTOR, dl, 144519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TempWideVector, &LoadVals[0], LoadVals.size()); 144619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 144719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Cast to the correct type 144819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ValRes = DAG.getNode(ISD::BITCAST, dl, Node->getValueType(0), ValRes); 144919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes. 145119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = LegalizeOp(Result.getValue(0)); // Relegalize new nodes. 1452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 145319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 145619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: This does not work for vectors on most targets. Sign- and 145719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // zero-extend operations are currently folded into extending loads, 145819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // whether they are legal or not, and then we end up here without any 145919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // support for legalizing them. 146019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(ExtType != ISD::EXTLOAD && 146119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "EXTLOAD should always be supported!"); 146219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Turn the unsupported load into an EXTLOAD followed by an explicit 146319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // zero/sign extend inreg. 146419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0), 146519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1, Tmp2, LD->getPointerInfo(), SrcVT, 146619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->isVolatile(), LD->isNonTemporal(), 146719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LD->getAlignment()); 146819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ValRes; 146919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (ExtType == ISD::SEXTLOAD) 147019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, 147119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result.getValueType(), 147219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result, DAG.getValueType(SrcVT)); 147319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 147419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT.getScalarType()); 147519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes. 147619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = LegalizeOp(Result.getValue(1)); // Relegalize new nodes. 147719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 147819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 1479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 148019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 148119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Since loads produce two values, make sure to remember that we legalized 148219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // both of them. 148319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddLegalizedOperand(SDValue(Node, 0), Tmp1); 148419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman AddLegalizedOperand(SDValue(Node, 1), Tmp2); 148519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Op.getResNo() ? Tmp2 : Tmp1; 1486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::STORE: { 1488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StoreSDNode *ST = cast<StoreSDNode>(Node); 1489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = LegalizeOp(ST->getChain()); // Legalize the chain. 1490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = LegalizeOp(ST->getBasePtr()); // Legalize the pointer. 1491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = ST->getAlignment(); 1492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isVolatile = ST->isVolatile(); 1493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isNonTemporal = ST->isNonTemporal(); 1494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!ST->isTruncatingStore()) { 1496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) { 1497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = SDValue(OptStore, 0); 1498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { 1502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = LegalizeOp(ST->getValue()); 1503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, Tmp3, Tmp2, 1505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ST->getOffset()), 1506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result.getResNo()); 1507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Tmp3.getValueType(); 1509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (TLI.getOperationAction(ISD::STORE, VT)) { 1510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "This action is not supported yet!"); 1511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Legal: 1512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is an unaligned store and the target doesn't support it, 1513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // expand it. 1514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { 151519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); 1516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty); 1517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ST->getAlignment() < ABIAlignment) 1518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.getNode()), 1519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG, TLI); 1520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Custom: 1523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = TLI.LowerOperation(Result, DAG); 1524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp1.getNode()) Result = Tmp1; 1525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Promote: 1527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(VT.isVector() && "Unknown legal promote case!"); 152819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp3 = DAG.getNode(ISD::BITCAST, dl, 1529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3); 1530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, 153119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo(), isVolatile, 1532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isNonTemporal, Alignment); 1533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = LegalizeOp(ST->getValue()); 1539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT StVT = ST->getMemoryVT(); 1541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned StWidth = StVT.getSizeInBits(); 1542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (StWidth != StVT.getStoreSizeInBits()) { 1544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote to a byte-sized store with upper bits zero if not 1545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // storing an integral number of bytes. For example, promote 1546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1) 1547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = EVT::getIntegerVT(*DAG.getContext(), 1548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StVT.getStoreSizeInBits()); 1549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT); 155019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 155119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NVT, isVolatile, isNonTemporal, Alignment); 1552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (StWidth & (StWidth - 1)) { 1553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If not storing a power-of-2 number of bits, expand as two stores. 1554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!StVT.isVector() && "Unsupported truncstore!"); 1555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned RoundWidth = 1 << Log2_32(StWidth); 1556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(RoundWidth < StWidth); 1557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExtraWidth = StWidth - RoundWidth; 1558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(ExtraWidth < RoundWidth); 1559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!(RoundWidth % 8) && !(ExtraWidth % 8) && 1560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Store size not an integral number of bytes!"); 1561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT RoundVT = EVT::getIntegerVT(*DAG.getContext(), RoundWidth); 1562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ExtraVT = EVT::getIntegerVT(*DAG.getContext(), ExtraWidth); 1563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo, Hi; 1564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned IncrementSize; 1565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isLittleEndian()) { 1567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 X, TRUNCSTORE@+2:i8 (srl X, 16) 1568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the bottom RoundWidth bits. 156919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 157019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RoundVT, 1571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isVolatile, isNonTemporal, Alignment); 1572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the remaining ExtraWidth bits. 1574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IncrementSize = RoundWidth / 8; 1575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 1576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(IncrementSize)); 1577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, 157819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(RoundWidth, 157919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(Tmp3.getValueType()))); 158019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, 158119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo().getWithOffset(IncrementSize), 158219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtraVT, isVolatile, isNonTemporal, 1583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MinAlign(Alignment, IncrementSize)); 1584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Big endian - avoid unaligned stores. 1586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE@+2:i8 X 1587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the top RoundWidth bits. 1588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, 158919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(ExtraWidth, 159019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(Tmp3.getValueType()))); 159119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getPointerInfo(), 159219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RoundVT, isVolatile, isNonTemporal, Alignment); 1593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the remaining ExtraWidth bits. 1595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman IncrementSize = RoundWidth / 8; 1596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 1597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(IncrementSize)); 159819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, 159919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo().getWithOffset(IncrementSize), 160019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtraVT, isVolatile, isNonTemporal, 1601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MinAlign(Alignment, IncrementSize)); 1602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The order of the stores doesn't matter. 1605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 1606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() || 1608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 != ST->getBasePtr()) 1609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, Tmp3, Tmp2, 1611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ST->getOffset()), 1612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result.getResNo()); 1613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) { 1615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "This action is not supported yet!"); 1616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Legal: 1617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is an unaligned store and the target doesn't support it, 1618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // expand it. 1619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { 162019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); 1621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty); 1622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ST->getAlignment() < ABIAlignment) 1623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.getNode()), 1624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG, TLI); 1625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Custom: 1628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = TLI.LowerOperation(Result, DAG); 1629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 163019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case TargetLowering::Expand: 163119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 163219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT WideScalarVT = Tmp3.getValueType().getScalarType(); 163319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT NarrowScalarVT = StVT.getScalarType(); 163419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 163519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (StVT.isVector()) { 163619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned NumElem = StVT.getVectorNumElements(); 163719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The type of the data we want to save 163819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT RegVT = Tmp3.getValueType(); 163919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT RegSclVT = RegVT.getScalarType(); 164019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The type of data as saved in memory. 164119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT MemSclVT = StVT.getScalarType(); 164219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 164319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool RegScalarLegal = TLI.isTypeLegal(RegSclVT); 164419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool MemScalarLegal = TLI.isTypeLegal(MemSclVT); 164519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 164619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We need to expand this store. If the register element type 164719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // is legal then we can scalarize the vector and use 164819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // truncating stores. 164919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (RegScalarLegal) { 165019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Cast floats into integers 165119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned ScalarSize = MemSclVT.getSizeInBits(); 165219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT EltVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize); 165319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 165419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Round odd types to the next pow of two. 165519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!isPowerOf2_32(ScalarSize)) 165619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ScalarSize = NextPowerOf2(ScalarSize); 165719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 165819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Store Stride in bytes 165919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Stride = ScalarSize/8; 166019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Extract each of the elements from the original vector 166119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // and save them into memory individually. 166219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> Stores; 166319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned Idx = 0; Idx < NumElem; Idx++) { 166419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 166519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RegSclVT, Tmp3, DAG.getIntPtrConstant(Idx)); 166619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 166719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 166819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(Stride)); 166919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 167019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This scalar TruncStore may be illegal, but we lehalize it 167119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // later. 167219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Store = DAG.getTruncStore(Tmp1, dl, Ex, Tmp2, 167319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo().getWithOffset(Idx*Stride), MemSclVT, 167419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isVolatile, isNonTemporal, Alignment); 167519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 167619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Stores.push_back(Store); 167719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 167819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 167919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 168019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman &Stores[0], Stores.size()); 168119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 168219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 168319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 168419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The scalar register type is illegal. 168519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // For example saving <2 x i64> -> <2 x i32> on a x86. 168619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // In here we bitcast the value into a vector of smaller parts and 168719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // save it using smaller scalars. 168819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!RegScalarLegal && MemScalarLegal) { 168919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Store Stride in bytes 169019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Stride = MemSclVT.getSizeInBits()/8; 169119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 169219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned SizeRatio = 169319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (RegSclVT.getSizeInBits() / MemSclVT.getSizeInBits()); 169419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 169519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT CastValueVT = EVT::getVectorVT(*DAG.getContext(), 169619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MemSclVT, 169719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SizeRatio * NumElem); 169819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 169919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Cast the wide elem vector to wider vec with smaller elem type. 170019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Example <2 x i64> -> <4 x i32> 170119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp3 = DAG.getNode(ISD::BITCAST, dl, CastValueVT, Tmp3); 170219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 170319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVector<SDValue, 8> Stores; 170419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned Idx=0; Idx < NumElem * SizeRatio; Idx++) { 170519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Extract the Ith element. 170619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 170719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman NarrowScalarVT, Tmp3, DAG.getIntPtrConstant(Idx)); 170819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Bump pointer. 170919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 171019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(Stride)); 171119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 171219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Store if, this element is: 171319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // - First element on big endian, or 171419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // - Last element on little endian 171519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (( TLI.isBigEndian() && (Idx % SizeRatio == 0)) || 171619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ((!TLI.isBigEndian() && (Idx % SizeRatio == SizeRatio-1)))) { 171719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2, 171819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ST->getPointerInfo().getWithOffset(Idx*Stride), 171919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isVolatile, isNonTemporal, Alignment); 172019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Stores.push_back(Store); 172119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 172219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 172319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 172419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman &Stores[0], Stores.size()); 172519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 172619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 172719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 172819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(false && "Unable to legalize the vector trunc store!"); 172919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman }// is vector 173019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 173119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 1732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // TRUNCSTORE:i16 i32 -> STORE i16 173319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(TLI.isTypeLegal(StVT) && "Do not know how to expand this store!"); 1734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3); 173519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 173619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman isVolatile, isNonTemporal, Alignment); 1737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Result.getValueType() == Op.getValueType() && 1745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Bad legalization!"); 1746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Make sure that the generated code is itself legal. 1748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Result != Op) 1749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = LegalizeOp(Result); 1750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Note that LegalizeOp may be reentered even from single-use nodes, which 1752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // means that we always must cache transformed nodes. 1753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AddLegalizedOperand(Op, Result); 1754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result; 1755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) { 1758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Vec = Op.getOperand(0); 1759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Idx = Op.getOperand(1); 1760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Op.getDebugLoc(); 1761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the value to a temporary stack slot, then LOAD the returned part. 1762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); 176319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 176419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), false, false, 0); 1765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add the offset to the index. 1767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EltSize = 1768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Vec.getValueType().getVectorElementType().getSizeInBits()/8; 1769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx, 1770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(EltSize, Idx.getValueType())); 1771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Idx.getValueType().bitsGT(TLI.getPointerTy())) 1773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx); 1774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); 1776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr); 1778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op.getValueType().isVector()) 178019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr,MachinePointerInfo(), 1781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 178219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getExtLoad(ISD::EXTLOAD, dl, Op.getValueType(), Ch, StackPtr, 178319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), 178419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vec.getValueType().getVectorElementType(), 178519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 178619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 178719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 178819bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue SelectionDAGLegalize::ExpandInsertToVectorThroughStack(SDValue Op) { 178919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Op.getValueType().isVector() && "Non-vector insert subvector!"); 179019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 179119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Vec = Op.getOperand(0); 179219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Part = Op.getOperand(1); 179319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Idx = Op.getOperand(2); 179419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = Op.getDebugLoc(); 179519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 179619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Store the value to a temporary stack slot, then LOAD the returned part. 179719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 179819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); 179919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman int FI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); 180019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(FI); 180119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 180219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // First store the whole vector. 180319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo, 180419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 180519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 180619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Then store the inserted part. 180719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 180819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Add the offset to the index. 180919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned EltSize = 181019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Vec.getValueType().getVectorElementType().getSizeInBits()/8; 181119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 181219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx, 181319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(EltSize, Idx.getValueType())); 181419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 181519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (Idx.getValueType().bitsGT(TLI.getPointerTy())) 181619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx); 1817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 181819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); 181919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 182019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue SubStackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, 182119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman StackPtr); 182219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 182319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Store the subvector. 182419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Ch = DAG.getStore(DAG.getEntryNode(), dl, Part, SubStackPtr, 182519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), false, false, 0); 182619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 182719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Finally, load the updated vector. 182819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, PtrInfo, 182919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 1830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) { 1833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We can't handle this case efficiently. Allocate a sufficiently 1834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // aligned object on the stack, store each element into it, then load 1835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the result as a vector. 1836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create the stack frame object. 1837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 1838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EltVT = VT.getVectorElementType(); 1839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 1840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue FIPtr = DAG.CreateStackTemporary(VT); 1841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex(); 184219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(FI); 1843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit a store of each element to the stack slot. 1845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Stores; 1846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned TypeByteSize = EltVT.getSizeInBits() / 8; 1847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store (in the right endianness) the elements to memory. 1848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 1849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Ignore undef elements. 1850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue; 1851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Offset = TypeByteSize*i; 1853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Idx = DAG.getConstant(Offset, FIPtr.getValueType()); 1855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx); 1856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the destination vector element type is narrower than the source 1858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // element type, only store the bits necessary. 1859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (EltVT.bitsLT(Node->getOperand(i).getValueType().getScalarType())) { 1860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl, 186119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(i), Idx, 186219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PtrInfo.getWithOffset(Offset), 1863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EltVT, false, false, 0)); 1864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else 1865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, 186619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(i), Idx, 186719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PtrInfo.getWithOffset(Offset), 1868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0)); 1869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue StoreChain; 1872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Stores.empty()) // Not all undef elements? 1873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StoreChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman &Stores[0], Stores.size()); 1875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 1876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StoreChain = DAG.getEntryNode(); 1877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Result is a load from the stack slot. 187919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getLoad(VT, dl, StoreChain, FIPtr, PtrInfo, false, false, 0); 1880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) { 1883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 1884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1 = Node->getOperand(0); 1885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp2 = Node->getOperand(1); 1886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the sign bit of the RHS. First obtain a value that has the same 1888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // sign as the sign bit, i.e. negative if and only if the sign bit is 1. 1889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SignBit; 1890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT FloatVT = Tmp2.getValueType(); 1891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT IVT = EVT::getIntegerVT(*DAG.getContext(), FloatVT.getSizeInBits()); 189219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TLI.isTypeLegal(IVT)) { 1893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Convert to an integer with the same sign bit. 189419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SignBit = DAG.getNode(ISD::BITCAST, dl, IVT, Tmp2); 1895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 1896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the float to memory, then load the sign part out as an integer. 1897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT LoadTy = TLI.getPointerTy(); 1898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // First create a temporary that is aligned for both the load and store. 1899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue StackPtr = DAG.CreateStackTemporary(FloatVT, LoadTy); 1900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Then store the float to it. 1901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ch = 190219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StackPtr, MachinePointerInfo(), 1903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 1904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isBigEndian()) { 1905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(FloatVT.isByteSized() && "Unsupported floating point type!"); 1906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load out a legal integer with the same sign bit as the float. 190719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SignBit = DAG.getLoad(LoadTy, dl, Ch, StackPtr, MachinePointerInfo(), 190819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 1909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { // Little endian 1910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoadPtr = StackPtr; 1911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The float may be wider than the integer we are going to load. Advance 1912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the pointer so that the loaded integer will contain the sign bit. 1913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Strides = (FloatVT.getSizeInBits()-1)/LoadTy.getSizeInBits(); 1914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ByteOffset = (Strides * LoadTy.getSizeInBits()) / 8; 1915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoadPtr = DAG.getNode(ISD::ADD, dl, LoadPtr.getValueType(), 1916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LoadPtr, DAG.getIntPtrConstant(ByteOffset)); 1917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load a legal integer containing the sign bit. 191819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SignBit = DAG.getLoad(LoadTy, dl, Ch, LoadPtr, MachinePointerInfo(), 191919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 1920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Move the sign bit to the top bit of the loaded integer. 1921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned BitShift = LoadTy.getSizeInBits() - 1922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (FloatVT.getSizeInBits() - 8 * ByteOffset); 1923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(BitShift < LoadTy.getSizeInBits() && "Pointer advanced wrong?"); 1924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (BitShift) 1925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SignBit = DAG.getNode(ISD::SHL, dl, LoadTy, SignBit, 192619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(BitShift, 192719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(SignBit.getValueType()))); 1928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 1930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Now get the sign bit proper, by seeing whether the value is negative. 1931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SignBit = DAG.getSetCC(dl, TLI.getSetCCResultType(SignBit.getValueType()), 1932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SignBit, DAG.getConstant(0, SignBit.getValueType()), 1933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETLT); 1934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the absolute value of the result. 1935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue AbsVal = DAG.getNode(ISD::FABS, dl, Tmp1.getValueType(), Tmp1); 1936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Select between the nabs and abs value based on the sign bit of 1937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the input. 1938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SELECT, dl, AbsVal.getValueType(), SignBit, 1939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::FNEG, dl, AbsVal.getValueType(), AbsVal), 1940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman AbsVal); 1941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(SDNode* Node, 1944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<SDValue> &Results) { 1945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore(); 1946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and" 1947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman " not tell us which reg is the stack pointer!"); 1948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 1949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 1950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1 = SDValue(Node, 0); 1951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp2 = SDValue(Node, 1); 1952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp3 = Node->getOperand(2); 1953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Chain = Tmp1.getOperand(0); 1954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Chain the dynamic stack allocation so that it doesn't modify the stack 1956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // pointer when other instructions are using the stack. 1957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true)); 1958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Size = Tmp2.getOperand(1); 1960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT); 1961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = SP.getValue(1); 1962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue(); 196319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned StackAlign = TM.getFrameLowering()->getStackAlignment(); 1964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Align > StackAlign) 1965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SP = DAG.getNode(ISD::AND, dl, VT, SP, 1966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(-(uint64_t)Align, VT)); 1967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value 1968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1); // Output chain 1969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true), 1971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(0, true), SDValue()); 1972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 1974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp2); 1975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 1976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 1977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// LegalizeSetCCCondCode - Legalize a SETCC with given LHS and RHS and 1978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// condition code CC on the current target. This routine expands SETCC with 1979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// illegal condition code into AND / OR of multiple SETCC values. 1980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid SelectionDAGLegalize::LegalizeSetCCCondCode(EVT VT, 1981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &LHS, SDValue &RHS, 1982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue &CC, 1983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 1984894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpVT = LHS.getValueType(); 1985894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get(); 1986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (TLI.getCondCodeAction(CCCode, OpVT)) { 1987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "Unknown condition code action!"); 1988894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Legal: 1989894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Nothing to do. 1990894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 1991894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case TargetLowering::Expand: { 1992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID; 1993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = 0; 1994894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (CCCode) { 1995894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "Don't know how to expand this condition!"); 1996894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETO; Opc = ISD::AND; break; 1997894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOGT: CC1 = ISD::SETGT; CC2 = ISD::SETO; Opc = ISD::AND; break; 1998894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOGE: CC1 = ISD::SETGE; CC2 = ISD::SETO; Opc = ISD::AND; break; 1999894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOLT: CC1 = ISD::SETLT; CC2 = ISD::SETO; Opc = ISD::AND; break; 2000894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETOLE: CC1 = ISD::SETLE; CC2 = ISD::SETO; Opc = ISD::AND; break; 2001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETONE: CC1 = ISD::SETNE; CC2 = ISD::SETO; Opc = ISD::AND; break; 2002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2003894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUGT: CC1 = ISD::SETGT; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUGE: CC1 = ISD::SETGE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETULT: CC1 = ISD::SETLT; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETULE: CC1 = ISD::SETLE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2007894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETUNE: CC1 = ISD::SETNE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2008894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: Implement more expansions. 2009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1); 2012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2); 2013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS = DAG.getNode(Opc, dl, VT, SetCC1, SetCC2); 2014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RHS = SDValue(); 2015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CC = SDValue(); 2016894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2017894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2018894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2019894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2020894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2021894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// EmitStackConvert - Emit a store/load combination to the stack. This stores 2022894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// SrcOp to a stack slot of type SlotVT, truncating it if needed. It then does 2023894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// a load from the stack slot to DestVT, extending it if needed. 2024894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// The resultant code need not be legal. 2025894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, 2026894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT SlotVT, 2027894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT DestVT, 2028894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 2029894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create the stack frame object. 2030894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SrcAlign = 2031894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getTargetData()->getPrefTypeAlignment(SrcOp.getValueType(). 2032894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getTypeForEVT(*DAG.getContext())); 2033894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign); 2034894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2035894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(FIPtr); 2036894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SPFI = StackPtrFI->getIndex(); 203719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(SPFI); 2038894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2039894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SrcSize = SrcOp.getValueType().getSizeInBits(); 2040894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SlotSize = SlotVT.getSizeInBits(); 2041894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DestSize = DestVT.getSizeInBits(); 204219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *DestType = DestVT.getTypeForEVT(*DAG.getContext()); 2043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DestAlign = TLI.getTargetData()->getPrefTypeAlignment(DestType); 2044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Emit a store to the stack slot. Use a truncstore if the input value is 2046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // later than DestVT. 2047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Store; 2048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SrcSize > SlotSize) 2050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, 205119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PtrInfo, SlotVT, false, false, SrcAlign); 2052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else { 2053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(SrcSize == SlotSize && "Invalid store"); 2054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, 205519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PtrInfo, false, false, SrcAlign); 2056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Result is a load from the stack slot. 2059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SlotSize == DestSize) 206019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getLoad(DestVT, dl, Store, FIPtr, PtrInfo, 206119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, DestAlign); 2062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(SlotSize < DestSize && "Unknown extension!"); 206419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, 206519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman PtrInfo, SlotVT, false, false, DestAlign); 2066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { 2069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 2070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Create a vector sized/aligned stack slot, store the value to element #0, 2071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // then load the whole vector back out. 2072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue StackPtr = DAG.CreateStackTemporary(Node->getValueType(0)); 2073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr); 2075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int SPFI = StackPtrFI->getIndex(); 2076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), dl, Node->getOperand(0), 2078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman StackPtr, 207919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getFixedStack(SPFI), 2080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getValueType(0).getVectorElementType(), 2081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 2082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr, 208319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getFixedStack(SPFI), 2084894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 2085894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandBUILD_VECTOR - Expand a BUILD_VECTOR node on targets that don't 2089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// support the operation, but do support the resultant vector type. 2090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { 2091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumElems = Node->getNumOperands(); 2092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Value1, Value2; 2093894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 2094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 2095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpVT = Node->getOperand(0).getValueType(); 2096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EltVT = VT.getVectorElementType(); 2097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the only non-undef value is the low element, turn this into a 2099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SCALAR_TO_VECTOR node. If this is { X, X, X, X }, determine X. 2100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isOnlyLowElement = true; 2101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool MoreThanTwoValues = false; 2102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isConstant = true; 2103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < NumElems; ++i) { 2104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue V = Node->getOperand(i); 2105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (V.getOpcode() == ISD::UNDEF) 2106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 2107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (i > 0) 2108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isOnlyLowElement = false; 2109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V)) 2110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isConstant = false; 2111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Value1.getNode()) { 2113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Value1 = V; 2114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (!Value2.getNode()) { 2115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (V != Value1) 2116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Value2 = V; 2117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (V != Value1 && V != Value2) { 2118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MoreThanTwoValues = true; 2119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!Value1.getNode()) 2123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getUNDEF(VT); 2124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isOnlyLowElement) 2126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Node->getOperand(0)); 2127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If all elements are constants, create a load from the constant pool. 2129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isConstant) { 2130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::vector<Constant*> CV; 2131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = NumElems; i != e; ++i) { 2132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (ConstantFPSDNode *V = 2133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) { 2134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CV.push_back(const_cast<ConstantFP *>(V->getConstantFPValue())); 2135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (ConstantSDNode *V = 2136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dyn_cast<ConstantSDNode>(Node->getOperand(i))) { 2137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpVT==EltVT) 2138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue())); 2139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else { 2140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If OpVT and EltVT don't match, EltVT is not legal and the 2141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // element values have been promoted/truncated earlier. Undo this; 2142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // we don't want a v16i8 to become a v16i32 for example. 2143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const ConstantInt *CI = V->getConstantIntValue(); 2144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CV.push_back(ConstantInt::get(EltVT.getTypeForEVT(*DAG.getContext()), 2145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CI->getZExtValue())); 2146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(Node->getOperand(i).getOpcode() == ISD::UNDEF); 214919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *OpNTy = EltVT.getTypeForEVT(*DAG.getContext()); 2150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CV.push_back(UndefValue::get(OpNTy)); 2151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Constant *CP = ConstantVector::get(CV); 2154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy()); 2155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 2156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx, 215719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getConstantPool(), 2158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, Alignment); 2159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!MoreThanTwoValues) { 2162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<int, 8> ShuffleVec(NumElems, -1); 2163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < NumElems; ++i) { 2164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue V = Node->getOperand(i); 2165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (V.getOpcode() == ISD::UNDEF) 2166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 2167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShuffleVec[i] = V == Value1 ? 0 : NumElems; 2168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isShuffleMaskLegal(ShuffleVec, Node->getValueType(0))) { 2170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the splatted value into the low element of a vector register. 2171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Vec1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value1); 2172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Vec2; 2173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Value2.getNode()) 2174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Vec2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value2); 2175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 2176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Vec2 = DAG.getUNDEF(VT); 2177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Return shuffle(LowValVec, undef, <0,0,0,0>) 2179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec.data()); 2180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, we can't handle this case efficiently. 2184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ExpandVectorBuildThroughStack(Node); 2185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// ExpandLibCall - Expand a node into a call to a libcall. If the result value 2188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// does not fit into a register, return the lo part and set the hi part to the 2189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// by-reg argument. If it does fit into a single register, return the result 2190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// and leave the Hi part unset. 2191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, 2192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned) { 2193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!IsLegalizingCall && "Cannot overlap legalization of calls!"); 2194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The input chain to this libcall is the entry node of the function. 2195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalizing the call will automatically add the previous call to the 2196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // dependence. 2197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InChain = DAG.getEntryNode(); 2198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::ArgListTy Args; 2200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::ArgListEntry Entry; 2201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 2202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ArgVT = Node->getOperand(i).getValueType(); 220319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 2204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; 2205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.isSExt = isSigned; 2206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.isZExt = !isSigned; 2207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Args.push_back(Entry); 2208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 2210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy()); 2211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Splice the libcall in wherever FindInputOutputChains tells us to. 221319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); 221419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 221519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // isTailCall may be true since the callee does not reference caller stack 221619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // frame. Check if it's in the right position. 221719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isTailCall = isInTailCallPosition(DAG, Node, TLI); 2218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::pair<SDValue, SDValue> CallInfo = 2219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 222019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 0, TLI.getLibcallCallingConv(LC), isTailCall, 2221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*isReturnValueUsed=*/true, 2222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee, Args, DAG, Node->getDebugLoc()); 2223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 222419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!CallInfo.second.getNode()) 222519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // It's a tailcall, return the chain (which is the DAG root). 222619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getRoot(); 222719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 222819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Legalize the call sequence, starting with the chain. This will advance 222919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that 223019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // was added by LowerCallTo (guaranteeing proper serialization of calls). 223119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LegalizeOp(CallInfo.second); 223219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return CallInfo.first; 223319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 223419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 223519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ExpandLibCall - Generate a libcall taking the given operands as arguments 223619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// and returning a result of type RetVT. 223719bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, EVT RetVT, 223819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const SDValue *Ops, unsigned NumOps, 223919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isSigned, DebugLoc dl) { 224019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::ArgListTy Args; 224119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Args.reserve(NumOps); 224219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 224319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::ArgListEntry Entry; 224419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0; i != NumOps; ++i) { 224519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Node = Ops[i]; 224619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); 224719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isSExt = isSigned; 224819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isZExt = !isSigned; 224919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Args.push_back(Entry); 225019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 225119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 225219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getPointerTy()); 225319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 225419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); 225519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<SDValue,SDValue> CallInfo = 225619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, 225719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, 0, TLI.getLibcallCallingConv(LC), false, 225819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /*isReturnValueUsed=*/true, 225919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Callee, Args, DAG, dl); 226019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalize the call sequence, starting with the chain. This will advance 2262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that 2263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // was added by LowerCallTo (guaranteeing proper serialization of calls). 2264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeOp(CallInfo.second); 226519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CallInfo.first; 2267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// ExpandChainLibCall - Expand a node into a call to a libcall. Similar to 2270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// ExpandLibCall except that the first operand is the in-chain. 2271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstd::pair<SDValue, SDValue> 2272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC, 2273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDNode *Node, 2274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned) { 2275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!IsLegalizingCall && "Cannot overlap legalization of calls!"); 2276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InChain = Node->getOperand(0); 2277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::ArgListTy Args; 2279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::ArgListEntry Entry; 2280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) { 2281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ArgVT = Node->getOperand(i).getValueType(); 228219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 2283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.Node = Node->getOperand(i); 2284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.Ty = ArgTy; 2285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.isSExt = isSigned; 2286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Entry.isZExt = !isSigned; 2287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Args.push_back(Entry); 2288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 2290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy()); 2291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Splice the libcall in wherever FindInputOutputChains tells us to. 229319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); 2294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::pair<SDValue, SDValue> CallInfo = 2295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 229619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, 2297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*isReturnValueUsed=*/true, 2298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Callee, Args, DAG, Node->getDebugLoc()); 2299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Legalize the call sequence, starting with the chain. This will advance 2301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that 2302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // was added by LowerCallTo (guaranteeing proper serialization of calls). 2303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeOp(CallInfo.second); 2304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return CallInfo; 2305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node, 2308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_F32, 2309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_F64, 2310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_F80, 2311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_PPCF128) { 2312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC; 2313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 2314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "Unexpected request for libcall!"); 2315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f32: LC = Call_F32; break; 2316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f64: LC = Call_F64; break; 2317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::f80: LC = Call_F80; break; 2318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::ppcf128: LC = Call_PPCF128; break; 2319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ExpandLibCall(LC, Node, false); 2321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned, 2324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I8, 2325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I16, 2326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I32, 2327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I64, 2328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall Call_I128) { 2329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC; 2330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 2331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "Unexpected request for libcall!"); 2332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = Call_I8; break; 2333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = Call_I16; break; 2334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = Call_I32; break; 2335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = Call_I64; break; 2336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i128: LC = Call_I128; break; 2337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ExpandLibCall(LC, Node, isSigned); 2339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 234119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// isDivRemLibcallAvailable - Return true if divmod libcall is available. 234219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool isDivRemLibcallAvailable(SDNode *Node, bool isSigned, 234319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetLowering &TLI) { 234419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RTLIB::Libcall LC; 234519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 234619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: assert(0 && "Unexpected request for libcall!"); 234719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break; 234819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break; 234919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; 235019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break; 235119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; break; 235219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 235319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 235419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return TLI.getLibcallName(LC) != 0; 235519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 235619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 235719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// UseDivRem - Only issue divrem libcall if both quotient and remainder are 235819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// needed. 235919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic bool UseDivRem(SDNode *Node, bool isSigned, bool isDIV) { 236019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned OtherOpcode = 0; 236119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (isSigned) 236219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OtherOpcode = isDIV ? ISD::SREM : ISD::SDIV; 236319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 236419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman OtherOpcode = isDIV ? ISD::UREM : ISD::UDIV; 236519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 236619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op0 = Node->getOperand(0); 236719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Op1 = Node->getOperand(1); 236819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (SDNode::use_iterator UI = Op0.getNode()->use_begin(), 236919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman UE = Op0.getNode()->use_end(); UI != UE; ++UI) { 237019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDNode *User = *UI; 237119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (User == Node) 237219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman continue; 237319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (User->getOpcode() == OtherOpcode && 237419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman User->getOperand(0) == Op0 && 237519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman User->getOperand(1) == Op1) 237619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return true; 237719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 237819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return false; 237919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 238019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 238119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// ExpandDivRemLibCall - Issue libcalls to __{u}divmod to compute div / rem 238219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// pairs. 238319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid 238419bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanSelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node, 238519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SmallVectorImpl<SDValue> &Results) { 238619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Opcode = Node->getOpcode(); 238719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isSigned = Opcode == ISD::SDIVREM; 238819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 238919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RTLIB::Libcall LC; 239019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 239119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman default: assert(0 && "Unexpected request for libcall!"); 239219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break; 239319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break; 239419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; 239519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break; 239619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; break; 239719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 239819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 239919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The input chain to this libcall is the entry node of the function. 240019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Legalizing the call will automatically add the previous call to the 240119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // dependence. 240219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue InChain = DAG.getEntryNode(); 240319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 240419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT RetVT = Node->getValueType(0); 240519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); 240619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 240719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::ArgListTy Args; 240819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TargetLowering::ArgListEntry Entry; 240919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 241019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ArgVT = Node->getOperand(i).getValueType(); 241119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 241219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; 241319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isSExt = isSigned; 241419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isZExt = !isSigned; 241519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Args.push_back(Entry); 241619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 241719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 241819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Also pass the return address of the remainder. 241919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue FIPtr = DAG.CreateStackTemporary(RetVT); 242019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Node = FIPtr; 242119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.Ty = RetTy->getPointerTo(); 242219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isSExt = isSigned; 242319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Entry.isZExt = !isSigned; 242419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Args.push_back(Entry); 242519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 242619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 242719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getPointerTy()); 242819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 242919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Splice the libcall in wherever FindInputOutputChains tells us to. 243019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DebugLoc dl = Node->getDebugLoc(); 243119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman std::pair<SDValue, SDValue> CallInfo = 243219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 243319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, 243419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /*isReturnValueUsed=*/true, Callee, Args, DAG, dl); 243519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 243619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Legalize the call sequence, starting with the chain. This will advance 243719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that 243819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // was added by LowerCallTo (guaranteeing proper serialization of calls). 243919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LegalizeOp(CallInfo.second); 244019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 244119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Remainder is loaded back from the stack frame. 244219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Rem = DAG.getLoad(RetVT, dl, LastCALLSEQ_END, FIPtr, 244319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), false, false, 0); 244419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(CallInfo.first); 244519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(Rem); 244619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 244719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandLegalINT_TO_FP - This function is responsible for legalizing a 2449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// INT_TO_FP operation of the specified operand when the target requests that 2450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// we expand it. At this point, we know that the result and operand types are 2451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// legal for the target. 2452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, 2453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0, 2454894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT DestVT, 2455894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 2456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getValueType() == MVT::i32) { 2457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // simple 32-bit [signed|unsigned] integer to float/double expansion 2458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the stack frame index of a 8 byte buffer. 2460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue StackSlot = DAG.CreateStackTemporary(MVT::f64); 2461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2462894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // word offset constant for Hi/Lo address computation 2463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy()); 2464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // set up Hi and Lo (into buffer) address based on endian 2465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Hi = StackSlot; 2466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo = DAG.getNode(ISD::ADD, dl, 2467894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy(), StackSlot, WordOff); 2468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isLittleEndian()) 2469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::swap(Hi, Lo); 2470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // if signed map to unsigned space 2472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Op0Mapped; 2473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isSigned) { 2474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // constant used to invert sign bit (signed to unsigned mapping) 2475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SignBit = DAG.getConstant(0x80000000u, MVT::i32); 2476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0Mapped = DAG.getNode(ISD::XOR, dl, MVT::i32, Op0, SignBit); 2477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 2478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0Mapped = Op0; 2479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // store the lo of the constructed double - based on integer input 2481894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, 248219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op0Mapped, Lo, MachinePointerInfo(), 2483894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 2484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // initial hi portion of constructed double 2485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue InitialHi = DAG.getConstant(0x43300000u, MVT::i32); 2486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // store the hi of the constructed double - biased exponent 248719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Store2 = DAG.getStore(Store1, dl, InitialHi, Hi, 248819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), 248919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 2490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // load the constructed double 249119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, 249219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(), false, false, 0); 2493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FP constant to bias correct the final result 2494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Bias = DAG.getConstantFP(isSigned ? 2495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitsToDouble(0x4330000080000000ULL) : 2496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BitsToDouble(0x4330000000000000ULL), 2497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::f64); 2498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // subtract the bias 2499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::f64, Load, Bias); 2500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // final result 2501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Result; 2502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // handle final rounding 2503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DestVT == MVT::f64) { 2504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // do nothing 2505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = Sub; 2506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (DestVT.bitsLT(MVT::f64)) { 2507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = DAG.getNode(ISD::FP_ROUND, dl, DestVT, Sub, 2508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(0)); 2509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (DestVT.bitsGT(MVT::f64)) { 2510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Result = DAG.getNode(ISD::FP_EXTEND, dl, DestVT, Sub); 2511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2512894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Result; 2513894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2514894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet"); 2515894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Code below here assumes !isSigned without checking again. 2516894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Implementation of unsigned i64 to f64 following the algorithm in 2518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // __floatundidf in compiler_rt. This implementation has the advantage 2519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // of performing rounding correctly, both in the default rounding mode 2520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // and in all alternate rounding modes. 2521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // TODO: Generalize this for use with other types. 2522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getValueType() == MVT::i64 && DestVT == MVT::f64) { 2523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TwoP52 = 2524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(UINT64_C(0x4330000000000000), MVT::i64); 2525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TwoP84PlusTwoP52 = 2526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstantFP(BitsToDouble(UINT64_C(0x4530000000100000)), MVT::f64); 2527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TwoP84 = 2528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(UINT64_C(0x4530000000000000), MVT::i64); 2529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo = DAG.getZeroExtendInReg(Op0, dl, MVT::i32); 2531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i64, Op0, 2532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(32, MVT::i64)); 2533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LoOr = DAG.getNode(ISD::OR, dl, MVT::i64, Lo, TwoP52); 2534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiOr = DAG.getNode(ISD::OR, dl, MVT::i64, Hi, TwoP84); 253519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue LoFlt = DAG.getNode(ISD::BITCAST, dl, MVT::f64, LoOr); 253619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue HiFlt = DAG.getNode(ISD::BITCAST, dl, MVT::f64, HiOr); 2537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue HiSub = DAG.getNode(ISD::FSUB, dl, MVT::f64, HiFlt, 2538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TwoP84PlusTwoP52); 2539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::FADD, dl, MVT::f64, LoFlt, HiSub); 2540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 254219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Implementation of unsigned i64 to f32. 2543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // TODO: Generalize this for use with other types. 2544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Op0.getValueType() == MVT::i64 && DestVT == MVT::f32) { 254519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // For unsigned conversions, convert them to signed conversions using the 254619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // algorithm from the x86_64 __floatundidf in compiler_rt. 254719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!isSigned) { 254819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Fast = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, Op0); 254919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 255019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue ShiftConst = 255119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(1, TLI.getShiftAmountTy(Op0.getValueType())); 255219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Shr = DAG.getNode(ISD::SRL, dl, MVT::i64, Op0, ShiftConst); 255319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue AndConst = DAG.getConstant(1, MVT::i64); 255419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue And = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, AndConst); 255519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i64, And, Shr); 255619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 255719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue SignCvt = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, Or); 255819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Slow = DAG.getNode(ISD::FADD, dl, MVT::f32, SignCvt, SignCvt); 255919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 256019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // TODO: This really should be implemented using a branch rather than a 256119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // select. We happen to get lucky and machinesink does the right 256219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // thing most of the time. This would be a good candidate for a 256319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman //pseudo-op, or, even better, for whole-function isel. 256419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue SignBitTest = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 256519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op0, DAG.getConstant(0, MVT::i64), ISD::SETLT); 256619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return DAG.getNode(ISD::SELECT, dl, MVT::f32, SignBitTest, Slow, Fast); 256719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 256819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 256919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Otherwise, implement the fully general conversion. 2570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue And = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, 2572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(UINT64_C(0xfffffffffffff800), MVT::i64)); 2573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i64, And, 2574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(UINT64_C(0x800), MVT::i64)); 2575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue And2 = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, 2576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(UINT64_C(0x7ff), MVT::i64)); 2577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ne = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 2578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman And2, DAG.getConstant(UINT64_C(0), MVT::i64), ISD::SETNE); 2579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sel = DAG.getNode(ISD::SELECT, dl, MVT::i64, Ne, Or, Op0); 2580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Ge = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 2581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0, DAG.getConstant(UINT64_C(0x0020000000000000), MVT::i64), 258219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ISD::SETUGE); 2583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sel2 = DAG.getNode(ISD::SELECT, dl, MVT::i64, Ge, Sel, Op0); 258419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT SHVT = TLI.getShiftAmountTy(Sel2.getValueType()); 2585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sh = DAG.getNode(ISD::SRL, dl, MVT::i64, Sel2, 2587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(32, SHVT)); 2588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Sh); 2589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Fcvt = DAG.getNode(ISD::UINT_TO_FP, dl, MVT::f64, Trunc); 2590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TwoP32 = 2591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstantFP(BitsToDouble(UINT64_C(0x41f0000000000000)), MVT::f64); 2592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Fmul = DAG.getNode(ISD::FMUL, dl, MVT::f64, TwoP32, Fcvt); 2593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Lo = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Sel2); 2594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Fcvt2 = DAG.getNode(ISD::UINT_TO_FP, dl, MVT::f64, Lo); 2595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Fadd = DAG.getNode(ISD::FADD, dl, MVT::f64, Fmul, Fcvt2); 2596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, Fadd, 2597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(0)); 2598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, dl, DestVT, Op0); 2601894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SignSet = DAG.getSetCC(dl, TLI.getSetCCResultType(Op0.getValueType()), 2603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op0, DAG.getConstant(0, Op0.getValueType()), 2604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETLT); 2605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4); 2606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CstOffset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), 2607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SignSet, Four, Zero); 2608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the sign bit of the integer is set, the large number will be treated 2610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // as a negative number. To counteract this, the dynamic code adds an 2611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // offset depending on the data type. 2612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman uint64_t FF; 2613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Op0.getValueType().getSimpleVT().SimpleTy) { 2614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "Unsupported integer type!"); 2615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8 : FF = 0x43800000ULL; break; // 2^8 (as a float) 2616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: FF = 0x47800000ULL; break; // 2^16 (as a float) 2617894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: FF = 0x4F800000ULL; break; // 2^32 (as a float) 2618894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: FF = 0x5F800000ULL; break; // 2^64 (as a float) 2619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isLittleEndian()) FF <<= 32; 2621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Constant *FudgeFactor = ConstantInt::get( 2622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Type::getInt64Ty(*DAG.getContext()), FF); 2623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); 2625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 2626894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset); 2627894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Alignment = std::min(Alignment, 4u); 2628894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue FudgeInReg; 2629894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (DestVT == MVT::f32) 2630894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx, 263119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getConstantPool(), 2632894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, Alignment); 2633894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else { 2634894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FudgeInReg = 263519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, 2636894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getEntryNode(), CPIdx, 263719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getConstantPool(), 2638894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT::f32, false, false, Alignment)); 2639894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2640894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2641894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg); 2642894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2643894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2644894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a 2645894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// *INT_TO_FP operation of the specified operand when the target requests that 2646894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// we promote it. At this point, we know that the result and operand types are 2647894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP 2648894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// operation that takes a larger input. 2649894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, 2650894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT DestVT, 2651894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned, 2652894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 2653894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // First step, figure out the appropriate *INT_TO_FP operation to use. 2654894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NewInTy = LegalOp.getValueType(); 2655894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2656894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned OpToUse = 0; 2657894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2658894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Scan for the appropriate larger type to use. 2659894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (1) { 2660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewInTy = (MVT::SimpleValueType)(NewInTy.getSimpleVT().SimpleTy+1); 2661894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NewInTy.isInteger() && "Ran out of possibilities!"); 2662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2663894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the target supports SINT_TO_FP of this type, use it. 2664894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, NewInTy)) { 2665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpToUse = ISD::SINT_TO_FP; 2666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isSigned) continue; 2669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the target supports UINT_TO_FP of this type, use it. 2671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isOperationLegalOrCustom(ISD::UINT_TO_FP, NewInTy)) { 2672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpToUse = ISD::UINT_TO_FP; 2673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, try a larger type. 2677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Okay, we found the operation and type to use. Zero extend our input to the 2680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // desired type then run the operation on it. 2681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(OpToUse, dl, DestVT, 2682894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, 2683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman dl, NewInTy, LegalOp)); 2684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a 2687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// FP_TO_*INT operation of the specified operand when the target requests that 2688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// we promote it. At this point, we know that the result and operand types are 2689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT 2690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// operation that returns a larger result. 2691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, 2692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT DestVT, 2693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned, 2694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 2695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // First step, figure out the appropriate FP_TO*INT operation to use. 2696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NewOutTy = DestVT; 2697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned OpToUse = 0; 2699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Scan for the appropriate larger type to use. 2701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (1) { 2702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman NewOutTy = (MVT::SimpleValueType)(NewOutTy.getSimpleVT().SimpleTy+1); 2703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(NewOutTy.isInteger() && "Ran out of possibilities!"); 2704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewOutTy)) { 2706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpToUse = ISD::FP_TO_SINT; 2707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewOutTy)) { 2711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpToUse = ISD::FP_TO_UINT; 2712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, try a larger type. 2716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2717894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2718894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Okay, we found the operation and type to use. 2720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Operation = DAG.getNode(OpToUse, dl, NewOutTy, LegalOp); 2721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Truncate the result of the extended FP_TO_*INT operation to the desired 2723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // size. 2724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::TRUNCATE, dl, DestVT, Operation); 2725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. 2728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 2729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, DebugLoc dl) { 2730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 273119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT SHVT = TLI.getShiftAmountTy(VT); 2732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8; 2733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.getSimpleVT().SimpleTy) { 2734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "Unhandled Expand type in BSWAP!"); 2735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: 2736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 2737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 2738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2); 2739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: 2740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); 2741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 2742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 2743894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); 2744894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(0xFF0000, VT)); 2745894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(0xFF00, VT)); 2746894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); 2747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); 2748894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); 2749894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: 2750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp8 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(56, SHVT)); 2751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp7 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(40, SHVT)); 2752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp6 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); 2753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp5 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 2754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 2755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); 2756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(40, SHVT)); 2757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(56, SHVT)); 2758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp7 = DAG.getNode(ISD::AND, dl, VT, Tmp7, DAG.getConstant(255ULL<<48, VT)); 2759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp6 = DAG.getNode(ISD::AND, dl, VT, Tmp6, DAG.getConstant(255ULL<<40, VT)); 2760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp5 = DAG.getNode(ISD::AND, dl, VT, Tmp5, DAG.getConstant(255ULL<<32, VT)); 2761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = DAG.getNode(ISD::AND, dl, VT, Tmp4, DAG.getConstant(255ULL<<24, VT)); 2762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(255ULL<<16, VT)); 2763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT)); 2764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp7); 2765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp6 = DAG.getNode(ISD::OR, dl, VT, Tmp6, Tmp5); 2766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); 2767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); 2768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp6); 2769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); 2770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp4); 2771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 277419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// SplatByte - Distribute ByteVal over NumBits bits. 277519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// FIXME: Move this helper to a common place. 277619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic APInt SplatByte(unsigned NumBits, uint8_t ByteVal) { 277719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman APInt Val = APInt(NumBits, ByteVal); 277819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Shift = 8; 277919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (unsigned i = NumBits; i > 8; i >>= 1) { 278019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Val = (Val << Shift) | Val; 278119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Shift <<= 1; 278219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 278319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return Val; 278419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 278519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// ExpandBitCount - Expand the specified bitcount instruction into operations. 2787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/// 2788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, 2789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl) { 2790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Opc) { 2791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: assert(0 && "Cannot expand this yet!"); 2792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTPOP: { 2793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 279419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ShVT = TLI.getShiftAmountTy(VT); 279519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Len = VT.getSizeInBits(); 279619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 279719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(VT.isInteger() && Len <= 128 && Len % 8 == 0 && 279819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman "CTPOP not implemented for this type."); 279919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 280019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // This is the "best" algorithm from 280119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel 280219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 280319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Mask55 = DAG.getConstant(SplatByte(Len, 0x55), VT); 280419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Mask33 = DAG.getConstant(SplatByte(Len, 0x33), VT); 280519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Mask0F = DAG.getConstant(SplatByte(Len, 0x0F), VT); 280619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Mask01 = DAG.getConstant(SplatByte(Len, 0x01), VT); 280719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 280819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // v = v - ((v >> 1) & 0x55555555...) 280919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op = DAG.getNode(ISD::SUB, dl, VT, Op, 281019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::AND, dl, VT, 281119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SRL, dl, VT, Op, 281219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(1, ShVT)), 281319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Mask55)); 281419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // v = (v & 0x33333333...) + ((v >> 2) & 0x33333333...) 281519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op = DAG.getNode(ISD::ADD, dl, VT, 281619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::AND, dl, VT, Op, Mask33), 281719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::AND, dl, VT, 281819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SRL, dl, VT, Op, 281919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(2, ShVT)), 282019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Mask33)); 282119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // v = (v + (v >> 4)) & 0x0F0F0F0F... 282219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op = DAG.getNode(ISD::AND, dl, VT, 282319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::ADD, dl, VT, Op, 282419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::SRL, dl, VT, Op, 282519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(4, ShVT))), 282619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Mask0F); 282719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // v = (v * 0x01010101...) >> (Len - 8) 282819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Op = DAG.getNode(ISD::SRL, dl, VT, 282919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::MUL, dl, VT, Op, Mask01), 283019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(Len - 8, ShVT)); 283119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 2832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return Op; 2833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTLZ: { 2835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // for now, we do this: 2836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // x = x | (x >> 1); 2837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // x = x | (x >> 2); 2838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // ... 2839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // x = x | (x >>16); 2840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // x = x | (x >>32); // for 64-bit input 2841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // return popcount(~x); 2842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 2843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // but see also: http://www.hackersdelight.org/HDcode/nlz.cc 2844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 284519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ShVT = TLI.getShiftAmountTy(VT); 2846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned len = VT.getSizeInBits(); 2847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { 2848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); 2849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op = DAG.getNode(ISD::OR, dl, VT, Op, 2850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SRL, dl, VT, Op, Tmp3)); 2851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Op = DAG.getNOT(dl, Op, VT); 2853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::CTPOP, dl, VT, Op); 2854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTTZ: { 2856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // for now, we use: { return popcount(~x & (x - 1)); } 2857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // unless the target has ctlz but not ctpop, in which case we use: 2858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // { return 32 - nlz(~x & (x-1)); } 2859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // see also http://www.hackersdelight.org/HDcode/ntz.cc 2860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Op.getValueType(); 2861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp3 = DAG.getNode(ISD::AND, dl, VT, 2862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNOT(dl, Op, VT), 2863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::SUB, dl, VT, Op, 2864894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(1, VT))); 2865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If ISD::CTLZ is legal and CTPOP isn't, then do that instead. 2866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) && 2867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) 2868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::SUB, dl, VT, 2869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(VT.getSizeInBits(), VT), 2870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::CTLZ, dl, VT, Tmp3)); 2871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return DAG.getNode(ISD::CTPOP, dl, VT, Tmp3); 2872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanstd::pair <SDValue, SDValue> SelectionDAGLegalize::ExpandAtomic(SDNode *Node) { 2877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = Node->getOpcode(); 2878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT(); 2879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::Libcall LC; 2880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Opc) { 2882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: 2883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Unhandled atomic intrinsic Expand!"); 2884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2885894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_SWAP: 2886894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.SimpleTy) { 2887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 2888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break; 2889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break; 2890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break; 2891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break; 2892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_CMP_SWAP: 2895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.SimpleTy) { 2896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 2897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break; 2898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break; 2899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break; 2900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break; 2901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2903894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_ADD: 2904894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.SimpleTy) { 2905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 2906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_ADD_1; break; 2907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break; 2908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break; 2909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break; 2910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_SUB: 2913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.SimpleTy) { 2914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 2915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_SUB_1; break; 2916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break; 2917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break; 2918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break; 2919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_AND: 2922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.SimpleTy) { 2923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 2924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_AND_1; break; 2925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break; 2926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break; 2927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break; 2928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_OR: 2931894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.SimpleTy) { 2932894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 2933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_OR_1; break; 2934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break; 2935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break; 2936894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break; 2937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_XOR: 2940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.SimpleTy) { 2941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 2942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_XOR_1; break; 2943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break; 2944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break; 2945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break; 2946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_NAND: 2949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (VT.SimpleTy) { 2950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: llvm_unreachable("Unexpected value type for atomic!"); 2951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_NAND_1; break; 2952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break; 2953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break; 2954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break; 2955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 2958894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return ExpandChainLibCall(LC, Node, false); 2960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 2961894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid SelectionDAGLegalize::ExpandNode(SDNode *Node, 2963894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<SDValue> &Results) { 2964894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 2965894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1, Tmp2, Tmp3, Tmp4; 2966894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Node->getOpcode()) { 2967894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTPOP: 2968894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTLZ: 2969894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTTZ: 2970894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ExpandBitCount(Node->getOpcode(), Node->getOperand(0), dl); 2971894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 2972894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2973894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BSWAP: 2974894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandBSWAP(Node->getOperand(0), dl)); 2975894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2976894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FRAMEADDR: 2977894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::RETURNADDR: 2978894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FRAME_TO_ARGS_OFFSET: 2979894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getConstant(0, Node->getValueType(0))); 2980894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 2981894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FLT_ROUNDS_: 2982894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getConstant(1, Node->getValueType(0))); 2983894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 298419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_RETURN: 298519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_LABEL: 2986894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::PREFETCH: 2987894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VAEND: 298819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_SJLJ_LONGJMP: 298919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_SJLJ_DISPATCHSETUP: 299019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If the target didn't expand these, there's nothing to do, so just 299119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // preserve the chain and be done. 2992894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Node->getOperand(0)); 2993894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 299419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EH_SJLJ_SETJMP: 299519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // If the target didn't expand this, just return 'zero' and preserve the 299619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // chain. 299719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(DAG.getConstant(0, MVT::i32)); 299819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(Node->getOperand(0)); 299919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 300019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_FENCE: 3001894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MEMBARRIER: { 3002894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the target didn't lower this, lower it to '__sync_synchronize()' call 300319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // FIXME: handle "fence singlethread" more efficiently. 3004894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::ArgListTy Args; 3005894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::pair<SDValue, SDValue> CallResult = 3006894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.LowerCallTo(Node->getOperand(0), Type::getVoidTy(*DAG.getContext()), 300719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, false, false, 0, CallingConv::C, 300819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /*isTailCall=*/false, 3009894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*isReturnValueUsed=*/true, 3010894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getExternalSymbol("__sync_synchronize", 3011894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy()), 3012894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Args, DAG, dl); 3013894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(CallResult.second); 3014894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3015894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 301619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_LOAD: { 301719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // There is no libcall for atomic load; fake it with ATOMIC_CMP_SWAP. 301819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Zero = DAG.getConstant(0, Node->getValueType(0)); 301919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Swap = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, dl, 302019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(Node)->getMemoryVT(), 302119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(0), 302219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(1), Zero, Zero, 302319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(Node)->getMemOperand(), 302419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(Node)->getOrdering(), 302519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(Node)->getSynchScope()); 302619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(Swap.getValue(0)); 302719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(Swap.getValue(1)); 302819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 302919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 303019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::ATOMIC_STORE: { 303119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // There is no libcall for atomic store; fake it with ATOMIC_SWAP. 303219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl, 303319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(Node)->getMemoryVT(), 303419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(0), 303519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(1), Node->getOperand(2), 303619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(Node)->getMemOperand(), 303719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(Node)->getOrdering(), 303819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman cast<AtomicSDNode>(Node)->getSynchScope()); 303919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(Swap.getValue(1)); 304019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 304119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 3042894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // By default, atomic intrinsics are marked Legal and lowered. Targets 3043894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // which don't support them directly, however, may want libcalls, in which 3044894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // case they mark them Expand, and we get here. 3045894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_SWAP: 3046894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_ADD: 3047894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_SUB: 3048894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_AND: 3049894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_OR: 3050894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_XOR: 3051894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_NAND: 3052894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_MIN: 3053894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_MAX: 3054894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_UMIN: 3055894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_LOAD_UMAX: 3056894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ATOMIC_CMP_SWAP: { 3057894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::pair<SDValue, SDValue> Tmp = ExpandAtomic(Node); 3058894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp.first); 3059894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp.second); 3060894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3061894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3062894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::DYNAMIC_STACKALLOC: 3063894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExpandDYNAMIC_STACKALLOC(Node, Results); 3064894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3065894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MERGE_VALUES: 3066894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i < Node->getNumValues(); i++) 3067894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Node->getOperand(i)); 3068894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3069894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UNDEF: { 3070894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3071894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT.isInteger()) 3072894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getConstant(0, VT)); 3073894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else { 3074894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(VT.isFloatingPoint() && "Unknown value type!"); 3075894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getConstantFP(0, VT)); 3076894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3077894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3078894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3079894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::TRAP: { 3080894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this operation is not supported, lower it to 'abort()' call 3081894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TargetLowering::ArgListTy Args; 3082894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman std::pair<SDValue, SDValue> CallResult = 3083894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.LowerCallTo(Node->getOperand(0), Type::getVoidTy(*DAG.getContext()), 308419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, false, false, 0, CallingConv::C, 308519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman /*isTailCall=*/false, 3086894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /*isReturnValueUsed=*/true, 3087894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getExternalSymbol("abort", TLI.getPointerTy()), 3088894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Args, DAG, dl); 3089894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(CallResult.second); 3090894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3091894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3092894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_ROUND: 309319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::BITCAST: 3094894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = EmitStackConvert(Node->getOperand(0), Node->getValueType(0), 3095894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getValueType(0), dl); 3096894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3097894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3098894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_EXTEND: 3099894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = EmitStackConvert(Node->getOperand(0), 3100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0).getValueType(), 3101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getValueType(0), dl); 3102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SIGN_EXTEND_INREG: { 3105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: we could fall back on load/store here too for targets without 3106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SAR. However, it is doubtful that any exist. 3107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); 3108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 310919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT ShiftAmountTy = TLI.getShiftAmountTy(VT); 3110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (VT.isVector()) 3111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ShiftAmountTy = VT; 3112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned BitsDiff = VT.getScalarType().getSizeInBits() - 3113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExtraVT.getScalarType().getSizeInBits(); 3114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue ShiftCst = DAG.getConstant(BitsDiff, ShiftAmountTy); 3115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SHL, dl, Node->getValueType(0), 3116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0), ShiftCst); 3117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SRA, dl, Node->getValueType(0), Tmp1, ShiftCst); 3118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_ROUND_INREG: { 3122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // The only way we can lower this is to turn it into a TRUNCSTORE, 312319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // EXTLOAD pair, targeting a temporary location (a stack slot). 3124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // NOTE: there is a choice here between constantly creating new stack 3126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // slots and always reusing the same one. We currently always create 3127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // new ones, as reuse may inhibit scheduling. 3128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); 3129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = EmitStackConvert(Node->getOperand(0), ExtraVT, 3130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getValueType(0), dl); 3131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SINT_TO_FP: 3135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UINT_TO_FP: 3136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ExpandLegalINT_TO_FP(Node->getOpcode() == ISD::SINT_TO_FP, 3137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0), Node->getValueType(0), dl); 3138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_UINT: { 3141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue True, False; 3142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getOperand(0).getValueType(); 3143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = Node->getValueType(0); 314419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman APFloat apf(APInt::getNullValue(VT.getSizeInBits())); 3145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman APInt x = APInt::getSignBit(NVT.getSizeInBits()); 3146894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman (void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven); 3147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getConstantFP(apf, VT); 3148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), 3149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0), 3150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, ISD::SETLT); 3151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0)); 3152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, 3153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getNode(ISD::FSUB, dl, VT, 3154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0), Tmp1)); 3155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman False = DAG.getNode(ISD::XOR, dl, NVT, False, 3156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(x, NVT)); 3157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, True, False); 3158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VAARG: { 3162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 3163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = Node->getOperand(0); 3165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = Node->getOperand(1); 3166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Align = Node->getConstantOperandVal(3); 3167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 316819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue VAListLoad = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, 316919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(V), false, false, 0); 3170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue VAList = VAListLoad; 3171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Align > TLI.getMinStackArgumentAlignment()) { 3173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(((Align & (Align-1)) == 0) && "Expected Align to be a power of 2"); 3174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VAList = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, 3176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(Align - 1, 3177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy())); 3178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman VAList = DAG.getNode(ISD::AND, dl, TLI.getPointerTy(), VAList, 318019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(-(int64_t)Align, 3181894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy())); 3182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Increment the pointer, VAList, to the next vaarg 3185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, 3186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(TLI.getTargetData()-> 3187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext())), 3188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPointerTy())); 3189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Store the incremented VAList to the legalized pointer 319019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp3 = DAG.getStore(VAListLoad.getValue(1), dl, Tmp3, Tmp2, 319119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(V), false, false, 0); 3192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Load the actual argument out of the pointer VAList 319319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, MachinePointerInfo(), 3194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0)); 3195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Results[0].getValue(1)); 3196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VACOPY: { 3199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This defaults to loading a pointer from the input and storing it to the 3200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // output, returning the chain. 3201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue(); 3202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue(); 3203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getLoad(TLI.getPointerTy(), dl, Node->getOperand(0), 320419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getOperand(2), MachinePointerInfo(VS), 320519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman false, false, 0); 320619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), 320719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo(VD), false, false, 0); 3208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_VECTOR_ELT: 3212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getOperand(0).getValueType().getVectorNumElements() == 1) 3213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // This must be an access of the only element. Return it. 321419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = DAG.getNode(ISD::BITCAST, dl, Node->getValueType(0), 3215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0)); 3216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 3217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ExpandExtractFromVectorThroughStack(SDValue(Node, 0)); 3218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_SUBVECTOR: 3221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandExtractFromVectorThroughStack(SDValue(Node, 0))); 3222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 322319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::INSERT_SUBVECTOR: 322419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(ExpandInsertToVectorThroughStack(SDValue(Node, 0))); 322519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 3226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CONCAT_VECTORS: { 3227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandVectorBuildThroughStack(Node)); 3228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SCALAR_TO_VECTOR: 3231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandSCALAR_TO_VECTOR(Node)); 3232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INSERT_VECTOR_ELT: 3234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandINSERT_VECTOR_ELT(Node->getOperand(0), 3235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(1), 3236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(2), dl)); 3237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VECTOR_SHUFFLE: { 3239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<int, 8> Mask; 3240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cast<ShuffleVectorSDNode>(Node)->getMask(Mask); 3241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT EltVT = VT.getVectorElementType(); 324419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (!TLI.isTypeLegal(EltVT)) 3245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT); 3246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned NumElems = VT.getVectorNumElements(); 3247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<SDValue, 8> Ops; 3248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0; i != NumElems; ++i) { 3249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Mask[i] < 0) { 3250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.push_back(DAG.getUNDEF(EltVT)); 3251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman continue; 3252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Idx = Mask[i]; 3254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Idx < NumElems) 3255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, 3256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0), 3257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(Idx))); 3258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 3259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, 3260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(1), 3261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(Idx - NumElems))); 3262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size()); 3264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::EXTRACT_ELEMENT: { 3268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OpTy = Node->getOperand(0).getValueType(); 3269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { 3270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 1 -> Hi 3271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0), 3272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(OpTy.getSizeInBits()/2, 327319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(Node->getOperand(0).getValueType()))); 3274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1); 3275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 3276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 0 -> Lo 3277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), 3278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0)); 3279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::STACKSAVE: 3284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand to CopyFromReg if the target set 3285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // StackPointerRegisterToSaveRestore. 3286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) { 3287894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, SP, 3288894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getValueType(0))); 3289894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Results[0].getValue(1)); 3290894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 3291894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getUNDEF(Node->getValueType(0))); 3292894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Node->getOperand(0)); 3293894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3294894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3295894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::STACKRESTORE: 3296894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand to CopyToReg if the target set 3297894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // StackPointerRegisterToSaveRestore. 3298894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) { 3299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getCopyToReg(Node->getOperand(0), dl, SP, 3300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(1))); 3301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 3302894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Node->getOperand(0)); 3303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FCOPYSIGN: 3306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFCOPYSIGN(Node)); 3307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FNEG: 3309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand Y = FNEG(X) -> Y = SUB -0.0, X 3310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getConstantFP(-0.0, Node->getValueType(0)); 3311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp1, 3312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(0)); 3313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FABS: { 3316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). 3317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = Node->getOperand(0); 3319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getConstantFP(0.0, VT); 3320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), 3321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, Tmp2, ISD::SETUGT); 3322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1); 3323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3); 3324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FSQRT: 3328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::SQRT_F32, RTLIB::SQRT_F64, 3329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128)); 3330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FSIN: 3332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::SIN_F32, RTLIB::SIN_F64, 3333894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::SIN_F80, RTLIB::SIN_PPCF128)); 3334894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3335894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FCOS: 3336894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::COS_F32, RTLIB::COS_F64, 3337894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::COS_F80, RTLIB::COS_PPCF128)); 3338894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3339894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FLOG: 3340894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG_F32, RTLIB::LOG_F64, 3341894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::LOG_F80, RTLIB::LOG_PPCF128)); 3342894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3343894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FLOG2: 3344894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64, 3345894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128)); 3346894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3347894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FLOG10: 3348894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64, 3349894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::LOG10_F80, RTLIB::LOG10_PPCF128)); 3350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FEXP: 3352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP_F32, RTLIB::EXP_F64, 3353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::EXP_F80, RTLIB::EXP_PPCF128)); 3354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FEXP2: 3356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64, 3357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128)); 3358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FTRUNC: 3360894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, 3361894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128)); 3362894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3363894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FFLOOR: 3364894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64, 3365894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::FLOOR_F80, RTLIB::FLOOR_PPCF128)); 3366894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3367894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FCEIL: 3368894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::CEIL_F32, RTLIB::CEIL_F64, 3369894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128)); 3370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FRINT: 3372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::RINT_F32, RTLIB::RINT_F64, 3373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::RINT_F80, RTLIB::RINT_PPCF128)); 3374894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FNEARBYINT: 3376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::NEARBYINT_F32, 3377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::NEARBYINT_F64, 3378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::NEARBYINT_F80, 3379894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::NEARBYINT_PPCF128)); 3380894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3381894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FPOWI: 3382894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::POWI_F32, RTLIB::POWI_F64, 3383894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::POWI_F80, RTLIB::POWI_PPCF128)); 3384894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3385894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FPOW: 3386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::POW_F32, RTLIB::POW_F64, 3387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::POW_F80, RTLIB::POW_PPCF128)); 3388894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FDIV: 3390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::DIV_F32, RTLIB::DIV_F64, 3391894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::DIV_F80, RTLIB::DIV_PPCF128)); 3392894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3393894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FREM: 3394894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::REM_F32, RTLIB::REM_F64, 3395894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::REM_F80, RTLIB::REM_PPCF128)); 3396894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 339719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::FMA: 339819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(ExpandFPLibCall(Node, RTLIB::FMA_F32, RTLIB::FMA_F64, 339919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RTLIB::FMA_F80, RTLIB::FMA_PPCF128)); 340019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 3401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP16_TO_FP32: 3402894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32, Node, false)); 3403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP32_TO_FP16: 3405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandLibCall(RTLIB::FPROUND_F32_F16, Node, false)); 3406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ConstantFP: { 3408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node); 3409894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Check to see if this FP immediate is already legal. 3410894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If this is a legal constant, turn it into a TargetConstantFP node. 3411894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isFPImmLegal(CFP->getValueAPF(), Node->getValueType(0))) 3412894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(SDValue(Node, 0)); 3413894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 3414894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(ExpandConstantFP(CFP, true, DAG, TLI)); 3415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 341719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EHSELECTION: { 341819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Reg = TLI.getExceptionSelectorRegister(); 341919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Reg && "Can't expand to unknown register!"); 342019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(DAG.getCopyFromReg(Node->getOperand(1), dl, Reg, 342119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getValueType(0))); 342219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(Results[0].getValue(1)); 342319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 342419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 342519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::EXCEPTIONADDR: { 342619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned Reg = TLI.getExceptionAddressRegister(); 342719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(Reg && "Can't expand to unknown register!"); 342819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, Reg, 342919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Node->getValueType(0))); 343019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Results.push_back(Results[0].getValue(1)); 343119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 343219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 3433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SUB: { 3434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(TLI.isOperationLegalOrCustom(ISD::ADD, VT) && 3436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.isOperationLegalOrCustom(ISD::XOR, VT) && 3437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "Don't know how to expand this subtraction!"); 3438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::XOR, dl, VT, Node->getOperand(1), 3439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT)); 3440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::ADD, dl, VT, Tmp2, DAG.getConstant(1, VT)); 3441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getNode(ISD::ADD, dl, VT, Node->getOperand(0), Tmp1)); 3442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UREM: 3445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SREM: { 3446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDVTList VTs = DAG.getVTList(VT, VT); 3448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned = Node->getOpcode() == ISD::SREM; 3449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DivOpc = isSigned ? ISD::SDIV : ISD::UDIV; 3450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM; 3451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = Node->getOperand(0); 3452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = Node->getOperand(1); 345319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) || 345419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (isDivRemLibcallAvailable(Node, isSigned, TLI) && 345519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman UseDivRem(Node, isSigned, false))) { 3456894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Tmp2, Tmp3).getValue(1); 3457894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (TLI.isOperationLegalOrCustom(DivOpc, VT)) { 3458894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // X % Y -> X-X/Y*Y 3459894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(DivOpc, dl, VT, Tmp2, Tmp3); 3460894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::MUL, dl, VT, Tmp1, Tmp3); 3461894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Tmp2, Tmp1); 346219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (isSigned) 3463894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ExpandIntLibCall(Node, true, 3464894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::SREM_I8, 3465894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::SREM_I16, RTLIB::SREM_I32, 3466894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::SREM_I64, RTLIB::SREM_I128); 346719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else 3468894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ExpandIntLibCall(Node, false, 3469894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::UREM_I8, 3470894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::UREM_I16, RTLIB::UREM_I32, 3471894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::UREM_I64, RTLIB::UREM_I128); 3472894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3473894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3474894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3475894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UDIV: 3476894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SDIV: { 3477894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned = Node->getOpcode() == ISD::SDIV; 3478894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM; 3479894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3480894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDVTList VTs = DAG.getVTList(VT, VT); 348119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) || 348219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman (isDivRemLibcallAvailable(Node, isSigned, TLI) && 348319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman UseDivRem(Node, isSigned, true))) 3484894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Node->getOperand(0), 3485894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(1)); 3486894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else if (isSigned) 3487894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ExpandIntLibCall(Node, true, 3488894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::SDIV_I8, 3489894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::SDIV_I16, RTLIB::SDIV_I32, 3490894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::SDIV_I64, RTLIB::SDIV_I128); 3491894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 3492894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ExpandIntLibCall(Node, false, 3493894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::UDIV_I8, 3494894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::UDIV_I16, RTLIB::UDIV_I32, 3495894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::UDIV_I64, RTLIB::UDIV_I128); 3496894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3497894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3498894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3499894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MULHU: 3500894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MULHS: { 3501894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExpandOpcode = Node->getOpcode() == ISD::MULHU ? ISD::UMUL_LOHI : 3502894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SMUL_LOHI; 3503894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3504894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDVTList VTs = DAG.getVTList(VT, VT); 3505894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(TLI.isOperationLegalOrCustom(ExpandOpcode, VT) && 3506894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "If this wasn't legal, it shouldn't have been created!"); 3507894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ExpandOpcode, dl, VTs, Node->getOperand(0), 3508894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(1)); 3509894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1.getValue(1)); 3510894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3511894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 351219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::SDIVREM: 351319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman case ISD::UDIVREM: 351419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Expand into divrem libcall 351519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExpandDivRemLibCall(Node, Results); 351619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 3517894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::MUL: { 3518894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3519894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDVTList VTs = DAG.getVTList(VT, VT); 3520894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // See if multiply or divide can be lowered using two-result operations. 3521894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We just need the low half of the multiply; try both the signed 3522894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // and unsigned forms. If the target supports both SMUL_LOHI and 3523894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // UMUL_LOHI, form a preference by checking which forms of plain 3524894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // MULH it supports. 3525894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT); 3526894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT); 3527894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT); 3528894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT); 3529894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned OpToUse = 0; 3530894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (HasSMUL_LOHI && !HasMULHS) { 3531894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpToUse = ISD::SMUL_LOHI; 3532894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (HasUMUL_LOHI && !HasMULHU) { 3533894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpToUse = ISD::UMUL_LOHI; 3534894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (HasSMUL_LOHI) { 3535894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpToUse = ISD::SMUL_LOHI; 3536894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (HasUMUL_LOHI) { 3537894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OpToUse = ISD::UMUL_LOHI; 3538894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3539894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OpToUse) { 3540894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getNode(OpToUse, dl, VTs, Node->getOperand(0), 3541894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(1))); 3542894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3543894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3544894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ExpandIntLibCall(Node, false, 3545894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::MUL_I8, 3546894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::MUL_I16, RTLIB::MUL_I32, 3547894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RTLIB::MUL_I64, RTLIB::MUL_I128); 3548894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3549894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3550894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3551894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SADDO: 3552894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SSUBO: { 3553894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = Node->getOperand(0); 3554894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = Node->getOperand(1); 3555894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ? 3556894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 3557894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS, RHS); 3558894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Sum); 3559894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OType = Node->getValueType(1); 3560894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3561894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Zero = DAG.getConstant(0, LHS.getValueType()); 3562894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3563894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // LHSSign -> LHS >= 0 3564894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // RHSSign -> RHS >= 0 3565894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // SumSign -> Sum >= 0 3566894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 3567894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Add: 3568894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign) 3569894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Sub: 3570894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign) 3571894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // 3572894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE); 3573894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE); 3574894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign, 3575894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOpcode() == ISD::SADDO ? 3576894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETEQ : ISD::SETNE); 3577894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3578894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE); 3579894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE); 3580894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3581894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE); 3582894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Cmp); 3583894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3584894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3585894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UADDO: 3586894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::USUBO: { 3587894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = Node->getOperand(0); 3588894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = Node->getOperand(1); 3589894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::UADDO ? 3590894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 3591894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS, RHS); 3592894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Sum); 3593894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getSetCC(dl, Node->getValueType(1), Sum, LHS, 3594894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOpcode () == ISD::UADDO ? 3595894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETULT : ISD::SETUGT)); 3596894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3597894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3598894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UMULO: 3599894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SMULO: { 3600894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 360119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits() * 2); 3602894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue LHS = Node->getOperand(0); 3603894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue RHS = Node->getOperand(1); 3604894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue BottomHalf; 3605894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue TopHalf; 3606894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static const unsigned Ops[2][3] = 3607894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { { ISD::MULHU, ISD::UMUL_LOHI, ISD::ZERO_EXTEND }, 3608894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { ISD::MULHS, ISD::SMUL_LOHI, ISD::SIGN_EXTEND }}; 3609894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool isSigned = Node->getOpcode() == ISD::SMULO; 3610894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TLI.isOperationLegalOrCustom(Ops[isSigned][0], VT)) { 3611894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BottomHalf = DAG.getNode(ISD::MUL, dl, VT, LHS, RHS); 3612894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TopHalf = DAG.getNode(Ops[isSigned][0], dl, VT, LHS, RHS); 3613894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (TLI.isOperationLegalOrCustom(Ops[isSigned][1], VT)) { 3614894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BottomHalf = DAG.getNode(Ops[isSigned][1], dl, DAG.getVTList(VT, VT), LHS, 3615894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RHS); 3616894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TopHalf = BottomHalf.getValue(1); 361719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else if (TLI.isTypeLegal(EVT::getIntegerVT(*DAG.getContext(), 361819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman VT.getSizeInBits() * 2))) { 3619894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, LHS); 3620894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, RHS); 3621894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::MUL, dl, WideVT, LHS, RHS); 3622894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Tmp1, 3623894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(0)); 3624894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Tmp1, 3625894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(1)); 362619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } else { 362719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We can fall back to a libcall with an illegal type for the MUL if we 362819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // have a libcall big enough. 362919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Also, we can fall back to a division in some cases, but that's a big 363019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // performance hit in the general case. 363119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 363219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (WideVT == MVT::i16) 363319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LC = RTLIB::MUL_I16; 363419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (WideVT == MVT::i32) 363519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LC = RTLIB::MUL_I32; 363619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (WideVT == MVT::i64) 363719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LC = RTLIB::MUL_I64; 363819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman else if (WideVT == MVT::i128) 363919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman LC = RTLIB::MUL_I128; 364019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(LC != RTLIB::UNKNOWN_LIBCALL && "Cannot expand this operation!"); 364119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 364219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // The high part is obtained by SRA'ing all but one of the bits of low 364319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // part. 364419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman unsigned LoSize = VT.getSizeInBits(); 364519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, RHS, 364619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(LoSize-1, TLI.getPointerTy())); 364719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue HiRHS = DAG.getNode(ISD::SRA, dl, VT, LHS, 364819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(LoSize-1, TLI.getPointerTy())); 364919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 365019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Here we're passing the 2 arguments explicitly as 4 arguments that are 365119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // pre-lowered to the correct types. This all depends upon WideVT not 365219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // being a legal type for the architecture and thus has to be split to 365319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // two arguments. 365419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Args[] = { LHS, HiLHS, RHS, HiRHS }; 365519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl); 365619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret, 365719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(0)); 365819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret, 365919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getIntPtrConstant(1)); 3660894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 366119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 3662894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isSigned) { 366319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = DAG.getConstant(VT.getSizeInBits() - 1, 366419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(BottomHalf.getValueType())); 3665894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, Tmp1); 3666894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TopHalf = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), TopHalf, Tmp1, 3667894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETNE); 3668894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 3669894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TopHalf = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), TopHalf, 3670894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(0, VT), ISD::SETNE); 3671894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3672894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(BottomHalf); 3673894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(TopHalf); 3674894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3675894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3676894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BUILD_PAIR: { 3677894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PairTy = Node->getValueType(0); 3678894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, PairTy, Node->getOperand(0)); 3679894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::ANY_EXTEND, dl, PairTy, Node->getOperand(1)); 3680894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ISD::SHL, dl, PairTy, Tmp2, 3681894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(PairTy.getSizeInBits()/2, 368219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TLI.getShiftAmountTy(PairTy))); 3683894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getNode(ISD::OR, dl, PairTy, Tmp1, Tmp2)); 3684894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3685894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3686894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT: 3687894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = Node->getOperand(0); 3688894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = Node->getOperand(1); 3689894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = Node->getOperand(2); 3690894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp1.getOpcode() == ISD::SETCC) { 3691894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getSelectCC(dl, Tmp1.getOperand(0), Tmp1.getOperand(1), 3692894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2, Tmp3, 3693894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cast<CondCodeSDNode>(Tmp1.getOperand(2))->get()); 3694894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 3695894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getSelectCC(dl, Tmp1, 3696894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(0, Tmp1.getValueType()), 3697894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2, Tmp3, ISD::SETNE); 3698894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3699894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3700894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3701894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BR_JT: { 3702894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Chain = Node->getOperand(0); 3703894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Table = Node->getOperand(1); 3704894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Index = Node->getOperand(2); 3705894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3706894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT PTy = TLI.getPointerTy(); 3707894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3708894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetData &TD = *TLI.getTargetData(); 3709894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned EntrySize = 3710894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD); 3711894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3712894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index = DAG.getNode(ISD::MUL, dl, PTy, 3713894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Index, DAG.getConstant(EntrySize, PTy)); 3714894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); 3715894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3716894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8); 371719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr, 371819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachinePointerInfo::getJumpTable(), MemVT, 3719894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman false, false, 0); 3720894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Addr = LD; 3721894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TM.getRelocationModel() == Reloc::PIC_) { 3722894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // For PIC, the sequence is: 3723894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // BRIND(load(Jumptable + index) + RelocBase) 3724894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // RelocBase can be JumpTable, GOT or some sort of global base. 3725894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, 3726894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TLI.getPICJumpTableRelocBase(Table, DAG)); 3727894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3728894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::BRIND, dl, MVT::Other, LD.getValue(1), Addr); 3729894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3730894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3731894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3732894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BRCOND: 3733894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Expand brcond's setcc into its constituent parts and create a BR_CC 3734894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Node. 3735894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = Node->getOperand(0); 3736894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = Node->getOperand(1); 3737894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp2.getOpcode() == ISD::SETCC) { 3738894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::BR_CC, dl, MVT::Other, 3739894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, Tmp2.getOperand(2), 3740894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2.getOperand(0), Tmp2.getOperand(1), 3741894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(2)); 3742894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 374319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // We test only the i1 bit. Skip the AND if UNDEF. 374419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp3 = (Tmp2.getOpcode() == ISD::UNDEF) ? Tmp2 : 374519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getNode(ISD::AND, dl, Tmp2.getValueType(), Tmp2, 374619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(1, Tmp2.getValueType())); 3747894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::BR_CC, dl, MVT::Other, Tmp1, 374819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getCondCode(ISD::SETNE), Tmp3, 374919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(0, Tmp3.getValueType()), 3750894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOperand(2)); 3751894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3752894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3753894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3754894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETCC: { 3755894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = Node->getOperand(0); 3756894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = Node->getOperand(1); 3757894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = Node->getOperand(2); 3758894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeSetCCCondCode(Node->getValueType(0), Tmp1, Tmp2, Tmp3, dl); 3759894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3760894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If we expanded the SETCC into an AND/OR, return the new node 3761894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Tmp2.getNode() == 0) { 3762894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3763894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3764894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3765894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3766894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, SETCC for the given comparison type must be completely 3767894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // illegal; expand it into a SELECT_CC. 3768894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT VT = Node->getValueType(0); 3769894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, VT, Tmp1, Tmp2, 3770894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(1, VT), DAG.getConstant(0, VT), Tmp3); 3771894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3772894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3773894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3774894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT_CC: { 3775894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = Node->getOperand(0); // LHS 3776894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = Node->getOperand(1); // RHS 3777894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = Node->getOperand(2); // True 3778894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = Node->getOperand(3); // False 3779894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue CC = Node->getOperand(4); 3780894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3781894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp1.getValueType()), 3782894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, Tmp2, CC, dl); 3783894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3784894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!Tmp2.getNode() && "Can't legalize SELECT_CC with legal condition!"); 3785894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getConstant(0, Tmp1.getValueType()); 3786894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CC = DAG.getCondCode(ISD::SETNE); 3787894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1, Tmp2, 3788894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3, Tmp4, CC); 3789894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3790894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3791894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3792894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BR_CC: { 3793894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = Node->getOperand(0); // Chain 3794894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = Node->getOperand(2); // LHS 3795894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = Node->getOperand(3); // RHS 3796894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = Node->getOperand(1); // CC 3797894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3798894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp2.getValueType()), 3799894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2, Tmp3, Tmp4, dl); 3800894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman LastCALLSEQ_END = DAG.getEntryNode(); 3801894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3802894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(!Tmp3.getNode() && "Can't legalize BR_CC with legal condition!"); 3803894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getConstant(0, Tmp2.getValueType()); 3804894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp4 = DAG.getCondCode(ISD::SETNE); 3805894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::BR_CC, dl, Node->getValueType(0), Tmp1, Tmp4, Tmp2, 3806894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3, Node->getOperand(4)); 3807894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3808894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3809894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3810894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::GLOBAL_OFFSET_TABLE: 3811894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::GlobalAddress: 3812894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::GlobalTLSAddress: 3813894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ExternalSymbol: 3814894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::ConstantPool: 3815894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::JumpTable: 3816894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INTRINSIC_W_CHAIN: 3817894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INTRINSIC_WO_CHAIN: 3818894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::INTRINSIC_VOID: 3819894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // FIXME: Custom lowering for these operations shouldn't return null! 3820894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 3821894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(SDValue(Node, i)); 3822894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3823894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3824894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3825894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid SelectionDAGLegalize::PromoteNode(SDNode *Node, 3826894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<SDValue> &Results) { 3827894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT OVT = Node->getValueType(0); 3828894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getOpcode() == ISD::UINT_TO_FP || 3829894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOpcode() == ISD::SINT_TO_FP || 3830894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOpcode() == ISD::SETCC) { 3831894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OVT = Node->getOperand(0).getValueType(); 3832894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3833894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman EVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); 3834894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc dl = Node->getDebugLoc(); 3835894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SDValue Tmp1, Tmp2, Tmp3; 3836894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (Node->getOpcode()) { 3837894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTTZ: 3838894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTLZ: 3839894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::CTPOP: 3840894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Zero extend the argument. 3841894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); 3842894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Perform the larger operation. 3843894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); 3844894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getOpcode() == ISD::CTTZ) { 3845894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) 3846894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), 3847894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT), 3848894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::SETEQ); 3849894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, 3850894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(OVT.getSizeInBits(), NVT), Tmp1); 3851894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Node->getOpcode() == ISD::CTLZ) { 3852894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT)) 3853894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SUB, dl, NVT, Tmp1, 3854894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getConstant(NVT.getSizeInBits() - 3855894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman OVT.getSizeInBits(), NVT)); 3856894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3857894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, OVT, Tmp1)); 3858894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3859894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::BSWAP: { 3860894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); 3861894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); 3862894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1); 3863894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, 386419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman DAG.getConstant(DiffBits, TLI.getShiftAmountTy(NVT))); 3865894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3866894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3867894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3868894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_UINT: 3869894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::FP_TO_SINT: 3870894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = PromoteLegalFP_TO_INT(Node->getOperand(0), Node->getValueType(0), 3871894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOpcode() == ISD::FP_TO_SINT, dl); 3872894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3873894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3874894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::UINT_TO_FP: 3875894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SINT_TO_FP: 3876894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = PromoteLegalINT_TO_FP(Node->getOperand(0), Node->getValueType(0), 3877894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Node->getOpcode() == ISD::SINT_TO_FP, dl); 3878894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3879894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3880894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::AND: 3881894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::OR: 3882894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::XOR: { 3883894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExtOp, TruncOp; 3884894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (OVT.isVector()) { 388519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtOp = ISD::BITCAST; 388619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TruncOp = ISD::BITCAST; 3887894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 3888894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(OVT.isInteger() && "Cannot promote logic operation"); 3889894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExtOp = ISD::ANY_EXTEND; 3890894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TruncOp = ISD::TRUNCATE; 3891894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3892894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote each of the values to the new type. 3893894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(0)); 3894894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3895894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Perform the larger operation, then convert back 3896894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); 3897894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getNode(TruncOp, dl, OVT, Tmp1)); 3898894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3899894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3900894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SELECT: { 3901894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExtOp, TruncOp; 3902894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Node->getValueType(0).isVector()) { 390319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman ExtOp = ISD::BITCAST; 390419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman TruncOp = ISD::BITCAST; 3905894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (Node->getValueType(0).isInteger()) { 3906894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExtOp = ISD::ANY_EXTEND; 3907894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TruncOp = ISD::TRUNCATE; 3908894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 3909894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExtOp = ISD::FP_EXTEND; 3910894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TruncOp = ISD::FP_ROUND; 3911894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3912894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = Node->getOperand(0); 3913894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Promote each of the values to the new type. 3914894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3915894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp3 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(2)); 3916894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Perform the larger operation, then round down. 3917894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp1, Tmp2, Tmp3); 3918894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (TruncOp != ISD::FP_ROUND) 3919894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(TruncOp, dl, Node->getValueType(0), Tmp1); 3920894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman else 3921894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(TruncOp, dl, Node->getValueType(0), Tmp1, 3922894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DAG.getIntPtrConstant(0)); 3923894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3924894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3925894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3926894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::VECTOR_SHUFFLE: { 3927894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVector<int, 8> Mask; 3928894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cast<ShuffleVectorSDNode>(Node)->getMask(Mask); 3929894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3930894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Cast the two input vectors. 393119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(0)); 393219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp2 = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(1)); 3933894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3934894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Convert the shuffle mask to the right # elements. 3935894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask); 393619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman Tmp1 = DAG.getNode(ISD::BITCAST, dl, OVT, Tmp1); 3937894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(Tmp1); 3938894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3939894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3940894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case ISD::SETCC: { 3941894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned ExtOp = ISD::FP_EXTEND; 3942894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (NVT.isInteger()) { 3943894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ISD::CondCode CCCode = 3944894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman cast<CondCodeSDNode>(Node->getOperand(2))->get(); 3945894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman ExtOp = isSignedIntSetCC(CCCode) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; 3946894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3947894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(0)); 3948894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3949894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Results.push_back(DAG.getNode(ISD::SETCC, dl, Node->getValueType(0), 3950894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Tmp1, Tmp2, Node->getOperand(2))); 3951894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 3952894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3953894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 3954894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3955894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 3956894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// SelectionDAG::Legalize - This is the entry point for the file. 3957894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 395819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanvoid SelectionDAG::Legalize() { 3959894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// run - This is the main entry point to this class. 3960894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman /// 396119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman SelectionDAGLegalize(*this).LegalizeDAG(); 3962894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 3963