LegalizeDAG.cpp revision bf923b815d6da97367e3eedab69230918bf128a3
13e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner//===-- LegalizeDAG.cpp - Implement SelectionDAG::Legalize ----------------===// 2edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 33e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// The LLVM Compiler Infrastructure 43e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// 54ee451de366474b9c228b4e5fa573795a715216dChris Lattner// This file is distributed under the University of Illinois Open Source 64ee451de366474b9c228b4e5fa573795a715216dChris Lattner// License. See LICENSE.TXT for details. 7edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman// 83e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner//===----------------------------------------------------------------------===// 93e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// 103e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// This file implements the SelectionDAG::Legalize method. 113e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// 123e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner//===----------------------------------------------------------------------===// 133e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 143d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng#include "llvm/Analysis/DebugInfo.h" 153d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng#include "llvm/CodeGen/Analysis.h" 163e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner#include "llvm/CodeGen/MachineFunction.h" 17acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey#include "llvm/CodeGen/MachineJumpTableInfo.h" 183d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng#include "llvm/CodeGen/SelectionDAG.h" 1916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov#include "llvm/Target/TargetFrameLowering.h" 203e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner#include "llvm/Target/TargetLowering.h" 21e1bd822ddb0099406d9f280535461033dfeeb190Chris Lattner#include "llvm/Target/TargetData.h" 223d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng#include "llvm/Target/TargetMachine.h" 23adf6a965a321372c640845407195594835921eb4Chris Lattner#include "llvm/CallingConv.h" 243e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner#include "llvm/Constants.h" 25c10305743c313558405079452138f03124e87581Reid Spencer#include "llvm/DerivedTypes.h" 269adc0abad3c3ed40a268ccbcee0c74cb9e1359feOwen Anderson#include "llvm/LLVMContext.h" 27993aacedfdc3f156f667b4efa280ee79eab3b898David Greene#include "llvm/Support/Debug.h" 28e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach#include "llvm/Support/ErrorHandling.h" 29dc84650679b6330e0fcdd4cf8bc2a351387db7caDuncan Sands#include "llvm/Support/MathExtras.h" 3045cfe545ec8177262dabc70580ce05feaa1c3880Chris Lattner#include "llvm/Support/raw_ostream.h" 317971514755a08ec156a1b9c0f7f05d67919c56b7Chris Lattner#include "llvm/ADT/DenseMap.h" 32f06f35e30b4c4d7db304f717a3d4dc6595fbd078Chris Lattner#include "llvm/ADT/SmallVector.h" 3300755df36c1448ac4728a74d907aa09e3d8b2d49Chris Lattner#include "llvm/ADT/SmallPtrSet.h" 343e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnerusing namespace llvm; 353e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 363e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner//===----------------------------------------------------------------------===// 373e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// SelectionDAGLegalize - This takes an arbitrary SelectionDAG as input and 383e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// hacks on it until the target machine can handle it. This involves 393e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// eliminating value sizes the machine cannot handle (promoting small sizes to 403e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// large sizes or splitting up large values into small values) as well as 413e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// eliminating operations the machine cannot handle. 423e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// 433e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// This code also does a small amount of optimization and recognition of idioms 443e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// as part of its processing. For example, if a target does not support a 453e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// 'setcc' instruction efficiently, but does support 'brcc' instruction, this 463e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// will attempt merge setcc and brc instructions into brcc's. 473e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// 483e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnernamespace { 49bf923b815d6da97367e3eedab69230918bf128a3Dan Gohmanclass SelectionDAGLegalize : public SelectionDAG::DAGUpdateListener { 5055e59c186303ff02c0be7429da3b1b36c347f164Dan Gohman const TargetMachine &TM; 51d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const TargetLowering &TLI; 523e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner SelectionDAG &DAG; 533e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 54bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman /// LegalizePosition - The iterator for walking through the node list. 55bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SelectionDAG::allnodes_iterator LegalizePosition; 5662c1d00dfd38996f381edae55e1028b8e52a1107Duncan Sands 57bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman /// LegalizedNodes - The set of nodes which have already been legalized. 58bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SmallPtrSet<SDNode *, 16> LegalizedNodes; 5962c1d00dfd38996f381edae55e1028b8e52a1107Duncan Sands 60bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // Libcall insertion helpers. 618afc48e44ad8868c1d41511db645e2ba1a4b894eChris Lattner 623e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnerpublic: 63975716af1b9a09274df6c2d92683449015bd8564Dan Gohman explicit SelectionDAGLegalize(SelectionDAG &DAG); 643e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 653e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner void LegalizeDAG(); 663e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 67456a93afcec7740c45cafa8354317f7b17987a6dChris Lattnerprivate: 68bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman /// LegalizeOp - Legalizes the given operation. 69bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman void LegalizeOp(SDNode *Node); 70fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 717ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue OptimizeFloatStore(StoreSDNode *ST); 727ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 736867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// PerformInsertVectorEltInMemory - Some target cannot handle a variable 746867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it 756867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// is necessary to spill the vector being inserted into to memory, perform 766867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// the insert there, and then read the result back. 77475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, 783f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SDValue Idx, DebugLoc dl); 793f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SDValue ExpandINSERT_VECTOR_ELT(SDValue Vec, SDValue Val, 803f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SDValue Idx, DebugLoc dl); 81826695281344e3a4c4d44d73dd155107aafd689bDan Gohman 825a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// ShuffleWithNarrowerEltType - Return a vector shuffle operation which 835a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// performs the same shuffe in terms of order or result bytes, but on a type 845a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// whose vector element type is narrower than the original shuffle type. 855a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3> 86e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue ShuffleWithNarrowerEltType(EVT NVT, EVT VT, DebugLoc dl, 876e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach SDValue N1, SDValue N2, 885a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman SmallVectorImpl<int> &Mask) const; 89fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 90e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson void LegalizeSetCCCondCode(EVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, 91775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DebugLoc dl); 92fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 9347b41f7e20b6af7aaaf0e050200102d55d038b9dEli Friedman SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned); 94abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue ExpandLibCall(RTLIB::Libcall LC, EVT RetVT, const SDValue *Ops, 95abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher unsigned NumOps, bool isSigned, DebugLoc dl); 96abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher 97e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach std::pair<SDValue, SDValue> ExpandChainLibCall(RTLIB::Libcall LC, 98e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach SDNode *Node, bool isSigned); 99f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman SDValue ExpandFPLibCall(SDNode *Node, RTLIB::Libcall Call_F32, 100f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80, 101f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_PPCF128); 1028983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov SDValue ExpandIntLibCall(SDNode *Node, bool isSigned, 1038983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I8, 1048983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I16, 1058983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I32, 1068983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I64, 107f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I128); 10865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng void ExpandDivRemLibCall(SDNode *Node, SmallVectorImpl<SDValue> &Results); 109475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 110e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue EmitStackConvert(SDValue SrcOp, EVT SlotVT, EVT DestVT, DebugLoc dl); 111475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ExpandBUILD_VECTOR(SDNode *Node); 112475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node); 1134bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman void ExpandDYNAMIC_STACKALLOC(SDNode *Node, 1144bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SmallVectorImpl<SDValue> &Results); 1154bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue ExpandFCOPYSIGN(SDNode *Node); 116e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, EVT DestVT, 117af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 118e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, EVT DestVT, bool isSigned, 119af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 120e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, EVT DestVT, bool isSigned, 121af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 122475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 1238a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue ExpandBSWAP(SDValue Op, DebugLoc dl); 1248a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue ExpandBitCount(unsigned Opc, SDValue Op, DebugLoc dl); 125475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 1263d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue ExpandExtractFromVectorThroughStack(SDValue Op); 127cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue ExpandInsertToVectorThroughStack(SDValue Op); 1287ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue ExpandVectorBuildThroughStack(SDNode* Node); 1298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 130bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP); 131bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman 132e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach std::pair<SDValue, SDValue> ExpandAtomic(SDNode *Node); 133e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 134bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman void ExpandNode(SDNode *Node); 135bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman void PromoteNode(SDNode *Node); 136bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman 137bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // DAGUpdateListener implementation. 138bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman virtual void NodeDeleted(SDNode *N, SDNode *E) { 139bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman LegalizedNodes.erase(N); 140bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (LegalizePosition == SelectionDAG::allnodes_iterator(N)) 141bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ++LegalizePosition; 142bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 143bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman 144bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman virtual void NodeUpdated(SDNode *N) {} 1453e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner}; 1463e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 1473e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 1485a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// ShuffleWithNarrowerEltType - Return a vector shuffle operation which 1495a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// performs the same shuffe in terms of order or result bytes, but on a type 1505a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// whose vector element type is narrower than the original shuffle type. 1519008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman/// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3> 1526e9926108a69efbc11f1cadf947e98500e4d4228Jim GrosbachSDValue 1536e9926108a69efbc11f1cadf947e98500e4d4228Jim GrosbachSelectionDAGLegalize::ShuffleWithNarrowerEltType(EVT NVT, EVT VT, DebugLoc dl, 1545a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman SDValue N1, SDValue N2, 1559008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVectorImpl<int> &Mask) const { 1565a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman unsigned NumMaskElts = VT.getVectorNumElements(); 1575a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman unsigned NumDestElts = NVT.getVectorNumElements(); 1589008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman unsigned NumEltsGrowth = NumDestElts / NumMaskElts; 1599008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 1609008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman assert(NumEltsGrowth && "Cannot promote to vector type with fewer elts!"); 1619008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 1629008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman if (NumEltsGrowth == 1) 1639008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman return DAG.getVectorShuffle(NVT, dl, N1, N2, &Mask[0]); 1646e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach 1659008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVector<int, 8> NewMask; 1665a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman for (unsigned i = 0; i != NumMaskElts; ++i) { 1679008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman int Idx = Mask[i]; 1689008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman for (unsigned j = 0; j != NumEltsGrowth; ++j) { 1696e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach if (Idx < 0) 1709008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman NewMask.push_back(-1); 1719008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman else 1729008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman NewMask.push_back(Idx * NumEltsGrowth + j); 1734352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner } 17415684b29552393553524171bff1913e750f390f8Rafael Espindola } 1755a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman assert(NewMask.size() == NumDestElts && "Non-integer NumEltsGrowth?"); 1769008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman assert(TLI.isShuffleMaskLegal(NewMask, NVT) && "Shuffle not legal?"); 1779008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman return DAG.getVectorShuffle(NVT, dl, N1, N2, &NewMask[0]); 1784352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner} 1794352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 180975716af1b9a09274df6c2d92683449015bd8564Dan GohmanSelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag) 18155e59c186303ff02c0be7429da3b1b36c347f164Dan Gohman : TM(dag.getTarget()), TLI(dag.getTargetLoweringInfo()), 182ea0270298de4d2a4186454fc39a6836e99271f1dDan Gohman DAG(dag) { 1833e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 1843e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 1853e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnervoid SelectionDAGLegalize::LegalizeDAG() { 186f06c835f769aa1cf67801ed1f6bd366a447c18b1Dan Gohman DAG.AssignTopologicalOrder(); 18762c1d00dfd38996f381edae55e1028b8e52a1107Duncan Sands 188bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // Visit all the nodes. We start in topological order, so that we see 189bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // nodes with their original operands intact. Legalization can produce 190bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // new nodes which may themselves need to be legalized. Iterate until all 191bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // nodes have been legalized. 192bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman for (;;) { 193bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman bool AnyLegalized = false; 194bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman for (LegalizePosition = DAG.allnodes_end(); 195bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman LegalizePosition != DAG.allnodes_begin(); ) { 196bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman --LegalizePosition; 197bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman 198bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDNode *N = LegalizePosition; 199bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (LegalizedNodes.insert(N)) { 200bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman AnyLegalized = true; 201bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman LegalizeOp(N); 202bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 203a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings } 204bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (!AnyLegalized) 2052ba60e593012ba9b2a9d20b86733eadca288bcb2Dan Gohman break; 2066831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 207c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner } 2086831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 209bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // Remove dead nodes now. 210bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.RemoveDeadNodes(); 2116831a815999dde4cf801e2076e66b4943964daf2Chris Lattner} 2126831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 2139f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng/// ExpandConstantFP - Expands the ConstantFP node to an integer constant or 2149f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng/// a load from the constant pool. 215bf923b815d6da97367e3eedab69230918bf128a3Dan GohmanSDValue 216bf923b815d6da97367e3eedab69230918bf128a3Dan GohmanSelectionDAGLegalize::ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP) { 217004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng bool Extend = false; 21833c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen DebugLoc dl = CFP->getDebugLoc(); 219004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 220004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // If a FP immediate is precise when represented as a float and if the 221004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // target can do an extending load from float to double, we put it into 222004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // the constant pool as a float, even if it's is statically typed as a 223aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // double. This shrinks FP constants and canonicalizes them for targets where 224aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // an FP extending load is the same cost as a normal load (such as on the x87 225aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // fp stack or PPC FP unit). 226e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = CFP->getValueType(0); 2274fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman ConstantFP *LLVMC = const_cast<ConstantFP*>(CFP->getConstantFPValue()); 2289f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng if (!UseCP) { 229825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert((VT == MVT::f64 || VT == MVT::f32) && "Invalid type expansion"); 2307111b02c734c992b8c97d9918118768026dad79eDale Johannesen return DAG.getConstant(LLVMC->getValueAPF().bitcastToAPInt(), 231825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (VT == MVT::f64) ? MVT::i64 : MVT::i32); 232279101eb1ac61e2d5b83d5bdcc5be56e710d2cd7Evan Cheng } 233279101eb1ac61e2d5b83d5bdcc5be56e710d2cd7Evan Cheng 234e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OrigVT = VT; 235e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT SVT = VT; 236825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson while (SVT != MVT::f32) { 237825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1); 2387720cb3823d5b5868f9b88b0127277820edcb562Dan Gohman if (ConstantFPSDNode::isValueValidForType(SVT, CFP->getValueAPF()) && 239ef12057737229452c17983faa20857dba441ef05Evan Cheng // Only do this if the target has a native EXTLOAD instruction from 240ef12057737229452c17983faa20857dba441ef05Evan Cheng // smaller type. 2410329466b6b4927f4e6f5d144891fef06a027fec5Evan Cheng TLI.isLoadExtLegal(ISD::EXTLOAD, SVT) && 242aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner TLI.ShouldShrinkFPConstant(OrigVT)) { 243db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *SType = SVT.getTypeForEVT(*DAG.getContext()); 244baf3c404409d5e47b13984a7f95bfbd6d1f2e79eOwen Anderson LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType)); 245ef12057737229452c17983faa20857dba441ef05Evan Cheng VT = SVT; 246ef12057737229452c17983faa20857dba441ef05Evan Cheng Extend = true; 247ef12057737229452c17983faa20857dba441ef05Evan Cheng } 248004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng } 249004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 250475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy()); 2511606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 252bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (Extend) { 253bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 254bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getExtLoad(ISD::EXTLOAD, dl, OrigVT, 255bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getEntryNode(), 256bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman CPIdx, MachinePointerInfo::getConstantPool(), 257bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman VT, false, false, Alignment); 258bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return Result; 259bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 260bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 261bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getLoad(OrigVT, dl, DAG.getEntryNode(), CPIdx, 262bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman MachinePointerInfo::getConstantPool(), false, false, 263bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Alignment); 264bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return Result; 265004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng} 266004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 267f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio/// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores. 268bf923b815d6da97367e3eedab69230918bf128a3Dan Gohmanstatic void ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, 269bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman const TargetLowering &TLI, 270bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SelectionDAG::DAGUpdateListener *DUL) { 271475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = ST->getChain(); 272475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ptr = ST->getBasePtr(); 273475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Val = ST->getValue(); 274e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Val.getValueType(); 275907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen int Alignment = ST->getAlignment(); 276bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl = ST->getDebugLoc(); 27783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (ST->getMemoryVT().isFloatingPoint() || 27883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands ST->getMemoryVT().isVector()) { 27923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT intVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits()); 28005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (TLI.isTypeLegal(intVT)) { 28105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Expand to a bitconvert of the value to the integer type of the 28205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // same size, then a (misaligned) int store. 28305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // FIXME: Does not handle truncating floating point stores! 284bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue Result = DAG.getNode(ISD::BITCAST, dl, intVT, Val); 285bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Result = DAG.getStore(Chain, dl, Result, Ptr, ST->getPointerInfo(), 286bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ST->isVolatile(), ST->isNonTemporal(), Alignment); 287bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL); 288bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 28905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } 2901b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Do a (aligned) store to a stack slot, then copy from the stack slot 2911b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // to the final destination using (unaligned) integer loads and stores. 2921b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman EVT StoredVT = ST->getMemoryVT(); 2931b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman EVT RegVT = 2941b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman TLI.getRegisterType(*DAG.getContext(), 2951b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman EVT::getIntegerVT(*DAG.getContext(), 2961b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman StoredVT.getSizeInBits())); 2971b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman unsigned StoredBytes = StoredVT.getSizeInBits() / 8; 2981b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman unsigned RegBytes = RegVT.getSizeInBits() / 8; 2991b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman unsigned NumRegs = (StoredBytes + RegBytes - 1) / RegBytes; 3001b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 3011b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Make sure the stack slot is also aligned for the register type. 3021b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue StackPtr = DAG.CreateStackTemporary(StoredVT, RegVT); 3031b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 3041b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Perform the original store, only redirected to the stack slot. 3051b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue Store = DAG.getTruncStore(Chain, dl, 3061b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Val, StackPtr, MachinePointerInfo(), 3071b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman StoredVT, false, false, 0); 3081b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); 3091b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SmallVector<SDValue, 8> Stores; 3101b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman unsigned Offset = 0; 3111b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 3121b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Do all but one copies using the full register width. 3131b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman for (unsigned i = 1; i < NumRegs; i++) { 3141b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Load one integer register's worth from the stack slot. 3151b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, 3161b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MachinePointerInfo(), 3171b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman false, false, 0); 3181b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Store it to the final location. Remember the store. 3191b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr, 3201b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman ST->getPointerInfo().getWithOffset(Offset), 3211b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman ST->isVolatile(), ST->isNonTemporal(), 3221b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MinAlign(ST->getAlignment(), Offset))); 3231b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Increment the pointers. 3241b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Offset += RegBytes; 3251b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 3261b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Increment); 3271b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); 3281b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman } 3291b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 3301b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // The last store may be partial. Do a truncating store. On big-endian 3311b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // machines this requires an extending load from the stack slot to ensure 3321b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // that the bits are in the right place. 3331b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), 3341b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 8 * (StoredBytes - Offset)); 3351b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 3361b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Load from the stack slot. 3371b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr, 3381b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MachinePointerInfo(), 3391b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MemVT, false, false, 0); 3401b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 3411b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr, 3421b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman ST->getPointerInfo() 3431b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman .getWithOffset(Offset), 3441b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MemVT, ST->isVolatile(), 3451b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman ST->isNonTemporal(), 3461b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MinAlign(ST->getAlignment(), Offset))); 3471b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // The order of the stores doesn't matter - say it with a TokenFactor. 348bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 349bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], 350bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Stores.size()); 351bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL); 352bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 353907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen } 35483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(ST->getMemoryVT().isInteger() && 35583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands !ST->getMemoryVT().isVector() && 356907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen "Unaligned store of unknown type."); 357f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Get the half-size VT 358bceddbdc919fc2ca7bc8c3911586ba93367686f0Ken Dyck EVT NewStoredVT = ST->getMemoryVT().getHalfSizedIntegerVT(*DAG.getContext()); 35983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands int NumBits = NewStoredVT.getSizeInBits(); 360f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio int IncrementSize = NumBits / 8; 361f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 362f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Divide the stored value in two parts. 36395771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson SDValue ShiftAmount = DAG.getConstant(NumBits, 36495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Val.getValueType())); 365475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo = Val; 366bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Hi = DAG.getNode(ISD::SRL, dl, VT, Val, ShiftAmount); 367f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 368f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Store the two parts 369475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Store1, Store2; 370bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr, 371da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo(), NewStoredVT, 3721e559443a17d1b335f697551c6263ba60d5dd827David Greene ST->isVolatile(), ST->isNonTemporal(), Alignment); 373bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 374f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 375dc84650679b6330e0fcdd4cf8bc2a351387db7caDuncan Sands Alignment = MinAlign(Alignment, IncrementSize); 376bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr, 377da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo().getWithOffset(IncrementSize), 3781e559443a17d1b335f697551c6263ba60d5dd827David Greene NewStoredVT, ST->isVolatile(), ST->isNonTemporal(), 3791e559443a17d1b335f697551c6263ba60d5dd827David Greene Alignment); 380f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 381bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 382bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2); 383bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(ST, 0), Result, DUL); 384f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio} 385f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 386f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio/// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads. 387bf923b815d6da97367e3eedab69230918bf128a3Dan Gohmanstatic void 388bf923b815d6da97367e3eedab69230918bf128a3Dan GohmanExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, 389bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman const TargetLowering &TLI, 390bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue &ValResult, SDValue &ChainResult) { 391475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = LD->getChain(); 392475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ptr = LD->getBasePtr(); 393e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = LD->getValueType(0); 394e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT LoadedVT = LD->getMemoryVT(); 395bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl = LD->getDebugLoc(); 39683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (VT.isFloatingPoint() || VT.isVector()) { 39723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT intVT = EVT::getIntegerVT(*DAG.getContext(), LoadedVT.getSizeInBits()); 39805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (TLI.isTypeLegal(intVT)) { 39905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Expand to a (misaligned) integer load of the same size, 40005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // then bitconvert to floating point or vector. 401ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getPointerInfo(), 402ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->isVolatile(), 4031e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->isNonTemporal(), LD->getAlignment()); 404bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue Result = DAG.getNode(ISD::BITCAST, dl, LoadedVT, newLoad); 40505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (VT.isFloatingPoint() && LoadedVT != VT) 406bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result); 407907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen 408bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ValResult = Result; 409bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ChainResult = Chain; 410bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 411ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner } 412bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 413ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Copy the value to a (aligned) stack slot using (unaligned) integer 414ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // loads and stores, then do a (aligned) load from the stack slot. 415ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner EVT RegVT = TLI.getRegisterType(*DAG.getContext(), intVT); 416ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner unsigned LoadedBytes = LoadedVT.getSizeInBits() / 8; 417ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner unsigned RegBytes = RegVT.getSizeInBits() / 8; 418ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner unsigned NumRegs = (LoadedBytes + RegBytes - 1) / RegBytes; 419ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 420ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Make sure the stack slot is also aligned for the register type. 421ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue StackBase = DAG.CreateStackTemporary(LoadedVT, RegVT); 422ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 423ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); 424ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SmallVector<SDValue, 8> Stores; 425ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue StackPtr = StackBase; 426ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner unsigned Offset = 0; 427ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 428ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Do all but one copies using the full register width. 429ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner for (unsigned i = 1; i < NumRegs; i++) { 430ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Load one integer register's worth from the original location. 431ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, 432ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(Offset), 433ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->isVolatile(), LD->isNonTemporal(), 434ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MinAlign(LD->getAlignment(), Offset)); 43505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Follow the load with a store to the stack slot. Remember the store. 436ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr, 4376229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(), false, false, 0)); 438ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Increment the pointers. 439ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Offset += RegBytes; 440ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); 441ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 442ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Increment); 44305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } 444ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 445ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // The last copy may be partial. Do an extending load. 446ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), 447ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 8 * (LoadedBytes - Offset)); 448a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr, 449ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(Offset), 450ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MemVT, LD->isVolatile(), 451ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->isNonTemporal(), 452ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MinAlign(LD->getAlignment(), Offset)); 453ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Follow the load with a store to the stack slot. Remember the store. 454ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // On big-endian machines this requires a truncating store to ensure 455ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // that the bits end up in the right place. 456ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr, 457ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(), MemVT, 458ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, 0)); 459ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 460ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // The order of the stores doesn't matter - say it with a TokenFactor. 461ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], 462ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Stores.size()); 463ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 464ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Finally, perform the original load only redirected to the stack slot. 465a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase, 466ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(), LoadedVT, false, false, 0); 467ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 468ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Callers expect a MERGE_VALUES node. 469bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ValResult = Load; 470bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ChainResult = TF; 471bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 472907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen } 47383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(LoadedVT.isInteger() && !LoadedVT.isVector() && 474e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner "Unaligned load of unsupported type."); 475e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner 4768155d64c2ffab8b17e0fd8e3b7a66fcef6a8ec9dDale Johannesen // Compute the new VT that is half the size of the old one. This is an 4778155d64c2ffab8b17e0fd8e3b7a66fcef6a8ec9dDale Johannesen // integer MVT. 47883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned NumBits = LoadedVT.getSizeInBits(); 479e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NewLoadedVT; 48023b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson NewLoadedVT = EVT::getIntegerVT(*DAG.getContext(), NumBits/2); 481e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner NumBits >>= 1; 482fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 483e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner unsigned Alignment = LD->getAlignment(); 484e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner unsigned IncrementSize = NumBits / 8; 485f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio ISD::LoadExtType HiExtType = LD->getExtensionType(); 486f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 487f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD. 488f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (HiExtType == ISD::NON_EXTLOAD) 489f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio HiExtType = ISD::ZEXTLOAD; 490f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 491f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Load the value in two parts 492475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 493f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (TLI.isLittleEndian()) { 494a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getPointerInfo(), 495ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner NewLoadedVT, LD->isVolatile(), 4961e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->isNonTemporal(), Alignment); 497bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 498f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 499a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, 500ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 501ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner NewLoadedVT, LD->isVolatile(), 5026e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach LD->isNonTemporal(), MinAlign(Alignment,IncrementSize)); 503f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } else { 504a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getPointerInfo(), 505ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner NewLoadedVT, LD->isVolatile(), 5061e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->isNonTemporal(), Alignment); 507bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 508f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 509a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, 510ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 511ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner NewLoadedVT, LD->isVolatile(), 5126e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach LD->isNonTemporal(), MinAlign(Alignment,IncrementSize)); 513f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 514f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 515f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // aggregate the two parts 51695771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson SDValue ShiftAmount = DAG.getConstant(NumBits, 51795771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Hi.getValueType())); 518bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Result = DAG.getNode(ISD::SHL, dl, VT, Hi, ShiftAmount); 519bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Result = DAG.getNode(ISD::OR, dl, VT, Result, Lo); 520f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 521825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 522f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio Hi.getValue(1)); 523f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 524bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ValResult = Result; 525bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ChainResult = TF; 526f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio} 527912095becac923ff614d7b07728eb345ada67765Evan Cheng 5286867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// PerformInsertVectorEltInMemory - Some target cannot handle a variable 5296867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it 5306867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// is necessary to spill the vector being inserted into to memory, perform 5316867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// the insert there, and then read the result back. 532475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize:: 533bb5da918545efb54857a09c983a5a7f22a7e04d4Dale JohannesenPerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx, 534bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl) { 535475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1 = Vec; 536475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp2 = Val; 537475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp3 = Idx; 538fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 5396867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // If the target doesn't support this, we have to spill the input vector 5406867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // to a temporary stack slot, update the element, then reload it. This is 5416867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // badness. We could also load the value into a vector register (either 5426867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // with a "move to register" or "extload into register" instruction, then 5436867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // permute it into place, if the idx is a constant and if the idx is 5446867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // supported by the target. 545e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Tmp1.getValueType(); 546e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT EltVT = VT.getVectorElementType(); 547e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT IdxVT = Tmp3.getValueType(); 548e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PtrVT = TLI.getPointerTy(); 549475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue StackPtr = DAG.CreateStackTemporary(VT); 5506867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 551ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); 552ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng 5536867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Store the vector. 554bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr, 55585ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getFixedStack(SPFI), 5561e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 5576867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 5586867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Truncate or zero extend offset to target pointer type. 5598e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; 560bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Tmp3 = DAG.getNode(CastOpc, dl, PtrVT, Tmp3); 5616867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Add the offset to the index. 562aa9d854b334cab2f29ca6d95413a0946b8a38429Dan Gohman unsigned EltSize = EltVT.getSizeInBits()/8; 563bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Tmp3 = DAG.getNode(ISD::MUL, dl, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT)); 564bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr); 5656867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Store the scalar value. 56685ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2, MachinePointerInfo(), EltVT, 5671e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 5686867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Load the updated vector. 569bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getLoad(VT, dl, Ch, StackPtr, 57085ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getFixedStack(SPFI), false, false, 0); 5716867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman} 5726867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 573e9f1015d1f184a51aaadfd03be0846bd5e7d08a2Mon P Wang 5743f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli FriedmanSDValue SelectionDAGLegalize:: 5753f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli FriedmanExpandINSERT_VECTOR_ELT(SDValue Vec, SDValue Val, SDValue Idx, DebugLoc dl) { 5763f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman if (ConstantSDNode *InsertPos = dyn_cast<ConstantSDNode>(Idx)) { 5773f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // SCALAR_TO_VECTOR requires that the type of the value being inserted 5783f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // match the element type of the vector being created, except for 5793f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // integers in which case the inserted value can be over width. 580e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT EltVT = Vec.getValueType().getVectorElementType(); 5813f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman if (Val.getValueType() == EltVT || 5823f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman (EltVT.isInteger() && Val.getValueType().bitsGE(EltVT))) { 5833f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SDValue ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, 5843f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman Vec.getValueType(), Val); 5853f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman 5863f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman unsigned NumElts = Vec.getValueType().getVectorNumElements(); 5873f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // We generate a shuffle of InVec and ScVec, so the shuffle mask 5883f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // should be 0,1,2,3,4,5... with the appropriate element replaced with 5893f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // elt 0 of the RHS. 5903f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SmallVector<int, 8> ShufOps; 5913f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman for (unsigned i = 0; i != NumElts; ++i) 5923f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman ShufOps.push_back(i != InsertPos->getZExtValue() ? i : NumElts); 5933f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman 5943f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman return DAG.getVectorShuffle(Vec.getValueType(), dl, Vec, ScVec, 5953f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman &ShufOps[0]); 5963f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman } 5973f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman } 5983f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman return PerformInsertVectorEltInMemory(Vec, Val, Idx, dl); 5993f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman} 6003f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman 6017ef3d178660b82d1571757e49f44b004d772a116Eli FriedmanSDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) { 6027ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr' 6037ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // FIXME: We shouldn't do this for TargetConstantFP's. 6047ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // FIXME: move this to the DAG Combiner! Note that we can't regress due 6057ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // to phase ordering between legalized code and the dag combiner. This 6067ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // probably means that we need to integrate dag combiner and legalizer 6077ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // together. 6087ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // We generally can't do this one for long doubles. 6097ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue Tmp1 = ST->getChain(); 6107ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue Tmp2 = ST->getBasePtr(); 6117ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue Tmp3; 6127ef3d178660b82d1571757e49f44b004d772a116Eli Friedman unsigned Alignment = ST->getAlignment(); 6137ef3d178660b82d1571757e49f44b004d772a116Eli Friedman bool isVolatile = ST->isVolatile(); 6141e559443a17d1b335f697551c6263ba60d5dd827David Greene bool isNonTemporal = ST->isNonTemporal(); 6157ef3d178660b82d1571757e49f44b004d772a116Eli Friedman DebugLoc dl = ST->getDebugLoc(); 6167ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) { 617825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (CFP->getValueType(0) == MVT::f32 && 61875b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman TLI.isTypeLegal(MVT::i32)) { 6197ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Tmp3 = DAG.getConstant(CFP->getValueAPF(). 6207ef3d178660b82d1571757e49f44b004d772a116Eli Friedman bitcastToAPInt().zextOrTrunc(32), 621825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::i32); 622da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 623da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner isVolatile, isNonTemporal, Alignment); 624da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner } 625bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 626da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner if (CFP->getValueType(0) == MVT::f64) { 6277ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // If this target supports 64-bit registers, do a single 64-bit store. 62875b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman if (TLI.isTypeLegal(MVT::i64)) { 6297ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). 630825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson zextOrTrunc(64), MVT::i64); 631da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 632da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner isVolatile, isNonTemporal, Alignment); 633da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner } 634bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 63575b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman if (TLI.isTypeLegal(MVT::i32) && !ST->isVolatile()) { 6367ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Otherwise, if the target supports 32-bit registers, use 2 32-bit 6377ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // stores. If the target supports neither 32- nor 64-bits, this 6387ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // xform is certainly not worth it. 6397ef3d178660b82d1571757e49f44b004d772a116Eli Friedman const APInt &IntVal =CFP->getValueAPF().bitcastToAPInt(); 64040f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad SDValue Lo = DAG.getConstant(IntVal.trunc(32), MVT::i32); 641825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue Hi = DAG.getConstant(IntVal.lshr(32).trunc(32), MVT::i32); 6427ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (TLI.isBigEndian()) std::swap(Lo, Hi); 6437ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 644da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getPointerInfo(), isVolatile, 645da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner isNonTemporal, Alignment); 6467ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 6477ef3d178660b82d1571757e49f44b004d772a116Eli Friedman DAG.getIntPtrConstant(4)); 648da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, 649da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo().getWithOffset(4), 6501e559443a17d1b335f697551c6263ba60d5dd827David Greene isVolatile, isNonTemporal, MinAlign(Alignment, 4U)); 6517ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 652825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 6537ef3d178660b82d1571757e49f44b004d772a116Eli Friedman } 6547ef3d178660b82d1571757e49f44b004d772a116Eli Friedman } 6557ef3d178660b82d1571757e49f44b004d772a116Eli Friedman } 6568e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng return SDValue(0, 0); 6577ef3d178660b82d1571757e49f44b004d772a116Eli Friedman} 6587ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 6596a109f9d70bf7f75541400145a7a89880cc48166Dan Gohman/// LegalizeOp - Return a legal replacement for the given operation, with 6606a109f9d70bf7f75541400145a7a89880cc48166Dan Gohman/// all legal operands. 661bf923b815d6da97367e3eedab69230918bf128a3Dan Gohmanvoid SelectionDAGLegalize::LegalizeOp(SDNode *Node) { 662bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (Node->getOpcode() == ISD::TargetConstant) // Allow illegal target nodes. 663bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 664fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 6657d2ad624fa749a6d3edac0d94e9c107989c16304Dale Johannesen DebugLoc dl = Node->getDebugLoc(); 666e3304a3d24afc952d3cb415d1b504d973573c5c5Chris Lattner 6671fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 66875b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman assert(TLI.getTypeAction(*DAG.getContext(), Node->getValueType(i)) == 66975b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman TargetLowering::TypeLegal && 6701fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman "Unexpected illegal type!"); 6711fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman 6721fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 67375b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman assert((TLI.getTypeAction(*DAG.getContext(), 67475b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman Node->getOperand(i).getValueType()) == 67575b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman TargetLowering::TypeLegal || 6761fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman Node->getOperand(i).getOpcode() == ISD::TargetConstant) && 6771fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman "Unexpected illegal type!"); 6783e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 679475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1, Tmp2, Tmp3, Tmp4; 680456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner bool isCustom = false; 681fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 6828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Figure out the correct action; the way to query this varies by opcode 6836b9a293a0c7d86c07d704da5facb34cc03ce1d02Bill Wendling TargetLowering::LegalizeAction Action = TargetLowering::Legal; 6848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman bool SimpleFinishLegalizing = true; 6853e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner switch (Node->getOpcode()) { 6868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_W_CHAIN: 6878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_WO_CHAIN: 6888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_VOID: 6898c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VAARG: 6908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::STACKSAVE: 691825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Action = TLI.getOperationAction(Node->getOpcode(), MVT::Other); 6928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 6938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 6948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 6958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_VECTOR_ELT: 6968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), 6978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0).getValueType()); 6988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 6998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND_INREG: 7008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SIGN_EXTEND_INREG: { 701e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT InnerType = cast<VTSDNode>(Node->getOperand(1))->getVT(); 7028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), InnerType); 7038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 705327236cd6c211e54fc6288b0ac2b413901cc0611Eli Friedman case ISD::ATOMIC_STORE: { 706327236cd6c211e54fc6288b0ac2b413901cc0611Eli Friedman Action = TLI.getOperationAction(Node->getOpcode(), 707327236cd6c211e54fc6288b0ac2b413901cc0611Eli Friedman Node->getOperand(2).getValueType()); 708327236cd6c211e54fc6288b0ac2b413901cc0611Eli Friedman break; 709327236cd6c211e54fc6288b0ac2b413901cc0611Eli Friedman } 7103be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman case ISD::SELECT_CC: 7113be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman case ISD::SETCC: 7123be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman case ISD::BR_CC: { 7133be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman unsigned CCOperand = Node->getOpcode() == ISD::SELECT_CC ? 4 : 7143be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Node->getOpcode() == ISD::SETCC ? 2 : 1; 7153be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman unsigned CompareOperand = Node->getOpcode() == ISD::BR_CC ? 2 : 0; 716e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpVT = Node->getOperand(CompareOperand).getValueType(); 7173be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman ISD::CondCode CCCode = 7183be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman cast<CondCodeSDNode>(Node->getOperand(CCOperand))->get(); 7193be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Action = TLI.getCondCodeAction(CCCode, OpVT); 7203be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (Action == TargetLowering::Legal) { 7213be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (Node->getOpcode() == ISD::SELECT_CC) 7223be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Action = TLI.getOperationAction(Node->getOpcode(), 7233be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Node->getValueType(0)); 7243be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman else 7253be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Action = TLI.getOperationAction(Node->getOpcode(), OpVT); 7263be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman } 7273be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman break; 7283be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman } 7298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::LOAD: 7308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::STORE: 731ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // FIXME: Model these properly. LOAD and STORE are complicated, and 732ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // STORE expects the unlegalized operand in some cases. 733ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman SimpleFinishLegalizing = false; 734ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 7358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CALLSEQ_START: 7368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CALLSEQ_END: 737ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // FIXME: This shouldn't be necessary. These nodes have special properties 738ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // dealing with the recursive nature of legalization. Removing this 739ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // special case should be done as part of making LegalizeDAG non-recursive. 740ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman SimpleFinishLegalizing = false; 741ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 7428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_ELEMENT: 7438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLT_ROUNDS_: 7448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SADDO: 7458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SSUBO: 7468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UADDO: 7478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::USUBO: 7488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SMULO: 7498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UMULO: 7508c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FPOWI: 7518c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::MERGE_VALUES: 7528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_RETURN: 7538c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAME_TO_ARGS_OFFSET: 754c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach case ISD::EH_SJLJ_SETJMP: 755c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach case ISD::EH_SJLJ_LONGJMP: 756e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach case ISD::EH_SJLJ_DISPATCHSETUP: 757f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman // These operations lie about being legal: when they claim to be legal, 758f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman // they should actually be expanded. 7598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 7608c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Action == TargetLowering::Legal) 7618c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TargetLowering::Expand; 7628c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7634a544a79bd735967f1d33fe675ae4566dbd17813Duncan Sands case ISD::INIT_TRAMPOLINE: 7644a544a79bd735967f1d33fe675ae4566dbd17813Duncan Sands case ISD::ADJUST_TRAMPOLINE: 7658c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAMEADDR: 7668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::RETURNADDR: 7674bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // These operations lie about being legal: when they claim to be legal, 7684bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // they should actually be custom-lowered. 7694bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 7704bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman if (Action == TargetLowering::Legal) 7714bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Action = TargetLowering::Custom; 7728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7733e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner default: 774d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner if (Node->getOpcode() >= ISD::BUILTIN_OP_END) { 7758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TargetLowering::Legal; 7768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else { 7778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 7788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 7798c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7808c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 781d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner 7828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (SimpleFinishLegalizing) { 783bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SmallVector<SDValue, 8> Ops; 7848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 785bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Ops.push_back(Node->getOperand(i)); 7868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 7878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman default: break; 7888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SHL: 7898c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SRL: 7908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SRA: 7918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::ROTL: 7928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::ROTR: 7938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Legalizing shifts/rotates requires adjusting the shift amount 7948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // to the appropriate width. 795bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (!Ops[1].getValueType().isVector()) { 796bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue SAO = DAG.getShiftAmountOperand(Ops[0].getValueType(), Ops[1]); 797bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman HandleSDNode Handle(SAO); 798bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman LegalizeOp(SAO.getNode()); 799bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Ops[1] = Handle.getValue(); 800bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 8018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 802db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman case ISD::SRL_PARTS: 803db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman case ISD::SRA_PARTS: 804db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman case ISD::SHL_PARTS: 805db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman // Legalizing shifts/rotates requires adjusting the shift amount 806db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman // to the appropriate width. 807bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (!Ops[2].getValueType().isVector()) { 808bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue SAO = DAG.getShiftAmountOperand(Ops[0].getValueType(), Ops[2]); 809bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman HandleSDNode Handle(SAO); 810bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman LegalizeOp(SAO.getNode()); 811bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Ops[2] = Handle.getValue(); 812bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 8132c9489d6e96d99f77b6c31919805b5e61954deb2Dan Gohman break; 8148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 816bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDNode *NewNode = DAG.UpdateNodeOperands(Node, Ops.data(), Ops.size()); 817bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (NewNode != Node) { 818bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(Node, NewNode, this); 819bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 820bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.TransferDbgValues(SDValue(Node, i), SDValue(NewNode, i)); 821bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.RemoveDeadNode(Node, this); 822bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Node = NewNode; 823bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 8248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Action) { 8258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Legal: 826bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 8278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Custom: 8288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // FIXME: The handling for custom lowering with multiple results is 8298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // a complete mess. 830bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = TLI.LowerOperation(SDValue(Node, 0), DAG); 8318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Tmp1.getNode()) { 832bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SmallVector<SDValue, 8> ResultVals; 8338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) { 8348c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (e == 1) 8358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals.push_back(Tmp1); 8368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman else 8378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals.push_back(Tmp1.getValue(i)); 8388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 839bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (Tmp1.getNode() != Node || Tmp1.getResNo() != 0) { 840bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(Node, ResultVals.data(), this); 841bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 842bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.TransferDbgValues(SDValue(Node, i), ResultVals[i]); 843bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.RemoveDeadNode(Node, this); 844bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 845bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 8468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 8488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // FALL THROUGH 8498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Expand: 850bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ExpandNode(Node); 851bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 8528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Promote: 853bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman PromoteNode(Node); 854bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 855d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner } 8568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 8588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 8598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman default: 860e37fe9b3a1cadceb42ac27fa0718f5a10ea2f0e6Jim Laskey#ifndef NDEBUG 861993aacedfdc3f156f667b4efa280ee79eab3b898David Greene dbgs() << "NODE: "; 862993aacedfdc3f156f667b4efa280ee79eab3b898David Greene Node->dump( &DAG); 863993aacedfdc3f156f667b4efa280ee79eab3b898David Greene dbgs() << "\n"; 864e37fe9b3a1cadceb42ac27fa0718f5a10ea2f0e6Jim Laskey#endif 86535a389344d21178ee280c2410401b2060b5b879cChris Lattner assert(0 && "Do not know how to legalize this operator!"); 86698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 867bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman case ISD::CALLSEQ_START: 86862c1d00dfd38996f381edae55e1028b8e52a1107Duncan Sands case ISD::CALLSEQ_END: 869bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman break; 870f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng case ISD::LOAD: { 871466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng LoadSDNode *LD = cast<LoadSDNode>(Node); 872bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = LD->getChain(); // Legalize the chain. 873bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp2 = LD->getBasePtr(); // Legalize the base pointer. 8742d86ea21dd76647cb054fd5d27df9e49efc672b6Andrew Lenharth 875466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng ISD::LoadExtType ExtType = LD->getExtensionType(); 876466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng if (ExtType == ISD::NON_EXTLOAD) { 877e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 878bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Node = DAG.UpdateNodeOperands(Node, Tmp1, Tmp2, LD->getOffset()); 879bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp3 = SDValue(Node, 0); 880bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp4 = SDValue(Node, 1); 881fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 882466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 88335a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "This action is not supported yet!"); 884f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio case TargetLowering::Legal: 885f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If this is an unaligned load and the target doesn't support it, 886f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // expand it. 887bc037cfcdef8e88274d7dd167fb9d8ba545f2229Benjamin Kramer if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { 888db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); 889e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng unsigned ABIAlignment = TLI.getTargetData()->getABITypeAlignment(Ty); 890f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (LD->getAlignment() < ABIAlignment){ 891bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ExpandUnalignedLoad(cast<LoadSDNode>(Node), 892bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG, TLI, Tmp3, Tmp4); 893f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 894f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 895f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio break; 896466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng case TargetLowering::Custom: 897466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp1 = TLI.LowerOperation(Tmp3, DAG); 898ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) { 899bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp3 = Tmp1; 900bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp4 = Tmp1.getValue(1); 901466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 902466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 903466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng case TargetLowering::Promote: { 904466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // Only promote a load of vector type to another. 90583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(VT.isVector() && "Cannot promote this load!"); 906466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // Change base type to a different vector type. 907e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT); 908466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng 909ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getPointerInfo(), 9101e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->isVolatile(), LD->isNonTemporal(), 9111e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->getAlignment()); 912bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp3 = DAG.getNode(ISD::BITCAST, dl, VT, Tmp1); 913bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp4 = Tmp1.getValue(1); 914466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 915f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 916466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 917fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Since loads produce two values, make sure to remember that we 918466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // legalized both of them. 919bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), Tmp3); 920bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), Tmp4); 921bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman return; 9223d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } 923bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 9243d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner EVT SrcVT = LD->getMemoryVT(); 9253d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned SrcWidth = SrcVT.getSizeInBits(); 9263d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned Alignment = LD->getAlignment(); 9273d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner bool isVolatile = LD->isVolatile(); 9283d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner bool isNonTemporal = LD->isNonTemporal(); 9293d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 9303d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (SrcWidth != SrcVT.getStoreSizeInBits() && 9313d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Some targets pretend to have an i1 loading operation, and actually 9323d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // load an i8. This trick is correct for ZEXTLOAD because the top 7 9333d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // bits are guaranteed to be zero; it helps the optimizers understand 9343d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // that these bits are zero. It is also useful for EXTLOAD, since it 9353d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // tells the optimizers that those bits are undefined. It would be 9363d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // nice to have an effective generic way of getting these benefits... 9373d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Until such a way is found, don't insist on promoting i1 here. 9383d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner (SrcVT != MVT::i1 || 9393d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner TLI.getLoadExtAction(ExtType, MVT::i1) == TargetLowering::Promote)) { 9403d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Promote to a byte-sized load if not loading an integral number of 9413d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // bytes. For example, promote EXTLOAD:i20 -> EXTLOAD:i24. 9423d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned NewWidth = SrcVT.getStoreSizeInBits(); 9433d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner EVT NVT = EVT::getIntegerVT(*DAG.getContext(), NewWidth); 9443d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner SDValue Ch; 9453d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 9463d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // The extra bits are guaranteed to be zero, since we stored them that 9473d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // way. A zext load from NVT thus automatically gives zext from SrcVT. 9483d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 9493d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ISD::LoadExtType NewExtType = 9503d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ExtType == ISD::ZEXTLOAD ? ISD::ZEXTLOAD : ISD::EXTLOAD; 9513d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 952bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 953bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getExtLoad(NewExtType, dl, Node->getValueType(0), 954bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1, Tmp2, LD->getPointerInfo(), 955bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman NVT, isVolatile, isNonTemporal, Alignment); 9563d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 9573d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Ch = Result.getValue(1); // The chain. 9583d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 9593d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (ExtType == ISD::SEXTLOAD) 9603d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Having the top bits zero doesn't help when sign extending. 9613d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, 9623d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result.getValueType(), 9633d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result, DAG.getValueType(SrcVT)); 9643d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner else if (ExtType == ISD::ZEXTLOAD || NVT == Result.getValueType()) 9653d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // All the top bits are guaranteed to be zero - inform the optimizers. 9663d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = DAG.getNode(ISD::AssertZext, dl, 9673d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result.getValueType(), Result, 9683d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner DAG.getValueType(SrcVT)); 9693d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 970bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = Result; 971bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp2 = Ch; 9723d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } else if (SrcWidth & (SrcWidth - 1)) { 9733d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // If not loading a power-of-2 number of bits, expand as two loads. 9743d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(!SrcVT.isVector() && "Unsupported extload!"); 9753d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned RoundWidth = 1 << Log2_32(SrcWidth); 9763d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(RoundWidth < SrcWidth); 9773d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned ExtraWidth = SrcWidth - RoundWidth; 9783d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(ExtraWidth < RoundWidth); 9793d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(!(RoundWidth % 8) && !(ExtraWidth % 8) && 9803d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner "Load size not an integral number of bytes!"); 9813d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner EVT RoundVT = EVT::getIntegerVT(*DAG.getContext(), RoundWidth); 9823d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner EVT ExtraVT = EVT::getIntegerVT(*DAG.getContext(), ExtraWidth); 9833d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner SDValue Lo, Hi, Ch; 9843d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned IncrementSize; 9853d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 9863d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (TLI.isLittleEndian()) { 9873d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // EXTLOAD:i24 -> ZEXTLOAD:i16 | (shl EXTLOAD@+2:i8, 16) 9883d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Load the bottom RoundWidth bits. 989a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, Node->getValueType(0), 9903d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1, Tmp2, 9913d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo(), RoundVT, isVolatile, 9923d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner isNonTemporal, Alignment); 9933d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 9943d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Load the remaining ExtraWidth bits. 9953d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner IncrementSize = RoundWidth / 8; 9963d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 9973d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner DAG.getIntPtrConstant(IncrementSize)); 998a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, 9993d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 10003d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ExtraVT, isVolatile, isNonTemporal, 10013d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner MinAlign(Alignment, IncrementSize)); 10023d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 10033d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Build a factor node to remember that this load is independent of 10043d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // the other one. 10053d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 10063d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Hi.getValue(1)); 10073d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 10083d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Move the top bits to the right place. 10093d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, 101095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(RoundWidth, 101195771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Hi.getValueType()))); 10123d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 10133d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Join the hi and lo parts. 1014bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); 10153d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } else { 10163d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Big endian - avoid unaligned loads. 10173d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // EXTLOAD:i24 -> (shl EXTLOAD:i16, 8) | ZEXTLOAD@+2:i8 10183d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Load the top RoundWidth bits. 1019a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, 10203d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo(), RoundVT, isVolatile, 10213d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner isNonTemporal, Alignment); 10223d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 10233d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Load the remaining ExtraWidth bits. 10243d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner IncrementSize = RoundWidth / 8; 10253d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 10263d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner DAG.getIntPtrConstant(IncrementSize)); 10273d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Lo = DAG.getExtLoad(ISD::ZEXTLOAD, 1028a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings dl, Node->getValueType(0), Tmp1, Tmp2, 10293d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 10303d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ExtraVT, isVolatile, isNonTemporal, 10313d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner MinAlign(Alignment, IncrementSize)); 10323d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 10333d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Build a factor node to remember that this load is independent of 10343d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // the other one. 10353d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 10363d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Hi.getValue(1)); 10373d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 10383d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Move the top bits to the right place. 10393d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, 104095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(ExtraWidth, 104195771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Hi.getValueType()))); 10423d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 10433d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Join the hi and lo parts. 1044bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); 10453d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } 1046f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1047bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp2 = Ch; 10483d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } else { 10493d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner switch (TLI.getLoadExtAction(ExtType, SrcVT)) { 10503d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner default: assert(0 && "This action is not supported yet!"); 10513d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case TargetLowering::Custom: 10523d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner isCustom = true; 10533d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // FALLTHROUGH 10543d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case TargetLowering::Legal: 1055bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Node = DAG.UpdateNodeOperands(Node, 1056bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1, Tmp2, LD->getOffset()); 1057bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = SDValue(Node, 0); 1058bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp2 = SDValue(Node, 1); 10593d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 10603d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (isCustom) { 1061bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp3 = TLI.LowerOperation(SDValue(Node, 0), DAG); 10623d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (Tmp3.getNode()) { 1063bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = Tmp3; 1064bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp2 = Tmp3.getValue(1); 10653d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } 1066f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } else { 10673d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // If this is an unaligned load and the target doesn't support it, 10683d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // expand it. 10693d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { 1070db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = 10713d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); 10723d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned ABIAlignment = 10733d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner TLI.getTargetData()->getABITypeAlignment(Ty); 10743d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (LD->getAlignment() < ABIAlignment){ 1075bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ExpandUnalignedLoad(cast<LoadSDNode>(Node), 1076bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG, TLI, Tmp1, Tmp2); 1077f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1078f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 10793d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } 10803d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner break; 10813d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case TargetLowering::Expand: 108275b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman if (!TLI.isLoadExtLegal(ISD::EXTLOAD, SrcVT) && TLI.isTypeLegal(SrcVT)) { 10833d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, 10843d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo(), 10853d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->isVolatile(), LD->isNonTemporal(), 10863d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getAlignment()); 10873d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned ExtendOp; 10883d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner switch (ExtType) { 10893d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case ISD::EXTLOAD: 10903d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ExtendOp = (SrcVT.isFloatingPoint() ? 10913d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ISD::FP_EXTEND : ISD::ANY_EXTEND); 1092f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands break; 10933d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case ISD::SEXTLOAD: ExtendOp = ISD::SIGN_EXTEND; break; 10943d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case ISD::ZEXTLOAD: ExtendOp = ISD::ZERO_EXTEND; break; 10953d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner default: llvm_unreachable("Unexpected extend load type!"); 1096f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } 1097bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = DAG.getNode(ExtendOp, dl, Node->getValueType(0), Load); 1098bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp2 = Load.getValue(1); 1099466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 1100466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 1101c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1102e9b58d0aac4e89b53a4be0e6f289b66649e1512bNadav Rotem assert(!SrcVT.isVector() && 1103e9b58d0aac4e89b53a4be0e6f289b66649e1512bNadav Rotem "Vector Loads are handled in LegalizeVectorOps"); 1104c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 11053d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // FIXME: This does not work for vectors on most targets. Sign- and 11063d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // zero-extend operations are currently folded into extending loads, 11073d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // whether they are legal or not, and then we end up here without any 11083d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // support for legalizing them. 11093d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(ExtType != ISD::EXTLOAD && 11103d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner "EXTLOAD should always be supported!"); 11113d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Turn the unsupported load into an EXTLOAD followed by an explicit 11123d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // zero/sign extend inreg. 1113bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0), 1114bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1, Tmp2, LD->getPointerInfo(), SrcVT, 1115bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman LD->isVolatile(), LD->isNonTemporal(), 1116bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman LD->getAlignment()); 11173d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner SDValue ValRes; 11183d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (ExtType == ISD::SEXTLOAD) 11193d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, 11203d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result.getValueType(), 11213d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result, DAG.getValueType(SrcVT)); 11223d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner else 1123dd11ea4a372b992775f67b64fb703edf2de0d27bDan Gohman ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT.getScalarType()); 1124bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = ValRes; 1125bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp2 = Result.getValue(1); 11263d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner break; 11279d416f713e8b9e4f0c0c2b3f6f57ce2dd8993209Andrew Lenharth } 112801ff7216dd7829d4094754086baf28aa2d7149acChris Lattner } 11293d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 11303d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Since loads produce two values, make sure to remember that we legalized 11313d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // both of them. 1132bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 0), Tmp1); 1133bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesOfValueWith(SDValue(Node, 1), Tmp2); 1134bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman break; 113501ff7216dd7829d4094754086baf28aa2d7149acChris Lattner } 1136f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng case ISD::STORE: { 11378b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng StoreSDNode *ST = cast<StoreSDNode>(Node); 1138bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = ST->getChain(); 1139bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp2 = ST->getBasePtr(); 1140d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman unsigned Alignment = ST->getAlignment(); 1141d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman bool isVolatile = ST->isVolatile(); 11421e559443a17d1b335f697551c6263ba60d5dd827David Greene bool isNonTemporal = ST->isNonTemporal(); 11438b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng 11448b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng if (!ST->isTruncatingStore()) { 11457ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) { 1146bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(ST, OptStore, this); 11477ef3d178660b82d1571757e49f44b004d772a116Eli Friedman break; 1148d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner } 1149fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1150957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman { 1151bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp3 = ST->getValue(); 1152bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Node = DAG.UpdateNodeOperands(Node, 1153bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1, Tmp3, Tmp2, 1154bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ST->getOffset()); 11558b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng 1156e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Tmp3.getValueType(); 11578b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng switch (TLI.getOperationAction(ISD::STORE, VT)) { 115835a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "This action is not supported yet!"); 1159f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio case TargetLowering::Legal: 1160f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If this is an unaligned store and the target doesn't support it, 1161f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // expand it. 1162bc037cfcdef8e88274d7dd167fb9d8ba545f2229Benjamin Kramer if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { 1163db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); 11646e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty); 1165f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (ST->getAlignment() < ABIAlignment) 1166bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ExpandUnalignedStore(cast<StoreSDNode>(Node), 1167bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG, TLI, this); 1168f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1169f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio break; 11708b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng case TargetLowering::Custom: 1171bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp1 = TLI.LowerOperation(SDValue(Node, 0), DAG); 1172bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (Tmp1.getNode()) 1173bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(Node, 0), Tmp1, this); 11748b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng break; 1175bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman case TargetLowering::Promote: { 117683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(VT.isVector() && "Unknown legal promote case!"); 1177bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp3 = DAG.getNode(ISD::BITCAST, dl, 11788b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3); 1179bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 1180bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getStore(Tmp1, dl, Tmp3, Tmp2, 1181bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ST->getPointerInfo(), isVolatile, 1182bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman isNonTemporal, Alignment); 1183bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); 11848b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng break; 11858b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } 1186bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 11872efce0a589e2a688a1a06b5dc2ed0db32ae79924Chris Lattner break; 1188f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 11898b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } else { 1190bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Tmp3 = ST->getValue(); 11917e857201f387d004571e6058e2ea709163500f38Duncan Sands 1192e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT StVT = ST->getMemoryVT(); 119383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned StWidth = StVT.getSizeInBits(); 11947e857201f387d004571e6058e2ea709163500f38Duncan Sands 119583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (StWidth != StVT.getStoreSizeInBits()) { 11967e857201f387d004571e6058e2ea709163500f38Duncan Sands // Promote to a byte-sized store with upper bits zero if not 11977e857201f387d004571e6058e2ea709163500f38Duncan Sands // storing an integral number of bytes. For example, promote 11987e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1) 1199adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng EVT NVT = EVT::getIntegerVT(*DAG.getContext(), 1200adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng StVT.getStoreSizeInBits()); 1201a1c415cfc2dba4446021f322e4b7a43534a96f1aNadav Rotem Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT); 1202bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 1203bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 1204bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman NVT, isVolatile, isNonTemporal, Alignment); 1205bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); 12067e857201f387d004571e6058e2ea709163500f38Duncan Sands } else if (StWidth & (StWidth - 1)) { 12077e857201f387d004571e6058e2ea709163500f38Duncan Sands // If not storing a power-of-2 number of bits, expand as two stores. 1208bceddbdc919fc2ca7bc8c3911586ba93367686f0Ken Dyck assert(!StVT.isVector() && "Unsupported truncstore!"); 12097e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned RoundWidth = 1 << Log2_32(StWidth); 12107e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(RoundWidth < StWidth); 12117e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned ExtraWidth = StWidth - RoundWidth; 12127e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(ExtraWidth < RoundWidth); 12137e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(!(RoundWidth % 8) && !(ExtraWidth % 8) && 12147e857201f387d004571e6058e2ea709163500f38Duncan Sands "Store size not an integral number of bytes!"); 121523b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT RoundVT = EVT::getIntegerVT(*DAG.getContext(), RoundWidth); 121623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT ExtraVT = EVT::getIntegerVT(*DAG.getContext(), ExtraWidth); 1217475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 12187e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned IncrementSize; 12197e857201f387d004571e6058e2ea709163500f38Duncan Sands 12207e857201f387d004571e6058e2ea709163500f38Duncan Sands if (TLI.isLittleEndian()) { 12217e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 X, TRUNCSTORE@+2:i8 (srl X, 16) 12227e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the bottom RoundWidth bits. 1223da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 1224da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner RoundVT, 12251e559443a17d1b335f697551c6263ba60d5dd827David Greene isVolatile, isNonTemporal, Alignment); 12267e857201f387d004571e6058e2ea709163500f38Duncan Sands 12277e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the remaining ExtraWidth bits. 12287e857201f387d004571e6058e2ea709163500f38Duncan Sands IncrementSize = RoundWidth / 8; 1229ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 12307e857201f387d004571e6058e2ea709163500f38Duncan Sands DAG.getIntPtrConstant(IncrementSize)); 1231ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, 123295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(RoundWidth, 123395771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Tmp3.getValueType()))); 1234da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, 1235da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo().getWithOffset(IncrementSize), 1236da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ExtraVT, isVolatile, isNonTemporal, 12377e857201f387d004571e6058e2ea709163500f38Duncan Sands MinAlign(Alignment, IncrementSize)); 12387e857201f387d004571e6058e2ea709163500f38Duncan Sands } else { 12397e857201f387d004571e6058e2ea709163500f38Duncan Sands // Big endian - avoid unaligned stores. 12407e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE@+2:i8 X 12417e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the top RoundWidth bits. 1242ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, 124395771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(ExtraWidth, 124495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Tmp3.getValueType()))); 1245da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getPointerInfo(), 1246da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner RoundVT, isVolatile, isNonTemporal, Alignment); 12477e857201f387d004571e6058e2ea709163500f38Duncan Sands 12487e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the remaining ExtraWidth bits. 12497e857201f387d004571e6058e2ea709163500f38Duncan Sands IncrementSize = RoundWidth / 8; 1250ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 12517e857201f387d004571e6058e2ea709163500f38Duncan Sands DAG.getIntPtrConstant(IncrementSize)); 1252da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, 1253da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo().getWithOffset(IncrementSize), 1254da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ExtraVT, isVolatile, isNonTemporal, 12557e857201f387d004571e6058e2ea709163500f38Duncan Sands MinAlign(Alignment, IncrementSize)); 12567e857201f387d004571e6058e2ea709163500f38Duncan Sands } 1257c7029805ef35ce9805931067b841e6af11db382eChris Lattner 12587e857201f387d004571e6058e2ea709163500f38Duncan Sands // The order of the stores doesn't matter. 1259bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 1260bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); 12617e857201f387d004571e6058e2ea709163500f38Duncan Sands } else { 12627e857201f387d004571e6058e2ea709163500f38Duncan Sands if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() || 12637e857201f387d004571e6058e2ea709163500f38Duncan Sands Tmp2 != ST->getBasePtr()) 1264bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Node = DAG.UpdateNodeOperands(Node, Tmp1, Tmp3, Tmp2, 1265bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ST->getOffset()); 12667e857201f387d004571e6058e2ea709163500f38Duncan Sands 12677e857201f387d004571e6058e2ea709163500f38Duncan Sands switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) { 126835a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "This action is not supported yet!"); 12697e857201f387d004571e6058e2ea709163500f38Duncan Sands case TargetLowering::Legal: 12707e857201f387d004571e6058e2ea709163500f38Duncan Sands // If this is an unaligned store and the target doesn't support it, 12717e857201f387d004571e6058e2ea709163500f38Duncan Sands // expand it. 1272bc037cfcdef8e88274d7dd167fb9d8ba545f2229Benjamin Kramer if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { 1273db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); 12746e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty); 12757e857201f387d004571e6058e2ea709163500f38Duncan Sands if (ST->getAlignment() < ABIAlignment) 1276bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman ExpandUnalignedStore(cast<StoreSDNode>(Node), DAG, TLI, this); 12777e857201f387d004571e6058e2ea709163500f38Duncan Sands } 12787e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 12797e857201f387d004571e6058e2ea709163500f38Duncan Sands case TargetLowering::Custom: 1280bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(Node, 0), 1281bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman TLI.LowerOperation(SDValue(Node, 0), DAG), 1282bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman this); 12837e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 1284e63e5ab50ab37fd59cc6e815fffcb90e75537ca3Dan Gohman case TargetLowering::Expand: 1285e9b58d0aac4e89b53a4be0e6f289b66649e1512bNadav Rotem assert(!StVT.isVector() && 1286e9b58d0aac4e89b53a4be0e6f289b66649e1512bNadav Rotem "Vector Stores are handled in LegalizeVectorOps"); 1287c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 12887e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i16 i32 -> STORE i16 128975b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman assert(TLI.isTypeLegal(StVT) && "Do not know how to expand this store!"); 1290ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3); 1291bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 1292bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 1293bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman isVolatile, isNonTemporal, Alignment); 1294bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); 12957e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 1296f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 12978b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } 12983e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 12993e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 1300f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 130145b8caf1c5a1fd8337038d64c6da8fba2d299fdfChris Lattner } 13023e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 13033e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 13043d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli FriedmanSDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) { 13053d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue Vec = Op.getOperand(0); 13063d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue Idx = Op.getOperand(1); 13073d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman DebugLoc dl = Op.getDebugLoc(); 13083d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman // Store the value to a temporary stack slot, then LOAD the returned part. 13093d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); 13106229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 13116229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(), false, false, 0); 13123d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 13133d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman // Add the offset to the index. 1314aa9d854b334cab2f29ca6d95413a0946b8a38429Dan Gohman unsigned EltSize = 1315aa9d854b334cab2f29ca6d95413a0946b8a38429Dan Gohman Vec.getValueType().getVectorElementType().getSizeInBits()/8; 13163d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx, 13173d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman DAG.getConstant(EltSize, Idx.getValueType())); 13183d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 13193d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman if (Idx.getValueType().bitsGT(TLI.getPointerTy())) 13203d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx); 13213d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman else 13223d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); 13233d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 13243d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr); 13253d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 1326c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman if (Op.getValueType().isVector()) 1327ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr,MachinePointerInfo(), 13281e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 1329a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings return DAG.getExtLoad(ISD::EXTLOAD, dl, Op.getValueType(), Ch, StackPtr, 13303d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner MachinePointerInfo(), 13313d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Vec.getValueType().getVectorElementType(), 13323d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner false, false, 0); 13333d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman} 13343d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 1335cfe33c46aa50f04adb0431243e7d25f79b719ac6David GreeneSDValue SelectionDAGLegalize::ExpandInsertToVectorThroughStack(SDValue Op) { 1336cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene assert(Op.getValueType().isVector() && "Non-vector insert subvector!"); 1337cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1338cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue Vec = Op.getOperand(0); 1339cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue Part = Op.getOperand(1); 1340cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue Idx = Op.getOperand(2); 1341cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene DebugLoc dl = Op.getDebugLoc(); 1342cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1343cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Store the value to a temporary stack slot, then LOAD the returned part. 1344cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1345cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); 1346cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene int FI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); 1347cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(FI); 1348cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1349cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // First store the whole vector. 1350cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo, 1351cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene false, false, 0); 1352cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1353cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Then store the inserted part. 1354cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1355cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Add the offset to the index. 1356cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene unsigned EltSize = 1357cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Vec.getValueType().getVectorElementType().getSizeInBits()/8; 1358cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1359cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx, 1360cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene DAG.getConstant(EltSize, Idx.getValueType())); 1361cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1362cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene if (Idx.getValueType().bitsGT(TLI.getPointerTy())) 1363cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx); 1364cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene else 1365cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); 1366cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1367cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue SubStackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, 1368cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene StackPtr); 1369cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1370cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Store the subvector. 1371cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Ch = DAG.getStore(DAG.getEntryNode(), dl, Part, SubStackPtr, 1372cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene MachinePointerInfo(), false, false, 0); 1373cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1374cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Finally, load the updated vector. 1375cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, PtrInfo, 1376cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene false, false, 0); 1377cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene} 1378cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 13797ef3d178660b82d1571757e49f44b004d772a116Eli FriedmanSDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) { 13807ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // We can't handle this case efficiently. Allocate a sufficiently 13817ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // aligned object on the stack, store each element into it, then load 13827ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // the result as a vector. 13837ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Create the stack frame object. 1384e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 13855b8bce11d60694a651965cf019b9cb5d84ed3b90Dale Johannesen EVT EltVT = VT.getVectorElementType(); 13867ef3d178660b82d1571757e49f44b004d772a116Eli Friedman DebugLoc dl = Node->getDebugLoc(); 13877ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue FIPtr = DAG.CreateStackTemporary(VT); 1388ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex(); 1389ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(FI); 13907ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 13917ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Emit a store of each element to the stack slot. 13927ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SmallVector<SDValue, 8> Stores; 1393aa9d854b334cab2f29ca6d95413a0946b8a38429Dan Gohman unsigned TypeByteSize = EltVT.getSizeInBits() / 8; 13947ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Store (in the right endianness) the elements to memory. 13957ef3d178660b82d1571757e49f44b004d772a116Eli Friedman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 13967ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Ignore undef elements. 13977ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue; 13987ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 13997ef3d178660b82d1571757e49f44b004d772a116Eli Friedman unsigned Offset = TypeByteSize*i; 14007ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 14017ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue Idx = DAG.getConstant(Offset, FIPtr.getValueType()); 14027ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx); 14037ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 14049949dd612c8100f7ea7e6daaa56e465f106dd0bdDan Gohman // If the destination vector element type is narrower than the source 14059949dd612c8100f7ea7e6daaa56e465f106dd0bdDan Gohman // element type, only store the bits necessary. 14069949dd612c8100f7ea7e6daaa56e465f106dd0bdDan Gohman if (EltVT.bitsLT(Node->getOperand(i).getValueType().getScalarType())) { 14075b8bce11d60694a651965cf019b9cb5d84ed3b90Dale Johannesen Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl, 1408ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Node->getOperand(i), Idx, 1409ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner PtrInfo.getWithOffset(Offset), 14101e559443a17d1b335f697551c6263ba60d5dd827David Greene EltVT, false, false, 0)); 1411eb38ebf15c326a5bb45ca9da6329cdf19ad6df95Mon P Wang } else 14126e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, 1413ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Node->getOperand(i), Idx, 1414ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner PtrInfo.getWithOffset(Offset), 14151e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0)); 14167ef3d178660b82d1571757e49f44b004d772a116Eli Friedman } 14177ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 14187ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue StoreChain; 14197ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (!Stores.empty()) // Not all undef elements? 1420825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson StoreChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 14217ef3d178660b82d1571757e49f44b004d772a116Eli Friedman &Stores[0], Stores.size()); 14227ef3d178660b82d1571757e49f44b004d772a116Eli Friedman else 14237ef3d178660b82d1571757e49f44b004d772a116Eli Friedman StoreChain = DAG.getEntryNode(); 14247ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 14257ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Result is a load from the stack slot. 1426ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner return DAG.getLoad(VT, dl, StoreChain, FIPtr, PtrInfo, false, false, 0); 14277ef3d178660b82d1571757e49f44b004d772a116Eli Friedman} 14287ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 14294bc8c718218159fe410462f6e3670e7cb76c0c04Eli FriedmanSDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) { 14304bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DebugLoc dl = Node->getDebugLoc(); 14314bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp1 = Node->getOperand(0); 14324bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp2 = Node->getOperand(1); 14335d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands 14345d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Get the sign bit of the RHS. First obtain a value that has the same 14355d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // sign as the sign bit, i.e. negative if and only if the sign bit is 1. 14364bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SignBit; 14375d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands EVT FloatVT = Tmp2.getValueType(); 14385d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands EVT IVT = EVT::getIntegerVT(*DAG.getContext(), FloatVT.getSizeInBits()); 143975b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman if (TLI.isTypeLegal(IVT)) { 14405d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Convert to an integer with the same sign bit. 1441bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SignBit = DAG.getNode(ISD::BITCAST, dl, IVT, Tmp2); 14424bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } else { 14435d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Store the float to memory, then load the sign part out as an integer. 14445d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands MVT LoadTy = TLI.getPointerTy(); 14455d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // First create a temporary that is aligned for both the load and store. 14465d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SDValue StackPtr = DAG.CreateStackTemporary(FloatVT, LoadTy); 14475d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Then store the float to it. 14484bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Ch = 14496229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StackPtr, MachinePointerInfo(), 14501e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 14515d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands if (TLI.isBigEndian()) { 14525d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands assert(FloatVT.isByteSized() && "Unsupported floating point type!"); 14535d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Load out a legal integer with the same sign bit as the float. 1454ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SignBit = DAG.getLoad(LoadTy, dl, Ch, StackPtr, MachinePointerInfo(), 1455ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, 0); 14565d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands } else { // Little endian 14575d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SDValue LoadPtr = StackPtr; 14585d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // The float may be wider than the integer we are going to load. Advance 14595d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // the pointer so that the loaded integer will contain the sign bit. 14605d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands unsigned Strides = (FloatVT.getSizeInBits()-1)/LoadTy.getSizeInBits(); 14615d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands unsigned ByteOffset = (Strides * LoadTy.getSizeInBits()) / 8; 14625d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands LoadPtr = DAG.getNode(ISD::ADD, dl, LoadPtr.getValueType(), 14635d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands LoadPtr, DAG.getIntPtrConstant(ByteOffset)); 14645d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Load a legal integer containing the sign bit. 1465ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SignBit = DAG.getLoad(LoadTy, dl, Ch, LoadPtr, MachinePointerInfo(), 1466ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, 0); 14675d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Move the sign bit to the top bit of the loaded integer. 14685d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands unsigned BitShift = LoadTy.getSizeInBits() - 14695d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands (FloatVT.getSizeInBits() - 8 * ByteOffset); 14705d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands assert(BitShift < LoadTy.getSizeInBits() && "Pointer advanced wrong?"); 14715d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands if (BitShift) 14725d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SignBit = DAG.getNode(ISD::SHL, dl, LoadTy, SignBit, 147395771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(BitShift, 147495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(SignBit.getValueType()))); 14755d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands } 14764bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 14775d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Now get the sign bit proper, by seeing whether the value is negative. 14785d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SignBit = DAG.getSetCC(dl, TLI.getSetCCResultType(SignBit.getValueType()), 14795d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SignBit, DAG.getConstant(0, SignBit.getValueType()), 14805d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands ISD::SETLT); 14814bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Get the absolute value of the result. 14824bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue AbsVal = DAG.getNode(ISD::FABS, dl, Tmp1.getValueType(), Tmp1); 14834bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Select between the nabs and abs value based on the sign bit of 14844bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // the input. 14854bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman return DAG.getNode(ISD::SELECT, dl, AbsVal.getValueType(), SignBit, 14864bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DAG.getNode(ISD::FNEG, dl, AbsVal.getValueType(), AbsVal), 14874bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman AbsVal); 14884bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman} 14894bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 14904bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedmanvoid SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(SDNode* Node, 14914bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SmallVectorImpl<SDValue> &Results) { 14924bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore(); 14934bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and" 14944bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman " not tell us which reg is the stack pointer!"); 14954bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DebugLoc dl = Node->getDebugLoc(); 1496e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 14974bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp1 = SDValue(Node, 0); 14984bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp2 = SDValue(Node, 1); 14994bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp3 = Node->getOperand(2); 15004bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Chain = Tmp1.getOperand(0); 15014bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 15024bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Chain the dynamic stack allocation so that it doesn't modify the stack 15034bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // pointer when other instructions are using the stack. 15044bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true)); 15054bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 15064bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Size = Tmp2.getOperand(1); 15074bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT); 15084bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Chain = SP.getValue(1); 15094bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue(); 151016c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned StackAlign = TM.getFrameLowering()->getStackAlignment(); 15114bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman if (Align > StackAlign) 15124bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SP = DAG.getNode(ISD::AND, dl, VT, SP, 15134bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DAG.getConstant(-(uint64_t)Align, VT)); 15144bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Tmp1 = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value 15154bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1); // Output chain 15164bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 15174bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true), 15184bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DAG.getIntPtrConstant(0, true), SDValue()); 15194bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 15204bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Tmp1); 15214bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Tmp2); 15224bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman} 15234bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 15247f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng/// LegalizeSetCCCondCode - Legalize a SETCC with given LHS and RHS and 1525f77fc92b03efe455008474894d217282e2a03cadDan Gohman/// condition code CC on the current target. This routine expands SETCC with 15267f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng/// illegal condition code into AND / OR of multiple SETCC values. 1527e50ed30282bb5b4a9ed952580523f2dda16215acOwen Andersonvoid SelectionDAGLegalize::LegalizeSetCCCondCode(EVT VT, 15287f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng SDValue &LHS, SDValue &RHS, 1529bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue &CC, 1530775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DebugLoc dl) { 1531e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpVT = LHS.getValueType(); 15327f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get(); 15337f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng switch (TLI.getCondCodeAction(CCCode, OpVT)) { 153435a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unknown condition code action!"); 15357f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng case TargetLowering::Legal: 15367f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng // Nothing to do. 15377f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng break; 15387f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng case TargetLowering::Expand: { 15397f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID; 15407f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng unsigned Opc = 0; 15417f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng switch (CCCode) { 154235a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Don't know how to expand this condition!"); 1543e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETO; Opc = ISD::AND; break; 1544e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOGT: CC1 = ISD::SETGT; CC2 = ISD::SETO; Opc = ISD::AND; break; 1545e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOGE: CC1 = ISD::SETGE; CC2 = ISD::SETO; Opc = ISD::AND; break; 1546e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOLT: CC1 = ISD::SETLT; CC2 = ISD::SETO; Opc = ISD::AND; break; 1547e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOLE: CC1 = ISD::SETLE; CC2 = ISD::SETO; Opc = ISD::AND; break; 1548e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETONE: CC1 = ISD::SETNE; CC2 = ISD::SETO; Opc = ISD::AND; break; 1549e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1550e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUGT: CC1 = ISD::SETGT; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1551e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUGE: CC1 = ISD::SETGE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1552e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETULT: CC1 = ISD::SETLT; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1553e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETULE: CC1 = ISD::SETLE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1554e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUNE: CC1 = ISD::SETNE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 15557f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng // FIXME: Implement more expansions. 15567f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 15577f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng 1558bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1); 1559bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2); 1560bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen LHS = DAG.getNode(Opc, dl, VT, SetCC1, SetCC2); 15617f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng RHS = SDValue(); 15627f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng CC = SDValue(); 15637f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng break; 15647f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 15657f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 15667f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng} 15677f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng 15681401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// EmitStackConvert - Emit a store/load combination to the stack. This stores 15691401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// SrcOp to a stack slot of type SlotVT, truncating it if needed. It then does 15701401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// a load from the stack slot to DestVT, extending it if needed. 15711401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// The resultant code need not be legal. 1572475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, 1573e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT SlotVT, 1574e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DestVT, 15758a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl) { 157635481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner // Create the stack frame object. 1577ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson unsigned SrcAlign = 1578ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson TLI.getTargetData()->getPrefTypeAlignment(SrcOp.getValueType(). 157923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson getTypeForEVT(*DAG.getContext())); 1580475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign); 1581fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1582ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(FIPtr); 1583ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int SPFI = StackPtrFI->getIndex(); 1584da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(SPFI); 1585ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng 158683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned SrcSize = SrcOp.getValueType().getSizeInBits(); 158783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned SlotSize = SlotVT.getSizeInBits(); 158883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned DestSize = DestVT.getSizeInBits(); 1589db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *DestType = DestVT.getTypeForEVT(*DAG.getContext()); 1590adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng unsigned DestAlign = TLI.getTargetData()->getPrefTypeAlignment(DestType); 1591fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 15921401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner // Emit a store to the stack slot. Use a truncstore if the input value is 15931401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner // later than DestVT. 1594475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Store; 1595ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng 15961401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner if (SrcSize > SlotSize) 15978a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, 1598da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner PtrInfo, SlotVT, false, false, SrcAlign); 15991401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner else { 16001401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner assert(SrcSize == SlotSize && "Invalid store"); 16018a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, 1602da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner PtrInfo, false, false, SrcAlign); 16031401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner } 1604fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 160535481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner // Result is a load from the stack slot. 16061401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner if (SlotSize == DestSize) 1607da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner return DAG.getLoad(DestVT, dl, Store, FIPtr, PtrInfo, 1608ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, DestAlign); 1609fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 16101401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner assert(SlotSize < DestSize && "Unknown extension!"); 1611a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, 1612da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner PtrInfo, SlotVT, false, false, DestAlign); 161335481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner} 161435481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner 1615475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { 16168a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl = Node->getDebugLoc(); 16174352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // Create a vector sized/aligned stack slot, store the value to element #0, 16184352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // then load the whole vector back out. 1619475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue StackPtr = DAG.CreateStackTemporary(Node->getValueType(0)); 162069de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman 1621ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr); 1622ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int SPFI = StackPtrFI->getIndex(); 1623ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng 1624b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), dl, Node->getOperand(0), 1625b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands StackPtr, 162685ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getFixedStack(SPFI), 16271e559443a17d1b335f697551c6263ba60d5dd827David Greene Node->getValueType(0).getVectorElementType(), 16281e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 16298a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr, 163085ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getFixedStack(SPFI), 16311e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 16324352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner} 16334352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 16344352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 1635ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner/// ExpandBUILD_VECTOR - Expand a BUILD_VECTOR node on targets that don't 163607a96765daedf180a7102d39fe56c499878312b7Dan Gohman/// support the operation, but do support the resultant vector type. 1637475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { 163826cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson unsigned NumElems = Node->getNumOperands(); 16397a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SDValue Value1, Value2; 164026cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson DebugLoc dl = Node->getDebugLoc(); 1641e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 1642e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpVT = Node->getOperand(0).getValueType(); 1643e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT EltVT = VT.getVectorElementType(); 1644fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1645fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // If the only non-undef value is the low element, turn this into a 164687100e0b83b808757bf44dabecd1d1048255d1adChris Lattner // SCALAR_TO_VECTOR node. If this is { X, X, X, X }, determine X. 1647ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner bool isOnlyLowElement = true; 16487a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman bool MoreThanTwoValues = false; 16492eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner bool isConstant = true; 16507a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman for (unsigned i = 0; i < NumElems; ++i) { 1651475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue V = Node->getOperand(i); 16527a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (V.getOpcode() == ISD::UNDEF) 16537a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman continue; 16547a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (i > 0) 1655ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner isOnlyLowElement = false; 16567a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V)) 16572eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner isConstant = false; 16587a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman 16597a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (!Value1.getNode()) { 16607a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman Value1 = V; 16617a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman } else if (!Value2.getNode()) { 16627a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (V != Value1) 16637a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman Value2 = V; 16647a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman } else if (V != Value1 && V != Value2) { 16657a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman MoreThanTwoValues = true; 16667a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman } 1667ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 1668fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 16697a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (!Value1.getNode()) 16707a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman return DAG.getUNDEF(VT); 16717a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman 16727a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (isOnlyLowElement) 167326cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Node->getOperand(0)); 1674fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 16752eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // If all elements are constants, create a load from the constant pool. 1676ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner if (isConstant) { 1677ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner std::vector<Constant*> CV; 1678033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng for (unsigned i = 0, e = NumElems; i != e; ++i) { 1679fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel if (ConstantFPSDNode *V = 1680ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) { 16814fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman CV.push_back(const_cast<ConstantFP *>(V->getConstantFPValue())); 1682fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel } else if (ConstantSDNode *V = 1683ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson dyn_cast<ConstantSDNode>(Node->getOperand(i))) { 16849a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen if (OpVT==EltVT) 16859a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue())); 16869a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen else { 16879a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen // If OpVT and EltVT don't match, EltVT is not legal and the 16889a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen // element values have been promoted/truncated earlier. Undo this; 16899a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen // we don't want a v16i8 to become a v16i32 for example. 16909a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen const ConstantInt *CI = V->getConstantIntValue(); 16919a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen CV.push_back(ConstantInt::get(EltVT.getTypeForEVT(*DAG.getContext()), 16929a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen CI->getZExtValue())); 16939a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen } 1694ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } else { 1695ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner assert(Node->getOperand(i).getOpcode() == ISD::UNDEF); 1696db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *OpNTy = EltVT.getTypeForEVT(*DAG.getContext()); 16979e9a0d5fc26878e51a58a8b57900fcbf952c2691Owen Anderson CV.push_back(UndefValue::get(OpNTy)); 1698ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 1699ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 1700af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Constant *CP = ConstantVector::get(CV); 1701475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy()); 17021606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 17038a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx, 170485ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getConstantPool(), 17051e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, Alignment); 1706ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 1707fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 17087a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (!MoreThanTwoValues) { 17097a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SmallVector<int, 8> ShuffleVec(NumElems, -1); 17107a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman for (unsigned i = 0; i < NumElems; ++i) { 17117a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SDValue V = Node->getOperand(i); 17127a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (V.getOpcode() == ISD::UNDEF) 17137a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman continue; 17147a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman ShuffleVec[i] = V == Value1 ? 0 : NumElems; 17157a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman } 17167a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (TLI.isShuffleMaskLegal(ShuffleVec, Node->getValueType(0))) { 17172eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // Get the splatted value into the low element of a vector register. 17187a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SDValue Vec1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value1); 17197a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SDValue Vec2; 17207a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (Value2.getNode()) 17217a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman Vec2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value2); 17227a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman else 17237a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman Vec2 = DAG.getUNDEF(VT); 1724fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 17252eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // Return shuffle(LowValVec, undef, <0,0,0,0>) 17267a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman return DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec.data()); 1727033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng } 1728033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng } 1729fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 17307ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Otherwise, we can't handle this case efficiently. 17317ef3d178660b82d1571757e49f44b004d772a116Eli Friedman return ExpandVectorBuildThroughStack(Node); 1732ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner} 1733ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner 173477e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// ExpandLibCall - Expand a node into a call to a libcall. If the result value 173577e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// does not fit into a register, return the lo part and set the hi part to the 173677e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// by-reg argument. If it does fit into a single register, return the result 173777e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// and leave the Hi part unset. 1738475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, 173947b41f7e20b6af7aaaf0e050200102d55d038b9dEli Friedman bool isSigned) { 1740fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // The input chain to this libcall is the entry node of the function. 17416831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Legalizing the call will automatically add the previous call to the 17426831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // dependence. 1743475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InChain = DAG.getEntryNode(); 1744fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 174577e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner TargetLowering::ArgListTy Args; 174647857812e29324a9d1560796a05b53d3a9217fd9Reid Spencer TargetLowering::ArgListEntry Entry; 174777e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 1748e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ArgVT = Node->getOperand(i).getValueType(); 1749db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 1750fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; 1751d0b82b301d700217a716526f9329bb031e0d6578Anton Korobeynikov Entry.isSExt = isSigned; 175200fee65fd21f9615d1a604b8b7d42cd16a3f6b47Duncan Sands Entry.isZExt = !isSigned; 175347857812e29324a9d1560796a05b53d3a9217fd9Reid Spencer Args.push_back(Entry); 175477e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner } 1755056292fd738924f3f7703725d8f630983794b5a5Bill Wendling SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 17560c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang TLI.getPointerTy()); 1757edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 1758db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); 17593d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng 17603d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng // isTailCall may be true since the callee does not reference caller stack 17613d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng // frame. Check if it's in the right position. 17623d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng bool isTailCall = isInTailCallPosition(DAG, Node, TLI); 1763ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson std::pair<SDValue, SDValue> CallInfo = 176486098bd6a63d2cdf0c9be9ef3151bd2728281fd7Dale Johannesen TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 17653d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng 0, TLI.getLibcallCallingConv(LC), isTailCall, 176698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman /*isReturnValueUsed=*/true, 176746ada19645c981a0b7932487d163f7582074a4d9Bill Wendling Callee, Args, DAG, Node->getDebugLoc()); 17680d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner 17693d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng if (!CallInfo.second.getNode()) 17703d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng // It's a tailcall, return the chain (which is the DAG root). 17713d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng return DAG.getRoot(); 17723d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng 177374807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman return CallInfo.first; 177422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 177522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 1776f316eb70743e88227b8919370fe38587ffe93512Dan Gohman/// ExpandLibCall - Generate a libcall taking the given operands as arguments 1777abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher/// and returning a result of type RetVT. 1778abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric ChristopherSDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, EVT RetVT, 1779abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher const SDValue *Ops, unsigned NumOps, 1780abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher bool isSigned, DebugLoc dl) { 1781abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TargetLowering::ArgListTy Args; 1782abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Args.reserve(NumOps); 1783f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 1784abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TargetLowering::ArgListEntry Entry; 1785abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher for (unsigned i = 0; i != NumOps; ++i) { 1786abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Entry.Node = Ops[i]; 1787abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); 1788abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Entry.isSExt = isSigned; 1789abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Entry.isZExt = !isSigned; 1790abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Args.push_back(Entry); 1791abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher } 1792abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 1793abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TLI.getPointerTy()); 1794f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 1795db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); 1796abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher std::pair<SDValue,SDValue> CallInfo = 1797abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, 1798abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher false, 0, TLI.getLibcallCallingConv(LC), false, 1799abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher /*isReturnValueUsed=*/true, 1800abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Callee, Args, DAG, dl); 1801f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 1802abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher return CallInfo.first; 1803abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher} 1804abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher 1805e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach// ExpandChainLibCall - Expand a node into a call to a libcall. Similar to 1806e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach// ExpandLibCall except that the first operand is the in-chain. 1807e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbachstd::pair<SDValue, SDValue> 1808e03262fcfc09356a0e3ec589041bc2e0248944e9Jim GrosbachSelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC, 1809e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach SDNode *Node, 1810e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach bool isSigned) { 1811e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach SDValue InChain = Node->getOperand(0); 1812e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 1813e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach TargetLowering::ArgListTy Args; 1814e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach TargetLowering::ArgListEntry Entry; 1815e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) { 1816e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach EVT ArgVT = Node->getOperand(i).getValueType(); 1817db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 1818e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Entry.Node = Node->getOperand(i); 1819e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Entry.Ty = ArgTy; 1820e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Entry.isSExt = isSigned; 1821e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Entry.isZExt = !isSigned; 1822e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Args.push_back(Entry); 1823e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 1824e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 1825e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach TLI.getPointerTy()); 1826e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 1827db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); 1828e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach std::pair<SDValue, SDValue> CallInfo = 1829e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 18303d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, 1831e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach /*isReturnValueUsed=*/true, 1832e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Callee, Args, DAG, Node->getDebugLoc()); 1833e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 1834e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach return CallInfo; 1835e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach} 1836e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 1837f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli FriedmanSDValue SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node, 1838f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_F32, 1839f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_F64, 1840f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_F80, 1841f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_PPCF128) { 1842f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall LC; 1843825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 184435a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unexpected request for libcall!"); 1845825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f32: LC = Call_F32; break; 1846825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f64: LC = Call_F64; break; 1847825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f80: LC = Call_F80; break; 1848825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::ppcf128: LC = Call_PPCF128; break; 1849f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman } 1850f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman return ExpandLibCall(LC, Node, false); 1851f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman} 1852f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman 1853f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli FriedmanSDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned, 18548983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I8, 1855f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I16, 1856f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I32, 1857f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I64, 1858f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I128) { 1859f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall LC; 1860825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 186135a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unexpected request for libcall!"); 18628983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov case MVT::i8: LC = Call_I8; break; 18638983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov case MVT::i16: LC = Call_I16; break; 18648983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov case MVT::i32: LC = Call_I32; break; 18658983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov case MVT::i64: LC = Call_I64; break; 1866825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i128: LC = Call_I128; break; 1867f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman } 1868f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman return ExpandLibCall(LC, Node, isSigned); 1869f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman} 1870f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman 187165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// isDivRemLibcallAvailable - Return true if divmod libcall is available. 187265279cb9bd985721ac6ad090fed02298396ba06dEvan Chengstatic bool isDivRemLibcallAvailable(SDNode *Node, bool isSigned, 187365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng const TargetLowering &TLI) { 18748e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng RTLIB::Libcall LC; 18758e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 18768e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng default: assert(0 && "Unexpected request for libcall!"); 18778e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break; 18788e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break; 18798e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; 18808e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break; 18818e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; break; 18828e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng } 18838e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 188465279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng return TLI.getLibcallName(LC) != 0; 188565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng} 18868e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 188765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// UseDivRem - Only issue divrem libcall if both quotient and remainder are 188865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// needed. 188965279cb9bd985721ac6ad090fed02298396ba06dEvan Chengstatic bool UseDivRem(SDNode *Node, bool isSigned, bool isDIV) { 18908e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng unsigned OtherOpcode = 0; 189165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng if (isSigned) 18928e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng OtherOpcode = isDIV ? ISD::SREM : ISD::SDIV; 189365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng else 18948e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng OtherOpcode = isDIV ? ISD::UREM : ISD::UDIV; 189565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng 18968e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue Op0 = Node->getOperand(0); 18978e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue Op1 = Node->getOperand(1); 18988e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng for (SDNode::use_iterator UI = Op0.getNode()->use_begin(), 18998e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng UE = Op0.getNode()->use_end(); UI != UE; ++UI) { 19008e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDNode *User = *UI; 19018e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng if (User == Node) 19028e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng continue; 19038e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng if (User->getOpcode() == OtherOpcode && 19048e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng User->getOperand(0) == Op0 && 190565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng User->getOperand(1) == Op1) 190665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng return true; 19078e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng } 190865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng return false; 190965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng} 191065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng 191165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// ExpandDivRemLibCall - Issue libcalls to __{u}divmod to compute div / rem 191265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// pairs. 191365279cb9bd985721ac6ad090fed02298396ba06dEvan Chengvoid 191465279cb9bd985721ac6ad090fed02298396ba06dEvan ChengSelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node, 191565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng SmallVectorImpl<SDValue> &Results) { 191665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng unsigned Opcode = Node->getOpcode(); 191765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng bool isSigned = Opcode == ISD::SDIVREM; 191865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng 191965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::Libcall LC; 192065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 192165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng default: assert(0 && "Unexpected request for libcall!"); 192265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break; 192365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break; 192465279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; 192565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break; 192665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; break; 19278e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng } 19288e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 19298e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // The input chain to this libcall is the entry node of the function. 19308e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // Legalizing the call will automatically add the previous call to the 19318e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // dependence. 19328e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue InChain = DAG.getEntryNode(); 19338e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 19348e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng EVT RetVT = Node->getValueType(0); 1935db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); 19368e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 19378e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng TargetLowering::ArgListTy Args; 19388e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng TargetLowering::ArgListEntry Entry; 19398e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 19408e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng EVT ArgVT = Node->getOperand(i).getValueType(); 1941db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 19428e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; 19438e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.isSExt = isSigned; 19448e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.isZExt = !isSigned; 19458e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Args.push_back(Entry); 19468e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng } 19478e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 19488e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // Also pass the return address of the remainder. 19498e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue FIPtr = DAG.CreateStackTemporary(RetVT); 19508e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.Node = FIPtr; 19518e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.Ty = RetTy->getPointerTo(); 19528e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.isSExt = isSigned; 19538e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.isZExt = !isSigned; 19548e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Args.push_back(Entry); 19558e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 19568e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 19578e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng TLI.getPointerTy()); 19588e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 19598e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng DebugLoc dl = Node->getDebugLoc(); 19608e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng std::pair<SDValue, SDValue> CallInfo = 19618e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 19628e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, 19638e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng /*isReturnValueUsed=*/true, Callee, Args, DAG, dl); 19648e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 19658e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // Remainder is loaded back from the stack frame. 1966bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Rem = DAG.getLoad(RetVT, dl, CallInfo.second, FIPtr, 19678e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng MachinePointerInfo(), false, false, 0); 196865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Results.push_back(CallInfo.first); 196965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Results.push_back(Rem); 19708e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng} 19718e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 197222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandLegalINT_TO_FP - This function is responsible for legalizing a 197322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// INT_TO_FP operation of the specified operand when the target requests that 197422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we expand it. At this point, we know that the result and operand types are 197522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target. 1976475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, 1977475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0, 1978e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DestVT, 1979af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 1980825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (Op0.getValueType() == MVT::i32) { 198122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // simple 32-bit [signed|unsigned] integer to float/double expansion 1982fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 198323594d4537fb88a963c6d6993af5027eac9bfbacChris Lattner // Get the stack frame index of a 8 byte buffer. 1984825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue StackSlot = DAG.CreateStackTemporary(MVT::f64); 1985fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 198622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // word offset constant for Hi/Lo address computation 1987475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy()); 198822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // set up Hi and Lo (into buffer) address based on endian 1989475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Hi = StackSlot; 1990fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel SDValue Lo = DAG.getNode(ISD::ADD, dl, 1991ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson TLI.getPointerTy(), StackSlot, WordOff); 1992408c428096df3a3970a8387f9dd258ae948663a6Chris Lattner if (TLI.isLittleEndian()) 1993408c428096df3a3970a8387f9dd258ae948663a6Chris Lattner std::swap(Hi, Lo); 1994fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 199522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // if signed map to unsigned space 1996475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0Mapped; 199722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (isSigned) { 199822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // constant used to invert sign bit (signed to unsigned mapping) 1999825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue SignBit = DAG.getConstant(0x80000000u, MVT::i32); 2000825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Op0Mapped = DAG.getNode(ISD::XOR, dl, MVT::i32, Op0, SignBit); 200122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } else { 200222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner Op0Mapped = Op0; 200322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 200422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // store the lo of the constructed double - based on integer input 2005af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, 20066229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner Op0Mapped, Lo, MachinePointerInfo(), 20071e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 200822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // initial hi portion of constructed double 2009825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue InitialHi = DAG.getConstant(0x43300000u, MVT::i32); 201022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // store the hi of the constructed double - biased exponent 20116229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner SDValue Store2 = DAG.getStore(Store1, dl, InitialHi, Hi, 20126229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(), 20136229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner false, false, 0); 201422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // load the constructed double 2015ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, 2016ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(), false, false, 0); 201722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // FP constant to bias correct the final result 2018475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Bias = DAG.getConstantFP(isSigned ? 2019ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson BitsToDouble(0x4330000080000000ULL) : 2020ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson BitsToDouble(0x4330000000000000ULL), 2021825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::f64); 202222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // subtract the bias 2023825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::f64, Load, Bias); 202422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // final result 2025475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Result; 202622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // handle final rounding 2027825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (DestVT == MVT::f64) { 202822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // do nothing 202922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner Result = Sub; 2030825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (DestVT.bitsLT(MVT::f64)) { 2031af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen Result = DAG.getNode(ISD::FP_ROUND, dl, DestVT, Sub, 20320bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner DAG.getIntPtrConstant(0)); 2033825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (DestVT.bitsGT(MVT::f64)) { 2034af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen Result = DAG.getNode(ISD::FP_EXTEND, dl, DestVT, Sub); 203522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 203622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner return Result; 203722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 203822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet"); 2039a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen // Code below here assumes !isSigned without checking again. 20400fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman 20410fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // Implementation of unsigned i64 to f64 following the algorithm in 20420fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // __floatundidf in compiler_rt. This implementation has the advantage 20430fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // of performing rounding correctly, both in the default rounding mode 20440fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // and in all alternate rounding modes. 20450fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // TODO: Generalize this for use with other types. 20460fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman if (Op0.getValueType() == MVT::i64 && DestVT == MVT::f64) { 20470fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue TwoP52 = 20480fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman DAG.getConstant(UINT64_C(0x4330000000000000), MVT::i64); 20490fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue TwoP84PlusTwoP52 = 20500fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman DAG.getConstantFP(BitsToDouble(UINT64_C(0x4530000000100000)), MVT::f64); 20510fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue TwoP84 = 20520fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman DAG.getConstant(UINT64_C(0x4530000000000000), MVT::i64); 20530fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman 20540fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue Lo = DAG.getZeroExtendInReg(Op0, dl, MVT::i32); 20550fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i64, Op0, 20560fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman DAG.getConstant(32, MVT::i64)); 20570fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue LoOr = DAG.getNode(ISD::OR, dl, MVT::i64, Lo, TwoP52); 20580fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue HiOr = DAG.getNode(ISD::OR, dl, MVT::i64, Hi, TwoP84); 2059bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue LoFlt = DAG.getNode(ISD::BITCAST, dl, MVT::f64, LoOr); 2060bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue HiFlt = DAG.getNode(ISD::BITCAST, dl, MVT::f64, HiOr); 20616e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach SDValue HiSub = DAG.getNode(ISD::FSUB, dl, MVT::f64, HiFlt, 20626e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach TwoP84PlusTwoP52); 20630fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman return DAG.getNode(ISD::FADD, dl, MVT::f64, LoFlt, HiSub); 20640fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman } 20650fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman 20663a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // Implementation of unsigned i64 to f32. 2067a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen // TODO: Generalize this for use with other types. 2068a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen if (Op0.getValueType() == MVT::i64 && DestVT == MVT::f32) { 20693a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // For unsigned conversions, convert them to signed conversions using the 20703a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // algorithm from the x86_64 __floatundidf in compiler_rt. 20713a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson if (!isSigned) { 20723a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue Fast = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, Op0); 2073bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 207495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson SDValue ShiftConst = 207595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(1, TLI.getShiftAmountTy(Op0.getValueType())); 20763a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue Shr = DAG.getNode(ISD::SRL, dl, MVT::i64, Op0, ShiftConst); 20773a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue AndConst = DAG.getConstant(1, MVT::i64); 20783a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue And = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, AndConst); 20793a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i64, And, Shr); 2080bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 20813a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue SignCvt = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, Or); 20823a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue Slow = DAG.getNode(ISD::FADD, dl, MVT::f32, SignCvt, SignCvt); 2083bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 20843a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // TODO: This really should be implemented using a branch rather than a 2085bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck // select. We happen to get lucky and machinesink does the right 2086bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck // thing most of the time. This would be a good candidate for a 20873a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson //pseudo-op, or, even better, for whole-function isel. 2088bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue SignBitTest = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 20893a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson Op0, DAG.getConstant(0, MVT::i64), ISD::SETLT); 20903a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson return DAG.getNode(ISD::SELECT, dl, MVT::f32, SignBitTest, Slow, Fast); 20913a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson } 2092bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 20933a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // Otherwise, implement the fully general conversion. 2094bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 20956e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach SDValue And = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, 2096a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstant(UINT64_C(0xfffffffffffff800), MVT::i64)); 2097a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i64, And, 2098a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstant(UINT64_C(0x800), MVT::i64)); 20996e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach SDValue And2 = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, 2100a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstant(UINT64_C(0x7ff), MVT::i64)); 2101a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Ne = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 2102a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen And2, DAG.getConstant(UINT64_C(0), MVT::i64), ISD::SETNE); 2103a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Sel = DAG.getNode(ISD::SELECT, dl, MVT::i64, Ne, Or, Op0); 2104a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Ge = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 2105a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen Op0, DAG.getConstant(UINT64_C(0x0020000000000000), MVT::i64), 21063a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson ISD::SETUGE); 2107a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Sel2 = DAG.getNode(ISD::SELECT, dl, MVT::i64, Ge, Sel, Op0); 210895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT SHVT = TLI.getShiftAmountTy(Sel2.getValueType()); 2109bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 2110a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Sh = DAG.getNode(ISD::SRL, dl, MVT::i64, Sel2, 2111a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstant(32, SHVT)); 2112a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Sh); 2113a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Fcvt = DAG.getNode(ISD::UINT_TO_FP, dl, MVT::f64, Trunc); 2114a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue TwoP32 = 2115a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstantFP(BitsToDouble(UINT64_C(0x41f0000000000000)), MVT::f64); 2116a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Fmul = DAG.getNode(ISD::FMUL, dl, MVT::f64, TwoP32, Fcvt); 2117a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Lo = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Sel2); 2118a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Fcvt2 = DAG.getNode(ISD::UINT_TO_FP, dl, MVT::f64, Lo); 2119a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Fadd = DAG.getNode(ISD::FADD, dl, MVT::f64, Fmul, Fcvt2); 2120a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen return DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, Fadd, 2121a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getIntPtrConstant(0)); 2122a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen } 2123a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen 2124b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, dl, DestVT, Op0); 2125b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman 2126b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue SignSet = DAG.getSetCC(dl, TLI.getSetCCResultType(Op0.getValueType()), 2127b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman Op0, DAG.getConstant(0, Op0.getValueType()), 2128b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman ISD::SETLT); 2129b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4); 2130b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue CstOffset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), 2131b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SignSet, Four, Zero); 2132b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman 2133b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman // If the sign bit of the integer is set, the large number will be treated 2134b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman // as a negative number. To counteract this, the dynamic code adds an 2135b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman // offset depending on the data type. 2136b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman uint64_t FF; 2137b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman switch (Op0.getValueType().getSimpleVT().SimpleTy) { 213835a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unsupported integer type!"); 2139b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman case MVT::i8 : FF = 0x43800000ULL; break; // 2^8 (as a float) 2140b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman case MVT::i16: FF = 0x47800000ULL; break; // 2^16 (as a float) 2141b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman case MVT::i32: FF = 0x4F800000ULL; break; // 2^32 (as a float) 2142b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman case MVT::i64: FF = 0x5F800000ULL; break; // 2^64 (as a float) 2143b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman } 2144b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman if (TLI.isLittleEndian()) FF <<= 32; 2145b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman Constant *FudgeFactor = ConstantInt::get( 2146b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman Type::getInt64Ty(*DAG.getContext()), FF); 2147b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman 2148b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); 2149b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 2150b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset); 2151b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman Alignment = std::min(Alignment, 4u); 2152b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue FudgeInReg; 2153b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman if (DestVT == MVT::f32) 2154b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx, 215585ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getConstantPool(), 2156b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman false, false, Alignment); 2157b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman else { 2158bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, 2159bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getEntryNode(), CPIdx, 2160bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman MachinePointerInfo::getConstantPool(), 2161bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman MVT::f32, false, false, Alignment); 2162bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman HandleSDNode Handle(Load); 2163bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman LegalizeOp(Load.getNode()); 2164bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman FudgeInReg = Handle.getValue(); 2165b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman } 216622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 2167b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg); 216822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 216922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 217022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a 217122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// *INT_TO_FP operation of the specified operand when the target requests that 217222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we promote it. At this point, we know that the result and operand types are 217322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP 217422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// operation that takes a larger input. 2175475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, 2176e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DestVT, 2177af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen bool isSigned, 2178af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 217922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // First step, figure out the appropriate *INT_TO_FP operation to use. 2180e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NewInTy = LegalOp.getValueType(); 218122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 218222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner unsigned OpToUse = 0; 218322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 218422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Scan for the appropriate larger type to use. 218522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner while (1) { 2186825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson NewInTy = (MVT::SimpleValueType)(NewInTy.getSimpleVT().SimpleTy+1); 218783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(NewInTy.isInteger() && "Ran out of possibilities!"); 218822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 218922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the target supports SINT_TO_FP of this type, use it. 21903be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, NewInTy)) { 21913be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman OpToUse = ISD::SINT_TO_FP; 21923be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman break; 219322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 219422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (isSigned) continue; 219522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 219622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the target supports UINT_TO_FP of this type, use it. 21973be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (TLI.isOperationLegalOrCustom(ISD::UINT_TO_FP, NewInTy)) { 21983be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman OpToUse = ISD::UINT_TO_FP; 21993be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman break; 220022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 220122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 220222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Otherwise, try a larger type. 220322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 220422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 220522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Okay, we found the operation and type to use. Zero extend our input to the 220622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // desired type then run the operation on it. 2207af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen return DAG.getNode(OpToUse, dl, DestVT, 220822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, 2209af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen dl, NewInTy, LegalOp)); 221077e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner} 221177e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner 221222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a 221322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// FP_TO_*INT operation of the specified operand when the target requests that 221422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we promote it. At this point, we know that the result and operand types are 221522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT 221622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// operation that returns a larger result. 2217475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, 2218e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DestVT, 2219af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen bool isSigned, 2220af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 222122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // First step, figure out the appropriate FP_TO*INT operation to use. 2222e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NewOutTy = DestVT; 22239c32d3b798dc6caeebe6cea2effe80ca5e84e66eChris Lattner 222422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner unsigned OpToUse = 0; 2225e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner 222622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Scan for the appropriate larger type to use. 222722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner while (1) { 2228825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson NewOutTy = (MVT::SimpleValueType)(NewOutTy.getSimpleVT().SimpleTy+1); 222983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(NewOutTy.isInteger() && "Ran out of possibilities!"); 223066de05b606cf31f1f23ed0c4eb1f097738cd1506Chris Lattner 22313be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewOutTy)) { 223222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner OpToUse = ISD::FP_TO_SINT; 223322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; 223422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 2235e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner 22363be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewOutTy)) { 223722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner OpToUse = ISD::FP_TO_UINT; 223822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; 2239e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner } 22400d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner 224122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Otherwise, try a larger type. 2242a88a260dbd874a3bdd3e47f4f15ab0d7c7803044Chris Lattner } 2243a88a260dbd874a3bdd3e47f4f15ab0d7c7803044Chris Lattner 2244fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 224527a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // Okay, we found the operation and type to use. 2246af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Operation = DAG.getNode(OpToUse, dl, NewOutTy, LegalOp); 2247126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands 224827a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // Truncate the result of the extended FP_TO_*INT operation to the desired 224927a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // size. 2250af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen return DAG.getNode(ISD::TRUNCATE, dl, DestVT, Operation); 225122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 225213689e2009e71f7982d1313ed699e0e6a50157d0Chris Lattner 225322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. 225422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// 22558a782a2a8c2f0c82f292d03a3f707232b0bae27bDale JohannesenSDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, DebugLoc dl) { 2256e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 225795771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT SHVT = TLI.getShiftAmountTy(VT); 2258475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8; 2259825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (VT.getSimpleVT().SimpleTy) { 226035a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unhandled Expand type in BSWAP!"); 2261825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 22628a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 22638a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 22648a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2); 2265825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: 22668a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); 22678a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 22688a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 22698a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); 22708a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(0xFF0000, VT)); 22718a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(0xFF00, VT)); 22728a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); 22738a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); 22748a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); 2275825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i64: 22768a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(56, SHVT)); 22778a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp7 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(40, SHVT)); 22788a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); 22798a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp5 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 22808a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 22818a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); 22828a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(40, SHVT)); 22838a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(56, SHVT)); 22848a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp7 = DAG.getNode(ISD::AND, dl, VT, Tmp7, DAG.getConstant(255ULL<<48, VT)); 22858a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::AND, dl, VT, Tmp6, DAG.getConstant(255ULL<<40, VT)); 22868a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp5 = DAG.getNode(ISD::AND, dl, VT, Tmp5, DAG.getConstant(255ULL<<32, VT)); 22878a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::AND, dl, VT, Tmp4, DAG.getConstant(255ULL<<24, VT)); 22888a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(255ULL<<16, VT)); 22898a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT)); 22908a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp7); 22918a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::OR, dl, VT, Tmp6, Tmp5); 22928a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); 22938a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); 22948a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp6); 22958a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); 22968a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp4); 22970d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner } 229877e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner} 2299edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 2300b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer/// SplatByte - Distribute ByteVal over NumBits bits. 23015df5a22d1a098961edebac59fbddcab045fddd29Benjamin Kramer// FIXME: Move this helper to a common place. 2302b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramerstatic APInt SplatByte(unsigned NumBits, uint8_t ByteVal) { 2303b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer APInt Val = APInt(NumBits, ByteVal); 2304b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer unsigned Shift = 8; 2305b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer for (unsigned i = NumBits; i > 8; i >>= 1) { 2306b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Val = (Val << Shift) | Val; 2307b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Shift <<= 1; 2308b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer } 2309b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer return Val; 2310b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer} 2311b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer 231222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandBitCount - Expand the specified bitcount instruction into operations. 231322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// 2314fdc40a0a696c658d550d894ea03772e5f8af2c94Scott MichelSDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, 23158a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl) { 231622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner switch (Opc) { 231735a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Cannot expand this yet!"); 231822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTPOP: { 2319e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 232095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT ShVT = TLI.getShiftAmountTy(VT); 2321b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer unsigned Len = VT.getSizeInBits(); 2322b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer 23235df5a22d1a098961edebac59fbddcab045fddd29Benjamin Kramer assert(VT.isInteger() && Len <= 128 && Len % 8 == 0 && 23245df5a22d1a098961edebac59fbddcab045fddd29Benjamin Kramer "CTPOP not implemented for this type."); 23255df5a22d1a098961edebac59fbddcab045fddd29Benjamin Kramer 2326b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // This is the "best" algorithm from 2327b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel 2328b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer 2329b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer SDValue Mask55 = DAG.getConstant(SplatByte(Len, 0x55), VT); 2330b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer SDValue Mask33 = DAG.getConstant(SplatByte(Len, 0x33), VT); 2331b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer SDValue Mask0F = DAG.getConstant(SplatByte(Len, 0x0F), VT); 2332b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer SDValue Mask01 = DAG.getConstant(SplatByte(Len, 0x01), VT); 2333b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer 2334b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // v = v - ((v >> 1) & 0x55555555...) 2335b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Op = DAG.getNode(ISD::SUB, dl, VT, Op, 2336b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::AND, dl, VT, 2337b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::SRL, dl, VT, Op, 2338b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getConstant(1, ShVT)), 2339b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Mask55)); 2340b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // v = (v & 0x33333333...) + ((v >> 2) & 0x33333333...) 2341b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Op = DAG.getNode(ISD::ADD, dl, VT, 2342b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::AND, dl, VT, Op, Mask33), 2343b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::AND, dl, VT, 2344b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::SRL, dl, VT, Op, 2345b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getConstant(2, ShVT)), 2346b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Mask33)); 2347b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // v = (v + (v >> 4)) & 0x0F0F0F0F... 2348b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Op = DAG.getNode(ISD::AND, dl, VT, 2349b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::ADD, dl, VT, Op, 2350b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::SRL, dl, VT, Op, 2351b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getConstant(4, ShVT))), 2352b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Mask0F); 2353b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // v = (v * 0x01010101...) >> (Len - 8) 2354b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Op = DAG.getNode(ISD::SRL, dl, VT, 2355b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::MUL, dl, VT, Op, Mask01), 2356b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getConstant(Len - 8, ShVT)); 235795771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson 235822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner return Op; 235922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 236022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTLZ: { 236122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // for now, we do this: 236222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >> 1); 236322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >> 2); 236422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // ... 236522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >>16); 236622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >>32); // for 64-bit input 236722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // return popcount(~x); 236822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // 236922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // but see also: http://www.hackersdelight.org/HDcode/nlz.cc 2370e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 237195771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT ShVT = TLI.getShiftAmountTy(VT); 237283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned len = VT.getSizeInBits(); 237322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { 2374475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); 2375fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Op = DAG.getNode(ISD::OR, dl, VT, Op, 2376e72c5964d5263f2489bf2c7e9d32f71271d205fcDale Johannesen DAG.getNode(ISD::SRL, dl, VT, Op, Tmp3)); 237722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 23788a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Op = DAG.getNOT(dl, Op, VT); 23798a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::CTPOP, dl, VT, Op); 238022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 238122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTTZ: { 238222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // for now, we use: { return popcount(~x & (x - 1)); } 238322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // unless the target has ctlz but not ctpop, in which case we use: 238422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // { return 32 - nlz(~x & (x-1)); } 238522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // see also http://www.hackersdelight.org/HDcode/ntz.cc 2386e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 23878a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue Tmp3 = DAG.getNode(ISD::AND, dl, VT, 23888a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNOT(dl, Op, VT), 23898a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNode(ISD::SUB, dl, VT, Op, 23907581bfa2757a3149c6d17c0fe592e5c3808aa843Bill Wendling DAG.getConstant(1, VT))); 239122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If ISD::CTLZ is legal and CTPOP isn't, then do that instead. 2392f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) && 2393f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) 23948a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::SUB, dl, VT, 239583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands DAG.getConstant(VT.getSizeInBits(), VT), 23968a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNode(ISD::CTLZ, dl, VT, Tmp3)); 23978a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::CTPOP, dl, VT, Tmp3); 239822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 239922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 240022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 2401e34b396ab7d28469bf3d9679a748b643d8e30458Chris Lattner 2402e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbachstd::pair <SDValue, SDValue> SelectionDAGLegalize::ExpandAtomic(SDNode *Node) { 2403e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach unsigned Opc = Node->getOpcode(); 2404e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT(); 2405e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach RTLIB::Libcall LC; 2406e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2407e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (Opc) { 2408e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: 2409e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach llvm_unreachable("Unhandled atomic intrinsic Expand!"); 2410e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2411ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case ISD::ATOMIC_SWAP: 2412ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach switch (VT.SimpleTy) { 2413ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2414ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case MVT::i8: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break; 2415ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break; 2416ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break; 2417ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break; 2418ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach } 2419ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach break; 2420e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_CMP_SWAP: 2421e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2422e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2423e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break; 2424e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break; 2425e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break; 2426e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break; 2427e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2428e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2429e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_ADD: 2430e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2431e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2432e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_ADD_1; break; 2433e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break; 2434e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break; 2435e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break; 2436e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2437e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2438e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_SUB: 2439e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2440e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2441e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_SUB_1; break; 2442e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break; 2443e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break; 2444e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break; 2445e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2446e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2447e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_AND: 2448e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2449e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2450e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_AND_1; break; 2451e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break; 2452e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break; 2453e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break; 2454e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2455e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2456e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_OR: 2457e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2458e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2459e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_OR_1; break; 2460e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break; 2461e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break; 2462e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break; 2463e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2464e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2465e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_XOR: 2466e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2467e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2468e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_XOR_1; break; 2469e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break; 2470e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break; 2471e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break; 2472e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2473e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2474e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_NAND: 2475e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2476e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2477e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_NAND_1; break; 2478e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break; 2479e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break; 2480e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break; 2481e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2482e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2483e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2484e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2485e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach return ExpandChainLibCall(LC, Node, false); 2486e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach} 2487e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2488bf923b815d6da97367e3eedab69230918bf128a3Dan Gohmanvoid SelectionDAGLegalize::ExpandNode(SDNode *Node) { 2489bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SmallVector<SDValue, 8> Results; 24908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DebugLoc dl = Node->getDebugLoc(); 2491bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman SDValue Tmp1, Tmp2, Tmp3, Tmp4; 24928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 24938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTPOP: 24948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTLZ: 24958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTTZ: 24968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandBitCount(Node->getOpcode(), Node->getOperand(0), dl); 24978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 24988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 24998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BSWAP: 2500775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandBSWAP(Node->getOperand(0), dl)); 25018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 25028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAMEADDR: 25038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::RETURNADDR: 25048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAME_TO_ARGS_OFFSET: 25058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(0, Node->getValueType(0))); 25068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 25078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLT_ROUNDS_: 25088c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(1, Node->getValueType(0))); 25098c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 25108c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_RETURN: 25118c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_LABEL: 25128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::PREFETCH: 25138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VAEND: 2514c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach case ISD::EH_SJLJ_LONGJMP: 2515e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach case ISD::EH_SJLJ_DISPATCHSETUP: 2516e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach // If the target didn't expand these, there's nothing to do, so just 2517e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach // preserve the chain and be done. 2518c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach Results.push_back(Node->getOperand(0)); 2519c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach break; 2520c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach case ISD::EH_SJLJ_SETJMP: 2521e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach // If the target didn't expand this, just return 'zero' and preserve the 2522e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach // chain. 2523c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach Results.push_back(DAG.getConstant(0, MVT::i32)); 25248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Node->getOperand(0)); 25258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 252614648468011c92a4210f8118721d58c25043daf8Eli Friedman case ISD::ATOMIC_FENCE: 2527bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach case ISD::MEMBARRIER: { 2528bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach // If the target didn't lower this, lower it to '__sync_synchronize()' call 252914648468011c92a4210f8118721d58c25043daf8Eli Friedman // FIXME: handle "fence singlethread" more efficiently. 2530bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach TargetLowering::ArgListTy Args; 2531bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach std::pair<SDValue, SDValue> CallResult = 2532bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach TLI.LowerCallTo(Node->getOperand(0), Type::getVoidTy(*DAG.getContext()), 25333d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng false, false, false, false, 0, CallingConv::C, 25343d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng /*isTailCall=*/false, 2535bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach /*isReturnValueUsed=*/true, 2536bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach DAG.getExternalSymbol("__sync_synchronize", 2537bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach TLI.getPointerTy()), 2538bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach Args, DAG, dl); 2539bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach Results.push_back(CallResult.second); 2540bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach break; 2541bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach } 2542069e2ed794a90cb5108a35627ee148866795f140Eli Friedman case ISD::ATOMIC_LOAD: { 2543069e2ed794a90cb5108a35627ee148866795f140Eli Friedman // There is no libcall for atomic load; fake it with ATOMIC_CMP_SWAP. 2544331120b1a482b782e8dffce63033bb8514ba2a96Eli Friedman SDValue Zero = DAG.getConstant(0, Node->getValueType(0)); 2545069e2ed794a90cb5108a35627ee148866795f140Eli Friedman SDValue Swap = DAG.getAtomic(ISD::ATOMIC_CMP_SWAP, dl, 2546069e2ed794a90cb5108a35627ee148866795f140Eli Friedman cast<AtomicSDNode>(Node)->getMemoryVT(), 2547069e2ed794a90cb5108a35627ee148866795f140Eli Friedman Node->getOperand(0), 2548069e2ed794a90cb5108a35627ee148866795f140Eli Friedman Node->getOperand(1), Zero, Zero, 2549069e2ed794a90cb5108a35627ee148866795f140Eli Friedman cast<AtomicSDNode>(Node)->getMemOperand(), 2550069e2ed794a90cb5108a35627ee148866795f140Eli Friedman cast<AtomicSDNode>(Node)->getOrdering(), 2551069e2ed794a90cb5108a35627ee148866795f140Eli Friedman cast<AtomicSDNode>(Node)->getSynchScope()); 2552069e2ed794a90cb5108a35627ee148866795f140Eli Friedman Results.push_back(Swap.getValue(0)); 2553069e2ed794a90cb5108a35627ee148866795f140Eli Friedman Results.push_back(Swap.getValue(1)); 2554069e2ed794a90cb5108a35627ee148866795f140Eli Friedman break; 2555069e2ed794a90cb5108a35627ee148866795f140Eli Friedman } 2556069e2ed794a90cb5108a35627ee148866795f140Eli Friedman case ISD::ATOMIC_STORE: { 2557069e2ed794a90cb5108a35627ee148866795f140Eli Friedman // There is no libcall for atomic store; fake it with ATOMIC_SWAP. 2558069e2ed794a90cb5108a35627ee148866795f140Eli Friedman SDValue Swap = DAG.getAtomic(ISD::ATOMIC_SWAP, dl, 2559069e2ed794a90cb5108a35627ee148866795f140Eli Friedman cast<AtomicSDNode>(Node)->getMemoryVT(), 2560069e2ed794a90cb5108a35627ee148866795f140Eli Friedman Node->getOperand(0), 2561069e2ed794a90cb5108a35627ee148866795f140Eli Friedman Node->getOperand(1), Node->getOperand(2), 2562069e2ed794a90cb5108a35627ee148866795f140Eli Friedman cast<AtomicSDNode>(Node)->getMemOperand(), 2563069e2ed794a90cb5108a35627ee148866795f140Eli Friedman cast<AtomicSDNode>(Node)->getOrdering(), 2564069e2ed794a90cb5108a35627ee148866795f140Eli Friedman cast<AtomicSDNode>(Node)->getSynchScope()); 2565069e2ed794a90cb5108a35627ee148866795f140Eli Friedman Results.push_back(Swap.getValue(1)); 2566069e2ed794a90cb5108a35627ee148866795f140Eli Friedman break; 2567069e2ed794a90cb5108a35627ee148866795f140Eli Friedman } 2568b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach // By default, atomic intrinsics are marked Legal and lowered. Targets 2569b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach // which don't support them directly, however, may want libcalls, in which 2570b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach // case they mark them Expand, and we get here. 2571b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_SWAP: 2572b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_ADD: 2573b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_SUB: 2574b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_AND: 2575b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_OR: 2576b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_XOR: 2577b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_NAND: 2578b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_MIN: 2579b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_MAX: 2580b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_UMIN: 2581b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_UMAX: 2582a845706dc1cebfe75913832e07ef114519a879d6Evan Cheng case ISD::ATOMIC_CMP_SWAP: { 2583e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach std::pair<SDValue, SDValue> Tmp = ExpandAtomic(Node); 2584e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Results.push_back(Tmp.first); 2585e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Results.push_back(Tmp.second); 258659c38f31acf87901208bbf790508196b1c0ad1fdJim Grosbach break; 2587a845706dc1cebfe75913832e07ef114519a879d6Evan Cheng } 25884bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::DYNAMIC_STACKALLOC: 25894bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman ExpandDYNAMIC_STACKALLOC(Node, Results); 25904bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 25918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::MERGE_VALUES: 25928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0; i < Node->getNumValues(); i++) 25938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Node->getOperand(i)); 25948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 25958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UNDEF: { 2596e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 25978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (VT.isInteger()) 25988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(0, VT)); 259935a389344d21178ee280c2410401b2060b5b879cChris Lattner else { 260035a389344d21178ee280c2410401b2060b5b879cChris Lattner assert(VT.isFloatingPoint() && "Unknown value type!"); 26018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstantFP(0, VT)); 260235a389344d21178ee280c2410401b2060b5b879cChris Lattner } 26038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 26058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::TRAP: { 26068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // If this operation is not supported, lower it to 'abort()' call 26078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman TargetLowering::ArgListTy Args; 26088c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman std::pair<SDValue, SDValue> CallResult = 26091d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson TLI.LowerCallTo(Node->getOperand(0), Type::getVoidTy(*DAG.getContext()), 26103d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng false, false, false, false, 0, CallingConv::C, 26113d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng /*isTailCall=*/false, 261298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman /*isReturnValueUsed=*/true, 26138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getExternalSymbol("abort", TLI.getPointerTy()), 261446ada19645c981a0b7932487d163f7582074a4d9Bill Wendling Args, DAG, dl); 26158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(CallResult.second); 26168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 26188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND: 2619bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck case ISD::BITCAST: 26208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), Node->getValueType(0), 26218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 26228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 26238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_EXTEND: 26258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), 26268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0).getValueType(), 26278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 26288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 26298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SIGN_EXTEND_INREG: { 26318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // NOTE: we could fall back on load/store here too for targets without 26328c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // SAR. However, it is doubtful that any exist. 2633e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); 263487862e77bbf90cf1b68c9eea1f3641ad81435e38Dan Gohman EVT VT = Node->getValueType(0); 263595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT ShiftAmountTy = TLI.getShiftAmountTy(VT); 2636d1996360399ad6dbe75ee185b661b16c83146373Dan Gohman if (VT.isVector()) 263787862e77bbf90cf1b68c9eea1f3641ad81435e38Dan Gohman ShiftAmountTy = VT; 2638d1996360399ad6dbe75ee185b661b16c83146373Dan Gohman unsigned BitsDiff = VT.getScalarType().getSizeInBits() - 2639d1996360399ad6dbe75ee185b661b16c83146373Dan Gohman ExtraVT.getScalarType().getSizeInBits(); 264087862e77bbf90cf1b68c9eea1f3641ad81435e38Dan Gohman SDValue ShiftCst = DAG.getConstant(BitsDiff, ShiftAmountTy); 26418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SHL, dl, Node->getValueType(0), 26428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), ShiftCst); 2643775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::SRA, dl, Node->getValueType(0), Tmp1, ShiftCst); 2644775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Tmp1); 26458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 26478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND_INREG: { 26488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // The only way we can lower this is to turn it into a TRUNCSTORE, 26497a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // EXTLOAD pair, targeting a temporary location (a stack slot). 26508c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 26518c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // NOTE: there is a choice here between constantly creating new stack 26528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // slots and always reusing the same one. We currently always create 26538c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // new ones, as reuse may inhibit scheduling. 2654e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); 26558c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), ExtraVT, 26568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 26578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 26588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 26608c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 26618c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 26628c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandLegalINT_TO_FP(Node->getOpcode() == ISD::SINT_TO_FP, 26638c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), Node->getValueType(0), dl); 26648c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 26658c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_UINT: { 26678c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SDValue True, False; 2668e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getOperand(0).getValueType(); 2669e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NVT = Node->getValueType(0); 26703069cbf7b3ef9a31bbb8e434686b7259052c364aBenjamin Kramer APFloat apf(APInt::getNullValue(VT.getSizeInBits())); 26718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman APInt x = APInt::getSignBit(NVT.getSizeInBits()); 26728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman (void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven); 26738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getConstantFP(apf, VT); 26748c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), 26758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), 26768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1, ISD::SETLT); 26778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0)); 2678775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, 2679775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DAG.getNode(ISD::FSUB, dl, VT, 2680775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(0), Tmp1)); 26818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman False = DAG.getNode(ISD::XOR, dl, NVT, False, 26828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(x, NVT)); 26838c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, True, False); 26848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 26858c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 2687509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::VAARG: { 2688509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 2689e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 2690509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = Node->getOperand(0); 2691509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2 = Node->getOperand(1); 269272d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola unsigned Align = Node->getConstantOperandVal(3); 269372d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola 2694ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue VAListLoad = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, 2695ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(V), false, false, 0); 269672d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola SDValue VAList = VAListLoad; 269772d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola 2698cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola if (Align > TLI.getMinStackArgumentAlignment()) { 2699cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola assert(((Align & (Align-1)) == 0) && "Expected Align to be a power of 2"); 2700cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola 270172d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola VAList = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, 270272d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola DAG.getConstant(Align - 1, 270372d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola TLI.getPointerTy())); 270472d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola 270572d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola VAList = DAG.getNode(ISD::AND, dl, TLI.getPointerTy(), VAList, 270607e3a38c78d2788e05d716e7fa552b9449c87c33Chris Lattner DAG.getConstant(-(int64_t)Align, 270772d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola TLI.getPointerTy())); 270872d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola } 270972d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola 2710509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Increment the pointer, VAList, to the next vaarg 2711509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, 2712509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman DAG.getConstant(TLI.getTargetData()-> 2713adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext())), 2714509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman TLI.getPointerTy())); 2715509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Store the incremented VAList to the legalized pointer 27166229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner Tmp3 = DAG.getStore(VAListLoad.getValue(1), dl, Tmp3, Tmp2, 27176229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(V), false, false, 0); 2718509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Load the actual argument out of the pointer VAList 2719ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, MachinePointerInfo(), 27201e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0)); 2721509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Results.push_back(Results[0].getValue(1)); 2722509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 2723509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 27248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VACOPY: { 27258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // This defaults to loading a pointer from the input and storing it to the 27268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // output, returning the chain. 27278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue(); 27288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue(); 27298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getLoad(TLI.getPointerTy(), dl, Node->getOperand(0), 2730ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Node->getOperand(2), MachinePointerInfo(VS), 2731ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, 0); 2732ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), 2733ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(VD), false, false, 0); 2734775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Tmp1); 27358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 27368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 27378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_VECTOR_ELT: 27388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOperand(0).getValueType().getVectorNumElements() == 1) 27398c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // This must be an access of the only element. Return it. 2740bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp1 = DAG.getNode(ISD::BITCAST, dl, Node->getValueType(0), 27418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0)); 27428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman else 27438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandExtractFromVectorThroughStack(SDValue(Node, 0)); 27448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 27458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 27468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_SUBVECTOR: 2747775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandExtractFromVectorThroughStack(SDValue(Node, 0))); 27488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 2749cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene case ISD::INSERT_SUBVECTOR: 2750cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Results.push_back(ExpandInsertToVectorThroughStack(SDValue(Node, 0))); 2751cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene break; 2752509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::CONCAT_VECTORS: { 2753775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandVectorBuildThroughStack(Node)); 2754509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 2755509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 27568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SCALAR_TO_VECTOR: 2757775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandSCALAR_TO_VECTOR(Node)); 27588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 27593f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::INSERT_VECTOR_ELT: 2760775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandINSERT_VECTOR_ELT(Node->getOperand(0), 2761775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(1), 2762775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(2), dl)); 27633f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman break; 2764509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::VECTOR_SHUFFLE: { 2765509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman SmallVector<int, 8> Mask; 2766509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman cast<ShuffleVectorSDNode>(Node)->getMask(Mask); 2767509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman 2768e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 2769e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT EltVT = VT.getVectorElementType(); 277075b10047fc57c30c86bb7c9ea0ee923ff3c33a7eDan Gohman if (!TLI.isTypeLegal(EltVT)) 277114b2141497a913a2d5b508a0174ba09cac61e0bfBob Wilson EltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT); 2772509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman unsigned NumElems = VT.getVectorNumElements(); 2773509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman SmallVector<SDValue, 8> Ops; 2774509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman for (unsigned i = 0; i != NumElems; ++i) { 2775509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman if (Mask[i] < 0) { 2776509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Ops.push_back(DAG.getUNDEF(EltVT)); 2777509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman continue; 2778509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 2779509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman unsigned Idx = Mask[i]; 2780509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman if (Idx < NumElems) 2781775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, 2782775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(0), 2783775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DAG.getIntPtrConstant(Idx))); 2784509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman else 2785775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, 2786775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(1), 2787775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DAG.getIntPtrConstant(Idx - NumElems))); 2788509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 2789509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size()); 2790509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Results.push_back(Tmp1); 2791509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 2792509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 27938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_ELEMENT: { 2794e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpTy = Node->getOperand(0).getValueType(); 27958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { 27968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // 1 -> Hi 27978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0), 27988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(OpTy.getSizeInBits()/2, 279995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Node->getOperand(0).getValueType()))); 28008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1); 28018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else { 28028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // 0 -> Lo 28038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), 28048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0)); 28058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 28068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 28078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 28088c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 28093f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::STACKSAVE: 28103f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // Expand to CopyFromReg if the target set 28113f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // StackPointerRegisterToSaveRestore. 28123f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) { 2813775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, SP, 2814775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getValueType(0))); 28153f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman Results.push_back(Results[0].getValue(1)); 28163f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman } else { 2817775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getUNDEF(Node->getValueType(0))); 28183f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman Results.push_back(Node->getOperand(0)); 28193f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman } 28203f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman break; 28213f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::STACKRESTORE: 2822775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // Expand to CopyToReg if the target set 2823775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // StackPointerRegisterToSaveRestore. 2824775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) { 2825775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getCopyToReg(Node->getOperand(0), dl, SP, 2826775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(1))); 2827775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } else { 2828775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Node->getOperand(0)); 2829775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } 28303f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman break; 28314bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::FCOPYSIGN: 2832775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFCOPYSIGN(Node)); 28334bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 2834f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FNEG: 2835f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman // Expand Y = FNEG(X) -> Y = SUB -0.0, X 2836f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp1 = DAG.getConstantFP(-0.0, Node->getValueType(0)); 2837f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp1 = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp1, 2838f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Node->getOperand(0)); 2839f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Results.push_back(Tmp1); 2840f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2841f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FABS: { 2842f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). 2843e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 2844f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp1 = Node->getOperand(0); 2845f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp2 = DAG.getConstantFP(0.0, VT); 2846775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), 2847f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp1, Tmp2, ISD::SETUGT); 2848775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1); 2849775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3); 2850f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Results.push_back(Tmp1); 2851f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2852f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman } 2853f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FSQRT: 2854775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::SQRT_F32, RTLIB::SQRT_F64, 2855775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128)); 2856f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2857f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FSIN: 2858775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::SIN_F32, RTLIB::SIN_F64, 2859775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::SIN_F80, RTLIB::SIN_PPCF128)); 2860f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2861f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FCOS: 2862775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::COS_F32, RTLIB::COS_F64, 2863775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::COS_F80, RTLIB::COS_PPCF128)); 2864f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2865f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FLOG: 2866775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG_F32, RTLIB::LOG_F64, 2867775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::LOG_F80, RTLIB::LOG_PPCF128)); 2868f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2869f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FLOG2: 2870775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64, 2871775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128)); 2872f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2873f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FLOG10: 2874775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64, 2875775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::LOG10_F80, RTLIB::LOG10_PPCF128)); 2876f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2877f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FEXP: 2878775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP_F32, RTLIB::EXP_F64, 2879775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::EXP_F80, RTLIB::EXP_PPCF128)); 2880f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2881f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FEXP2: 2882775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64, 2883775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128)); 2884f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2885f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FTRUNC: 2886775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, 2887775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128)); 2888f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2889f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FFLOOR: 2890775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64, 2891775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::FLOOR_F80, RTLIB::FLOOR_PPCF128)); 2892f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2893f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FCEIL: 2894775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::CEIL_F32, RTLIB::CEIL_F64, 2895775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128)); 2896f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2897f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FRINT: 2898775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::RINT_F32, RTLIB::RINT_F64, 2899775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::RINT_F80, RTLIB::RINT_PPCF128)); 2900f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2901f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FNEARBYINT: 2902775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::NEARBYINT_F32, 2903775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::NEARBYINT_F64, 2904775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::NEARBYINT_F80, 2905775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::NEARBYINT_PPCF128)); 2906f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2907f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FPOWI: 2908775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::POWI_F32, RTLIB::POWI_F64, 2909775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::POWI_F80, RTLIB::POWI_PPCF128)); 2910f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2911f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FPOW: 2912775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::POW_F32, RTLIB::POW_F64, 2913775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::POW_F80, RTLIB::POW_PPCF128)); 2914f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2915f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FDIV: 2916775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::DIV_F32, RTLIB::DIV_F64, 2917775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::DIV_F80, RTLIB::DIV_PPCF128)); 2918f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 2919f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FREM: 2920775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::REM_F32, RTLIB::REM_F64, 2921775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::REM_F80, RTLIB::REM_PPCF128)); 2922f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 292333390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich case ISD::FMA: 292433390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich Results.push_back(ExpandFPLibCall(Node, RTLIB::FMA_F32, RTLIB::FMA_F64, 292533390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich RTLIB::FMA_F80, RTLIB::FMA_PPCF128)); 292633390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich break; 2927927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov case ISD::FP16_TO_FP32: 2928927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov Results.push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32, Node, false)); 2929927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov break; 2930927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov case ISD::FP32_TO_FP16: 2931927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov Results.push_back(ExpandLibCall(RTLIB::FPROUND_F32_F16, Node, false)); 2932927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov break; 2933f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::ConstantFP: { 2934f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node); 2935775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // Check to see if this FP immediate is already legal. 2936775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // If this is a legal constant, turn it into a TargetConstantFP node. 2937bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (!TLI.isFPImmLegal(CFP->getValueAPF(), Node->getValueType(0))) 2938bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Results.push_back(ExpandConstantFP(CFP, true)); 2939f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman break; 2940f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman } 294126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::EHSELECTION: { 294226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman unsigned Reg = TLI.getExceptionSelectorRegister(); 294326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman assert(Reg && "Can't expand to unknown register!"); 2944775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getCopyFromReg(Node->getOperand(1), dl, Reg, 2945775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getValueType(0))); 294626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Results[0].getValue(1)); 294726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 294826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 294926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::EXCEPTIONADDR: { 295026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman unsigned Reg = TLI.getExceptionAddressRegister(); 295126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman assert(Reg && "Can't expand to unknown register!"); 2952775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, Reg, 2953775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getValueType(0))); 295426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Results[0].getValue(1)); 295526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 295626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 295726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::SUB: { 2958e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 295926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman assert(TLI.isOperationLegalOrCustom(ISD::ADD, VT) && 296026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman TLI.isOperationLegalOrCustom(ISD::XOR, VT) && 296126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman "Don't know how to expand this subtraction!"); 296226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Tmp1 = DAG.getNode(ISD::XOR, dl, VT, Node->getOperand(1), 296326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT)); 2964775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::ADD, dl, VT, Tmp2, DAG.getConstant(1, VT)); 2965775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(ISD::ADD, dl, VT, Node->getOperand(0), Tmp1)); 296626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 296726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 2968f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::UREM: 2969f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::SREM: { 2970e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 297126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman SDVTList VTs = DAG.getVTList(VT, VT); 2972f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman bool isSigned = Node->getOpcode() == ISD::SREM; 2973f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman unsigned DivOpc = isSigned ? ISD::SDIV : ISD::UDIV; 2974f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM; 2975f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp2 = Node->getOperand(0); 2976f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp3 = Node->getOperand(1); 297765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) || 297865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng (isDivRemLibcallAvailable(Node, isSigned, TLI) && 297965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng UseDivRem(Node, isSigned, false))) { 29803be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Tmp2, Tmp3).getValue(1); 29813be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman } else if (TLI.isOperationLegalOrCustom(DivOpc, VT)) { 2982f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman // X % Y -> X-X/Y*Y 2983f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(DivOpc, dl, VT, Tmp2, Tmp3); 2984f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(ISD::MUL, dl, VT, Tmp1, Tmp3); 2985f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Tmp2, Tmp1); 298665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng } else if (isSigned) 298765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Tmp1 = ExpandIntLibCall(Node, true, 298865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SREM_I8, 298965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SREM_I16, RTLIB::SREM_I32, 299065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SREM_I64, RTLIB::SREM_I128); 299165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng else 299265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Tmp1 = ExpandIntLibCall(Node, false, 299365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UREM_I8, 299465279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UREM_I16, RTLIB::UREM_I32, 299565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UREM_I64, RTLIB::UREM_I128); 299626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Tmp1); 299726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 299826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 2999f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::UDIV: 3000f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::SDIV: { 3001f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman bool isSigned = Node->getOpcode() == ISD::SDIV; 3002f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM; 3003e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 300426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman SDVTList VTs = DAG.getVTList(VT, VT); 300565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) || 300665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng (isDivRemLibcallAvailable(Node, isSigned, TLI) && 300765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng UseDivRem(Node, isSigned, true))) 3008f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Node->getOperand(0), 3009f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Node->getOperand(1)); 301065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng else if (isSigned) 301165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Tmp1 = ExpandIntLibCall(Node, true, 301265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SDIV_I8, 301365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SDIV_I16, RTLIB::SDIV_I32, 301465279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SDIV_I64, RTLIB::SDIV_I128); 301565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng else 301665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Tmp1 = ExpandIntLibCall(Node, false, 301765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UDIV_I8, 301865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UDIV_I16, RTLIB::UDIV_I32, 301965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UDIV_I64, RTLIB::UDIV_I128); 302026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Tmp1); 302126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 302226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 302326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::MULHU: 302426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::MULHS: { 302526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman unsigned ExpandOpcode = Node->getOpcode() == ISD::MULHU ? ISD::UMUL_LOHI : 302626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman ISD::SMUL_LOHI; 3027e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 302826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman SDVTList VTs = DAG.getVTList(VT, VT); 302926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman assert(TLI.isOperationLegalOrCustom(ExpandOpcode, VT) && 303026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman "If this wasn't legal, it shouldn't have been created!"); 303126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Tmp1 = DAG.getNode(ExpandOpcode, dl, VTs, Node->getOperand(0), 303226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Node->getOperand(1)); 303326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Tmp1.getValue(1)); 303426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 303526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 303665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case ISD::SDIVREM: 303765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case ISD::UDIVREM: 303865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng // Expand into divrem libcall 303965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng ExpandDivRemLibCall(Node, Results); 304065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng break; 304126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::MUL: { 3042e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 304326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman SDVTList VTs = DAG.getVTList(VT, VT); 304426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // See if multiply or divide can be lowered using two-result operations. 304526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // We just need the low half of the multiply; try both the signed 304626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // and unsigned forms. If the target supports both SMUL_LOHI and 304726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // UMUL_LOHI, form a preference by checking which forms of plain 304826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // MULH it supports. 304926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT); 305026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT); 305126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT); 305226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT); 305326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman unsigned OpToUse = 0; 305426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman if (HasSMUL_LOHI && !HasMULHS) { 305526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman OpToUse = ISD::SMUL_LOHI; 305626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } else if (HasUMUL_LOHI && !HasMULHU) { 305726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman OpToUse = ISD::UMUL_LOHI; 305826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } else if (HasSMUL_LOHI) { 305926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman OpToUse = ISD::SMUL_LOHI; 306026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } else if (HasUMUL_LOHI) { 306126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman OpToUse = ISD::UMUL_LOHI; 306226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 306326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman if (OpToUse) { 3064775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(OpToUse, dl, VTs, Node->getOperand(0), 3065775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(1))); 306626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 306726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 30688983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov Tmp1 = ExpandIntLibCall(Node, false, 30698983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::MUL_I8, 30708983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::MUL_I16, RTLIB::MUL_I32, 307126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman RTLIB::MUL_I64, RTLIB::MUL_I128); 307226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Tmp1); 307326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 307426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 30754bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::SADDO: 30764bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::SSUBO: { 30774bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue LHS = Node->getOperand(0); 30784bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue RHS = Node->getOperand(1); 30794bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ? 30804bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 30814bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman LHS, RHS); 30824bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Sum); 3083122d06de7482dcb39e7dbcbfe302e39cc55627e5Bill Wendling EVT OType = Node->getValueType(1); 3084775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling 30854bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Zero = DAG.getConstant(0, LHS.getValueType()); 30864bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 30874bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // LHSSign -> LHS >= 0 30884bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // RHSSign -> RHS >= 0 30894bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // SumSign -> Sum >= 0 30904bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // 30914bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Add: 30924bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign) 30934bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Sub: 30944bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign) 30954bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // 30964bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE); 30974bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE); 30984bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign, 30994bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Node->getOpcode() == ISD::SADDO ? 31004bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman ISD::SETEQ : ISD::SETNE); 31014bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 31024bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE); 31034bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE); 31044bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 31054bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE); 31064bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Cmp); 31074bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 31084bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 31094bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::UADDO: 31104bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::USUBO: { 31114bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue LHS = Node->getOperand(0); 31124bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue RHS = Node->getOperand(1); 31134bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::UADDO ? 31144bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 31154bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman LHS, RHS); 31164bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Sum); 3117775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getSetCC(dl, Node->getValueType(1), Sum, LHS, 3118775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOpcode () == ISD::UADDO ? 3119775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling ISD::SETULT : ISD::SETUGT)); 31204bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 31214bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 3122db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman case ISD::UMULO: 3123db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman case ISD::SMULO: { 3124e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 3125abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits() * 2); 3126db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman SDValue LHS = Node->getOperand(0); 3127db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman SDValue RHS = Node->getOperand(1); 3128db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman SDValue BottomHalf; 3129db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman SDValue TopHalf; 3130ec9d8b00470b2ddabef4e1b58b4f60d69995d8ceNuno Lopes static const unsigned Ops[2][3] = 3131db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman { { ISD::MULHU, ISD::UMUL_LOHI, ISD::ZERO_EXTEND }, 3132db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman { ISD::MULHS, ISD::SMUL_LOHI, ISD::SIGN_EXTEND }}; 3133db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman bool isSigned = Node->getOpcode() == ISD::SMULO; 3134db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman if (TLI.isOperationLegalOrCustom(Ops[isSigned][0], VT)) { 3135db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman BottomHalf = DAG.getNode(ISD::MUL, dl, VT, LHS, RHS); 3136db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = DAG.getNode(Ops[isSigned][0], dl, VT, LHS, RHS); 3137db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } else if (TLI.isOperationLegalOrCustom(Ops[isSigned][1], VT)) { 3138db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman BottomHalf = DAG.getNode(Ops[isSigned][1], dl, DAG.getVTList(VT, VT), LHS, 3139db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman RHS); 3140db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = BottomHalf.getValue(1); 314138a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher } else if (TLI.isTypeLegal(EVT::getIntegerVT(*DAG.getContext(), 314238a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher VT.getSizeInBits() * 2))) { 3143db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman LHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, LHS); 3144db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman RHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, RHS); 3145db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman Tmp1 = DAG.getNode(ISD::MUL, dl, WideVT, LHS, RHS); 3146db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Tmp1, 3147db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman DAG.getIntPtrConstant(0)); 3148db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Tmp1, 3149db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman DAG.getIntPtrConstant(1)); 315038a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher } else { 315138a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher // We can fall back to a libcall with an illegal type for the MUL if we 315238a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher // have a libcall big enough. 315338a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher // Also, we can fall back to a division in some cases, but that's a big 315438a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher // performance hit in the general case. 315538a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 315638a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher if (WideVT == MVT::i16) 315738a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher LC = RTLIB::MUL_I16; 315838a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher else if (WideVT == MVT::i32) 315938a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher LC = RTLIB::MUL_I32; 316038a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher else if (WideVT == MVT::i64) 316138a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher LC = RTLIB::MUL_I64; 316238a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher else if (WideVT == MVT::i128) 316338a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher LC = RTLIB::MUL_I128; 316438a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher assert(LC != RTLIB::UNKNOWN_LIBCALL && "Cannot expand this operation!"); 3165f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 3166f316eb70743e88227b8919370fe38587ffe93512Dan Gohman // The high part is obtained by SRA'ing all but one of the bits of low 3167abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // part. 3168abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher unsigned LoSize = VT.getSizeInBits(); 3169abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, RHS, 3170abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher DAG.getConstant(LoSize-1, TLI.getPointerTy())); 3171abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue HiRHS = DAG.getNode(ISD::SRA, dl, VT, LHS, 3172abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher DAG.getConstant(LoSize-1, TLI.getPointerTy())); 3173abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher 3174abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // Here we're passing the 2 arguments explicitly as 4 arguments that are 3175abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // pre-lowered to the correct types. This all depends upon WideVT not 3176abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // being a legal type for the architecture and thus has to be split to 3177abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // two arguments. 3178abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue Args[] = { LHS, HiLHS, RHS, HiRHS }; 3179abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl); 3180abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret, 3181abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher DAG.getIntPtrConstant(0)); 3182abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret, 3183abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher DAG.getIntPtrConstant(1)); 3184bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // Ret is a node with an illegal type. Because such things are not 3185bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // generally permitted during this phase of legalization, delete the 3186bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // node. The above EXTRACT_ELEMENT nodes should have been folded. 3187bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.DeleteNode(Ret.getNode()); 3188db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } 3189f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 3190db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman if (isSigned) { 319195771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson Tmp1 = DAG.getConstant(VT.getSizeInBits() - 1, 319295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(BottomHalf.getValueType())); 3193db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, Tmp1); 3194db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), TopHalf, Tmp1, 3195db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman ISD::SETNE); 3196db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } else { 3197db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), TopHalf, 3198db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman DAG.getConstant(0, VT), ISD::SETNE); 3199db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } 3200db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman Results.push_back(BottomHalf); 3201db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman Results.push_back(TopHalf); 3202db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman break; 3203db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } 3204f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::BUILD_PAIR: { 3205e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PairTy = Node->getValueType(0); 3206f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, PairTy, Node->getOperand(0)); 3207f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp2 = DAG.getNode(ISD::ANY_EXTEND, dl, PairTy, Node->getOperand(1)); 3208775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp2 = DAG.getNode(ISD::SHL, dl, PairTy, Tmp2, 3209f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman DAG.getConstant(PairTy.getSizeInBits()/2, 321095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(PairTy))); 3211775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(ISD::OR, dl, PairTy, Tmp1, Tmp2)); 3212f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman break; 3213f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman } 3214509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::SELECT: 3215509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = Node->getOperand(0); 3216509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2 = Node->getOperand(1); 3217509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp3 = Node->getOperand(2); 3218775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling if (Tmp1.getOpcode() == ISD::SETCC) { 3219509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = DAG.getSelectCC(dl, Tmp1.getOperand(0), Tmp1.getOperand(1), 3220509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2, Tmp3, 3221509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman cast<CondCodeSDNode>(Tmp1.getOperand(2))->get()); 3222775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } else { 3223509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = DAG.getSelectCC(dl, Tmp1, 3224509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman DAG.getConstant(0, Tmp1.getValueType()), 3225509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2, Tmp3, ISD::SETNE); 3226775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } 3227509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Results.push_back(Tmp1); 3228509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 32294bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::BR_JT: { 32304bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Chain = Node->getOperand(0); 32314bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Table = Node->getOperand(1); 32324bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Index = Node->getOperand(2); 32334bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 3234e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PTy = TLI.getPointerTy(); 3235071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner 3236071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner const TargetData &TD = *TLI.getTargetData(); 3237071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner unsigned EntrySize = 3238071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD); 32396e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach 3240071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner Index = DAG.getNode(ISD::MUL, dl, PTy, 32414bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Index, DAG.getConstant(EntrySize, PTy)); 32424bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); 32434bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 324423b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8); 3245a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr, 324685ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getJumpTable(), MemVT, 32471e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 32484bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Addr = LD; 324955e59c186303ff02c0be7429da3b1b36c347f164Dan Gohman if (TM.getRelocationModel() == Reloc::PIC_) { 32504bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // For PIC, the sequence is: 3251775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // BRIND(load(Jumptable + index) + RelocBase) 32524bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // RelocBase can be JumpTable, GOT or some sort of global base. 32534bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, 32544bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman TLI.getPICJumpTableRelocBase(Table, DAG)); 32554bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 3256825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Tmp1 = DAG.getNode(ISD::BRIND, dl, MVT::Other, LD.getValue(1), Addr); 32574bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Tmp1); 32584bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 32594bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 3260f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::BRCOND: 3261f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman // Expand brcond's setcc into its constituent parts and create a BR_CC 3262f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman // Node. 3263f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = Node->getOperand(0); 3264f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp2 = Node->getOperand(1); 3265775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling if (Tmp2.getOpcode() == ISD::SETCC) { 3266825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Tmp1 = DAG.getNode(ISD::BR_CC, dl, MVT::Other, 3267f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1, Tmp2.getOperand(2), 3268f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp2.getOperand(0), Tmp2.getOperand(1), 3269f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Node->getOperand(2)); 3270775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } else { 327188882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings // We test only the i1 bit. Skip the AND if UNDEF. 327288882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings Tmp3 = (Tmp2.getOpcode() == ISD::UNDEF) ? Tmp2 : 327388882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings DAG.getNode(ISD::AND, dl, Tmp2.getValueType(), Tmp2, 327488882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings DAG.getConstant(1, Tmp2.getValueType())); 3275825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Tmp1 = DAG.getNode(ISD::BR_CC, dl, MVT::Other, Tmp1, 327688882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings DAG.getCondCode(ISD::SETNE), Tmp3, 327788882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings DAG.getConstant(0, Tmp3.getValueType()), 3278f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Node->getOperand(2)); 3279775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } 3280f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Results.push_back(Tmp1); 3281f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman break; 3282ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman case ISD::SETCC: { 3283ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp1 = Node->getOperand(0); 3284ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp2 = Node->getOperand(1); 3285ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp3 = Node->getOperand(2); 3286775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling LegalizeSetCCCondCode(Node->getValueType(0), Tmp1, Tmp2, Tmp3, dl); 3287ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman 3288ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // If we expanded the SETCC into an AND/OR, return the new node 3289ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman if (Tmp2.getNode() == 0) { 3290ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Results.push_back(Tmp1); 3291ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 3292ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman } 3293ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman 3294ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // Otherwise, SETCC for the given comparison type must be completely 3295ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // illegal; expand it into a SELECT_CC. 3296e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 3297ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, VT, Tmp1, Tmp2, 3298ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman DAG.getConstant(1, VT), DAG.getConstant(0, VT), Tmp3); 3299ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Results.push_back(Tmp1); 3300ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 3301ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman } 3302bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman case ISD::SELECT_CC: { 3303bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp1 = Node->getOperand(0); // LHS 3304bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp2 = Node->getOperand(1); // RHS 3305bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3 = Node->getOperand(2); // True 3306bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp4 = Node->getOperand(3); // False 3307bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman SDValue CC = Node->getOperand(4); 3308bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman 3309bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp1.getValueType()), 3310775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1, Tmp2, CC, dl); 3311bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman 3312bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman assert(!Tmp2.getNode() && "Can't legalize SELECT_CC with legal condition!"); 3313bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp2 = DAG.getConstant(0, Tmp1.getValueType()); 3314bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman CC = DAG.getCondCode(ISD::SETNE); 3315bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1, Tmp2, 3316bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3, Tmp4, CC); 3317bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Results.push_back(Tmp1); 3318bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman break; 3319bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman } 3320bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman case ISD::BR_CC: { 3321bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp1 = Node->getOperand(0); // Chain 3322bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp2 = Node->getOperand(2); // LHS 3323bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3 = Node->getOperand(3); // RHS 3324bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp4 = Node->getOperand(1); // CC 3325bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman 3326bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp2.getValueType()), 3327775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp2, Tmp3, Tmp4, dl); 3328bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman 3329bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman assert(!Tmp3.getNode() && "Can't legalize BR_CC with legal condition!"); 3330bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3 = DAG.getConstant(0, Tmp2.getValueType()); 3331bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp4 = DAG.getCondCode(ISD::SETNE); 3332bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp1 = DAG.getNode(ISD::BR_CC, dl, Node->getValueType(0), Tmp1, Tmp4, Tmp2, 3333bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3, Node->getOperand(4)); 3334bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Results.push_back(Tmp1); 3335bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman break; 3336bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman } 3337bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman case ISD::BUILD_VECTOR: 3338bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Results.push_back(ExpandBUILD_VECTOR(Node)); 3339bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman break; 3340bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman case ISD::SRA: 3341bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman case ISD::SRL: 3342bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman case ISD::SHL: { 3343bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // Scalarize vector SRA/SRL/SHL. 3344bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman EVT VT = Node->getValueType(0); 3345bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman assert(VT.isVector() && "Unable to legalize non-vector shift"); 3346bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman assert(TLI.isTypeLegal(VT.getScalarType())&& "Element type must be legal"); 3347bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman unsigned NumElem = VT.getVectorNumElements(); 3348bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman 3349bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SmallVector<SDValue, 8> Scalars; 3350bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman for (unsigned Idx = 0; Idx < NumElem; Idx++) { 3351bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 3352bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman VT.getScalarType(), 3353bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Node->getOperand(0), DAG.getIntPtrConstant(Idx)); 3354bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Sh = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 3355bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman VT.getScalarType(), 3356bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Node->getOperand(1), DAG.getIntPtrConstant(Idx)); 3357bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman Scalars.push_back(DAG.getNode(Node->getOpcode(), dl, 3358bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman VT.getScalarType(), Ex, Sh)); 3359bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 3360bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SDValue Result = 3361bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.getNode(ISD::BUILD_VECTOR, dl, Node->getValueType(0), 3362bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman &Scalars[0], Scalars.size()); 3363bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(SDValue(Node, 0), Result, this); 3364bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman break; 3365bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman } 33663f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::GLOBAL_OFFSET_TABLE: 33673f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::GlobalAddress: 33683f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::GlobalTLSAddress: 33693f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::ExternalSymbol: 33703f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::ConstantPool: 33713f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::JumpTable: 33723f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::INTRINSIC_W_CHAIN: 33733f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::INTRINSIC_WO_CHAIN: 33743f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::INTRINSIC_VOID: 33753f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // FIXME: Custom lowering for these operations shouldn't return null! 33763f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman break; 33778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 3378bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman 3379bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // Replace the original node with the legalized result. 3380bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (!Results.empty()) 3381bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(Node, Results.data(), this); 33828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman} 3383bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman 3384bf923b815d6da97367e3eedab69230918bf128a3Dan Gohmanvoid SelectionDAGLegalize::PromoteNode(SDNode *Node) { 3385bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman SmallVector<SDValue, 8> Results; 3386e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OVT = Node->getValueType(0); 33878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOpcode() == ISD::UINT_TO_FP || 3388a64eb92fe305424ebde2e3de2b12160b8bf76047Eli Friedman Node->getOpcode() == ISD::SINT_TO_FP || 3389775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOpcode() == ISD::SETCC) { 33908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman OVT = Node->getOperand(0).getValueType(); 3391775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } 3392e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); 33938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DebugLoc dl = Node->getDebugLoc(); 3394509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman SDValue Tmp1, Tmp2, Tmp3; 33958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 33968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTTZ: 33978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTLZ: 33988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTPOP: 33998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Zero extend the argument. 34008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); 34018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Perform the larger operation. 34029a4ba45f4cd0496c422f81e104adf6c03ebdd3baJakob Stoklund Olesen Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); 34038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOpcode() == ISD::CTTZ) { 34048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) 34059a4ba45f4cd0496c422f81e104adf6c03ebdd3baJakob Stoklund Olesen Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), 34068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT), 34078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ISD::SETEQ); 34088c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, 34098c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(OVT.getSizeInBits(), NVT), Tmp1); 34108c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else if (Node->getOpcode() == ISD::CTLZ) { 34118c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT)) 34128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SUB, dl, NVT, Tmp1, 34138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(NVT.getSizeInBits() - 34148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman OVT.getSizeInBits(), NVT)); 34158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 3416775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, OVT, Tmp1)); 34178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 34188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BSWAP: { 34198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); 3420167bea71a4bd19329a218f5e1bd8facfd90a0cf9Bill Wendling Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); 3421775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1); 3422775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, 342395771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(DiffBits, TLI.getShiftAmountTy(NVT))); 3424775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Tmp1); 34258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 34268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 34278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_UINT: 34288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_SINT: 34298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = PromoteLegalFP_TO_INT(Node->getOperand(0), Node->getValueType(0), 34308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOpcode() == ISD::FP_TO_SINT, dl); 34318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 34328c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 34338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 34348c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 34358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = PromoteLegalINT_TO_FP(Node->getOperand(0), Node->getValueType(0), 34368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOpcode() == ISD::SINT_TO_FP, dl); 34378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 34388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 3439f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::AND: 3440f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::OR: 3441c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen case ISD::XOR: { 3442c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen unsigned ExtOp, TruncOp; 3443c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen if (OVT.isVector()) { 3444bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck ExtOp = ISD::BITCAST; 3445bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck TruncOp = ISD::BITCAST; 344635a389344d21178ee280c2410401b2060b5b879cChris Lattner } else { 344735a389344d21178ee280c2410401b2060b5b879cChris Lattner assert(OVT.isInteger() && "Cannot promote logic operation"); 3448c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen ExtOp = ISD::ANY_EXTEND; 3449c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen TruncOp = ISD::TRUNCATE; 3450c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen } 3451c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen // Promote each of the values to the new type. 3452c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(0)); 3453c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3454c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen // Perform the larger operation, then convert back 3455775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); 3456775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(TruncOp, dl, OVT, Tmp1)); 3457f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3458c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen } 3459c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen case ISD::SELECT: { 3460509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman unsigned ExtOp, TruncOp; 34614bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman if (Node->getValueType(0).isVector()) { 3462bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck ExtOp = ISD::BITCAST; 3463bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck TruncOp = ISD::BITCAST; 34644bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } else if (Node->getValueType(0).isInteger()) { 3465509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman ExtOp = ISD::ANY_EXTEND; 3466509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman TruncOp = ISD::TRUNCATE; 3467509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } else { 3468509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman ExtOp = ISD::FP_EXTEND; 3469509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman TruncOp = ISD::FP_ROUND; 3470509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 3471509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = Node->getOperand(0); 3472509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Promote each of the values to the new type. 3473509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3474509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp3 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(2)); 3475509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Perform the larger operation, then round down. 3476509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp1, Tmp2, Tmp3); 3477509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman if (TruncOp != ISD::FP_ROUND) 3478775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(TruncOp, dl, Node->getValueType(0), Tmp1); 3479509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman else 3480775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(TruncOp, dl, Node->getValueType(0), Tmp1, 3481509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman DAG.getIntPtrConstant(0)); 3482775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Tmp1); 3483509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 3484c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen } 3485509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::VECTOR_SHUFFLE: { 3486509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman SmallVector<int, 8> Mask; 3487509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman cast<ShuffleVectorSDNode>(Node)->getMask(Mask); 3488509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman 3489509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Cast the two input vectors. 3490bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp1 = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(0)); 3491bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp2 = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(1)); 3492509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman 3493509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Convert the shuffle mask to the right # elements. 3494775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask); 3495bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp1 = DAG.getNode(ISD::BITCAST, dl, OVT, Tmp1); 3496509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Results.push_back(Tmp1); 3497509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 3498509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 3499ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman case ISD::SETCC: { 350078d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen unsigned ExtOp = ISD::FP_EXTEND; 350178d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen if (NVT.isInteger()) { 350278d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen ISD::CondCode CCCode = 350378d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen cast<CondCodeSDNode>(Node->getOperand(2))->get(); 350478d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen ExtOp = isSignedIntSetCC(CCCode) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; 3505ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman } 350678d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(0)); 350778d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3508ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Results.push_back(DAG.getNode(ISD::SETCC, dl, Node->getValueType(0), 3509ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp1, Tmp2, Node->getOperand(2))); 3510ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 3511ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman } 35128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 3513bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman 3514bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman // Replace the original node with the legalized result. 3515bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman if (!Results.empty()) 3516bf923b815d6da97367e3eedab69230918bf128a3Dan Gohman DAG.ReplaceAllUsesWith(Node, Results.data(), this); 35178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman} 35188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 35193e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// SelectionDAG::Legalize - This is the entry point for the file. 35203e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// 3521975716af1b9a09274df6c2d92683449015bd8564Dan Gohmanvoid SelectionDAG::Legalize() { 35223e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// run - This is the main entry point to this class. 35233e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// 3524975716af1b9a09274df6c2d92683449015bd8564Dan Gohman SelectionDAGLegalize(*this).LegalizeDAG(); 35253e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 3526