LegalizeDAG.cpp revision ea0270298de4d2a4186454fc39a6836e99271f1d
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 { 496726b6d75a8b679068a58cb954ba97cf9d1690baNick Lewyckyclass SelectionDAGLegalize { 5055e59c186303ff02c0be7429da3b1b36c347f164Dan Gohman const TargetMachine &TM; 51d858e90f039f5fcdc2fa93035e911a5a9505cc50Dan Gohman const TargetLowering &TLI; 523e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner SelectionDAG &DAG; 533e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 546831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Libcall insertion helpers. 55fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 56fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings /// LastCALLSEQ - This keeps track of the CALLSEQ_END node that has been 576831a815999dde4cf801e2076e66b4943964daf2Chris Lattner /// legalized. We use this to ensure that calls are properly serialized 586831a815999dde4cf801e2076e66b4943964daf2Chris Lattner /// against each other, including inserted libcalls. 59fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings SmallVector<SDValue, 8> LastCALLSEQ; 60fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 613e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner enum LegalizeAction { 6268a17febc70d9beb5353454e0c6d136ca1e87605Chris Lattner Legal, // The target natively supports this operation. 6368a17febc70d9beb5353454e0c6d136ca1e87605Chris Lattner Promote, // This operation should be executed in a larger type. 64d74ea2bbd8bb630331f35ead42d385249bd42af8Chris Lattner Expand // Try to expand this to other ops, otherwise use a libcall. 653e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner }; 66fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 673e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// LegalizedNodes - For nodes that are of legal width, and that have more 683e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// than one use, this map indicates what regularized operand to use. This 693e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// allows us to avoid legalizing the same thing more than once. 70475871a144eb604ddaf37503397ba0941442e5fbDan Gohman DenseMap<SDValue, SDValue> LegalizedNodes; 713e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 72475871a144eb604ddaf37503397ba0941442e5fbDan Gohman void AddLegalizedOperand(SDValue From, SDValue To) { 7369a889eb35d59a10e78a07cc26d41cbab31eddceChris Lattner LegalizedNodes.insert(std::make_pair(From, To)); 7469a889eb35d59a10e78a07cc26d41cbab31eddceChris Lattner // If someone requests legalization of the new node, return itself. 7569a889eb35d59a10e78a07cc26d41cbab31eddceChris Lattner if (From != To) 7669a889eb35d59a10e78a07cc26d41cbab31eddceChris Lattner LegalizedNodes.insert(std::make_pair(To, To)); 7795771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson 78a778f5c798fc78ca15f813c362cdcdcc1eb86266Devang Patel // Transfer SDDbgValues. 79a778f5c798fc78ca15f813c362cdcdcc1eb86266Devang Patel DAG.TransferDbgValues(From, To); 808afc48e44ad8868c1d41511db645e2ba1a4b894eChris Lattner } 818afc48e44ad8868c1d41511db645e2ba1a4b894eChris Lattner 823e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnerpublic: 83975716af1b9a09274df6c2d92683449015bd8564Dan Gohman explicit SelectionDAGLegalize(SelectionDAG &DAG); 843e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 853e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// getTypeAction - Return how we should legalize values of this type, either 863e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// it is already legal or we need to expand it into multiple registers of 873e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// smaller integer type, or we need to promote it to a larger type. 88e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson LegalizeAction getTypeAction(EVT VT) const { 892d6dcb34b7f39682f3eed08180631189fb4b6636Nadav Rotem return (LegalizeAction)TLI.getTypeAction(*DAG.getContext(), VT); 903e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 913e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 923e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// isTypeLegal - Return true if this type is legal on this target. 933e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// 94e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson bool isTypeLegal(EVT VT) const { 953e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner return getTypeAction(VT) == Legal; 963e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 973e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 983e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner void LegalizeDAG(); 993e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 100456a93afcec7740c45cafa8354317f7b17987a6dChris Lattnerprivate: 1016a109f9d70bf7f75541400145a7a89880cc48166Dan Gohman /// LegalizeOp - Return a legal replacement for the given operation, with 1026a109f9d70bf7f75541400145a7a89880cc48166Dan Gohman /// all legal operands. 103475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LegalizeOp(SDValue O); 104fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1057ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue OptimizeFloatStore(StoreSDNode *ST); 1067ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 1076867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// PerformInsertVectorEltInMemory - Some target cannot handle a variable 1086867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it 1096867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// is necessary to spill the vector being inserted into to memory, perform 1106867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// the insert there, and then read the result back. 111475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, 1123f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SDValue Idx, DebugLoc dl); 1133f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SDValue ExpandINSERT_VECTOR_ELT(SDValue Vec, SDValue Val, 1143f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SDValue Idx, DebugLoc dl); 115826695281344e3a4c4d44d73dd155107aafd689bDan Gohman 1165a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// ShuffleWithNarrowerEltType - Return a vector shuffle operation which 1175a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// performs the same shuffe in terms of order or result bytes, but on a type 1185a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// whose vector element type is narrower than the original shuffle type. 1195a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3> 120e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue ShuffleWithNarrowerEltType(EVT NVT, EVT VT, DebugLoc dl, 1216e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach SDValue N1, SDValue N2, 1225a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman SmallVectorImpl<int> &Mask) const; 123fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 124c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner bool LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest, 12500755df36c1448ac4728a74d907aa09e3d8b2d49Chris Lattner SmallPtrSet<SDNode*, 32> &NodesLeadingTo); 1266831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 127e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson void LegalizeSetCCCondCode(EVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, 128775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DebugLoc dl); 129fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 13047b41f7e20b6af7aaaf0e050200102d55d038b9dEli Friedman SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned); 131abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue ExpandLibCall(RTLIB::Libcall LC, EVT RetVT, const SDValue *Ops, 132abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher unsigned NumOps, bool isSigned, DebugLoc dl); 133abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher 134e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach std::pair<SDValue, SDValue> ExpandChainLibCall(RTLIB::Libcall LC, 135e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach SDNode *Node, bool isSigned); 136f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman SDValue ExpandFPLibCall(SDNode *Node, RTLIB::Libcall Call_F32, 137f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_F64, RTLIB::Libcall Call_F80, 138f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_PPCF128); 1398983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov SDValue ExpandIntLibCall(SDNode *Node, bool isSigned, 1408983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I8, 1418983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I16, 1428983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I32, 1438983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I64, 144f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I128); 14565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng void ExpandDivRemLibCall(SDNode *Node, SmallVectorImpl<SDValue> &Results); 146475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 147e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue EmitStackConvert(SDValue SrcOp, EVT SlotVT, EVT DestVT, DebugLoc dl); 148475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ExpandBUILD_VECTOR(SDNode *Node); 149475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node); 1504bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman void ExpandDYNAMIC_STACKALLOC(SDNode *Node, 1514bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SmallVectorImpl<SDValue> &Results); 1524bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue ExpandFCOPYSIGN(SDNode *Node); 153e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, EVT DestVT, 154af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 155e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, EVT DestVT, bool isSigned, 156af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 157e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, EVT DestVT, bool isSigned, 158af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 159475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 1608a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue ExpandBSWAP(SDValue Op, DebugLoc dl); 1618a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue ExpandBitCount(unsigned Opc, SDValue Op, DebugLoc dl); 162475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 1633d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue ExpandExtractFromVectorThroughStack(SDValue Op); 164cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue ExpandInsertToVectorThroughStack(SDValue Op); 1657ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue ExpandVectorBuildThroughStack(SDNode* Node); 1668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 167e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach std::pair<SDValue, SDValue> ExpandAtomic(SDNode *Node); 168e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 1698c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman void ExpandNode(SDNode *Node, SmallVectorImpl<SDValue> &Results); 1708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman void PromoteNode(SDNode *Node, SmallVectorImpl<SDValue> &Results); 171fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings 172567cac0c511c2361ddb76eb4b8d49d306107a921Stuart Hastings SDValue getLastCALLSEQ() { return LastCALLSEQ.back(); } 173567cac0c511c2361ddb76eb4b8d49d306107a921Stuart Hastings void setLastCALLSEQ(const SDValue s) { LastCALLSEQ.back() = s; } 174fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings void pushLastCALLSEQ(SDValue s) { 175fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings LastCALLSEQ.push_back(s); 176fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings } 177fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings void popLastCALLSEQ() { 178fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings LastCALLSEQ.pop_back(); 179fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings } 1803e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner}; 1813e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 1823e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 1835a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// ShuffleWithNarrowerEltType - Return a vector shuffle operation which 1845a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// performs the same shuffe in terms of order or result bytes, but on a type 1855a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// whose vector element type is narrower than the original shuffle type. 1869008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman/// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3> 1876e9926108a69efbc11f1cadf947e98500e4d4228Jim GrosbachSDValue 1886e9926108a69efbc11f1cadf947e98500e4d4228Jim GrosbachSelectionDAGLegalize::ShuffleWithNarrowerEltType(EVT NVT, EVT VT, DebugLoc dl, 1895a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman SDValue N1, SDValue N2, 1909008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVectorImpl<int> &Mask) const { 1915a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman unsigned NumMaskElts = VT.getVectorNumElements(); 1925a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman unsigned NumDestElts = NVT.getVectorNumElements(); 1939008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman unsigned NumEltsGrowth = NumDestElts / NumMaskElts; 1949008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 1959008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman assert(NumEltsGrowth && "Cannot promote to vector type with fewer elts!"); 1969008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 1979008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman if (NumEltsGrowth == 1) 1989008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman return DAG.getVectorShuffle(NVT, dl, N1, N2, &Mask[0]); 1996e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach 2009008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVector<int, 8> NewMask; 2015a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman for (unsigned i = 0; i != NumMaskElts; ++i) { 2029008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman int Idx = Mask[i]; 2039008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman for (unsigned j = 0; j != NumEltsGrowth; ++j) { 2046e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach if (Idx < 0) 2059008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman NewMask.push_back(-1); 2069008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman else 2079008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman NewMask.push_back(Idx * NumEltsGrowth + j); 2084352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner } 20915684b29552393553524171bff1913e750f390f8Rafael Espindola } 2105a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman assert(NewMask.size() == NumDestElts && "Non-integer NumEltsGrowth?"); 2119008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman assert(TLI.isShuffleMaskLegal(NewMask, NVT) && "Shuffle not legal?"); 2129008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman return DAG.getVectorShuffle(NVT, dl, N1, N2, &NewMask[0]); 2134352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner} 2144352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 215975716af1b9a09274df6c2d92683449015bd8564Dan GohmanSelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag) 21655e59c186303ff02c0be7429da3b1b36c347f164Dan Gohman : TM(dag.getTarget()), TLI(dag.getTargetLoweringInfo()), 217ea0270298de4d2a4186454fc39a6836e99271f1dDan Gohman DAG(dag) { 2183e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 2193e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 2203e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnervoid SelectionDAGLegalize::LegalizeDAG() { 221fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings pushLastCALLSEQ(DAG.getEntryNode()); 222e5ab34e05d701da042619bf540046efc3c7bc41fMon P Wang 223ab510a76d6fed412f2dbbb29b3e123eef34f9c0aChris Lattner // The legalize process is inherently a bottom-up recursive process (users 224ab510a76d6fed412f2dbbb29b3e123eef34f9c0aChris Lattner // legalize their uses before themselves). Given infinite stack space, we 225ab510a76d6fed412f2dbbb29b3e123eef34f9c0aChris Lattner // could just start legalizing on the root and traverse the whole graph. In 226ab510a76d6fed412f2dbbb29b3e123eef34f9c0aChris Lattner // practice however, this causes us to run out of stack space on large basic 22732fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner // blocks. To avoid this problem, compute an ordering of the nodes where each 22832fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner // node is only legalized after all of its operands are legalized. 229f06c835f769aa1cf67801ed1f6bd366a447c18b1Dan Gohman DAG.AssignTopologicalOrder(); 230f06c835f769aa1cf67801ed1f6bd366a447c18b1Dan Gohman for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), 2317896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner E = prior(DAG.allnodes_end()); I != llvm::next(E); ++I) 232b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman LegalizeOp(SDValue(I, 0)); 23332fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner 23432fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner // Finally, it's possible the root changed. Get the new root. 235475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue OldRoot = DAG.getRoot(); 23632fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?"); 23732fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner DAG.setRoot(LegalizedNodes[OldRoot]); 2383e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 2393e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner LegalizedNodes.clear(); 2403e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 2413e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner // Remove dead nodes now. 242190a418bf6b49a4ef1c1980229a2f0d516e8a2cdChris Lattner DAG.RemoveDeadNodes(); 2433e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 2443e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 2456831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 2466831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// FindCallEndFromCallStart - Given a chained node that is part of a call 2476831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// sequence, find the CALLSEQ_END node that terminates the call sequence. 248a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastingsstatic SDNode *FindCallEndFromCallStart(SDNode *Node, int depth = 0) { 249fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings int next_depth = depth; 250a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings if (Node->getOpcode() == ISD::CALLSEQ_START) 251fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings next_depth = depth + 1; 252fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings if (Node->getOpcode() == ISD::CALLSEQ_END) { 253fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings assert(depth > 0 && "negative depth!"); 254fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings if (depth == 1) 25556500edc7a2599e651d39df71a714e1e255ed96aStuart Hastings return Node; 256fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings else 257fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings next_depth = depth - 1; 25856500edc7a2599e651d39df71a714e1e255ed96aStuart Hastings } 2596831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (Node->use_empty()) 2606831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return 0; // No CallSeqEnd 261fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2626831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // The chain is usually at the end. 263475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue TheChain(Node, Node->getNumValues()-1); 264825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (TheChain.getValueType() != MVT::Other) { 2656831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Sometimes it's at the beginning. 266475871a144eb604ddaf37503397ba0941442e5fbDan Gohman TheChain = SDValue(Node, 0); 267825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (TheChain.getValueType() != MVT::Other) { 2686831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Otherwise, hunt for it. 2696831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (unsigned i = 1, e = Node->getNumValues(); i != e; ++i) 270825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (Node->getValueType(i) == MVT::Other) { 271475871a144eb604ddaf37503397ba0941442e5fbDan Gohman TheChain = SDValue(Node, i); 2726831a815999dde4cf801e2076e66b4943964daf2Chris Lattner break; 2736831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 274fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 275fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Otherwise, we walked into a node without a chain. 276825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (TheChain.getValueType() != MVT::Other) 2776831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return 0; 2786831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 2796831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 280fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2816831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (SDNode::use_iterator UI = Node->use_begin(), 2826831a815999dde4cf801e2076e66b4943964daf2Chris Lattner E = Node->use_end(); UI != E; ++UI) { 283fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2846831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Make sure to only follow users of our token chain. 2858968450305c28444edc3c272d8752a8db0c2f34aDan Gohman SDNode *User = *UI; 2866831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) 2876831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (User->getOperand(i) == TheChain) 288fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings if (SDNode *Result = FindCallEndFromCallStart(User, next_depth)) 2896831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return Result; 2906831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 2916831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return 0; 2926831a815999dde4cf801e2076e66b4943964daf2Chris Lattner} 2936831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 294fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel/// FindCallStartFromCallEnd - Given a chained node that is part of a call 2956831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// sequence, find the CALLSEQ_START node that initiates the call sequence. 2966831a815999dde4cf801e2076e66b4943964daf2Chris Lattnerstatic SDNode *FindCallStartFromCallEnd(SDNode *Node) { 297a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings int nested = 0; 2986831a815999dde4cf801e2076e66b4943964daf2Chris Lattner assert(Node && "Didn't find callseq_start for a call??"); 299a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings while (Node->getOpcode() != ISD::CALLSEQ_START || nested) { 300a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings Node = Node->getOperand(0).getNode(); 301a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings assert(Node->getOperand(0).getValueType() == MVT::Other && 302a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings "Node doesn't have a token chain argument!"); 303a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings switch (Node->getOpcode()) { 304a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings default: 305a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings break; 306a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings case ISD::CALLSEQ_START: 307a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings if (!nested) 308a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings return Node; 309d673057c968ee6da2fc9084a26cbd1a500002d2bStuart Hastings Node = Node->getOperand(0).getNode(); 310a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings nested--; 311a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings break; 312a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings case ISD::CALLSEQ_END: 313a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings nested++; 314a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings break; 315a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings } 316a304d02791b3e0297a9d545e0c602c9f916691f9Stuart Hastings } 317d673057c968ee6da2fc9084a26cbd1a500002d2bStuart Hastings return (Node->getOpcode() == ISD::CALLSEQ_START) ? Node : 0; 3186831a815999dde4cf801e2076e66b4943964daf2Chris Lattner} 3196831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 3206831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// LegalizeAllNodesNotLeadingTo - Recursively walk the uses of N, looking to 321fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel/// see if any uses can reach Dest. If no dest operands can get to dest, 3226831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// legalize them, legalize ourself, and return false, otherwise, return true. 323c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner/// 324c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner/// Keep track of the nodes we fine that actually do lead to Dest in 325c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner/// NodesLeadingTo. This avoids retraversing them exponential number of times. 326c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner/// 327c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattnerbool SelectionDAGLegalize::LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest, 32800755df36c1448ac4728a74d907aa09e3d8b2d49Chris Lattner SmallPtrSet<SDNode*, 32> &NodesLeadingTo) { 3296831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (N == Dest) return true; // N certainly leads to Dest :) 330fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 331c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner // If we've already processed this node and it does lead to Dest, there is no 332c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner // need to reprocess it. 333c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner if (NodesLeadingTo.count(N)) return true; 334fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3356831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // If the first result of this node has been already legalized, then it cannot 3366831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // reach N. 33774807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman if (LegalizedNodes.count(SDValue(N, 0))) return false; 338fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3396831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Okay, this node has not already been legalized. Check and legalize all 3406831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // operands. If none lead to Dest, then we can legalize this node. 3416831a815999dde4cf801e2076e66b4943964daf2Chris Lattner bool OperandsLeadToDest = false; 3426831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) 3436831a815999dde4cf801e2076e66b4943964daf2Chris Lattner OperandsLeadToDest |= // If an operand leads to Dest, so do we. 3446e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach LegalizeAllNodesNotLeadingTo(N->getOperand(i).getNode(), Dest, 3456e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach NodesLeadingTo); 3466831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 347c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner if (OperandsLeadToDest) { 348c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner NodesLeadingTo.insert(N); 349c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner return true; 350c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner } 3516831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 3526831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Okay, this node looks safe, legalize it and return false. 353b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman LegalizeOp(SDValue(N, 0)); 3546831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return false; 3556831a815999dde4cf801e2076e66b4943964daf2Chris Lattner} 3566831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 3579f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng/// ExpandConstantFP - Expands the ConstantFP node to an integer constant or 3589f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng/// a load from the constant pool. 359475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP, 3600d137d7f35fba98f668098b3badf644efacf0e08Dan Gohman SelectionDAG &DAG, const TargetLowering &TLI) { 361004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng bool Extend = false; 36233c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen DebugLoc dl = CFP->getDebugLoc(); 363004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 364004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // If a FP immediate is precise when represented as a float and if the 365004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // target can do an extending load from float to double, we put it into 366004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // the constant pool as a float, even if it's is statically typed as a 367aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // double. This shrinks FP constants and canonicalizes them for targets where 368aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // an FP extending load is the same cost as a normal load (such as on the x87 369aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // fp stack or PPC FP unit). 370e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = CFP->getValueType(0); 3714fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman ConstantFP *LLVMC = const_cast<ConstantFP*>(CFP->getConstantFPValue()); 3729f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng if (!UseCP) { 373825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson assert((VT == MVT::f64 || VT == MVT::f32) && "Invalid type expansion"); 3747111b02c734c992b8c97d9918118768026dad79eDale Johannesen return DAG.getConstant(LLVMC->getValueAPF().bitcastToAPInt(), 375825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson (VT == MVT::f64) ? MVT::i64 : MVT::i32); 376279101eb1ac61e2d5b83d5bdcc5be56e710d2cd7Evan Cheng } 377279101eb1ac61e2d5b83d5bdcc5be56e710d2cd7Evan Cheng 378e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OrigVT = VT; 379e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT SVT = VT; 380825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson while (SVT != MVT::f32) { 381825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SVT = (MVT::SimpleValueType)(SVT.getSimpleVT().SimpleTy - 1); 3827720cb3823d5b5868f9b88b0127277820edcb562Dan Gohman if (ConstantFPSDNode::isValueValidForType(SVT, CFP->getValueAPF()) && 383ef12057737229452c17983faa20857dba441ef05Evan Cheng // Only do this if the target has a native EXTLOAD instruction from 384ef12057737229452c17983faa20857dba441ef05Evan Cheng // smaller type. 3850329466b6b4927f4e6f5d144891fef06a027fec5Evan Cheng TLI.isLoadExtLegal(ISD::EXTLOAD, SVT) && 386aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner TLI.ShouldShrinkFPConstant(OrigVT)) { 38723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson const Type *SType = SVT.getTypeForEVT(*DAG.getContext()); 388baf3c404409d5e47b13984a7f95bfbd6d1f2e79eOwen Anderson LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType)); 389ef12057737229452c17983faa20857dba441ef05Evan Cheng VT = SVT; 390ef12057737229452c17983faa20857dba441ef05Evan Cheng Extend = true; 391ef12057737229452c17983faa20857dba441ef05Evan Cheng } 392004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng } 393004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 394475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy()); 3951606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 396ef12057737229452c17983faa20857dba441ef05Evan Cheng if (Extend) 397a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings return DAG.getExtLoad(ISD::EXTLOAD, dl, OrigVT, 398bcc8017c738e92d9c1af221b11c4916cb524184eEvan Cheng DAG.getEntryNode(), 39985ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner CPIdx, MachinePointerInfo::getConstantPool(), 40085ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner VT, false, false, Alignment); 40133c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen return DAG.getLoad(OrigVT, dl, DAG.getEntryNode(), CPIdx, 40285ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getConstantPool(), false, false, 4031e559443a17d1b335f697551c6263ba60d5dd827David Greene Alignment); 404004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng} 405004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 406f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio/// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores. 407f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venanciostatic 408475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, 4090d137d7f35fba98f668098b3badf644efacf0e08Dan Gohman const TargetLowering &TLI) { 410475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = ST->getChain(); 411475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ptr = ST->getBasePtr(); 412475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Val = ST->getValue(); 413e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Val.getValueType(); 414907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen int Alignment = ST->getAlignment(); 415bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl = ST->getDebugLoc(); 41683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (ST->getMemoryVT().isFloatingPoint() || 41783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands ST->getMemoryVT().isVector()) { 41823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT intVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits()); 41905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (TLI.isTypeLegal(intVT)) { 42005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Expand to a bitconvert of the value to the integer type of the 42105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // same size, then a (misaligned) int store. 42205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // FIXME: Does not handle truncating floating point stores! 423bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue Result = DAG.getNode(ISD::BITCAST, dl, intVT, Val); 424da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner return DAG.getStore(Chain, dl, Result, Ptr, ST->getPointerInfo(), 425da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->isVolatile(), ST->isNonTemporal(), Alignment); 42605e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } 4271b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Do a (aligned) store to a stack slot, then copy from the stack slot 4281b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // to the final destination using (unaligned) integer loads and stores. 4291b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman EVT StoredVT = ST->getMemoryVT(); 4301b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman EVT RegVT = 4311b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman TLI.getRegisterType(*DAG.getContext(), 4321b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman EVT::getIntegerVT(*DAG.getContext(), 4331b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman StoredVT.getSizeInBits())); 4341b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman unsigned StoredBytes = StoredVT.getSizeInBits() / 8; 4351b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman unsigned RegBytes = RegVT.getSizeInBits() / 8; 4361b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman unsigned NumRegs = (StoredBytes + RegBytes - 1) / RegBytes; 4371b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 4381b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Make sure the stack slot is also aligned for the register type. 4391b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue StackPtr = DAG.CreateStackTemporary(StoredVT, RegVT); 4401b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 4411b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Perform the original store, only redirected to the stack slot. 4421b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue Store = DAG.getTruncStore(Chain, dl, 4431b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Val, StackPtr, MachinePointerInfo(), 4441b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman StoredVT, false, false, 0); 4451b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); 4461b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SmallVector<SDValue, 8> Stores; 4471b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman unsigned Offset = 0; 4481b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 4491b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Do all but one copies using the full register width. 4501b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman for (unsigned i = 1; i < NumRegs; i++) { 4511b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Load one integer register's worth from the stack slot. 4521b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, 4531b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MachinePointerInfo(), 4541b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman false, false, 0); 4551b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Store it to the final location. Remember the store. 4561b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr, 4571b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman ST->getPointerInfo().getWithOffset(Offset), 4581b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman ST->isVolatile(), ST->isNonTemporal(), 4591b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MinAlign(ST->getAlignment(), Offset))); 4601b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Increment the pointers. 4611b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Offset += RegBytes; 4621b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 4631b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Increment); 4641b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); 4651b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman } 4661b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 4671b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // The last store may be partial. Do a truncating store. On big-endian 4681b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // machines this requires an extending load from the stack slot to ensure 4691b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // that the bits are in the right place. 4701b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), 4711b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 8 * (StoredBytes - Offset)); 4721b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 4731b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // Load from the stack slot. 4741b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr, 4751b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MachinePointerInfo(), 4761b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MemVT, false, false, 0); 4771b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman 4781b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr, 4791b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman ST->getPointerInfo() 4801b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman .getWithOffset(Offset), 4811b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MemVT, ST->isVolatile(), 4821b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman ST->isNonTemporal(), 4831b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman MinAlign(ST->getAlignment(), Offset))); 4841b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman // The order of the stores doesn't matter - say it with a TokenFactor. 4851b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], 4861b32896bd2a6e001c8513fcf182d5a92ab7d487aDan Gohman Stores.size()); 487907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen } 48883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(ST->getMemoryVT().isInteger() && 48983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands !ST->getMemoryVT().isVector() && 490907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen "Unaligned store of unknown type."); 491f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Get the half-size VT 492bceddbdc919fc2ca7bc8c3911586ba93367686f0Ken Dyck EVT NewStoredVT = ST->getMemoryVT().getHalfSizedIntegerVT(*DAG.getContext()); 49383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands int NumBits = NewStoredVT.getSizeInBits(); 494f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio int IncrementSize = NumBits / 8; 495f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 496f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Divide the stored value in two parts. 49795771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson SDValue ShiftAmount = DAG.getConstant(NumBits, 49895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Val.getValueType())); 499475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo = Val; 500bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Hi = DAG.getNode(ISD::SRL, dl, VT, Val, ShiftAmount); 501f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 502f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Store the two parts 503475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Store1, Store2; 504bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr, 505da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo(), NewStoredVT, 5061e559443a17d1b335f697551c6263ba60d5dd827David Greene ST->isVolatile(), ST->isNonTemporal(), Alignment); 507bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 508f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 509dc84650679b6330e0fcdd4cf8bc2a351387db7caDuncan Sands Alignment = MinAlign(Alignment, IncrementSize); 510bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr, 511da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo().getWithOffset(IncrementSize), 5121e559443a17d1b335f697551c6263ba60d5dd827David Greene NewStoredVT, ST->isVolatile(), ST->isNonTemporal(), 5131e559443a17d1b335f697551c6263ba60d5dd827David Greene Alignment); 514f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 515825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2); 516f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio} 517f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 518f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio/// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads. 519f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venanciostatic 520475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, 521e9530ecae4897fe8157bd4d7616043bd8c0484e2Dan Gohman const TargetLowering &TLI) { 522475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = LD->getChain(); 523475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ptr = LD->getBasePtr(); 524e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = LD->getValueType(0); 525e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT LoadedVT = LD->getMemoryVT(); 526bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl = LD->getDebugLoc(); 52783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (VT.isFloatingPoint() || VT.isVector()) { 52823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT intVT = EVT::getIntegerVT(*DAG.getContext(), LoadedVT.getSizeInBits()); 52905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (TLI.isTypeLegal(intVT)) { 53005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Expand to a (misaligned) integer load of the same size, 53105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // then bitconvert to floating point or vector. 532ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getPointerInfo(), 533ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->isVolatile(), 5341e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->isNonTemporal(), LD->getAlignment()); 535bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue Result = DAG.getNode(ISD::BITCAST, dl, LoadedVT, newLoad); 53605e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (VT.isFloatingPoint() && LoadedVT != VT) 537bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result); 538907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen 53905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SDValue Ops[] = { Result, Chain }; 540bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getMergeValues(Ops, 2, dl); 541ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner } 542bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 543ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Copy the value to a (aligned) stack slot using (unaligned) integer 544ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // loads and stores, then do a (aligned) load from the stack slot. 545ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner EVT RegVT = TLI.getRegisterType(*DAG.getContext(), intVT); 546ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner unsigned LoadedBytes = LoadedVT.getSizeInBits() / 8; 547ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner unsigned RegBytes = RegVT.getSizeInBits() / 8; 548ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner unsigned NumRegs = (LoadedBytes + RegBytes - 1) / RegBytes; 549ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 550ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Make sure the stack slot is also aligned for the register type. 551ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue StackBase = DAG.CreateStackTemporary(LoadedVT, RegVT); 552ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 553ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); 554ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SmallVector<SDValue, 8> Stores; 555ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue StackPtr = StackBase; 556ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner unsigned Offset = 0; 557ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 558ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Do all but one copies using the full register width. 559ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner for (unsigned i = 1; i < NumRegs; i++) { 560ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Load one integer register's worth from the original location. 561ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, 562ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(Offset), 563ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->isVolatile(), LD->isNonTemporal(), 564ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MinAlign(LD->getAlignment(), Offset)); 56505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Follow the load with a store to the stack slot. Remember the store. 566ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr, 5676229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(), false, false, 0)); 568ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Increment the pointers. 569ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Offset += RegBytes; 570ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); 571ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 572ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Increment); 57305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } 574ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 575ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // The last copy may be partial. Do an extending load. 576ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), 577ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 8 * (LoadedBytes - Offset)); 578a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr, 579ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(Offset), 580ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MemVT, LD->isVolatile(), 581ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->isNonTemporal(), 582ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MinAlign(LD->getAlignment(), Offset)); 583ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Follow the load with a store to the stack slot. Remember the store. 584ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // On big-endian machines this requires a truncating store to ensure 585ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // that the bits end up in the right place. 586ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr, 587ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(), MemVT, 588ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, 0)); 589ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 590ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // The order of the stores doesn't matter - say it with a TokenFactor. 591ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], 592ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Stores.size()); 593ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 594ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Finally, perform the original load only redirected to the stack slot. 595a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase, 596ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(), LoadedVT, false, false, 0); 597ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner 598ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner // Callers expect a MERGE_VALUES node. 599ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue Ops[] = { Load, TF }; 600ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner return DAG.getMergeValues(Ops, 2, dl); 601907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen } 60283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(LoadedVT.isInteger() && !LoadedVT.isVector() && 603e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner "Unaligned load of unsupported type."); 604e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner 6058155d64c2ffab8b17e0fd8e3b7a66fcef6a8ec9dDale Johannesen // Compute the new VT that is half the size of the old one. This is an 6068155d64c2ffab8b17e0fd8e3b7a66fcef6a8ec9dDale Johannesen // integer MVT. 60783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned NumBits = LoadedVT.getSizeInBits(); 608e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NewLoadedVT; 60923b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson NewLoadedVT = EVT::getIntegerVT(*DAG.getContext(), NumBits/2); 610e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner NumBits >>= 1; 611fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 612e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner unsigned Alignment = LD->getAlignment(); 613e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner unsigned IncrementSize = NumBits / 8; 614f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio ISD::LoadExtType HiExtType = LD->getExtensionType(); 615f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 616f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD. 617f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (HiExtType == ISD::NON_EXTLOAD) 618f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio HiExtType = ISD::ZEXTLOAD; 619f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 620f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Load the value in two parts 621475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 622f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (TLI.isLittleEndian()) { 623a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getPointerInfo(), 624ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner NewLoadedVT, LD->isVolatile(), 6251e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->isNonTemporal(), Alignment); 626bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 627f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 628a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, 629ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 630ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner NewLoadedVT, LD->isVolatile(), 6316e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach LD->isNonTemporal(), MinAlign(Alignment,IncrementSize)); 632f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } else { 633a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getPointerInfo(), 634ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner NewLoadedVT, LD->isVolatile(), 6351e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->isNonTemporal(), Alignment); 636bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 637f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 638a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, 639ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 640ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner NewLoadedVT, LD->isVolatile(), 6416e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach LD->isNonTemporal(), MinAlign(Alignment,IncrementSize)); 642f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 643f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 644f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // aggregate the two parts 64595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson SDValue ShiftAmount = DAG.getConstant(NumBits, 64695771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Hi.getValueType())); 647bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Result = DAG.getNode(ISD::SHL, dl, VT, Hi, ShiftAmount); 648bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Result = DAG.getNode(ISD::OR, dl, VT, Result, Lo); 649f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 650825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 651f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio Hi.getValue(1)); 652f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 653475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[] = { Result, TF }; 654bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getMergeValues(Ops, 2, dl); 655f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio} 656912095becac923ff614d7b07728eb345ada67765Evan Cheng 6576867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// PerformInsertVectorEltInMemory - Some target cannot handle a variable 6586867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it 6596867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// is necessary to spill the vector being inserted into to memory, perform 6606867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// the insert there, and then read the result back. 661475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize:: 662bb5da918545efb54857a09c983a5a7f22a7e04d4Dale JohannesenPerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx, 663bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl) { 664475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1 = Vec; 665475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp2 = Val; 666475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp3 = Idx; 667fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 6686867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // If the target doesn't support this, we have to spill the input vector 6696867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // to a temporary stack slot, update the element, then reload it. This is 6706867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // badness. We could also load the value into a vector register (either 6716867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // with a "move to register" or "extload into register" instruction, then 6726867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // permute it into place, if the idx is a constant and if the idx is 6736867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // supported by the target. 674e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Tmp1.getValueType(); 675e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT EltVT = VT.getVectorElementType(); 676e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT IdxVT = Tmp3.getValueType(); 677e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PtrVT = TLI.getPointerTy(); 678475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue StackPtr = DAG.CreateStackTemporary(VT); 6796867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 680ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); 681ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng 6826867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Store the vector. 683bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr, 68485ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getFixedStack(SPFI), 6851e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 6866867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 6876867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Truncate or zero extend offset to target pointer type. 6888e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; 689bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Tmp3 = DAG.getNode(CastOpc, dl, PtrVT, Tmp3); 6906867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Add the offset to the index. 691aa9d854b334cab2f29ca6d95413a0946b8a38429Dan Gohman unsigned EltSize = EltVT.getSizeInBits()/8; 692bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Tmp3 = DAG.getNode(ISD::MUL, dl, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT)); 693bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr); 6946867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Store the scalar value. 69585ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2, MachinePointerInfo(), EltVT, 6961e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 6976867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Load the updated vector. 698bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getLoad(VT, dl, Ch, StackPtr, 69985ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getFixedStack(SPFI), false, false, 0); 7006867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman} 7016867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 702e9f1015d1f184a51aaadfd03be0846bd5e7d08a2Mon P Wang 7033f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli FriedmanSDValue SelectionDAGLegalize:: 7043f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli FriedmanExpandINSERT_VECTOR_ELT(SDValue Vec, SDValue Val, SDValue Idx, DebugLoc dl) { 7053f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman if (ConstantSDNode *InsertPos = dyn_cast<ConstantSDNode>(Idx)) { 7063f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // SCALAR_TO_VECTOR requires that the type of the value being inserted 7073f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // match the element type of the vector being created, except for 7083f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // integers in which case the inserted value can be over width. 709e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT EltVT = Vec.getValueType().getVectorElementType(); 7103f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman if (Val.getValueType() == EltVT || 7113f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman (EltVT.isInteger() && Val.getValueType().bitsGE(EltVT))) { 7123f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SDValue ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, 7133f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman Vec.getValueType(), Val); 7143f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman 7153f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman unsigned NumElts = Vec.getValueType().getVectorNumElements(); 7163f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // We generate a shuffle of InVec and ScVec, so the shuffle mask 7173f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // should be 0,1,2,3,4,5... with the appropriate element replaced with 7183f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // elt 0 of the RHS. 7193f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman SmallVector<int, 8> ShufOps; 7203f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman for (unsigned i = 0; i != NumElts; ++i) 7213f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman ShufOps.push_back(i != InsertPos->getZExtValue() ? i : NumElts); 7223f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman 7233f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman return DAG.getVectorShuffle(Vec.getValueType(), dl, Vec, ScVec, 7243f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman &ShufOps[0]); 7253f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman } 7263f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman } 7273f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman return PerformInsertVectorEltInMemory(Vec, Val, Idx, dl); 7283f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman} 7293f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman 7307ef3d178660b82d1571757e49f44b004d772a116Eli FriedmanSDValue SelectionDAGLegalize::OptimizeFloatStore(StoreSDNode* ST) { 7317ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr' 7327ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // FIXME: We shouldn't do this for TargetConstantFP's. 7337ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // FIXME: move this to the DAG Combiner! Note that we can't regress due 7347ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // to phase ordering between legalized code and the dag combiner. This 7357ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // probably means that we need to integrate dag combiner and legalizer 7367ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // together. 7377ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // We generally can't do this one for long doubles. 7387ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue Tmp1 = ST->getChain(); 7397ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue Tmp2 = ST->getBasePtr(); 7407ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue Tmp3; 7417ef3d178660b82d1571757e49f44b004d772a116Eli Friedman unsigned Alignment = ST->getAlignment(); 7427ef3d178660b82d1571757e49f44b004d772a116Eli Friedman bool isVolatile = ST->isVolatile(); 7431e559443a17d1b335f697551c6263ba60d5dd827David Greene bool isNonTemporal = ST->isNonTemporal(); 7447ef3d178660b82d1571757e49f44b004d772a116Eli Friedman DebugLoc dl = ST->getDebugLoc(); 7457ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) { 746825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (CFP->getValueType(0) == MVT::f32 && 747825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson getTypeAction(MVT::i32) == Legal) { 7487ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Tmp3 = DAG.getConstant(CFP->getValueAPF(). 7497ef3d178660b82d1571757e49f44b004d772a116Eli Friedman bitcastToAPInt().zextOrTrunc(32), 750825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::i32); 751da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 752da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner isVolatile, isNonTemporal, Alignment); 753da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner } 754bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 755da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner if (CFP->getValueType(0) == MVT::f64) { 7567ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // If this target supports 64-bit registers, do a single 64-bit store. 757825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (getTypeAction(MVT::i64) == Legal) { 7587ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). 759825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson zextOrTrunc(64), MVT::i64); 760da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner return DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 761da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner isVolatile, isNonTemporal, Alignment); 762da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner } 763bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 764da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner if (getTypeAction(MVT::i32) == Legal && !ST->isVolatile()) { 7657ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Otherwise, if the target supports 32-bit registers, use 2 32-bit 7667ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // stores. If the target supports neither 32- nor 64-bits, this 7677ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // xform is certainly not worth it. 7687ef3d178660b82d1571757e49f44b004d772a116Eli Friedman const APInt &IntVal =CFP->getValueAPF().bitcastToAPInt(); 76940f8f6264d5af2c38e797e0dc59827cd231e8ff7Jay Foad SDValue Lo = DAG.getConstant(IntVal.trunc(32), MVT::i32); 770825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue Hi = DAG.getConstant(IntVal.lshr(32).trunc(32), MVT::i32); 7717ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (TLI.isBigEndian()) std::swap(Lo, Hi); 7727ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 773da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getPointerInfo(), isVolatile, 774da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner isNonTemporal, Alignment); 7757ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 7767ef3d178660b82d1571757e49f44b004d772a116Eli Friedman DAG.getIntPtrConstant(4)); 777da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, 778da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo().getWithOffset(4), 7791e559443a17d1b335f697551c6263ba60d5dd827David Greene isVolatile, isNonTemporal, MinAlign(Alignment, 4U)); 7807ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 781825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 7827ef3d178660b82d1571757e49f44b004d772a116Eli Friedman } 7837ef3d178660b82d1571757e49f44b004d772a116Eli Friedman } 7847ef3d178660b82d1571757e49f44b004d772a116Eli Friedman } 7858e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng return SDValue(0, 0); 7867ef3d178660b82d1571757e49f44b004d772a116Eli Friedman} 7877ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 7886a109f9d70bf7f75541400145a7a89880cc48166Dan Gohman/// LegalizeOp - Return a legal replacement for the given operation, with 7896a109f9d70bf7f75541400145a7a89880cc48166Dan Gohman/// all legal operands. 790475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { 79109ec1b058331aadb29a348091611d23892b5c492Chris Lattner if (Op.getOpcode() == ISD::TargetConstant) // Allow illegal target nodes. 79209ec1b058331aadb29a348091611d23892b5c492Chris Lattner return Op; 793fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 794ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *Node = Op.getNode(); 7957d2ad624fa749a6d3edac0d94e9c107989c16304Dale Johannesen DebugLoc dl = Node->getDebugLoc(); 796e3304a3d24afc952d3cb415d1b504d973573c5c5Chris Lattner 7971fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 7981fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman assert(getTypeAction(Node->getValueType(i)) == Legal && 7991fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman "Unexpected illegal type!"); 8001fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman 8011fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 8026e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach assert((isTypeLegal(Node->getOperand(i).getValueType()) || 8031fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman Node->getOperand(i).getOpcode() == ISD::TargetConstant) && 8041fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman "Unexpected illegal type!"); 8053e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 80645982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner // Note that LegalizeOp may be reentered even from single-use nodes, which 80745982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner // means that we always must cache transformed nodes. 808475871a144eb604ddaf37503397ba0941442e5fbDan Gohman DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op); 809e1bd822ddb0099406d9f280535461033dfeeb190Chris Lattner if (I != LegalizedNodes.end()) return I->second; 8103e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 811475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1, Tmp2, Tmp3, Tmp4; 812475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Result = Op; 813456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner bool isCustom = false; 814fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 8158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Figure out the correct action; the way to query this varies by opcode 8166b9a293a0c7d86c07d704da5facb34cc03ce1d02Bill Wendling TargetLowering::LegalizeAction Action = TargetLowering::Legal; 8178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman bool SimpleFinishLegalizing = true; 8183e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner switch (Node->getOpcode()) { 8198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_W_CHAIN: 8208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_WO_CHAIN: 8218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_VOID: 8228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VAARG: 8238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::STACKSAVE: 824825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Action = TLI.getOperationAction(Node->getOpcode(), MVT::Other); 8258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 8278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 8288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_VECTOR_ELT: 8298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), 8308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0).getValueType()); 8318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8328c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND_INREG: 8338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SIGN_EXTEND_INREG: { 834e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT InnerType = cast<VTSDNode>(Node->getOperand(1))->getVT(); 8358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), InnerType); 8368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8383be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman case ISD::SELECT_CC: 8393be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman case ISD::SETCC: 8403be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman case ISD::BR_CC: { 8413be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman unsigned CCOperand = Node->getOpcode() == ISD::SELECT_CC ? 4 : 8423be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Node->getOpcode() == ISD::SETCC ? 2 : 1; 8433be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman unsigned CompareOperand = Node->getOpcode() == ISD::BR_CC ? 2 : 0; 844e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpVT = Node->getOperand(CompareOperand).getValueType(); 8453be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman ISD::CondCode CCCode = 8463be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman cast<CondCodeSDNode>(Node->getOperand(CCOperand))->get(); 8473be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Action = TLI.getCondCodeAction(CCCode, OpVT); 8483be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (Action == TargetLowering::Legal) { 8493be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (Node->getOpcode() == ISD::SELECT_CC) 8503be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Action = TLI.getOperationAction(Node->getOpcode(), 8513be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Node->getValueType(0)); 8523be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman else 8533be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Action = TLI.getOperationAction(Node->getOpcode(), OpVT); 8543be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman } 8553be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman break; 8563be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman } 8578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::LOAD: 8588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::STORE: 859ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // FIXME: Model these properly. LOAD and STORE are complicated, and 860ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // STORE expects the unlegalized operand in some cases. 861ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman SimpleFinishLegalizing = false; 862ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 8638c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CALLSEQ_START: 8648c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CALLSEQ_END: 865ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // FIXME: This shouldn't be necessary. These nodes have special properties 866ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // dealing with the recursive nature of legalization. Removing this 867ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // special case should be done as part of making LegalizeDAG non-recursive. 868ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman SimpleFinishLegalizing = false; 869ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 8708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_ELEMENT: 8718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLT_ROUNDS_: 8728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SADDO: 8738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SSUBO: 8748c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UADDO: 8758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::USUBO: 8768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SMULO: 8778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UMULO: 8788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FPOWI: 8798c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::MERGE_VALUES: 8808c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_RETURN: 8818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAME_TO_ARGS_OFFSET: 882c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach case ISD::EH_SJLJ_SETJMP: 883c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach case ISD::EH_SJLJ_LONGJMP: 884e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach case ISD::EH_SJLJ_DISPATCHSETUP: 885f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman // These operations lie about being legal: when they claim to be legal, 886f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman // they should actually be expanded. 8878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 8888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Action == TargetLowering::Legal) 8898c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TargetLowering::Expand; 8908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::TRAMPOLINE: 8928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAMEADDR: 8938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::RETURNADDR: 8944bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // These operations lie about being legal: when they claim to be legal, 8954bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // they should actually be custom-lowered. 8964bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 8974bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman if (Action == TargetLowering::Legal) 8984bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Action = TargetLowering::Custom; 8998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 9008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BUILD_VECTOR: 901b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman // A weird case: legalization for BUILD_VECTOR never legalizes the 902b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman // operands! 903b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman // FIXME: This really sucks... changing it isn't semantically incorrect, 904b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman // but it massively pessimizes the code for floating-point BUILD_VECTORs 905b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman // because ConstantFP operands get legalized into constant pool loads 906b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman // before the BUILD_VECTOR code can see them. It doesn't usually bite, 907b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman // though, because BUILD_VECTORS usually get lowered into other nodes 908b5da3f6f98b28afc0c62572c164ffccb4004827fEli Friedman // which get legalized properly. 9098c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SimpleFinishLegalizing = false; 910948c1b1cda280c6428dbeaa03a6c2c559dbb93f4Chris Lattner break; 9113e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner default: 912d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner if (Node->getOpcode() >= ISD::BUILTIN_OP_END) { 9138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TargetLowering::Legal; 9148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else { 9158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 9168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 9178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 9188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 919d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner 9208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (SimpleFinishLegalizing) { 9218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SmallVector<SDValue, 8> Ops, ResultVals; 9228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 9238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Ops.push_back(LegalizeOp(Node->getOperand(i))); 9248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 9258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman default: break; 9268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BR: 9278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BRIND: 9288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BR_JT: 9298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BR_CC: 9308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BRCOND: 931567cac0c511c2361ddb76eb4b8d49d306107a921Stuart Hastings assert(LastCALLSEQ.size() == 1 && "branch inside CALLSEQ_BEGIN/END?"); 932fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings // Branches tweak the chain to include LastCALLSEQ 933825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Ops[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ops[0], 934fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings getLastCALLSEQ()); 9358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Ops[0] = LegalizeOp(Ops[0]); 936fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings setLastCALLSEQ(DAG.getEntryNode()); 9378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 9388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SHL: 9398c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SRL: 9408c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SRA: 9418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::ROTL: 9428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::ROTR: 9438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Legalizing shifts/rotates requires adjusting the shift amount 9448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // to the appropriate width. 9458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (!Ops[1].getValueType().isVector()) 9466154f6c9292179fab6346ae8336f2ad790b52028Owen Anderson Ops[1] = LegalizeOp(DAG.getShiftAmountOperand(Ops[0].getValueType(), 9476154f6c9292179fab6346ae8336f2ad790b52028Owen Anderson Ops[1])); 9488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 949db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman case ISD::SRL_PARTS: 950db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman case ISD::SRA_PARTS: 951db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman case ISD::SHL_PARTS: 952db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman // Legalizing shifts/rotates requires adjusting the shift amount 953db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman // to the appropriate width. 954db8dc2b9faf346fbfa04c07f501981250948f5e2Dan Gohman if (!Ops[2].getValueType().isVector()) 9556154f6c9292179fab6346ae8336f2ad790b52028Owen Anderson Ops[2] = LegalizeOp(DAG.getShiftAmountOperand(Ops[0].getValueType(), 9566154f6c9292179fab6346ae8336f2ad790b52028Owen Anderson Ops[2])); 9572c9489d6e96d99f77b6c31919805b5e61954deb2Dan Gohman break; 9588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 9598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 960027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), Ops.data(), 961027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Ops.size()), 0); 9628c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Action) { 9638c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Legal: 964d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 9658c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals.push_back(Result.getValue(i)); 9668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 9678c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Custom: 9688c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // FIXME: The handling for custom lowering with multiple results is 9698c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // a complete mess. 9708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = TLI.LowerOperation(Result, DAG); 9718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Tmp1.getNode()) { 9728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) { 9738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (e == 1) 9748c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals.push_back(Tmp1); 9758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman else 9768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals.push_back(Tmp1.getValue(i)); 9778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 9788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 9798c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 9808c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 9818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // FALL THROUGH 9828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Expand: 9838c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ExpandNode(Result.getNode(), ResultVals); 9848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 9858c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Promote: 9868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman PromoteNode(Result.getNode(), ResultVals); 9878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 9888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 9898c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (!ResultVals.empty()) { 9908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0, e = ResultVals.size(); i != e; ++i) { 9918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (ResultVals[i] != SDValue(Node, i)) 9928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals[i] = LegalizeOp(ResultVals[i]); 9938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman AddLegalizedOperand(SDValue(Node, i), ResultVals[i]); 9948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 9958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman return ResultVals[Op.getResNo()]; 996d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner } 9978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 9988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 9998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 10008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman default: 1001e37fe9b3a1cadceb42ac27fa0718f5a10ea2f0e6Jim Laskey#ifndef NDEBUG 1002993aacedfdc3f156f667b4efa280ee79eab3b898David Greene dbgs() << "NODE: "; 1003993aacedfdc3f156f667b4efa280ee79eab3b898David Greene Node->dump( &DAG); 1004993aacedfdc3f156f667b4efa280ee79eab3b898David Greene dbgs() << "\n"; 1005e37fe9b3a1cadceb42ac27fa0718f5a10ea2f0e6Jim Laskey#endif 100635a389344d21178ee280c2410401b2060b5b879cChris Lattner assert(0 && "Do not know how to legalize this operator!"); 100798ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman 1008b2827b0901162169bb2692b77a839c9767849134Chris Lattner case ISD::BUILD_VECTOR: 1009b2827b0901162169bb2692b77a839c9767849134Chris Lattner switch (TLI.getOperationAction(ISD::BUILD_VECTOR, Node->getValueType(0))) { 101035a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "This action is not supported yet!"); 10112332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner case TargetLowering::Custom: 10122332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner Tmp3 = TLI.LowerOperation(Result, DAG); 1013ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()) { 10142332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner Result = Tmp3; 10152332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner break; 10162332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner } 10172332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner // FALLTHROUGH 1018ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner case TargetLowering::Expand: 1019ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif Result = ExpandBUILD_VECTOR(Result.getNode()); 1020b2827b0901162169bb2692b77a839c9767849134Chris Lattner break; 10212332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner } 10222332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner break; 10236831a815999dde4cf801e2076e66b4943964daf2Chris Lattner case ISD::CALLSEQ_START: { 10246831a815999dde4cf801e2076e66b4943964daf2Chris Lattner SDNode *CallEnd = FindCallEndFromCallStart(Node); 1025fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings assert(CallEnd && "didn't find CALLSEQ_END!"); 1026fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 10276831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Recursively Legalize all of the inputs of the call end that do not lead 10286831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // to this call start. This ensures that any libcalls that need be inserted 10296831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // are inserted *before* the CALLSEQ_START. 103000755df36c1448ac4728a74d907aa09e3d8b2d49Chris Lattner {SmallPtrSet<SDNode*, 32> NodesLeadingTo; 10316831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (unsigned i = 0, e = CallEnd->getNumOperands(); i != e; ++i) 1032ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif LegalizeAllNodesNotLeadingTo(CallEnd->getOperand(i).getNode(), Node, 1033c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner NodesLeadingTo); 1034c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner } 10356831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 1036ee7f8b5f058174a55372159bc23088198e5f5991Jim Grosbach // Now that we have legalized all of the inputs (which may have inserted 1037ee7f8b5f058174a55372159bc23088198e5f5991Jim Grosbach // libcalls), create the new CALLSEQ_START node. 10386831a815999dde4cf801e2076e66b4943964daf2Chris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 10396831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 1040ee7f8b5f058174a55372159bc23088198e5f5991Jim Grosbach // Merge in the last call to ensure that this call starts after the last 10416831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // call ended. 1042fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings if (getLastCALLSEQ().getOpcode() != ISD::EntryToken) { 1043825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1044fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings Tmp1, getLastCALLSEQ()); 1045b248e16afd105fd8c01e08d8bf997b08ff08d127Chris Lattner Tmp1 = LegalizeOp(Tmp1); 1046b248e16afd105fd8c01e08d8bf997b08ff08d127Chris Lattner } 1047fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 10486831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Do not try to legalize the target-specific arguments (#1+). 10496831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (Tmp1 != Node->getOperand(0)) { 1050475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 10516831a815999dde4cf801e2076e66b4943964daf2Chris Lattner Ops[0] = Tmp1; 10526e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), &Ops[0], 10536e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach Ops.size()), Result.getResNo()); 10546831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 1055fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 10566831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Remember that the CALLSEQ_START is legalized. 10574b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner AddLegalizedOperand(Op.getValue(0), Result); 10584b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner if (Node->getNumValues() == 2) // If this has a flag result, remember it. 10594b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); 1060fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 10616831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Now that the callseq_start and all of the non-call nodes above this call 1062fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // sequence have been legalized, legalize the call itself. During this 10636831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // process, no libcalls can/will be inserted, guaranteeing that no calls 10646831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // can overlap. 10656831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Note that we are selecting this call! 1066fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings setLastCALLSEQ(SDValue(CallEnd, 0)); 1067fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 10686831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Legalize the call, starting from the CALLSEQ_END. 1069fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings LegalizeOp(getLastCALLSEQ()); 10706831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return Result; 10716831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 107216cd04d26c53c6f81313cafb85f6c0e7a07cdff6Chris Lattner case ISD::CALLSEQ_END: 1073fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings { 1074fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings SDNode *myCALLSEQ_BEGIN = FindCallStartFromCallEnd(Node); 1075fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings 1076f316eb70743e88227b8919370fe38587ffe93512Dan Gohman // If the CALLSEQ_START node hasn't been legalized first, legalize it. 1077f316eb70743e88227b8919370fe38587ffe93512Dan Gohman // This will cause this node to be legalized as well as handling libcalls 1078f316eb70743e88227b8919370fe38587ffe93512Dan Gohman // right. 1079fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings if (getLastCALLSEQ().getNode() != Node) { 1080fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings LegalizeOp(SDValue(myCALLSEQ_BEGIN, 0)); 1081fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op); 1082fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings assert(I != LegalizedNodes.end() && 1083fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings "Legalizing the call start should have legalized this node!"); 1084fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings return I->second; 1085fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings } 1086fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings 1087fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings pushLastCALLSEQ(SDValue(myCALLSEQ_BEGIN, 0)); 10886831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 1089fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1090fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Otherwise, the call start has been legalized and everything is going 10916831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // according to plan. Just legalize ourselves normally here. 10923e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 109370814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner // Do not try to legalize the target-specific arguments (#1+), except for 109470814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner // an optional flag input. 1095f1b4eafbfec976f939ec0ea3e8acf91cef5363e3Chris Lattner if (Node->getOperand(Node->getNumOperands()-1).getValueType() != MVT::Glue){ 109670814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner if (Tmp1 != Node->getOperand(0)) { 1097475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 109870814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Ops[0] = Tmp1; 1099027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1100027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman &Ops[0], Ops.size()), 1101027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result.getResNo()); 110270814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner } 110370814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner } else { 110470814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Tmp2 = LegalizeOp(Node->getOperand(Node->getNumOperands()-1)); 110570814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner if (Tmp1 != Node->getOperand(0) || 110670814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Tmp2 != Node->getOperand(Node->getNumOperands()-1)) { 1107475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 110870814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Ops[0] = Tmp1; 110970814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Ops.back() = Tmp2; 1110027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1111027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman &Ops[0], Ops.size()), 1112027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result.getResNo()); 111370814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner } 11146a5428934ba6159c1acc541944332e51a6cfa59aChris Lattner } 11156831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // This finishes up call legalization. 1116fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings popLastCALLSEQ(); 11171809d5fa216bbdc505502468b7bd85629e1e44bcStuart Hastings 11184b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner // If the CALLSEQ_END node has a flag, remember that we legalized it. 1119475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0)); 11204b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner if (Node->getNumValues() == 2) 1121475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1)); 112299a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Result.getValue(Op.getResNo()); 1123f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng case ISD::LOAD: { 1124466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng LoadSDNode *LD = cast<LoadSDNode>(Node); 1125466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp1 = LegalizeOp(LD->getChain()); // Legalize the chain. 1126466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp2 = LegalizeOp(LD->getBasePtr()); // Legalize the base pointer. 11272d86ea21dd76647cb054fd5d27df9e49efc672b6Andrew Lenharth 1128466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng ISD::LoadExtType ExtType = LD->getExtensionType(); 1129466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng if (ExtType == ISD::NON_EXTLOAD) { 1130e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 1131027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1132027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Tmp1, Tmp2, LD->getOffset()), 1133027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result.getResNo()); 1134466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp3 = Result.getValue(0); 1135466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp4 = Result.getValue(1); 1136fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1137466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 113835a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "This action is not supported yet!"); 1139f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio case TargetLowering::Legal: 1140f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If this is an unaligned load and the target doesn't support it, 1141f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // expand it. 1142bc037cfcdef8e88274d7dd167fb9d8ba545f2229Benjamin Kramer if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { 1143e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng const Type *Ty = LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); 1144e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng unsigned ABIAlignment = TLI.getTargetData()->getABITypeAlignment(Ty); 1145f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (LD->getAlignment() < ABIAlignment){ 11466e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach Result = ExpandUnalignedLoad(cast<LoadSDNode>(Result.getNode()), 1147debcb01b0f0a15f568ca69e8f288fade4bfc7297Owen Anderson DAG, TLI); 1148f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio Tmp3 = Result.getOperand(0); 1149f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio Tmp4 = Result.getOperand(1); 1150907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen Tmp3 = LegalizeOp(Tmp3); 1151907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen Tmp4 = LegalizeOp(Tmp4); 1152f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1153f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1154f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio break; 1155466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng case TargetLowering::Custom: 1156466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp1 = TLI.LowerOperation(Tmp3, DAG); 1157ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) { 1158466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp3 = LegalizeOp(Tmp1); 1159466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp4 = LegalizeOp(Tmp1.getValue(1)); 1160466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 1161466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 1162466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng case TargetLowering::Promote: { 1163466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // Only promote a load of vector type to another. 116483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(VT.isVector() && "Cannot promote this load!"); 1165466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // Change base type to a different vector type. 1166e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT); 1167466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng 1168ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getPointerInfo(), 11691e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->isVolatile(), LD->isNonTemporal(), 11701e559443a17d1b335f697551c6263ba60d5dd827David Greene LD->getAlignment()); 1171bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp3 = LegalizeOp(DAG.getNode(ISD::BITCAST, dl, VT, Tmp1)); 117241f6cbbeb21d7d4376b8c0302b9766c3e43be5f2Evan Cheng Tmp4 = LegalizeOp(Tmp1.getValue(1)); 1173466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 1174f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 1175466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 1176fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Since loads produce two values, make sure to remember that we 1177466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // legalized both of them. 1178475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Tmp3); 1179475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Tmp4); 118099a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Op.getResNo() ? Tmp4 : Tmp3; 11813d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } 1182bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 11833d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner EVT SrcVT = LD->getMemoryVT(); 11843d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned SrcWidth = SrcVT.getSizeInBits(); 11853d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned Alignment = LD->getAlignment(); 11863d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner bool isVolatile = LD->isVolatile(); 11873d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner bool isNonTemporal = LD->isNonTemporal(); 11883d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 11893d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (SrcWidth != SrcVT.getStoreSizeInBits() && 11903d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Some targets pretend to have an i1 loading operation, and actually 11913d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // load an i8. This trick is correct for ZEXTLOAD because the top 7 11923d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // bits are guaranteed to be zero; it helps the optimizers understand 11933d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // that these bits are zero. It is also useful for EXTLOAD, since it 11943d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // tells the optimizers that those bits are undefined. It would be 11953d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // nice to have an effective generic way of getting these benefits... 11963d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Until such a way is found, don't insist on promoting i1 here. 11973d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner (SrcVT != MVT::i1 || 11983d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner TLI.getLoadExtAction(ExtType, MVT::i1) == TargetLowering::Promote)) { 11993d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Promote to a byte-sized load if not loading an integral number of 12003d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // bytes. For example, promote EXTLOAD:i20 -> EXTLOAD:i24. 12013d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned NewWidth = SrcVT.getStoreSizeInBits(); 12023d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner EVT NVT = EVT::getIntegerVT(*DAG.getContext(), NewWidth); 12033d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner SDValue Ch; 12043d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12053d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // The extra bits are guaranteed to be zero, since we stored them that 12063d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // way. A zext load from NVT thus automatically gives zext from SrcVT. 12073d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12083d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ISD::LoadExtType NewExtType = 12093d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ExtType == ISD::ZEXTLOAD ? ISD::ZEXTLOAD : ISD::EXTLOAD; 12103d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 1211a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Result = DAG.getExtLoad(NewExtType, dl, Node->getValueType(0), 12123d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1, Tmp2, LD->getPointerInfo(), 12133d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner NVT, isVolatile, isNonTemporal, Alignment); 12143d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12153d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Ch = Result.getValue(1); // The chain. 12163d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12173d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (ExtType == ISD::SEXTLOAD) 12183d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Having the top bits zero doesn't help when sign extending. 12193d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, 12203d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result.getValueType(), 12213d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result, DAG.getValueType(SrcVT)); 12223d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner else if (ExtType == ISD::ZEXTLOAD || NVT == Result.getValueType()) 12233d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // All the top bits are guaranteed to be zero - inform the optimizers. 12243d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = DAG.getNode(ISD::AssertZext, dl, 12253d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result.getValueType(), Result, 12263d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner DAG.getValueType(SrcVT)); 12273d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12283d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1 = LegalizeOp(Result); 12293d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = LegalizeOp(Ch); 12303d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } else if (SrcWidth & (SrcWidth - 1)) { 12313d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // If not loading a power-of-2 number of bits, expand as two loads. 12323d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(!SrcVT.isVector() && "Unsupported extload!"); 12333d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned RoundWidth = 1 << Log2_32(SrcWidth); 12343d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(RoundWidth < SrcWidth); 12353d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned ExtraWidth = SrcWidth - RoundWidth; 12363d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(ExtraWidth < RoundWidth); 12373d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(!(RoundWidth % 8) && !(ExtraWidth % 8) && 12383d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner "Load size not an integral number of bytes!"); 12393d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner EVT RoundVT = EVT::getIntegerVT(*DAG.getContext(), RoundWidth); 12403d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner EVT ExtraVT = EVT::getIntegerVT(*DAG.getContext(), ExtraWidth); 12413d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner SDValue Lo, Hi, Ch; 12423d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned IncrementSize; 12433d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12443d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (TLI.isLittleEndian()) { 12453d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // EXTLOAD:i24 -> ZEXTLOAD:i16 | (shl EXTLOAD@+2:i8, 16) 12463d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Load the bottom RoundWidth bits. 1247a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, Node->getValueType(0), 12483d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1, Tmp2, 12493d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo(), RoundVT, isVolatile, 12503d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner isNonTemporal, Alignment); 12513d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12523d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Load the remaining ExtraWidth bits. 12533d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner IncrementSize = RoundWidth / 8; 12543d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 12553d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner DAG.getIntPtrConstant(IncrementSize)); 1256a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, 12573d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 12583d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ExtraVT, isVolatile, isNonTemporal, 12593d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner MinAlign(Alignment, IncrementSize)); 12603d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12613d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Build a factor node to remember that this load is independent of 12623d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // the other one. 12633d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 12643d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Hi.getValue(1)); 12653d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12663d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Move the top bits to the right place. 12673d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, 126895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(RoundWidth, 126995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Hi.getValueType()))); 12703d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12713d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Join the hi and lo parts. 12723d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); 12733d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } else { 12743d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Big endian - avoid unaligned loads. 12753d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // EXTLOAD:i24 -> (shl EXTLOAD:i16, 8) | ZEXTLOAD@+2:i8 12763d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Load the top RoundWidth bits. 1277a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, 12783d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo(), RoundVT, isVolatile, 12793d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner isNonTemporal, Alignment); 12803d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12813d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Load the remaining ExtraWidth bits. 12823d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner IncrementSize = RoundWidth / 8; 12833d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 12843d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner DAG.getIntPtrConstant(IncrementSize)); 12853d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Lo = DAG.getExtLoad(ISD::ZEXTLOAD, 1286a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings dl, Node->getValueType(0), Tmp1, Tmp2, 12873d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo().getWithOffset(IncrementSize), 12883d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ExtraVT, isVolatile, isNonTemporal, 12893d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner MinAlign(Alignment, IncrementSize)); 12903d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12913d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Build a factor node to remember that this load is independent of 12923d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // the other one. 12933d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 12943d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Hi.getValue(1)); 12953d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 12963d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Move the top bits to the right place. 12973d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, 129895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(ExtraWidth, 129995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Hi.getValueType()))); 13003d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 13013d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Join the hi and lo parts. 13023d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); 13033d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } 1304f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 13053d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1 = LegalizeOp(Result); 13063d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = LegalizeOp(Ch); 13073d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } else { 13083d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner switch (TLI.getLoadExtAction(ExtType, SrcVT)) { 13093d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner default: assert(0 && "This action is not supported yet!"); 13103d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case TargetLowering::Custom: 13113d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner isCustom = true; 13123d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // FALLTHROUGH 13133d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case TargetLowering::Legal: 13143d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 13153d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1, Tmp2, LD->getOffset()), 13163d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result.getResNo()); 13173d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1 = Result.getValue(0); 13183d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = Result.getValue(1); 13193d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 13203d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (isCustom) { 13213d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp3 = TLI.LowerOperation(Result, DAG); 13223d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (Tmp3.getNode()) { 13233d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1 = LegalizeOp(Tmp3); 13243d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = LegalizeOp(Tmp3.getValue(1)); 13253d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } 1326f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } else { 13273d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // If this is an unaligned load and the target doesn't support it, 13283d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // expand it. 13293d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (!TLI.allowsUnalignedMemoryAccesses(LD->getMemoryVT())) { 13303d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner const Type *Ty = 13313d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getMemoryVT().getTypeForEVT(*DAG.getContext()); 13323d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned ABIAlignment = 13333d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner TLI.getTargetData()->getABITypeAlignment(Ty); 13343d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (LD->getAlignment() < ABIAlignment){ 13353d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = ExpandUnalignedLoad(cast<LoadSDNode>(Result.getNode()), 13363d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner DAG, TLI); 13373d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1 = Result.getOperand(0); 13383d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = Result.getOperand(1); 13393d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1 = LegalizeOp(Tmp1); 13403d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = LegalizeOp(Tmp2); 1341f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1342f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 13433d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner } 13443d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner break; 13453d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case TargetLowering::Expand: 13463d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (!TLI.isLoadExtLegal(ISD::EXTLOAD, SrcVT) && isTypeLegal(SrcVT)) { 13473d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, 13483d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getPointerInfo(), 13493d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->isVolatile(), LD->isNonTemporal(), 13503d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getAlignment()); 13513d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner unsigned ExtendOp; 13523d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner switch (ExtType) { 13533d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case ISD::EXTLOAD: 13543d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ExtendOp = (SrcVT.isFloatingPoint() ? 13553d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ISD::FP_EXTEND : ISD::ANY_EXTEND); 1356f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands break; 13573d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case ISD::SEXTLOAD: ExtendOp = ISD::SIGN_EXTEND; break; 13583d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner case ISD::ZEXTLOAD: ExtendOp = ISD::ZERO_EXTEND; break; 13593d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner default: llvm_unreachable("Unexpected extend load type!"); 1360f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } 13613d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result = DAG.getNode(ExtendOp, dl, Node->getValueType(0), Load); 13623d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1 = LegalizeOp(Result); // Relegalize new nodes. 13633d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = LegalizeOp(Load.getValue(1)); 1364466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 1365466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 1366c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1367c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // If this is a promoted vector load, and the vector element types are 1368c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // legal, then scalarize it. 1369c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem if (ExtType == ISD::EXTLOAD && SrcVT.isVector() && 1370c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem isTypeLegal(Node->getValueType(0).getScalarType())) { 1371c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SmallVector<SDValue, 8> LoadVals; 1372c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SmallVector<SDValue, 8> LoadChains; 1373c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned NumElem = SrcVT.getVectorNumElements(); 1374c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned Stride = SrcVT.getScalarType().getSizeInBits()/8; 1375c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1376c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem for (unsigned Idx=0; Idx<NumElem; Idx++) { 1377c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 1378c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem DAG.getIntPtrConstant(Stride)); 1379c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SDValue ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl, 1380c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Node->getValueType(0).getScalarType(), 1381c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp1, Tmp2, LD->getPointerInfo().getWithOffset(Idx * Stride), 1382c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SrcVT.getScalarType(), 1383c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LD->isVolatile(), LD->isNonTemporal(), 1384c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LD->getAlignment()); 1385c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1386c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LoadVals.push_back(ScalarLoad.getValue(0)); 1387c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LoadChains.push_back(ScalarLoad.getValue(1)); 1388c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1389c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1390c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem &LoadChains[0], LoadChains.size()); 1391c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SDValue ValRes = DAG.getNode(ISD::BUILD_VECTOR, dl, 1392c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Node->getValueType(0), &LoadVals[0], LoadVals.size()); 1393c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1394c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes. 1395c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp2 = LegalizeOp(Result.getValue(0)); // Relegalize new nodes. 1396c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem break; 1397c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1398c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1399c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // If this is a promoted vector load, and the vector element types are 1400c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // illegal, create the promoted vector from bitcasted segments. 1401c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem if (ExtType == ISD::EXTLOAD && SrcVT.isVector()) { 1402c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem EVT MemElemTy = Node->getValueType(0).getScalarType(); 1403c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem EVT SrcSclrTy = SrcVT.getScalarType(); 1404c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned SizeRatio = 1405c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem (MemElemTy.getSizeInBits() / SrcSclrTy.getSizeInBits()); 1406c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1407c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SmallVector<SDValue, 8> LoadVals; 1408c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SmallVector<SDValue, 8> LoadChains; 1409c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned NumElem = SrcVT.getVectorNumElements(); 1410c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned Stride = SrcVT.getScalarType().getSizeInBits()/8; 1411c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1412c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem for (unsigned Idx=0; Idx<NumElem; Idx++) { 1413c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 1414c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem DAG.getIntPtrConstant(Stride)); 1415c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SDValue ScalarLoad = DAG.getExtLoad(ISD::EXTLOAD, dl, 1416c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SrcVT.getScalarType(), 1417c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp1, Tmp2, LD->getPointerInfo().getWithOffset(Idx * Stride), 1418c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SrcVT.getScalarType(), 1419c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LD->isVolatile(), LD->isNonTemporal(), 1420c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LD->getAlignment()); 1421c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem if (TLI.isBigEndian()) { 1422c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // MSB (which is garbage, comes first) 1423c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LoadVals.push_back(ScalarLoad.getValue(0)); 1424c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem for (unsigned i = 0; i<SizeRatio-1; ++i) 1425c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LoadVals.push_back(DAG.getUNDEF(SrcVT.getScalarType())); 1426c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } else { 1427c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // LSB (which is data, comes first) 1428c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem for (unsigned i = 0; i<SizeRatio-1; ++i) 1429c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LoadVals.push_back(DAG.getUNDEF(SrcVT.getScalarType())); 1430c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LoadVals.push_back(ScalarLoad.getValue(0)); 1431c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1432c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem LoadChains.push_back(ScalarLoad.getValue(1)); 1433c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1434c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1435c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1436c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem &LoadChains[0], LoadChains.size()); 1437c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem EVT TempWideVector = EVT::getVectorVT(*DAG.getContext(), 1438c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SrcVT.getScalarType(), NumElem*SizeRatio); 1439c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SDValue ValRes = DAG.getNode(ISD::BUILD_VECTOR, dl, 1440c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem TempWideVector, &LoadVals[0], LoadVals.size()); 1441c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1442c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // Cast to the correct type 1443c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem ValRes = DAG.getNode(ISD::BITCAST, dl, Node->getValueType(0), ValRes); 1444c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1445c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes. 1446c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp2 = LegalizeOp(Result.getValue(0)); // Relegalize new nodes. 1447c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem break; 1448c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1449c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1450c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 14513d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // FIXME: This does not work for vectors on most targets. Sign- and 14523d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // zero-extend operations are currently folded into extending loads, 14533d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // whether they are legal or not, and then we end up here without any 14543d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // support for legalizing them. 14553d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner assert(ExtType != ISD::EXTLOAD && 14563d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner "EXTLOAD should always be supported!"); 14573d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Turn the unsupported load into an EXTLOAD followed by an explicit 14583d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // zero/sign extend inreg. 1459a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0), 14603d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1, Tmp2, LD->getPointerInfo(), SrcVT, 14613d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->isVolatile(), LD->isNonTemporal(), 14623d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner LD->getAlignment()); 14633d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner SDValue ValRes; 14643d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner if (ExtType == ISD::SEXTLOAD) 14653d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, 14663d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result.getValueType(), 14673d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Result, DAG.getValueType(SrcVT)); 14683d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner else 1469dd11ea4a372b992775f67b64fb703edf2de0d27bDan Gohman ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT.getScalarType()); 14703d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes. 14713d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Tmp2 = LegalizeOp(Result.getValue(1)); // Relegalize new nodes. 14723d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner break; 14739d416f713e8b9e4f0c0c2b3f6f57ce2dd8993209Andrew Lenharth } 147401ff7216dd7829d4094754086baf28aa2d7149acChris Lattner } 14753d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner 14763d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // Since loads produce two values, make sure to remember that we legalized 14773d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner // both of them. 14783d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner AddLegalizedOperand(SDValue(Node, 0), Tmp1); 14793d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner AddLegalizedOperand(SDValue(Node, 1), Tmp2); 14803d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner return Op.getResNo() ? Tmp2 : Tmp1; 148101ff7216dd7829d4094754086baf28aa2d7149acChris Lattner } 1482f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng case ISD::STORE: { 14838b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng StoreSDNode *ST = cast<StoreSDNode>(Node); 14848b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng Tmp1 = LegalizeOp(ST->getChain()); // Legalize the chain. 14858b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng Tmp2 = LegalizeOp(ST->getBasePtr()); // Legalize the pointer. 1486d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman unsigned Alignment = ST->getAlignment(); 1487d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman bool isVolatile = ST->isVolatile(); 14881e559443a17d1b335f697551c6263ba60d5dd827David Greene bool isNonTemporal = ST->isNonTemporal(); 14898b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng 14908b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng if (!ST->isTruncatingStore()) { 14917ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (SDNode *OptStore = OptimizeFloatStore(ST).getNode()) { 14927ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Result = SDValue(OptStore, 0); 14937ef3d178660b82d1571757e49f44b004d772a116Eli Friedman break; 1494d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner } 1495fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1496957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman { 14978b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng Tmp3 = LegalizeOp(ST->getValue()); 1498027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1499027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Tmp1, Tmp3, Tmp2, 1500027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman ST->getOffset()), 1501027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result.getResNo()); 15028b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng 1503e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Tmp3.getValueType(); 15048b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng switch (TLI.getOperationAction(ISD::STORE, VT)) { 150535a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "This action is not supported yet!"); 1506f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio case TargetLowering::Legal: 1507f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If this is an unaligned store and the target doesn't support it, 1508f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // expand it. 1509bc037cfcdef8e88274d7dd167fb9d8ba545f2229Benjamin Kramer if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { 1510e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng const Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); 15116e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty); 1512f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (ST->getAlignment() < ABIAlignment) 1513e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.getNode()), 1514e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng DAG, TLI); 1515f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1516f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio break; 15178b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng case TargetLowering::Custom: 15188b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng Tmp1 = TLI.LowerOperation(Result, DAG); 1519ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 15208b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng break; 15218b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng case TargetLowering::Promote: 152283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(VT.isVector() && "Unknown legal promote case!"); 1523bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp3 = DAG.getNode(ISD::BITCAST, dl, 15248b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3); 1525ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, 1526da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo(), isVolatile, 15271e559443a17d1b335f697551c6263ba60d5dd827David Greene isNonTemporal, Alignment); 15288b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng break; 15298b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } 15302efce0a589e2a688a1a06b5dc2ed0db32ae79924Chris Lattner break; 1531f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 15328b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } else { 1533957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman Tmp3 = LegalizeOp(ST->getValue()); 15347e857201f387d004571e6058e2ea709163500f38Duncan Sands 1535e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT StVT = ST->getMemoryVT(); 153683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned StWidth = StVT.getSizeInBits(); 15377e857201f387d004571e6058e2ea709163500f38Duncan Sands 153883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (StWidth != StVT.getStoreSizeInBits()) { 15397e857201f387d004571e6058e2ea709163500f38Duncan Sands // Promote to a byte-sized store with upper bits zero if not 15407e857201f387d004571e6058e2ea709163500f38Duncan Sands // storing an integral number of bytes. For example, promote 15417e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1) 1542adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng EVT NVT = EVT::getIntegerVT(*DAG.getContext(), 1543adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng StVT.getStoreSizeInBits()); 1544ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT); 1545da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 1546da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner NVT, isVolatile, isNonTemporal, Alignment); 15477e857201f387d004571e6058e2ea709163500f38Duncan Sands } else if (StWidth & (StWidth - 1)) { 15487e857201f387d004571e6058e2ea709163500f38Duncan Sands // If not storing a power-of-2 number of bits, expand as two stores. 1549bceddbdc919fc2ca7bc8c3911586ba93367686f0Ken Dyck assert(!StVT.isVector() && "Unsupported truncstore!"); 15507e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned RoundWidth = 1 << Log2_32(StWidth); 15517e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(RoundWidth < StWidth); 15527e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned ExtraWidth = StWidth - RoundWidth; 15537e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(ExtraWidth < RoundWidth); 15547e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(!(RoundWidth % 8) && !(ExtraWidth % 8) && 15557e857201f387d004571e6058e2ea709163500f38Duncan Sands "Store size not an integral number of bytes!"); 155623b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT RoundVT = EVT::getIntegerVT(*DAG.getContext(), RoundWidth); 155723b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT ExtraVT = EVT::getIntegerVT(*DAG.getContext(), ExtraWidth); 1558475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 15597e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned IncrementSize; 15607e857201f387d004571e6058e2ea709163500f38Duncan Sands 15617e857201f387d004571e6058e2ea709163500f38Duncan Sands if (TLI.isLittleEndian()) { 15627e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 X, TRUNCSTORE@+2:i8 (srl X, 16) 15637e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the bottom RoundWidth bits. 1564da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 1565da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner RoundVT, 15661e559443a17d1b335f697551c6263ba60d5dd827David Greene isVolatile, isNonTemporal, Alignment); 15677e857201f387d004571e6058e2ea709163500f38Duncan Sands 15687e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the remaining ExtraWidth bits. 15697e857201f387d004571e6058e2ea709163500f38Duncan Sands IncrementSize = RoundWidth / 8; 1570ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 15717e857201f387d004571e6058e2ea709163500f38Duncan Sands DAG.getIntPtrConstant(IncrementSize)); 1572ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, 157395771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(RoundWidth, 157495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Tmp3.getValueType()))); 1575da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, 1576da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo().getWithOffset(IncrementSize), 1577da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ExtraVT, isVolatile, isNonTemporal, 15787e857201f387d004571e6058e2ea709163500f38Duncan Sands MinAlign(Alignment, IncrementSize)); 15797e857201f387d004571e6058e2ea709163500f38Duncan Sands } else { 15807e857201f387d004571e6058e2ea709163500f38Duncan Sands // Big endian - avoid unaligned stores. 15817e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE@+2:i8 X 15827e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the top RoundWidth bits. 1583ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, 158495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(ExtraWidth, 158595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Tmp3.getValueType()))); 1586da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getPointerInfo(), 1587da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner RoundVT, isVolatile, isNonTemporal, Alignment); 15887e857201f387d004571e6058e2ea709163500f38Duncan Sands 15897e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the remaining ExtraWidth bits. 15907e857201f387d004571e6058e2ea709163500f38Duncan Sands IncrementSize = RoundWidth / 8; 1591ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 15927e857201f387d004571e6058e2ea709163500f38Duncan Sands DAG.getIntPtrConstant(IncrementSize)); 1593da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, 1594da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ST->getPointerInfo().getWithOffset(IncrementSize), 1595da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner ExtraVT, isVolatile, isNonTemporal, 15967e857201f387d004571e6058e2ea709163500f38Duncan Sands MinAlign(Alignment, IncrementSize)); 15977e857201f387d004571e6058e2ea709163500f38Duncan Sands } 1598c7029805ef35ce9805931067b841e6af11db382eChris Lattner 15997e857201f387d004571e6058e2ea709163500f38Duncan Sands // The order of the stores doesn't matter. 1600825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 16017e857201f387d004571e6058e2ea709163500f38Duncan Sands } else { 16027e857201f387d004571e6058e2ea709163500f38Duncan Sands if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() || 16037e857201f387d004571e6058e2ea709163500f38Duncan Sands Tmp2 != ST->getBasePtr()) 1604027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result = SDValue(DAG.UpdateNodeOperands(Result.getNode(), 1605027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Tmp1, Tmp3, Tmp2, 1606027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman ST->getOffset()), 1607027657db7cf60bcbf40403496d7e4a170f9ce1ecDan Gohman Result.getResNo()); 16087e857201f387d004571e6058e2ea709163500f38Duncan Sands 16097e857201f387d004571e6058e2ea709163500f38Duncan Sands switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) { 161035a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "This action is not supported yet!"); 16117e857201f387d004571e6058e2ea709163500f38Duncan Sands case TargetLowering::Legal: 16127e857201f387d004571e6058e2ea709163500f38Duncan Sands // If this is an unaligned store and the target doesn't support it, 16137e857201f387d004571e6058e2ea709163500f38Duncan Sands // expand it. 1614bc037cfcdef8e88274d7dd167fb9d8ba545f2229Benjamin Kramer if (!TLI.allowsUnalignedMemoryAccesses(ST->getMemoryVT())) { 1615e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng const Type *Ty = ST->getMemoryVT().getTypeForEVT(*DAG.getContext()); 16166e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach unsigned ABIAlignment= TLI.getTargetData()->getABITypeAlignment(Ty); 16177e857201f387d004571e6058e2ea709163500f38Duncan Sands if (ST->getAlignment() < ABIAlignment) 1618e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.getNode()), 1619e96507c73111d88743a15db6d6329f4fbdde7decEvan Cheng DAG, TLI); 16207e857201f387d004571e6058e2ea709163500f38Duncan Sands } 16217e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 16227e857201f387d004571e6058e2ea709163500f38Duncan Sands case TargetLowering::Custom: 16237e857201f387d004571e6058e2ea709163500f38Duncan Sands Result = TLI.LowerOperation(Result, DAG); 16247e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 16257e857201f387d004571e6058e2ea709163500f38Duncan Sands case Expand: 1626c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1627c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem EVT WideScalarVT = Tmp3.getValueType().getScalarType(); 1628c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem EVT NarrowScalarVT = StVT.getScalarType(); 1629c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1630c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // The Store type is illegal, must scalarize the vector store. 1631c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SmallVector<SDValue, 8> Stores; 1632c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem bool ScalarLegal = isTypeLegal(WideScalarVT); 1633c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem if (!isTypeLegal(StVT) && StVT.isVector() && ScalarLegal) { 1634c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned NumElem = StVT.getVectorNumElements(); 1635c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1636c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned ScalarSize = StVT.getScalarType().getSizeInBits(); 1637c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // Round odd types to the next pow of two. 1638c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem if (!isPowerOf2_32(ScalarSize)) 1639c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem ScalarSize = NextPowerOf2(ScalarSize); 1640c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // Types smaller than 8 bits are promoted to 8 bits. 1641c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem ScalarSize = std::max<unsigned>(ScalarSize, 8); 1642c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // Store stride 1643c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned Stride = ScalarSize/8; 1644c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem assert(isPowerOf2_32(Stride) && "Stride must be a power of two"); 1645c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1646c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem for (unsigned Idx=0; Idx<NumElem; Idx++) { 1647c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 1648c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem WideScalarVT, Tmp3, DAG.getIntPtrConstant(Idx)); 1649c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1650c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1651c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem EVT NVT = EVT::getIntegerVT(*DAG.getContext(), ScalarSize); 1652c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1653c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Ex = DAG.getNode(ISD::TRUNCATE, dl, NVT, Ex); 1654c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 1655c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem DAG.getIntPtrConstant(Stride)); 1656c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2, 1657c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem ST->getPointerInfo().getWithOffset(Idx*Stride), 1658c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem isVolatile, isNonTemporal, Alignment); 1659c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Stores.push_back(Store); 1660c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1661c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1662c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem &Stores[0], Stores.size()); 1663c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem break; 1664c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1665c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1666c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // The Store type is illegal, must scalarize the vector store. 1667c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // However, the scalar type is illegal. Must bitcast the result 1668c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // and store it in smaller parts. 1669c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem if (!isTypeLegal(StVT) && StVT.isVector()) { 1670c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned WideNumElem = StVT.getVectorNumElements(); 1671c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned Stride = NarrowScalarVT.getSizeInBits()/8; 1672c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1673c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem unsigned SizeRatio = 1674c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem (WideScalarVT.getSizeInBits() / NarrowScalarVT.getSizeInBits()); 1675c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1676c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem EVT CastValueVT = EVT::getVectorVT(*DAG.getContext(), NarrowScalarVT, 1677c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SizeRatio*WideNumElem); 1678c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1679c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // Cast the wide elem vector to wider vec with smaller elem type. 1680c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // Example <2 x i64> -> <4 x i32> 1681c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp3 = DAG.getNode(ISD::BITCAST, dl, CastValueVT, Tmp3); 1682c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1683c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem for (unsigned Idx=0; Idx<WideNumElem*SizeRatio; Idx++) { 1684c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // Extract elment i 1685c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SDValue Ex = DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, 1686c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem NarrowScalarVT, Tmp3, DAG.getIntPtrConstant(Idx)); 1687c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // bump pointer. 1688c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 1689c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem DAG.getIntPtrConstant(Stride)); 1690c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1691c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // Store if, this element is: 1692c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // - First element on big endian, or 1693c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem // - Last element on little endian 1694c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem if (( TLI.isBigEndian() && (Idx%SizeRatio == 0)) || 1695c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem ((!TLI.isBigEndian() && (Idx%SizeRatio == SizeRatio-1)))) { 1696c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem SDValue Store = DAG.getStore(Tmp1, dl, Ex, Tmp2, 1697c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem ST->getPointerInfo().getWithOffset(Idx*Stride), 1698c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem isVolatile, isNonTemporal, Alignment); 1699c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Stores.push_back(Store); 1700c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1701c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1702c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1703c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem &Stores[0], Stores.size()); 1704c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem break; 1705c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem } 1706c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 1707c2492c28ef04dbc77c5d47ec81ffc64c5407771fNadav Rotem 17087e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i16 i32 -> STORE i16 17097e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(isTypeLegal(StVT) && "Do not know how to expand this store!"); 1710ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3); 1711da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getPointerInfo(), 1712da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner isVolatile, isNonTemporal, Alignment); 17137e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 1714f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 17158b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } 17163e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 17173e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 1718f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 171945b8caf1c5a1fd8337038d64c6da8fba2d299fdfChris Lattner } 17204ddd283f6928fc337c1bf3277566d7b31526e8d9Chris Lattner assert(Result.getValueType() == Op.getValueType() && 17214ddd283f6928fc337c1bf3277566d7b31526e8d9Chris Lattner "Bad legalization!"); 1722fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1723456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner // Make sure that the generated code is itself legal. 1724456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner if (Result != Op) 1725456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Result = LegalizeOp(Result); 17263e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 172745982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner // Note that LegalizeOp may be reentered even from single-use nodes, which 172845982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner // means that we always must cache transformed nodes. 172945982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner AddLegalizedOperand(Op, Result); 17303e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner return Result; 17313e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 17323e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 17333d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli FriedmanSDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) { 17343d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue Vec = Op.getOperand(0); 17353d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue Idx = Op.getOperand(1); 17363d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman DebugLoc dl = Op.getDebugLoc(); 17373d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman // Store the value to a temporary stack slot, then LOAD the returned part. 17383d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); 17396229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, 17406229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(), false, false, 0); 17413d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 17423d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman // Add the offset to the index. 1743aa9d854b334cab2f29ca6d95413a0946b8a38429Dan Gohman unsigned EltSize = 1744aa9d854b334cab2f29ca6d95413a0946b8a38429Dan Gohman Vec.getValueType().getVectorElementType().getSizeInBits()/8; 17453d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx, 17463d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman DAG.getConstant(EltSize, Idx.getValueType())); 17473d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 17483d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman if (Idx.getValueType().bitsGT(TLI.getPointerTy())) 17493d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx); 17503d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman else 17513d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); 17523d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 17533d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr); 17543d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 1755c680ac90032bf455b2bba77de538fccea08eb267Eli Friedman if (Op.getValueType().isVector()) 1756ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr,MachinePointerInfo(), 17571e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 1758a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings return DAG.getExtLoad(ISD::EXTLOAD, dl, Op.getValueType(), Ch, StackPtr, 17593d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner MachinePointerInfo(), 17603d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner Vec.getValueType().getVectorElementType(), 17613d6ccfba314ed38e4506dae2781a060e9a3e07acChris Lattner false, false, 0); 17623d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman} 17633d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 1764cfe33c46aa50f04adb0431243e7d25f79b719ac6David GreeneSDValue SelectionDAGLegalize::ExpandInsertToVectorThroughStack(SDValue Op) { 1765cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene assert(Op.getValueType().isVector() && "Non-vector insert subvector!"); 1766cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1767cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue Vec = Op.getOperand(0); 1768cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue Part = Op.getOperand(1); 1769cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue Idx = Op.getOperand(2); 1770cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene DebugLoc dl = Op.getDebugLoc(); 1771cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1772cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Store the value to a temporary stack slot, then LOAD the returned part. 1773cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1774cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); 1775cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene int FI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); 1776cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(FI); 1777cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1778cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // First store the whole vector. 1779cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, PtrInfo, 1780cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene false, false, 0); 1781cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1782cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Then store the inserted part. 1783cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1784cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Add the offset to the index. 1785cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene unsigned EltSize = 1786cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Vec.getValueType().getVectorElementType().getSizeInBits()/8; 1787cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1788cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx, 1789cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene DAG.getConstant(EltSize, Idx.getValueType())); 1790cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1791cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene if (Idx.getValueType().bitsGT(TLI.getPointerTy())) 1792cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx); 1793cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene else 1794cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); 1795cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1796cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene SDValue SubStackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, 1797cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene StackPtr); 1798cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1799cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Store the subvector. 1800cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Ch = DAG.getStore(DAG.getEntryNode(), dl, Part, SubStackPtr, 1801cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene MachinePointerInfo(), false, false, 0); 1802cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 1803cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene // Finally, load the updated vector. 1804cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, PtrInfo, 1805cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene false, false, 0); 1806cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene} 1807cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene 18087ef3d178660b82d1571757e49f44b004d772a116Eli FriedmanSDValue SelectionDAGLegalize::ExpandVectorBuildThroughStack(SDNode* Node) { 18097ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // We can't handle this case efficiently. Allocate a sufficiently 18107ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // aligned object on the stack, store each element into it, then load 18117ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // the result as a vector. 18127ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Create the stack frame object. 1813e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 18145b8bce11d60694a651965cf019b9cb5d84ed3b90Dale Johannesen EVT EltVT = VT.getVectorElementType(); 18157ef3d178660b82d1571757e49f44b004d772a116Eli Friedman DebugLoc dl = Node->getDebugLoc(); 18167ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue FIPtr = DAG.CreateStackTemporary(VT); 1817ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex(); 1818ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(FI); 18197ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 18207ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Emit a store of each element to the stack slot. 18217ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SmallVector<SDValue, 8> Stores; 1822aa9d854b334cab2f29ca6d95413a0946b8a38429Dan Gohman unsigned TypeByteSize = EltVT.getSizeInBits() / 8; 18237ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Store (in the right endianness) the elements to memory. 18247ef3d178660b82d1571757e49f44b004d772a116Eli Friedman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 18257ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Ignore undef elements. 18267ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue; 18277ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 18287ef3d178660b82d1571757e49f44b004d772a116Eli Friedman unsigned Offset = TypeByteSize*i; 18297ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 18307ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue Idx = DAG.getConstant(Offset, FIPtr.getValueType()); 18317ef3d178660b82d1571757e49f44b004d772a116Eli Friedman Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx); 18327ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 18339949dd612c8100f7ea7e6daaa56e465f106dd0bdDan Gohman // If the destination vector element type is narrower than the source 18349949dd612c8100f7ea7e6daaa56e465f106dd0bdDan Gohman // element type, only store the bits necessary. 18359949dd612c8100f7ea7e6daaa56e465f106dd0bdDan Gohman if (EltVT.bitsLT(Node->getOperand(i).getValueType().getScalarType())) { 18365b8bce11d60694a651965cf019b9cb5d84ed3b90Dale Johannesen Stores.push_back(DAG.getTruncStore(DAG.getEntryNode(), dl, 1837ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Node->getOperand(i), Idx, 1838ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner PtrInfo.getWithOffset(Offset), 18391e559443a17d1b335f697551c6263ba60d5dd827David Greene EltVT, false, false, 0)); 1840eb38ebf15c326a5bb45ca9da6329cdf19ad6df95Mon P Wang } else 18416e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, 1842ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Node->getOperand(i), Idx, 1843ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner PtrInfo.getWithOffset(Offset), 18441e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0)); 18457ef3d178660b82d1571757e49f44b004d772a116Eli Friedman } 18467ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 18477ef3d178660b82d1571757e49f44b004d772a116Eli Friedman SDValue StoreChain; 18487ef3d178660b82d1571757e49f44b004d772a116Eli Friedman if (!Stores.empty()) // Not all undef elements? 1849825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson StoreChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 18507ef3d178660b82d1571757e49f44b004d772a116Eli Friedman &Stores[0], Stores.size()); 18517ef3d178660b82d1571757e49f44b004d772a116Eli Friedman else 18527ef3d178660b82d1571757e49f44b004d772a116Eli Friedman StoreChain = DAG.getEntryNode(); 18537ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 18547ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Result is a load from the stack slot. 1855ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner return DAG.getLoad(VT, dl, StoreChain, FIPtr, PtrInfo, false, false, 0); 18567ef3d178660b82d1571757e49f44b004d772a116Eli Friedman} 18577ef3d178660b82d1571757e49f44b004d772a116Eli Friedman 18584bc8c718218159fe410462f6e3670e7cb76c0c04Eli FriedmanSDValue SelectionDAGLegalize::ExpandFCOPYSIGN(SDNode* Node) { 18594bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DebugLoc dl = Node->getDebugLoc(); 18604bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp1 = Node->getOperand(0); 18614bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp2 = Node->getOperand(1); 18625d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands 18635d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Get the sign bit of the RHS. First obtain a value that has the same 18645d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // sign as the sign bit, i.e. negative if and only if the sign bit is 1. 18654bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SignBit; 18665d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands EVT FloatVT = Tmp2.getValueType(); 18675d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands EVT IVT = EVT::getIntegerVT(*DAG.getContext(), FloatVT.getSizeInBits()); 18684bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman if (isTypeLegal(IVT)) { 18695d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Convert to an integer with the same sign bit. 1870bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SignBit = DAG.getNode(ISD::BITCAST, dl, IVT, Tmp2); 18714bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } else { 18725d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Store the float to memory, then load the sign part out as an integer. 18735d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands MVT LoadTy = TLI.getPointerTy(); 18745d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // First create a temporary that is aligned for both the load and store. 18755d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SDValue StackPtr = DAG.CreateStackTemporary(FloatVT, LoadTy); 18765d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Then store the float to it. 18774bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Ch = 18786229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StackPtr, MachinePointerInfo(), 18791e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 18805d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands if (TLI.isBigEndian()) { 18815d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands assert(FloatVT.isByteSized() && "Unsupported floating point type!"); 18825d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Load out a legal integer with the same sign bit as the float. 1883ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SignBit = DAG.getLoad(LoadTy, dl, Ch, StackPtr, MachinePointerInfo(), 1884ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, 0); 18855d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands } else { // Little endian 18865d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SDValue LoadPtr = StackPtr; 18875d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // The float may be wider than the integer we are going to load. Advance 18885d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // the pointer so that the loaded integer will contain the sign bit. 18895d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands unsigned Strides = (FloatVT.getSizeInBits()-1)/LoadTy.getSizeInBits(); 18905d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands unsigned ByteOffset = (Strides * LoadTy.getSizeInBits()) / 8; 18915d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands LoadPtr = DAG.getNode(ISD::ADD, dl, LoadPtr.getValueType(), 18925d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands LoadPtr, DAG.getIntPtrConstant(ByteOffset)); 18935d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Load a legal integer containing the sign bit. 1894ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SignBit = DAG.getLoad(LoadTy, dl, Ch, LoadPtr, MachinePointerInfo(), 1895ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, 0); 18965d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Move the sign bit to the top bit of the loaded integer. 18975d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands unsigned BitShift = LoadTy.getSizeInBits() - 18985d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands (FloatVT.getSizeInBits() - 8 * ByteOffset); 18995d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands assert(BitShift < LoadTy.getSizeInBits() && "Pointer advanced wrong?"); 19005d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands if (BitShift) 19015d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SignBit = DAG.getNode(ISD::SHL, dl, LoadTy, SignBit, 190295771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(BitShift, 190395771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(SignBit.getValueType()))); 19045d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands } 19054bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 19065d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands // Now get the sign bit proper, by seeing whether the value is negative. 19075d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SignBit = DAG.getSetCC(dl, TLI.getSetCCResultType(SignBit.getValueType()), 19085d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands SignBit, DAG.getConstant(0, SignBit.getValueType()), 19095d54b4112d7b8bcd49a07e398ebff263fac1eb9cDuncan Sands ISD::SETLT); 19104bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Get the absolute value of the result. 19114bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue AbsVal = DAG.getNode(ISD::FABS, dl, Tmp1.getValueType(), Tmp1); 19124bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Select between the nabs and abs value based on the sign bit of 19134bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // the input. 19144bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman return DAG.getNode(ISD::SELECT, dl, AbsVal.getValueType(), SignBit, 19154bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DAG.getNode(ISD::FNEG, dl, AbsVal.getValueType(), AbsVal), 19164bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman AbsVal); 19174bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman} 19184bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 19194bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedmanvoid SelectionDAGLegalize::ExpandDYNAMIC_STACKALLOC(SDNode* Node, 19204bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SmallVectorImpl<SDValue> &Results) { 19214bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore(); 19224bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and" 19234bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman " not tell us which reg is the stack pointer!"); 19244bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DebugLoc dl = Node->getDebugLoc(); 1925e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 19264bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp1 = SDValue(Node, 0); 19274bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp2 = SDValue(Node, 1); 19284bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Tmp3 = Node->getOperand(2); 19294bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Chain = Tmp1.getOperand(0); 19304bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 19314bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Chain the dynamic stack allocation so that it doesn't modify the stack 19324bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // pointer when other instructions are using the stack. 19334bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true)); 19344bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 19354bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Size = Tmp2.getOperand(1); 19364bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT); 19374bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Chain = SP.getValue(1); 19384bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue(); 193916c29b5f285f375be53dabaa73e3e91107485fe4Anton Korobeynikov unsigned StackAlign = TM.getFrameLowering()->getStackAlignment(); 19404bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman if (Align > StackAlign) 19414bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SP = DAG.getNode(ISD::AND, dl, VT, SP, 19424bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DAG.getConstant(-(uint64_t)Align, VT)); 19434bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Tmp1 = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value 19444bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1); // Output chain 19454bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 19464bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true), 19474bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman DAG.getIntPtrConstant(0, true), SDValue()); 19484bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 19494bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Tmp1); 19504bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Tmp2); 19514bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman} 19524bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 19537f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng/// LegalizeSetCCCondCode - Legalize a SETCC with given LHS and RHS and 1954f77fc92b03efe455008474894d217282e2a03cadDan Gohman/// condition code CC on the current target. This routine expands SETCC with 19557f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng/// illegal condition code into AND / OR of multiple SETCC values. 1956e50ed30282bb5b4a9ed952580523f2dda16215acOwen Andersonvoid SelectionDAGLegalize::LegalizeSetCCCondCode(EVT VT, 19577f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng SDValue &LHS, SDValue &RHS, 1958bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue &CC, 1959775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DebugLoc dl) { 1960e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpVT = LHS.getValueType(); 19617f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get(); 19627f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng switch (TLI.getCondCodeAction(CCCode, OpVT)) { 196335a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unknown condition code action!"); 19647f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng case TargetLowering::Legal: 19657f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng // Nothing to do. 19667f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng break; 19677f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng case TargetLowering::Expand: { 19687f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID; 19697f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng unsigned Opc = 0; 19707f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng switch (CCCode) { 197135a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Don't know how to expand this condition!"); 1972e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETO; Opc = ISD::AND; break; 1973e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOGT: CC1 = ISD::SETGT; CC2 = ISD::SETO; Opc = ISD::AND; break; 1974e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOGE: CC1 = ISD::SETGE; CC2 = ISD::SETO; Opc = ISD::AND; break; 1975e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOLT: CC1 = ISD::SETLT; CC2 = ISD::SETO; Opc = ISD::AND; break; 1976e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOLE: CC1 = ISD::SETLE; CC2 = ISD::SETO; Opc = ISD::AND; break; 1977e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETONE: CC1 = ISD::SETNE; CC2 = ISD::SETO; Opc = ISD::AND; break; 1978e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1979e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUGT: CC1 = ISD::SETGT; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1980e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUGE: CC1 = ISD::SETGE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1981e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETULT: CC1 = ISD::SETLT; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1982e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETULE: CC1 = ISD::SETLE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 1983e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUNE: CC1 = ISD::SETNE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 19847f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng // FIXME: Implement more expansions. 19857f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 19867f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng 1987bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1); 1988bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2); 1989bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen LHS = DAG.getNode(Opc, dl, VT, SetCC1, SetCC2); 19907f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng RHS = SDValue(); 19917f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng CC = SDValue(); 19927f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng break; 19937f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 19947f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 19957f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng} 19967f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng 19971401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// EmitStackConvert - Emit a store/load combination to the stack. This stores 19981401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// SrcOp to a stack slot of type SlotVT, truncating it if needed. It then does 19991401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// a load from the stack slot to DestVT, extending it if needed. 20001401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// The resultant code need not be legal. 2001475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, 2002e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT SlotVT, 2003e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DestVT, 20048a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl) { 200535481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner // Create the stack frame object. 2006ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson unsigned SrcAlign = 2007ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson TLI.getTargetData()->getPrefTypeAlignment(SrcOp.getValueType(). 200823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson getTypeForEVT(*DAG.getContext())); 2009475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign); 2010fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2011ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(FIPtr); 2012ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int SPFI = StackPtrFI->getIndex(); 2013da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner MachinePointerInfo PtrInfo = MachinePointerInfo::getFixedStack(SPFI); 2014ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng 201583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned SrcSize = SrcOp.getValueType().getSizeInBits(); 201683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned SlotSize = SlotVT.getSizeInBits(); 201783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned DestSize = DestVT.getSizeInBits(); 2018adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng const Type *DestType = DestVT.getTypeForEVT(*DAG.getContext()); 2019adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng unsigned DestAlign = TLI.getTargetData()->getPrefTypeAlignment(DestType); 2020fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 20211401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner // Emit a store to the stack slot. Use a truncstore if the input value is 20221401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner // later than DestVT. 2023475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Store; 2024ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng 20251401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner if (SrcSize > SlotSize) 20268a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, 2027da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner PtrInfo, SlotVT, false, false, SrcAlign); 20281401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner else { 20291401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner assert(SrcSize == SlotSize && "Invalid store"); 20308a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, 2031da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner PtrInfo, false, false, SrcAlign); 20321401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner } 2033fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 203435481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner // Result is a load from the stack slot. 20351401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner if (SlotSize == DestSize) 2036da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner return DAG.getLoad(DestVT, dl, Store, FIPtr, PtrInfo, 2037ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, DestAlign); 2038fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 20391401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner assert(SlotSize < DestSize && "Unknown extension!"); 2040a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, 2041da2d8e1032eb4c2fefb1f647d7877910b9483835Chris Lattner PtrInfo, SlotVT, false, false, DestAlign); 204235481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner} 204335481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner 2044475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { 20458a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl = Node->getDebugLoc(); 20464352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // Create a vector sized/aligned stack slot, store the value to element #0, 20474352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // then load the whole vector back out. 2048475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue StackPtr = DAG.CreateStackTemporary(Node->getValueType(0)); 204969de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman 2050ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr); 2051ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng int SPFI = StackPtrFI->getIndex(); 2052ff89dcb06fbd103373436e2d0ae85f252fae2254Evan Cheng 2053b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), dl, Node->getOperand(0), 2054b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands StackPtr, 205585ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getFixedStack(SPFI), 20561e559443a17d1b335f697551c6263ba60d5dd827David Greene Node->getValueType(0).getVectorElementType(), 20571e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 20588a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr, 205985ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getFixedStack(SPFI), 20601e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 20614352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner} 20624352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 20634352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 2064ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner/// ExpandBUILD_VECTOR - Expand a BUILD_VECTOR node on targets that don't 206507a96765daedf180a7102d39fe56c499878312b7Dan Gohman/// support the operation, but do support the resultant vector type. 2066475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { 206726cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson unsigned NumElems = Node->getNumOperands(); 20687a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SDValue Value1, Value2; 206926cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson DebugLoc dl = Node->getDebugLoc(); 2070e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 2071e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpVT = Node->getOperand(0).getValueType(); 2072e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT EltVT = VT.getVectorElementType(); 2073fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2074fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // If the only non-undef value is the low element, turn this into a 207587100e0b83b808757bf44dabecd1d1048255d1adChris Lattner // SCALAR_TO_VECTOR node. If this is { X, X, X, X }, determine X. 2076ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner bool isOnlyLowElement = true; 20777a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman bool MoreThanTwoValues = false; 20782eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner bool isConstant = true; 20797a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman for (unsigned i = 0; i < NumElems; ++i) { 2080475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue V = Node->getOperand(i); 20817a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (V.getOpcode() == ISD::UNDEF) 20827a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman continue; 20837a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (i > 0) 2084ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner isOnlyLowElement = false; 20857a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V)) 20862eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner isConstant = false; 20877a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman 20887a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (!Value1.getNode()) { 20897a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman Value1 = V; 20907a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman } else if (!Value2.getNode()) { 20917a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (V != Value1) 20927a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman Value2 = V; 20937a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman } else if (V != Value1 && V != Value2) { 20947a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman MoreThanTwoValues = true; 20957a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman } 2096ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 2097fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 20987a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (!Value1.getNode()) 20997a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman return DAG.getUNDEF(VT); 21007a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman 21017a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (isOnlyLowElement) 210226cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Node->getOperand(0)); 2103fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 21042eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // If all elements are constants, create a load from the constant pool. 2105ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner if (isConstant) { 2106ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner std::vector<Constant*> CV; 2107033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng for (unsigned i = 0, e = NumElems; i != e; ++i) { 2108fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel if (ConstantFPSDNode *V = 2109ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) { 21104fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman CV.push_back(const_cast<ConstantFP *>(V->getConstantFPValue())); 2111fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel } else if (ConstantSDNode *V = 2112ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson dyn_cast<ConstantSDNode>(Node->getOperand(i))) { 21139a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen if (OpVT==EltVT) 21149a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue())); 21159a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen else { 21169a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen // If OpVT and EltVT don't match, EltVT is not legal and the 21179a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen // element values have been promoted/truncated earlier. Undo this; 21189a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen // we don't want a v16i8 to become a v16i32 for example. 21199a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen const ConstantInt *CI = V->getConstantIntValue(); 21209a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen CV.push_back(ConstantInt::get(EltVT.getTypeForEVT(*DAG.getContext()), 21219a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen CI->getZExtValue())); 21229a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen } 2123ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } else { 2124ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner assert(Node->getOperand(i).getOpcode() == ISD::UNDEF); 21259a645cd9d4c0e7d25e4b8836ed31deb5881c8101Dale Johannesen const Type *OpNTy = EltVT.getTypeForEVT(*DAG.getContext()); 21269e9a0d5fc26878e51a58a8b57900fcbf952c2691Owen Anderson CV.push_back(UndefValue::get(OpNTy)); 2127ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 2128ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 2129af7ec975870f92245f1f1484ac80a1e2db6a0afaOwen Anderson Constant *CP = ConstantVector::get(CV); 2130475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy()); 21311606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 21328a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx, 213385ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getConstantPool(), 21341e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, Alignment); 2135ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 2136fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 21377a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (!MoreThanTwoValues) { 21387a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SmallVector<int, 8> ShuffleVec(NumElems, -1); 21397a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman for (unsigned i = 0; i < NumElems; ++i) { 21407a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SDValue V = Node->getOperand(i); 21417a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (V.getOpcode() == ISD::UNDEF) 21427a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman continue; 21437a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman ShuffleVec[i] = V == Value1 ? 0 : NumElems; 21447a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman } 21457a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (TLI.isShuffleMaskLegal(ShuffleVec, Node->getValueType(0))) { 21462eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // Get the splatted value into the low element of a vector register. 21477a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SDValue Vec1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value1); 21487a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman SDValue Vec2; 21497a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman if (Value2.getNode()) 21507a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman Vec2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Value2); 21517a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman else 21527a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman Vec2 = DAG.getUNDEF(VT); 2153fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 21542eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // Return shuffle(LowValVec, undef, <0,0,0,0>) 21557a5e55509b99d579d56d126a7b503ec6fe153a8fEli Friedman return DAG.getVectorShuffle(VT, dl, Vec1, Vec2, ShuffleVec.data()); 2156033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng } 2157033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng } 2158fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 21597ef3d178660b82d1571757e49f44b004d772a116Eli Friedman // Otherwise, we can't handle this case efficiently. 21607ef3d178660b82d1571757e49f44b004d772a116Eli Friedman return ExpandVectorBuildThroughStack(Node); 2161ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner} 2162ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner 216377e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// ExpandLibCall - Expand a node into a call to a libcall. If the result value 216477e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// does not fit into a register, return the lo part and set the hi part to the 216577e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// by-reg argument. If it does fit into a single register, return the result 216677e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// and leave the Hi part unset. 2167475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, 216847b41f7e20b6af7aaaf0e050200102d55d038b9dEli Friedman bool isSigned) { 2169fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // The input chain to this libcall is the entry node of the function. 21706831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Legalizing the call will automatically add the previous call to the 21716831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // dependence. 2172475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InChain = DAG.getEntryNode(); 2173fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 217477e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner TargetLowering::ArgListTy Args; 217547857812e29324a9d1560796a05b53d3a9217fd9Reid Spencer TargetLowering::ArgListEntry Entry; 217677e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 2177e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ArgVT = Node->getOperand(i).getValueType(); 217823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 2179fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; 2180d0b82b301d700217a716526f9329bb031e0d6578Anton Korobeynikov Entry.isSExt = isSigned; 218100fee65fd21f9615d1a604b8b7d42cd16a3f6b47Duncan Sands Entry.isZExt = !isSigned; 218247857812e29324a9d1560796a05b53d3a9217fd9Reid Spencer Args.push_back(Entry); 218377e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner } 2184056292fd738924f3f7703725d8f630983794b5a5Bill Wendling SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 21850c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang TLI.getPointerTy()); 2186edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 21870d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner // Splice the libcall in wherever FindInputOutputChains tells us to. 218823b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson const Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); 21893d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng 21903d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng // isTailCall may be true since the callee does not reference caller stack 21913d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng // frame. Check if it's in the right position. 21923d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng bool isTailCall = isInTailCallPosition(DAG, Node, TLI); 2193ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson std::pair<SDValue, SDValue> CallInfo = 219486098bd6a63d2cdf0c9be9ef3151bd2728281fd7Dale Johannesen TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 21953d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng 0, TLI.getLibcallCallingConv(LC), isTailCall, 219698ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman /*isReturnValueUsed=*/true, 219746ada19645c981a0b7932487d163f7582074a4d9Bill Wendling Callee, Args, DAG, Node->getDebugLoc()); 21980d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner 21993d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng if (!CallInfo.second.getNode()) 22003d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng // It's a tailcall, return the chain (which is the DAG root). 22013d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng return DAG.getRoot(); 22023d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng 22036831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Legalize the call sequence, starting with the chain. This will advance 2204fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that 22056831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // was added by LowerCallTo (guaranteeing proper serialization of calls). 22066831a815999dde4cf801e2076e66b4943964daf2Chris Lattner LegalizeOp(CallInfo.second); 220774807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman return CallInfo.first; 220822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 220922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 2210f316eb70743e88227b8919370fe38587ffe93512Dan Gohman/// ExpandLibCall - Generate a libcall taking the given operands as arguments 2211abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher/// and returning a result of type RetVT. 2212abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric ChristopherSDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, EVT RetVT, 2213abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher const SDValue *Ops, unsigned NumOps, 2214abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher bool isSigned, DebugLoc dl) { 2215abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TargetLowering::ArgListTy Args; 2216abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Args.reserve(NumOps); 2217f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 2218abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TargetLowering::ArgListEntry Entry; 2219abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher for (unsigned i = 0; i != NumOps; ++i) { 2220abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Entry.Node = Ops[i]; 2221abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Entry.Ty = Entry.Node.getValueType().getTypeForEVT(*DAG.getContext()); 2222abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Entry.isSExt = isSigned; 2223abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Entry.isZExt = !isSigned; 2224abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Args.push_back(Entry); 2225abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher } 2226abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 2227abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TLI.getPointerTy()); 2228f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 2229abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); 2230abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher std::pair<SDValue,SDValue> CallInfo = 2231abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TLI.LowerCallTo(DAG.getEntryNode(), RetTy, isSigned, !isSigned, false, 2232abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher false, 0, TLI.getLibcallCallingConv(LC), false, 2233abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher /*isReturnValueUsed=*/true, 2234abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher Callee, Args, DAG, dl); 2235f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 2236abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // Legalize the call sequence, starting with the chain. This will advance 2237abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that 2238abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // was added by LowerCallTo (guaranteeing proper serialization of calls). 2239abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher LegalizeOp(CallInfo.second); 2240abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher 2241abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher return CallInfo.first; 2242abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher} 2243abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher 2244e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach// ExpandChainLibCall - Expand a node into a call to a libcall. Similar to 2245e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach// ExpandLibCall except that the first operand is the in-chain. 2246e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbachstd::pair<SDValue, SDValue> 2247e03262fcfc09356a0e3ec589041bc2e0248944e9Jim GrosbachSelectionDAGLegalize::ExpandChainLibCall(RTLIB::Libcall LC, 2248e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach SDNode *Node, 2249e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach bool isSigned) { 2250e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach SDValue InChain = Node->getOperand(0); 2251e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2252e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach TargetLowering::ArgListTy Args; 2253e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach TargetLowering::ArgListEntry Entry; 2254e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach for (unsigned i = 1, e = Node->getNumOperands(); i != e; ++i) { 2255e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach EVT ArgVT = Node->getOperand(i).getValueType(); 2256e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 2257e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Entry.Node = Node->getOperand(i); 2258e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Entry.Ty = ArgTy; 2259e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Entry.isSExt = isSigned; 2260e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Entry.isZExt = !isSigned; 2261e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Args.push_back(Entry); 2262e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2263e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 2264e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach TLI.getPointerTy()); 2265e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2266e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach // Splice the libcall in wherever FindInputOutputChains tells us to. 2267e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach const Type *RetTy = Node->getValueType(0).getTypeForEVT(*DAG.getContext()); 2268e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach std::pair<SDValue, SDValue> CallInfo = 2269e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 22703d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, 2271e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach /*isReturnValueUsed=*/true, 2272e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Callee, Args, DAG, Node->getDebugLoc()); 2273e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2274e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach // Legalize the call sequence, starting with the chain. This will advance 2275fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that 2276e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach // was added by LowerCallTo (guaranteeing proper serialization of calls). 2277e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach LegalizeOp(CallInfo.second); 2278e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach return CallInfo; 2279e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach} 2280e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2281f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli FriedmanSDValue SelectionDAGLegalize::ExpandFPLibCall(SDNode* Node, 2282f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_F32, 2283f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_F64, 2284f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_F80, 2285f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_PPCF128) { 2286f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall LC; 2287825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 228835a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unexpected request for libcall!"); 2289825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f32: LC = Call_F32; break; 2290825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f64: LC = Call_F64; break; 2291825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::f80: LC = Call_F80; break; 2292825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::ppcf128: LC = Call_PPCF128; break; 2293f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman } 2294f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman return ExpandLibCall(LC, Node, false); 2295f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman} 2296f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman 2297f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli FriedmanSDValue SelectionDAGLegalize::ExpandIntLibCall(SDNode* Node, bool isSigned, 22988983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::Libcall Call_I8, 2299f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I16, 2300f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I32, 2301f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I64, 2302f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall Call_I128) { 2303f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman RTLIB::Libcall LC; 2304825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 230535a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unexpected request for libcall!"); 23068983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov case MVT::i8: LC = Call_I8; break; 23078983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov case MVT::i16: LC = Call_I16; break; 23088983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov case MVT::i32: LC = Call_I32; break; 23098983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov case MVT::i64: LC = Call_I64; break; 2310825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i128: LC = Call_I128; break; 2311f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman } 2312f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman return ExpandLibCall(LC, Node, isSigned); 2313f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman} 2314f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman 231565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// isDivRemLibcallAvailable - Return true if divmod libcall is available. 231665279cb9bd985721ac6ad090fed02298396ba06dEvan Chengstatic bool isDivRemLibcallAvailable(SDNode *Node, bool isSigned, 231765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng const TargetLowering &TLI) { 23188e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng RTLIB::Libcall LC; 23198e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 23208e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng default: assert(0 && "Unexpected request for libcall!"); 23218e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break; 23228e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break; 23238e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; 23248e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break; 23258e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; break; 23268e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng } 23278e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 232865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng return TLI.getLibcallName(LC) != 0; 232965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng} 23308e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 233165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// UseDivRem - Only issue divrem libcall if both quotient and remainder are 233265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// needed. 233365279cb9bd985721ac6ad090fed02298396ba06dEvan Chengstatic bool UseDivRem(SDNode *Node, bool isSigned, bool isDIV) { 23348e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng unsigned OtherOpcode = 0; 233565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng if (isSigned) 23368e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng OtherOpcode = isDIV ? ISD::SREM : ISD::SDIV; 233765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng else 23388e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng OtherOpcode = isDIV ? ISD::UREM : ISD::UDIV; 233965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng 23408e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue Op0 = Node->getOperand(0); 23418e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue Op1 = Node->getOperand(1); 23428e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng for (SDNode::use_iterator UI = Op0.getNode()->use_begin(), 23438e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng UE = Op0.getNode()->use_end(); UI != UE; ++UI) { 23448e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDNode *User = *UI; 23458e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng if (User == Node) 23468e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng continue; 23478e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng if (User->getOpcode() == OtherOpcode && 23488e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng User->getOperand(0) == Op0 && 234965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng User->getOperand(1) == Op1) 235065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng return true; 23518e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng } 235265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng return false; 235365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng} 235465279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng 235565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// ExpandDivRemLibCall - Issue libcalls to __{u}divmod to compute div / rem 235665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng/// pairs. 235765279cb9bd985721ac6ad090fed02298396ba06dEvan Chengvoid 235865279cb9bd985721ac6ad090fed02298396ba06dEvan ChengSelectionDAGLegalize::ExpandDivRemLibCall(SDNode *Node, 235965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng SmallVectorImpl<SDValue> &Results) { 236065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng unsigned Opcode = Node->getOpcode(); 236165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng bool isSigned = Opcode == ISD::SDIVREM; 236265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng 236365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::Libcall LC; 236465279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng switch (Node->getValueType(0).getSimpleVT().SimpleTy) { 236565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng default: assert(0 && "Unexpected request for libcall!"); 236665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i8: LC= isSigned ? RTLIB::SDIVREM_I8 : RTLIB::UDIVREM_I8; break; 236765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i16: LC= isSigned ? RTLIB::SDIVREM_I16 : RTLIB::UDIVREM_I16; break; 236865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i32: LC= isSigned ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; break; 236965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i64: LC= isSigned ? RTLIB::SDIVREM_I64 : RTLIB::UDIVREM_I64; break; 237065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case MVT::i128: LC= isSigned ? RTLIB::SDIVREM_I128:RTLIB::UDIVREM_I128; break; 23718e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng } 23728e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 23738e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // The input chain to this libcall is the entry node of the function. 23748e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // Legalizing the call will automatically add the previous call to the 23758e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // dependence. 23768e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue InChain = DAG.getEntryNode(); 23778e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 23788e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng EVT RetVT = Node->getValueType(0); 23798e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng const Type *RetTy = RetVT.getTypeForEVT(*DAG.getContext()); 23808e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 23818e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng TargetLowering::ArgListTy Args; 23828e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng TargetLowering::ArgListEntry Entry; 23838e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 23848e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng EVT ArgVT = Node->getOperand(i).getValueType(); 23858e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng const Type *ArgTy = ArgVT.getTypeForEVT(*DAG.getContext()); 23868e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; 23878e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.isSExt = isSigned; 23888e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.isZExt = !isSigned; 23898e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Args.push_back(Entry); 23908e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng } 23918e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 23928e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // Also pass the return address of the remainder. 23938e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue FIPtr = DAG.CreateStackTemporary(RetVT); 23948e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.Node = FIPtr; 23958e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.Ty = RetTy->getPointerTo(); 23968e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.isSExt = isSigned; 23978e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Entry.isZExt = !isSigned; 23988e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng Args.push_back(Entry); 23998e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 24008e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 24018e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng TLI.getPointerTy()); 24028e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 24038e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // Splice the libcall in wherever FindInputOutputChains tells us to. 24048e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng DebugLoc dl = Node->getDebugLoc(); 24058e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng std::pair<SDValue, SDValue> CallInfo = 24068e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 24078e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 0, TLI.getLibcallCallingConv(LC), /*isTailCall=*/false, 24088e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng /*isReturnValueUsed=*/true, Callee, Args, DAG, dl); 24098e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 24108e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // Legalize the call sequence, starting with the chain. This will advance 2411fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings // the LastCALLSEQ to the legalized version of the CALLSEQ_END node that 24128e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // was added by LowerCallTo (guaranteeing proper serialization of calls). 24138e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng LegalizeOp(CallInfo.second); 24148e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 24158e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng // Remainder is loaded back from the stack frame. 2416fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings SDValue Rem = DAG.getLoad(RetVT, dl, getLastCALLSEQ(), FIPtr, 24178e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng MachinePointerInfo(), false, false, 0); 241865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Results.push_back(CallInfo.first); 241965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Results.push_back(Rem); 24208e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng} 24218e23e815ad1136721acdfcce76975a37c8a2c036Evan Cheng 242222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandLegalINT_TO_FP - This function is responsible for legalizing a 242322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// INT_TO_FP operation of the specified operand when the target requests that 242422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we expand it. At this point, we know that the result and operand types are 242522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target. 2426475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, 2427475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0, 2428e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DestVT, 2429af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 2430825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (Op0.getValueType() == MVT::i32) { 243122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // simple 32-bit [signed|unsigned] integer to float/double expansion 2432fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 243323594d4537fb88a963c6d6993af5027eac9bfbacChris Lattner // Get the stack frame index of a 8 byte buffer. 2434825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue StackSlot = DAG.CreateStackTemporary(MVT::f64); 2435fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 243622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // word offset constant for Hi/Lo address computation 2437475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy()); 243822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // set up Hi and Lo (into buffer) address based on endian 2439475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Hi = StackSlot; 2440fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel SDValue Lo = DAG.getNode(ISD::ADD, dl, 2441ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson TLI.getPointerTy(), StackSlot, WordOff); 2442408c428096df3a3970a8387f9dd258ae948663a6Chris Lattner if (TLI.isLittleEndian()) 2443408c428096df3a3970a8387f9dd258ae948663a6Chris Lattner std::swap(Hi, Lo); 2444fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 244522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // if signed map to unsigned space 2446475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0Mapped; 244722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (isSigned) { 244822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // constant used to invert sign bit (signed to unsigned mapping) 2449825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue SignBit = DAG.getConstant(0x80000000u, MVT::i32); 2450825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Op0Mapped = DAG.getNode(ISD::XOR, dl, MVT::i32, Op0, SignBit); 245122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } else { 245222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner Op0Mapped = Op0; 245322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 245422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // store the lo of the constructed double - based on integer input 2455af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, 24566229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner Op0Mapped, Lo, MachinePointerInfo(), 24571e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 245822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // initial hi portion of constructed double 2459825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue InitialHi = DAG.getConstant(0x43300000u, MVT::i32); 246022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // store the hi of the constructed double - biased exponent 24616229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner SDValue Store2 = DAG.getStore(Store1, dl, InitialHi, Hi, 24626229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(), 24636229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner false, false, 0); 246422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // load the constructed double 2465ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, 2466ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(), false, false, 0); 246722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // FP constant to bias correct the final result 2468475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Bias = DAG.getConstantFP(isSigned ? 2469ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson BitsToDouble(0x4330000080000000ULL) : 2470ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson BitsToDouble(0x4330000000000000ULL), 2471825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson MVT::f64); 247222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // subtract the bias 2473825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::f64, Load, Bias); 247422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // final result 2475475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Result; 247622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // handle final rounding 2477825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson if (DestVT == MVT::f64) { 247822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // do nothing 247922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner Result = Sub; 2480825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (DestVT.bitsLT(MVT::f64)) { 2481af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen Result = DAG.getNode(ISD::FP_ROUND, dl, DestVT, Sub, 24820bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner DAG.getIntPtrConstant(0)); 2483825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson } else if (DestVT.bitsGT(MVT::f64)) { 2484af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen Result = DAG.getNode(ISD::FP_EXTEND, dl, DestVT, Sub); 248522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 248622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner return Result; 248722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 248822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet"); 2489a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen // Code below here assumes !isSigned without checking again. 24900fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman 24910fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // Implementation of unsigned i64 to f64 following the algorithm in 24920fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // __floatundidf in compiler_rt. This implementation has the advantage 24930fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // of performing rounding correctly, both in the default rounding mode 24940fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // and in all alternate rounding modes. 24950fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman // TODO: Generalize this for use with other types. 24960fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman if (Op0.getValueType() == MVT::i64 && DestVT == MVT::f64) { 24970fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue TwoP52 = 24980fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman DAG.getConstant(UINT64_C(0x4330000000000000), MVT::i64); 24990fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue TwoP84PlusTwoP52 = 25000fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman DAG.getConstantFP(BitsToDouble(UINT64_C(0x4530000000100000)), MVT::f64); 25010fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue TwoP84 = 25020fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman DAG.getConstant(UINT64_C(0x4530000000000000), MVT::i64); 25030fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman 25040fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue Lo = DAG.getZeroExtendInReg(Op0, dl, MVT::i32); 25050fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue Hi = DAG.getNode(ISD::SRL, dl, MVT::i64, Op0, 25060fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman DAG.getConstant(32, MVT::i64)); 25070fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue LoOr = DAG.getNode(ISD::OR, dl, MVT::i64, Lo, TwoP52); 25080fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman SDValue HiOr = DAG.getNode(ISD::OR, dl, MVT::i64, Hi, TwoP84); 2509bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue LoFlt = DAG.getNode(ISD::BITCAST, dl, MVT::f64, LoOr); 2510bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue HiFlt = DAG.getNode(ISD::BITCAST, dl, MVT::f64, HiOr); 25116e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach SDValue HiSub = DAG.getNode(ISD::FSUB, dl, MVT::f64, HiFlt, 25126e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach TwoP84PlusTwoP52); 25130fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman return DAG.getNode(ISD::FADD, dl, MVT::f64, LoFlt, HiSub); 25140fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman } 25150fa9d1d9011a98212b66daf27f6a8a3d734ae818Dan Gohman 25163a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // Implementation of unsigned i64 to f32. 2517a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen // TODO: Generalize this for use with other types. 2518a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen if (Op0.getValueType() == MVT::i64 && DestVT == MVT::f32) { 25193a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // For unsigned conversions, convert them to signed conversions using the 25203a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // algorithm from the x86_64 __floatundidf in compiler_rt. 25213a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson if (!isSigned) { 25223a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue Fast = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, Op0); 2523bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 252495771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson SDValue ShiftConst = 252595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(1, TLI.getShiftAmountTy(Op0.getValueType())); 25263a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue Shr = DAG.getNode(ISD::SRL, dl, MVT::i64, Op0, ShiftConst); 25273a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue AndConst = DAG.getConstant(1, MVT::i64); 25283a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue And = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, AndConst); 25293a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i64, And, Shr); 2530bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 25313a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue SignCvt = DAG.getNode(ISD::SINT_TO_FP, dl, MVT::f32, Or); 25323a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson SDValue Slow = DAG.getNode(ISD::FADD, dl, MVT::f32, SignCvt, SignCvt); 2533bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 25343a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // TODO: This really should be implemented using a branch rather than a 2535bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck // select. We happen to get lucky and machinesink does the right 2536bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck // thing most of the time. This would be a good candidate for a 25373a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson //pseudo-op, or, even better, for whole-function isel. 2538bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck SDValue SignBitTest = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 25393a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson Op0, DAG.getConstant(0, MVT::i64), ISD::SETLT); 25403a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson return DAG.getNode(ISD::SELECT, dl, MVT::f32, SignBitTest, Slow, Fast); 25413a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson } 2542bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 25433a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson // Otherwise, implement the fully general conversion. 2544bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 25456e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach SDValue And = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, 2546a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstant(UINT64_C(0xfffffffffffff800), MVT::i64)); 2547a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Or = DAG.getNode(ISD::OR, dl, MVT::i64, And, 2548a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstant(UINT64_C(0x800), MVT::i64)); 25496e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach SDValue And2 = DAG.getNode(ISD::AND, dl, MVT::i64, Op0, 2550a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstant(UINT64_C(0x7ff), MVT::i64)); 2551a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Ne = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 2552a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen And2, DAG.getConstant(UINT64_C(0), MVT::i64), ISD::SETNE); 2553a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Sel = DAG.getNode(ISD::SELECT, dl, MVT::i64, Ne, Or, Op0); 2554a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Ge = DAG.getSetCC(dl, TLI.getSetCCResultType(MVT::i64), 2555a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen Op0, DAG.getConstant(UINT64_C(0x0020000000000000), MVT::i64), 25563a9e7690ba99c27d9b09fa8e61fb9f7ba01364c9Owen Anderson ISD::SETUGE); 2557a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Sel2 = DAG.getNode(ISD::SELECT, dl, MVT::i64, Ge, Sel, Op0); 255895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT SHVT = TLI.getShiftAmountTy(Sel2.getValueType()); 2559bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck 2560a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Sh = DAG.getNode(ISD::SRL, dl, MVT::i64, Sel2, 2561a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstant(32, SHVT)); 2562a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Trunc = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Sh); 2563a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Fcvt = DAG.getNode(ISD::UINT_TO_FP, dl, MVT::f64, Trunc); 2564a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue TwoP32 = 2565a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getConstantFP(BitsToDouble(UINT64_C(0x41f0000000000000)), MVT::f64); 2566a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Fmul = DAG.getNode(ISD::FMUL, dl, MVT::f64, TwoP32, Fcvt); 2567a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Lo = DAG.getNode(ISD::TRUNCATE, dl, MVT::i32, Sel2); 2568a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Fcvt2 = DAG.getNode(ISD::UINT_TO_FP, dl, MVT::f64, Lo); 2569a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen SDValue Fadd = DAG.getNode(ISD::FADD, dl, MVT::f64, Fmul, Fcvt2); 2570a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen return DAG.getNode(ISD::FP_ROUND, dl, MVT::f32, Fadd, 2571a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen DAG.getIntPtrConstant(0)); 2572a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen } 2573a5afa1cb214146fd270c86f606b634c8ed6682f2Dale Johannesen 2574b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, dl, DestVT, Op0); 2575b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman 2576b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue SignSet = DAG.getSetCC(dl, TLI.getSetCCResultType(Op0.getValueType()), 2577b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman Op0, DAG.getConstant(0, Op0.getValueType()), 2578b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman ISD::SETLT); 2579b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4); 2580b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue CstOffset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), 2581b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SignSet, Four, Zero); 2582b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman 2583b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman // If the sign bit of the integer is set, the large number will be treated 2584b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman // as a negative number. To counteract this, the dynamic code adds an 2585b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman // offset depending on the data type. 2586b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman uint64_t FF; 2587b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman switch (Op0.getValueType().getSimpleVT().SimpleTy) { 258835a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unsupported integer type!"); 2589b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman case MVT::i8 : FF = 0x43800000ULL; break; // 2^8 (as a float) 2590b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman case MVT::i16: FF = 0x47800000ULL; break; // 2^16 (as a float) 2591b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman case MVT::i32: FF = 0x4F800000ULL; break; // 2^32 (as a float) 2592b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman case MVT::i64: FF = 0x5F800000ULL; break; // 2^64 (as a float) 2593b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman } 2594b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman if (TLI.isLittleEndian()) FF <<= 32; 2595b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman Constant *FudgeFactor = ConstantInt::get( 2596b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman Type::getInt64Ty(*DAG.getContext()), FF); 2597b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman 2598b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); 2599b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 2600b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset); 2601b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman Alignment = std::min(Alignment, 4u); 2602b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman SDValue FudgeInReg; 2603b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman if (DestVT == MVT::f32) 2604b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx, 260585ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getConstantPool(), 2606b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman false, false, Alignment); 2607b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman else { 2608b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman FudgeInReg = 2609a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, 2610b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman DAG.getEntryNode(), CPIdx, 261185ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getConstantPool(), 2612b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman MVT::f32, false, false, Alignment)); 2613b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman } 261422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 2615b6b343d77acb5c290f7093e741fbce484d11cedcDan Gohman return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg); 261622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 261722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 261822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a 261922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// *INT_TO_FP operation of the specified operand when the target requests that 262022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we promote it. At this point, we know that the result and operand types are 262122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP 262222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// operation that takes a larger input. 2623475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, 2624e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DestVT, 2625af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen bool isSigned, 2626af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 262722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // First step, figure out the appropriate *INT_TO_FP operation to use. 2628e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NewInTy = LegalOp.getValueType(); 262922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 263022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner unsigned OpToUse = 0; 263122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 263222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Scan for the appropriate larger type to use. 263322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner while (1) { 2634825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson NewInTy = (MVT::SimpleValueType)(NewInTy.getSimpleVT().SimpleTy+1); 263583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(NewInTy.isInteger() && "Ran out of possibilities!"); 263622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 263722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the target supports SINT_TO_FP of this type, use it. 26383be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (TLI.isOperationLegalOrCustom(ISD::SINT_TO_FP, NewInTy)) { 26393be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman OpToUse = ISD::SINT_TO_FP; 26403be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman break; 264122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 264222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (isSigned) continue; 264322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 264422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the target supports UINT_TO_FP of this type, use it. 26453be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (TLI.isOperationLegalOrCustom(ISD::UINT_TO_FP, NewInTy)) { 26463be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman OpToUse = ISD::UINT_TO_FP; 26473be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman break; 264822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 264922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 265022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Otherwise, try a larger type. 265122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 265222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 265322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Okay, we found the operation and type to use. Zero extend our input to the 265422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // desired type then run the operation on it. 2655af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen return DAG.getNode(OpToUse, dl, DestVT, 265622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, 2657af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen dl, NewInTy, LegalOp)); 265877e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner} 265977e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner 266022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a 266122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// FP_TO_*INT operation of the specified operand when the target requests that 266222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we promote it. At this point, we know that the result and operand types are 266322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT 266422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// operation that returns a larger result. 2665475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, 2666e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT DestVT, 2667af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen bool isSigned, 2668af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 266922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // First step, figure out the appropriate FP_TO*INT operation to use. 2670e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NewOutTy = DestVT; 26719c32d3b798dc6caeebe6cea2effe80ca5e84e66eChris Lattner 267222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner unsigned OpToUse = 0; 2673e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner 267422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Scan for the appropriate larger type to use. 267522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner while (1) { 2676825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson NewOutTy = (MVT::SimpleValueType)(NewOutTy.getSimpleVT().SimpleTy+1); 267783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(NewOutTy.isInteger() && "Ran out of possibilities!"); 267866de05b606cf31f1f23ed0c4eb1f097738cd1506Chris Lattner 26793be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (TLI.isOperationLegalOrCustom(ISD::FP_TO_SINT, NewOutTy)) { 268022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner OpToUse = ISD::FP_TO_SINT; 268122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; 268222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 2683e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner 26843be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman if (TLI.isOperationLegalOrCustom(ISD::FP_TO_UINT, NewOutTy)) { 268522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner OpToUse = ISD::FP_TO_UINT; 268622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; 2687e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner } 26880d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner 268922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Otherwise, try a larger type. 2690a88a260dbd874a3bdd3e47f4f15ab0d7c7803044Chris Lattner } 2691a88a260dbd874a3bdd3e47f4f15ab0d7c7803044Chris Lattner 2692fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 269327a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // Okay, we found the operation and type to use. 2694af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Operation = DAG.getNode(OpToUse, dl, NewOutTy, LegalOp); 2695126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands 269627a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // Truncate the result of the extended FP_TO_*INT operation to the desired 269727a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // size. 2698af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen return DAG.getNode(ISD::TRUNCATE, dl, DestVT, Operation); 269922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 270013689e2009e71f7982d1313ed699e0e6a50157d0Chris Lattner 270122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. 270222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// 27038a782a2a8c2f0c82f292d03a3f707232b0bae27bDale JohannesenSDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, DebugLoc dl) { 2704e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 270595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT SHVT = TLI.getShiftAmountTy(VT); 2706475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8; 2707825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson switch (VT.getSimpleVT().SimpleTy) { 270835a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Unhandled Expand type in BSWAP!"); 2709825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i16: 27108a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 27118a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 27128a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2); 2713825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i32: 27148a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); 27158a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 27168a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 27178a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); 27188a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(0xFF0000, VT)); 27198a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(0xFF00, VT)); 27208a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); 27218a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); 27228a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); 2723825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson case MVT::i64: 27248a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(56, SHVT)); 27258a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp7 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(40, SHVT)); 27268a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); 27278a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp5 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 27288a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 27298a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); 27308a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(40, SHVT)); 27318a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(56, SHVT)); 27328a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp7 = DAG.getNode(ISD::AND, dl, VT, Tmp7, DAG.getConstant(255ULL<<48, VT)); 27338a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::AND, dl, VT, Tmp6, DAG.getConstant(255ULL<<40, VT)); 27348a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp5 = DAG.getNode(ISD::AND, dl, VT, Tmp5, DAG.getConstant(255ULL<<32, VT)); 27358a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::AND, dl, VT, Tmp4, DAG.getConstant(255ULL<<24, VT)); 27368a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(255ULL<<16, VT)); 27378a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT)); 27388a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp7); 27398a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::OR, dl, VT, Tmp6, Tmp5); 27408a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); 27418a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); 27428a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp6); 27438a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); 27448a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp4); 27450d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner } 274677e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner} 2747edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 2748b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer/// SplatByte - Distribute ByteVal over NumBits bits. 27495df5a22d1a098961edebac59fbddcab045fddd29Benjamin Kramer// FIXME: Move this helper to a common place. 2750b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramerstatic APInt SplatByte(unsigned NumBits, uint8_t ByteVal) { 2751b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer APInt Val = APInt(NumBits, ByteVal); 2752b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer unsigned Shift = 8; 2753b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer for (unsigned i = NumBits; i > 8; i >>= 1) { 2754b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Val = (Val << Shift) | Val; 2755b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Shift <<= 1; 2756b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer } 2757b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer return Val; 2758b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer} 2759b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer 276022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandBitCount - Expand the specified bitcount instruction into operations. 276122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// 2762fdc40a0a696c658d550d894ea03772e5f8af2c94Scott MichelSDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, 27638a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl) { 276422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner switch (Opc) { 276535a389344d21178ee280c2410401b2060b5b879cChris Lattner default: assert(0 && "Cannot expand this yet!"); 276622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTPOP: { 2767e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 276895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT ShVT = TLI.getShiftAmountTy(VT); 2769b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer unsigned Len = VT.getSizeInBits(); 2770b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer 27715df5a22d1a098961edebac59fbddcab045fddd29Benjamin Kramer assert(VT.isInteger() && Len <= 128 && Len % 8 == 0 && 27725df5a22d1a098961edebac59fbddcab045fddd29Benjamin Kramer "CTPOP not implemented for this type."); 27735df5a22d1a098961edebac59fbddcab045fddd29Benjamin Kramer 2774b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // This is the "best" algorithm from 2775b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel 2776b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer 2777b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer SDValue Mask55 = DAG.getConstant(SplatByte(Len, 0x55), VT); 2778b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer SDValue Mask33 = DAG.getConstant(SplatByte(Len, 0x33), VT); 2779b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer SDValue Mask0F = DAG.getConstant(SplatByte(Len, 0x0F), VT); 2780b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer SDValue Mask01 = DAG.getConstant(SplatByte(Len, 0x01), VT); 2781b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer 2782b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // v = v - ((v >> 1) & 0x55555555...) 2783b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Op = DAG.getNode(ISD::SUB, dl, VT, Op, 2784b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::AND, dl, VT, 2785b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::SRL, dl, VT, Op, 2786b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getConstant(1, ShVT)), 2787b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Mask55)); 2788b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // v = (v & 0x33333333...) + ((v >> 2) & 0x33333333...) 2789b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Op = DAG.getNode(ISD::ADD, dl, VT, 2790b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::AND, dl, VT, Op, Mask33), 2791b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::AND, dl, VT, 2792b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::SRL, dl, VT, Op, 2793b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getConstant(2, ShVT)), 2794b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Mask33)); 2795b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // v = (v + (v >> 4)) & 0x0F0F0F0F... 2796b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Op = DAG.getNode(ISD::AND, dl, VT, 2797b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::ADD, dl, VT, Op, 2798b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::SRL, dl, VT, Op, 2799b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getConstant(4, ShVT))), 2800b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Mask0F); 2801b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer // v = (v * 0x01010101...) >> (Len - 8) 2802b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer Op = DAG.getNode(ISD::SRL, dl, VT, 2803b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getNode(ISD::MUL, dl, VT, Op, Mask01), 2804b6516aeef12a05aa47515f76e18fc426d85babbdBenjamin Kramer DAG.getConstant(Len - 8, ShVT)); 280595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson 280622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner return Op; 280722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 280822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTLZ: { 280922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // for now, we do this: 281022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >> 1); 281122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >> 2); 281222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // ... 281322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >>16); 281422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >>32); // for 64-bit input 281522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // return popcount(~x); 281622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // 281722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // but see also: http://www.hackersdelight.org/HDcode/nlz.cc 2818e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 281995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT ShVT = TLI.getShiftAmountTy(VT); 282083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned len = VT.getSizeInBits(); 282122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { 2822475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); 2823fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Op = DAG.getNode(ISD::OR, dl, VT, Op, 2824e72c5964d5263f2489bf2c7e9d32f71271d205fcDale Johannesen DAG.getNode(ISD::SRL, dl, VT, Op, Tmp3)); 282522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 28268a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Op = DAG.getNOT(dl, Op, VT); 28278a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::CTPOP, dl, VT, Op); 282822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 282922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTTZ: { 283022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // for now, we use: { return popcount(~x & (x - 1)); } 283122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // unless the target has ctlz but not ctpop, in which case we use: 283222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // { return 32 - nlz(~x & (x-1)); } 283322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // see also http://www.hackersdelight.org/HDcode/ntz.cc 2834e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Op.getValueType(); 28358a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue Tmp3 = DAG.getNode(ISD::AND, dl, VT, 28368a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNOT(dl, Op, VT), 28378a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNode(ISD::SUB, dl, VT, Op, 28387581bfa2757a3149c6d17c0fe592e5c3808aa843Bill Wendling DAG.getConstant(1, VT))); 283922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If ISD::CTLZ is legal and CTPOP isn't, then do that instead. 2840f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) && 2841f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) 28428a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::SUB, dl, VT, 284383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands DAG.getConstant(VT.getSizeInBits(), VT), 28448a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNode(ISD::CTLZ, dl, VT, Tmp3)); 28458a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::CTPOP, dl, VT, Tmp3); 284622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 284722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 284822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 2849e34b396ab7d28469bf3d9679a748b643d8e30458Chris Lattner 2850e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbachstd::pair <SDValue, SDValue> SelectionDAGLegalize::ExpandAtomic(SDNode *Node) { 2851e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach unsigned Opc = Node->getOpcode(); 2852e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach MVT VT = cast<AtomicSDNode>(Node)->getMemoryVT().getSimpleVT(); 2853e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach RTLIB::Libcall LC; 2854e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2855e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (Opc) { 2856e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: 2857e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach llvm_unreachable("Unhandled atomic intrinsic Expand!"); 2858e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2859ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case ISD::ATOMIC_SWAP: 2860ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach switch (VT.SimpleTy) { 2861ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2862ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case MVT::i8: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_1; break; 2863ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case MVT::i16: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_2; break; 2864ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case MVT::i32: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_4; break; 2865ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach case MVT::i64: LC = RTLIB::SYNC_LOCK_TEST_AND_SET_8; break; 2866ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach } 2867ef6eb9c7ab7967790566c5e2d47977d89fc060eeJim Grosbach break; 2868e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_CMP_SWAP: 2869e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2870e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2871e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_1; break; 2872e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_2; break; 2873e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_4; break; 2874e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_VAL_COMPARE_AND_SWAP_8; break; 2875e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2876e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2877e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_ADD: 2878e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2879e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2880e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_ADD_1; break; 2881e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_ADD_2; break; 2882e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_ADD_4; break; 2883e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_ADD_8; break; 2884e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2885e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2886e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_SUB: 2887e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2888e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2889e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_SUB_1; break; 2890e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_SUB_2; break; 2891e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_SUB_4; break; 2892e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_SUB_8; break; 2893e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2894e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2895e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_AND: 2896e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2897e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2898e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_AND_1; break; 2899e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_AND_2; break; 2900e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_AND_4; break; 2901e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_AND_8; break; 2902e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2903e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2904e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_OR: 2905e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2906e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2907e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_OR_1; break; 2908e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_OR_2; break; 2909e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_OR_4; break; 2910e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_OR_8; break; 2911e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2912e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2913e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_XOR: 2914e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2915e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2916e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_XOR_1; break; 2917e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_XOR_2; break; 2918e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_XOR_4; break; 2919e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_XOR_8; break; 2920e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2921e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2922e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case ISD::ATOMIC_LOAD_NAND: 2923e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach switch (VT.SimpleTy) { 2924e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach default: llvm_unreachable("Unexpected value type for atomic!"); 2925e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i8: LC = RTLIB::SYNC_FETCH_AND_NAND_1; break; 2926e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i16: LC = RTLIB::SYNC_FETCH_AND_NAND_2; break; 2927e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i32: LC = RTLIB::SYNC_FETCH_AND_NAND_4; break; 2928e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach case MVT::i64: LC = RTLIB::SYNC_FETCH_AND_NAND_8; break; 2929e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2930e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach break; 2931e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach } 2932e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 2933e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach return ExpandChainLibCall(LC, Node, false); 2934e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach} 2935e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach 29368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedmanvoid SelectionDAGLegalize::ExpandNode(SDNode *Node, 29378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SmallVectorImpl<SDValue> &Results) { 29388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DebugLoc dl = Node->getDebugLoc(); 2939bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman SDValue Tmp1, Tmp2, Tmp3, Tmp4; 29408c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 29418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTPOP: 29428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTLZ: 29438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTTZ: 29448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandBitCount(Node->getOpcode(), Node->getOperand(0), dl); 29458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 29468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 29478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BSWAP: 2948775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandBSWAP(Node->getOperand(0), dl)); 29498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 29508c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAMEADDR: 29518c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::RETURNADDR: 29528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAME_TO_ARGS_OFFSET: 29538c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(0, Node->getValueType(0))); 29548c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 29558c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLT_ROUNDS_: 29568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(1, Node->getValueType(0))); 29578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 29588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_RETURN: 29598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_LABEL: 29608c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::PREFETCH: 29618c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VAEND: 2962c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach case ISD::EH_SJLJ_LONGJMP: 2963e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach case ISD::EH_SJLJ_DISPATCHSETUP: 2964e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach // If the target didn't expand these, there's nothing to do, so just 2965e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach // preserve the chain and be done. 2966c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach Results.push_back(Node->getOperand(0)); 2967c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach break; 2968c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach case ISD::EH_SJLJ_SETJMP: 2969e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach // If the target didn't expand this, just return 'zero' and preserve the 2970e4ad387a5a88dae20f0f7578e55170bbc8eee2a9Jim Grosbach // chain. 2971c66e150b2cb1f2f8e2f4eb124b9177ffc6ef3a74Jim Grosbach Results.push_back(DAG.getConstant(0, MVT::i32)); 29728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Node->getOperand(0)); 29738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 2974bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach case ISD::MEMBARRIER: { 2975bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach // If the target didn't lower this, lower it to '__sync_synchronize()' call 2976bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach TargetLowering::ArgListTy Args; 2977bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach std::pair<SDValue, SDValue> CallResult = 2978bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach TLI.LowerCallTo(Node->getOperand(0), Type::getVoidTy(*DAG.getContext()), 29793d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng false, false, false, false, 0, CallingConv::C, 29803d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng /*isTailCall=*/false, 2981bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach /*isReturnValueUsed=*/true, 2982bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach DAG.getExternalSymbol("__sync_synchronize", 2983bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach TLI.getPointerTy()), 2984bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach Args, DAG, dl); 2985bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach Results.push_back(CallResult.second); 2986bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach break; 2987bbfc0d22a9a8e197a5ea428f14d37366a1fadd5fJim Grosbach } 2988b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach // By default, atomic intrinsics are marked Legal and lowered. Targets 2989b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach // which don't support them directly, however, may want libcalls, in which 2990b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach // case they mark them Expand, and we get here. 2991b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_SWAP: 2992b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_ADD: 2993b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_SUB: 2994b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_AND: 2995b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_OR: 2996b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_XOR: 2997b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_NAND: 2998b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_MIN: 2999b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_MAX: 3000b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_UMIN: 3001b56ce8171ec52f44015d95127faaa7dd4ed92763Jim Grosbach case ISD::ATOMIC_LOAD_UMAX: 3002a845706dc1cebfe75913832e07ef114519a879d6Evan Cheng case ISD::ATOMIC_CMP_SWAP: { 3003e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach std::pair<SDValue, SDValue> Tmp = ExpandAtomic(Node); 3004e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Results.push_back(Tmp.first); 3005e03262fcfc09356a0e3ec589041bc2e0248944e9Jim Grosbach Results.push_back(Tmp.second); 300659c38f31acf87901208bbf790508196b1c0ad1fdJim Grosbach break; 3007a845706dc1cebfe75913832e07ef114519a879d6Evan Cheng } 30084bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::DYNAMIC_STACKALLOC: 30094bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman ExpandDYNAMIC_STACKALLOC(Node, Results); 30104bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 30118c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::MERGE_VALUES: 30128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0; i < Node->getNumValues(); i++) 30138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Node->getOperand(i)); 30148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 30158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UNDEF: { 3016e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 30178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (VT.isInteger()) 30188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(0, VT)); 301935a389344d21178ee280c2410401b2060b5b879cChris Lattner else { 302035a389344d21178ee280c2410401b2060b5b879cChris Lattner assert(VT.isFloatingPoint() && "Unknown value type!"); 30218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstantFP(0, VT)); 302235a389344d21178ee280c2410401b2060b5b879cChris Lattner } 30238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 30248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 30258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::TRAP: { 30268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // If this operation is not supported, lower it to 'abort()' call 30278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman TargetLowering::ArgListTy Args; 30288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman std::pair<SDValue, SDValue> CallResult = 30291d0be15f89cb5056e20e2d24faa8d6afb1573bcaOwen Anderson TLI.LowerCallTo(Node->getOperand(0), Type::getVoidTy(*DAG.getContext()), 30303d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng false, false, false, false, 0, CallingConv::C, 30313d2125c9dbac695c93f42c0f59fd040e413fd711Evan Cheng /*isTailCall=*/false, 303298ca4f2a325f72374a477f9deba7d09e8999c29bDan Gohman /*isReturnValueUsed=*/true, 30338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getExternalSymbol("abort", TLI.getPointerTy()), 303446ada19645c981a0b7932487d163f7582074a4d9Bill Wendling Args, DAG, dl); 30358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(CallResult.second); 30368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 30378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 30388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND: 3039bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck case ISD::BITCAST: 30408c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), Node->getValueType(0), 30418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 30428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 30438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 30448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_EXTEND: 30458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), 30468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0).getValueType(), 30478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 30488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 30498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 30508c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SIGN_EXTEND_INREG: { 30518c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // NOTE: we could fall back on load/store here too for targets without 30528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // SAR. However, it is doubtful that any exist. 3053e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); 305487862e77bbf90cf1b68c9eea1f3641ad81435e38Dan Gohman EVT VT = Node->getValueType(0); 305595771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson EVT ShiftAmountTy = TLI.getShiftAmountTy(VT); 3056d1996360399ad6dbe75ee185b661b16c83146373Dan Gohman if (VT.isVector()) 305787862e77bbf90cf1b68c9eea1f3641ad81435e38Dan Gohman ShiftAmountTy = VT; 3058d1996360399ad6dbe75ee185b661b16c83146373Dan Gohman unsigned BitsDiff = VT.getScalarType().getSizeInBits() - 3059d1996360399ad6dbe75ee185b661b16c83146373Dan Gohman ExtraVT.getScalarType().getSizeInBits(); 306087862e77bbf90cf1b68c9eea1f3641ad81435e38Dan Gohman SDValue ShiftCst = DAG.getConstant(BitsDiff, ShiftAmountTy); 30618c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SHL, dl, Node->getValueType(0), 30628c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), ShiftCst); 3063775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::SRA, dl, Node->getValueType(0), Tmp1, ShiftCst); 3064775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Tmp1); 30658c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 30668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 30678c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND_INREG: { 30688c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // The only way we can lower this is to turn it into a TRUNCSTORE, 30697a2bdde0a0eebcd2125055e0eacaca040f0b766cChris Lattner // EXTLOAD pair, targeting a temporary location (a stack slot). 30708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 30718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // NOTE: there is a choice here between constantly creating new stack 30728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // slots and always reusing the same one. We currently always create 30738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // new ones, as reuse may inhibit scheduling. 3074e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); 30758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), ExtraVT, 30768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 30778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 30788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 30798c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 30808c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 30818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 30828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandLegalINT_TO_FP(Node->getOpcode() == ISD::SINT_TO_FP, 30838c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), Node->getValueType(0), dl); 30848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 30858c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 30868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_UINT: { 30878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SDValue True, False; 3088e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getOperand(0).getValueType(); 3089e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NVT = Node->getValueType(0); 30903069cbf7b3ef9a31bbb8e434686b7259052c364aBenjamin Kramer APFloat apf(APInt::getNullValue(VT.getSizeInBits())); 30918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman APInt x = APInt::getSignBit(NVT.getSizeInBits()); 30928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman (void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven); 30938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getConstantFP(apf, VT); 30948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), 30958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), 30968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1, ISD::SETLT); 30978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0)); 3098775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, 3099775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DAG.getNode(ISD::FSUB, dl, VT, 3100775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(0), Tmp1)); 31018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman False = DAG.getNode(ISD::XOR, dl, NVT, False, 31028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(x, NVT)); 31038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, True, False); 31048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 31058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 31068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 3107509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::VAARG: { 3108509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 3109e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 3110509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = Node->getOperand(0); 3111509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2 = Node->getOperand(1); 311272d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola unsigned Align = Node->getConstantOperandVal(3); 311372d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola 3114ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner SDValue VAListLoad = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, 3115ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(V), false, false, 0); 311672d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola SDValue VAList = VAListLoad; 311772d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola 3118cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola if (Align > TLI.getMinStackArgumentAlignment()) { 3119cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola assert(((Align & (Align-1)) == 0) && "Expected Align to be a power of 2"); 3120cbeeae23c31d32b833c9c7c3e8984e4cbcf22f45Rafael Espindola 312172d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola VAList = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, 312272d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola DAG.getConstant(Align - 1, 312372d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola TLI.getPointerTy())); 312472d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola 312572d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola VAList = DAG.getNode(ISD::AND, dl, TLI.getPointerTy(), VAList, 312607e3a38c78d2788e05d716e7fa552b9449c87c33Chris Lattner DAG.getConstant(-(int64_t)Align, 312772d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola TLI.getPointerTy())); 312872d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola } 312972d13ff755fe8484c89468252f945ba23fe98f71Rafael Espindola 3130509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Increment the pointer, VAList, to the next vaarg 3131509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, 3132509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman DAG.getConstant(TLI.getTargetData()-> 3133adf979900c84d00e1fe0872a68d2819c654b6f29Evan Cheng getTypeAllocSize(VT.getTypeForEVT(*DAG.getContext())), 3134509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman TLI.getPointerTy())); 3135509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Store the incremented VAList to the legalized pointer 31366229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner Tmp3 = DAG.getStore(VAListLoad.getValue(1), dl, Tmp3, Tmp2, 31376229d0acb8f395552131a7015a5d1e7b2bae2111Chris Lattner MachinePointerInfo(V), false, false, 0); 3138509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Load the actual argument out of the pointer VAList 3139ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Results.push_back(DAG.getLoad(VT, dl, Tmp3, VAList, MachinePointerInfo(), 31401e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0)); 3141509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Results.push_back(Results[0].getValue(1)); 3142509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 3143509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 31448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VACOPY: { 31458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // This defaults to loading a pointer from the input and storing it to the 31468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // output, returning the chain. 31478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue(); 31488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue(); 31498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getLoad(TLI.getPointerTy(), dl, Node->getOperand(0), 3150ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Node->getOperand(2), MachinePointerInfo(VS), 3151ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner false, false, 0); 3152ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), 3153ecf42c4720aba6ee315d0166045c54187ac2de4dChris Lattner MachinePointerInfo(VD), false, false, 0); 3154775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Tmp1); 31558c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 31568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 31578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_VECTOR_ELT: 31588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOperand(0).getValueType().getVectorNumElements() == 1) 31598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // This must be an access of the only element. Return it. 3160bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp1 = DAG.getNode(ISD::BITCAST, dl, Node->getValueType(0), 31618c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0)); 31628c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman else 31638c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandExtractFromVectorThroughStack(SDValue(Node, 0)); 31648c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 31658c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 31668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_SUBVECTOR: 3167775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandExtractFromVectorThroughStack(SDValue(Node, 0))); 31688c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 3169cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene case ISD::INSERT_SUBVECTOR: 3170cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene Results.push_back(ExpandInsertToVectorThroughStack(SDValue(Node, 0))); 3171cfe33c46aa50f04adb0431243e7d25f79b719ac6David Greene break; 3172509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::CONCAT_VECTORS: { 3173775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandVectorBuildThroughStack(Node)); 3174509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 3175509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 31768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SCALAR_TO_VECTOR: 3177775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandSCALAR_TO_VECTOR(Node)); 31788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 31793f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::INSERT_VECTOR_ELT: 3180775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandINSERT_VECTOR_ELT(Node->getOperand(0), 3181775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(1), 3182775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(2), dl)); 31833f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman break; 3184509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::VECTOR_SHUFFLE: { 3185509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman SmallVector<int, 8> Mask; 3186509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman cast<ShuffleVectorSDNode>(Node)->getMask(Mask); 3187509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman 3188e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 3189e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT EltVT = VT.getVectorElementType(); 319014b2141497a913a2d5b508a0174ba09cac61e0bfBob Wilson if (getTypeAction(EltVT) == Promote) 319114b2141497a913a2d5b508a0174ba09cac61e0bfBob Wilson EltVT = TLI.getTypeToTransformTo(*DAG.getContext(), EltVT); 3192509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman unsigned NumElems = VT.getVectorNumElements(); 3193509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman SmallVector<SDValue, 8> Ops; 3194509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman for (unsigned i = 0; i != NumElems; ++i) { 3195509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman if (Mask[i] < 0) { 3196509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Ops.push_back(DAG.getUNDEF(EltVT)); 3197509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman continue; 3198509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 3199509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman unsigned Idx = Mask[i]; 3200509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman if (Idx < NumElems) 3201775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, 3202775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(0), 3203775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DAG.getIntPtrConstant(Idx))); 3204509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman else 3205775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, 3206775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(1), 3207775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling DAG.getIntPtrConstant(Idx - NumElems))); 3208509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 3209509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size()); 3210509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Results.push_back(Tmp1); 3211509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 3212509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 32138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_ELEMENT: { 3214e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OpTy = Node->getOperand(0).getValueType(); 32158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { 32168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // 1 -> Hi 32178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0), 32188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(OpTy.getSizeInBits()/2, 321995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(Node->getOperand(0).getValueType()))); 32208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1); 32218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else { 32228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // 0 -> Lo 32238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), 32248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0)); 32258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 32268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 32278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 32288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 32293f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::STACKSAVE: 32303f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // Expand to CopyFromReg if the target set 32313f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // StackPointerRegisterToSaveRestore. 32323f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) { 3233775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, SP, 3234775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getValueType(0))); 32353f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman Results.push_back(Results[0].getValue(1)); 32363f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman } else { 3237775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getUNDEF(Node->getValueType(0))); 32383f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman Results.push_back(Node->getOperand(0)); 32393f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman } 32403f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman break; 32413f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::STACKRESTORE: 3242775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // Expand to CopyToReg if the target set 3243775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // StackPointerRegisterToSaveRestore. 3244775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) { 3245775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getCopyToReg(Node->getOperand(0), dl, SP, 3246775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(1))); 3247775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } else { 3248775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Node->getOperand(0)); 3249775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } 32503f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman break; 32514bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::FCOPYSIGN: 3252775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFCOPYSIGN(Node)); 32534bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 3254f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FNEG: 3255f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman // Expand Y = FNEG(X) -> Y = SUB -0.0, X 3256f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp1 = DAG.getConstantFP(-0.0, Node->getValueType(0)); 3257f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp1 = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp1, 3258f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Node->getOperand(0)); 3259f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Results.push_back(Tmp1); 3260f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3261f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FABS: { 3262f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). 3263e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 3264f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp1 = Node->getOperand(0); 3265f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp2 = DAG.getConstantFP(0.0, VT); 3266775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), 3267f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Tmp1, Tmp2, ISD::SETUGT); 3268775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1); 3269775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3); 3270f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman Results.push_back(Tmp1); 3271f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3272f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman } 3273f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FSQRT: 3274775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::SQRT_F32, RTLIB::SQRT_F64, 3275775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128)); 3276f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3277f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FSIN: 3278775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::SIN_F32, RTLIB::SIN_F64, 3279775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::SIN_F80, RTLIB::SIN_PPCF128)); 3280f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3281f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FCOS: 3282775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::COS_F32, RTLIB::COS_F64, 3283775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::COS_F80, RTLIB::COS_PPCF128)); 3284f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3285f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FLOG: 3286775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG_F32, RTLIB::LOG_F64, 3287775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::LOG_F80, RTLIB::LOG_PPCF128)); 3288f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3289f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FLOG2: 3290775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG2_F32, RTLIB::LOG2_F64, 3291775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128)); 3292f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3293f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FLOG10: 3294775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::LOG10_F32, RTLIB::LOG10_F64, 3295775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::LOG10_F80, RTLIB::LOG10_PPCF128)); 3296f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3297f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FEXP: 3298775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP_F32, RTLIB::EXP_F64, 3299775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::EXP_F80, RTLIB::EXP_PPCF128)); 3300f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3301f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FEXP2: 3302775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::EXP2_F32, RTLIB::EXP2_F64, 3303775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128)); 3304f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3305f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FTRUNC: 3306775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, 3307775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128)); 3308f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3309f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FFLOOR: 3310775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64, 3311775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::FLOOR_F80, RTLIB::FLOOR_PPCF128)); 3312f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3313f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FCEIL: 3314775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::CEIL_F32, RTLIB::CEIL_F64, 3315775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128)); 3316f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3317f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FRINT: 3318775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::RINT_F32, RTLIB::RINT_F64, 3319775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::RINT_F80, RTLIB::RINT_PPCF128)); 3320f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3321f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FNEARBYINT: 3322775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::NEARBYINT_F32, 3323775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::NEARBYINT_F64, 3324775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::NEARBYINT_F80, 3325775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::NEARBYINT_PPCF128)); 3326f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3327f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FPOWI: 3328775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::POWI_F32, RTLIB::POWI_F64, 3329775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::POWI_F80, RTLIB::POWI_PPCF128)); 3330f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3331f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FPOW: 3332775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::POW_F32, RTLIB::POW_F64, 3333775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::POW_F80, RTLIB::POW_PPCF128)); 3334f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3335f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FDIV: 3336775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::DIV_F32, RTLIB::DIV_F64, 3337775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::DIV_F80, RTLIB::DIV_PPCF128)); 3338f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3339f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::FREM: 3340775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandFPLibCall(Node, RTLIB::REM_F32, RTLIB::REM_F64, 3341775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling RTLIB::REM_F80, RTLIB::REM_PPCF128)); 3342f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 334333390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich case ISD::FMA: 334433390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich Results.push_back(ExpandFPLibCall(Node, RTLIB::FMA_F32, RTLIB::FMA_F64, 334533390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich RTLIB::FMA_F80, RTLIB::FMA_PPCF128)); 334633390848a7eca75301d04a59b89b516d83e19ee0Cameron Zwarich break; 3347927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov case ISD::FP16_TO_FP32: 3348927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov Results.push_back(ExpandLibCall(RTLIB::FPEXT_F16_F32, Node, false)); 3349927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov break; 3350927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov case ISD::FP32_TO_FP16: 3351927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov Results.push_back(ExpandLibCall(RTLIB::FPROUND_F32_F16, Node, false)); 3352927411b7ce0b7852fe4f392d8cd4faaa3881f852Anton Korobeynikov break; 3353f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::ConstantFP: { 3354f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node); 3355775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // Check to see if this FP immediate is already legal. 3356775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // If this is a legal constant, turn it into a TargetConstantFP node. 3357a1eaa3c52b75d4fe2bcd4f7c52e56c405ee91d3cEvan Cheng if (TLI.isFPImmLegal(CFP->getValueAPF(), Node->getValueType(0))) 3358775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(SDValue(Node, 0)); 3359f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman else 3360775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(ExpandConstantFP(CFP, true, DAG, TLI)); 3361f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman break; 3362f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman } 336326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::EHSELECTION: { 336426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman unsigned Reg = TLI.getExceptionSelectorRegister(); 336526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman assert(Reg && "Can't expand to unknown register!"); 3366775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getCopyFromReg(Node->getOperand(1), dl, Reg, 3367775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getValueType(0))); 336826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Results[0].getValue(1)); 336926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 337026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 337126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::EXCEPTIONADDR: { 337226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman unsigned Reg = TLI.getExceptionAddressRegister(); 337326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman assert(Reg && "Can't expand to unknown register!"); 3374775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getCopyFromReg(Node->getOperand(0), dl, Reg, 3375775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getValueType(0))); 337626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Results[0].getValue(1)); 337726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 337826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 337926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::SUB: { 3380e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 338126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman assert(TLI.isOperationLegalOrCustom(ISD::ADD, VT) && 338226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman TLI.isOperationLegalOrCustom(ISD::XOR, VT) && 338326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman "Don't know how to expand this subtraction!"); 338426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Tmp1 = DAG.getNode(ISD::XOR, dl, VT, Node->getOperand(1), 338526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT)); 3386775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::ADD, dl, VT, Tmp2, DAG.getConstant(1, VT)); 3387775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(ISD::ADD, dl, VT, Node->getOperand(0), Tmp1)); 338826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 338926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 3390f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::UREM: 3391f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::SREM: { 3392e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 339326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman SDVTList VTs = DAG.getVTList(VT, VT); 3394f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman bool isSigned = Node->getOpcode() == ISD::SREM; 3395f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman unsigned DivOpc = isSigned ? ISD::SDIV : ISD::UDIV; 3396f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM; 3397f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp2 = Node->getOperand(0); 3398f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp3 = Node->getOperand(1); 339965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) || 340065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng (isDivRemLibcallAvailable(Node, isSigned, TLI) && 340165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng UseDivRem(Node, isSigned, false))) { 34023be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Tmp2, Tmp3).getValue(1); 34033be2e514c9e7b20135be5b9df3e9aa1cb08cb374Eli Friedman } else if (TLI.isOperationLegalOrCustom(DivOpc, VT)) { 3404f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman // X % Y -> X-X/Y*Y 3405f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(DivOpc, dl, VT, Tmp2, Tmp3); 3406f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(ISD::MUL, dl, VT, Tmp1, Tmp3); 3407f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(ISD::SUB, dl, VT, Tmp2, Tmp1); 340865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng } else if (isSigned) 340965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Tmp1 = ExpandIntLibCall(Node, true, 341065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SREM_I8, 341165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SREM_I16, RTLIB::SREM_I32, 341265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SREM_I64, RTLIB::SREM_I128); 341365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng else 341465279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Tmp1 = ExpandIntLibCall(Node, false, 341565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UREM_I8, 341665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UREM_I16, RTLIB::UREM_I32, 341765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UREM_I64, RTLIB::UREM_I128); 341826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Tmp1); 341926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 342026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 3421f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::UDIV: 3422f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::SDIV: { 3423f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman bool isSigned = Node->getOpcode() == ISD::SDIV; 3424f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman unsigned DivRemOpc = isSigned ? ISD::SDIVREM : ISD::UDIVREM; 3425e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 342626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman SDVTList VTs = DAG.getVTList(VT, VT); 342765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng if (TLI.isOperationLegalOrCustom(DivRemOpc, VT) || 342865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng (isDivRemLibcallAvailable(Node, isSigned, TLI) && 342965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng UseDivRem(Node, isSigned, true))) 3430f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(DivRemOpc, dl, VTs, Node->getOperand(0), 3431f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Node->getOperand(1)); 343265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng else if (isSigned) 343365279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Tmp1 = ExpandIntLibCall(Node, true, 343465279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SDIV_I8, 343565279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SDIV_I16, RTLIB::SDIV_I32, 343665279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::SDIV_I64, RTLIB::SDIV_I128); 343765279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng else 343865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng Tmp1 = ExpandIntLibCall(Node, false, 343965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UDIV_I8, 344065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UDIV_I16, RTLIB::UDIV_I32, 344165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng RTLIB::UDIV_I64, RTLIB::UDIV_I128); 344226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Tmp1); 344326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 344426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 344526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::MULHU: 344626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::MULHS: { 344726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman unsigned ExpandOpcode = Node->getOpcode() == ISD::MULHU ? ISD::UMUL_LOHI : 344826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman ISD::SMUL_LOHI; 3449e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 345026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman SDVTList VTs = DAG.getVTList(VT, VT); 345126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman assert(TLI.isOperationLegalOrCustom(ExpandOpcode, VT) && 345226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman "If this wasn't legal, it shouldn't have been created!"); 345326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Tmp1 = DAG.getNode(ExpandOpcode, dl, VTs, Node->getOperand(0), 345426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Node->getOperand(1)); 345526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Tmp1.getValue(1)); 345626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 345726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 345865279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case ISD::SDIVREM: 345965279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng case ISD::UDIVREM: 346065279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng // Expand into divrem libcall 346165279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng ExpandDivRemLibCall(Node, Results); 346265279cb9bd985721ac6ad090fed02298396ba06dEvan Cheng break; 346326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman case ISD::MUL: { 3464e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 346526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman SDVTList VTs = DAG.getVTList(VT, VT); 346626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // See if multiply or divide can be lowered using two-result operations. 346726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // We just need the low half of the multiply; try both the signed 346826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // and unsigned forms. If the target supports both SMUL_LOHI and 346926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // UMUL_LOHI, form a preference by checking which forms of plain 347026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman // MULH it supports. 347126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT); 347226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT); 347326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT); 347426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT); 347526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman unsigned OpToUse = 0; 347626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman if (HasSMUL_LOHI && !HasMULHS) { 347726ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman OpToUse = ISD::SMUL_LOHI; 347826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } else if (HasUMUL_LOHI && !HasMULHU) { 347926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman OpToUse = ISD::UMUL_LOHI; 348026ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } else if (HasSMUL_LOHI) { 348126ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman OpToUse = ISD::SMUL_LOHI; 348226ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } else if (HasUMUL_LOHI) { 348326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman OpToUse = ISD::UMUL_LOHI; 348426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 348526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman if (OpToUse) { 3486775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(OpToUse, dl, VTs, Node->getOperand(0), 3487775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOperand(1))); 348826ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 348926ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 34908983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov Tmp1 = ExpandIntLibCall(Node, false, 34918983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::MUL_I8, 34928983da729aa1ca99a11a3b98ae6280dfcdbadb39Anton Korobeynikov RTLIB::MUL_I16, RTLIB::MUL_I32, 349326ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman RTLIB::MUL_I64, RTLIB::MUL_I128); 349426ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman Results.push_back(Tmp1); 349526ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman break; 349626ea8f982fb58245d3735b80ce04bc8050348a19Eli Friedman } 34974bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::SADDO: 34984bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::SSUBO: { 34994bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue LHS = Node->getOperand(0); 35004bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue RHS = Node->getOperand(1); 35014bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ? 35024bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 35034bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman LHS, RHS); 35044bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Sum); 3505122d06de7482dcb39e7dbcbfe302e39cc55627e5Bill Wendling EVT OType = Node->getValueType(1); 3506775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling 35074bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Zero = DAG.getConstant(0, LHS.getValueType()); 35084bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 35094bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // LHSSign -> LHS >= 0 35104bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // RHSSign -> RHS >= 0 35114bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // SumSign -> Sum >= 0 35124bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // 35134bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Add: 35144bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign) 35154bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Sub: 35164bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign) 35174bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // 35184bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE); 35194bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE); 35204bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign, 35214bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Node->getOpcode() == ISD::SADDO ? 35224bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman ISD::SETEQ : ISD::SETNE); 35234bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 35244bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE); 35254bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE); 35264bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 35274bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE); 35284bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Cmp); 35294bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 35304bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 35314bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::UADDO: 35324bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::USUBO: { 35334bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue LHS = Node->getOperand(0); 35344bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue RHS = Node->getOperand(1); 35354bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::UADDO ? 35364bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 35374bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman LHS, RHS); 35384bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Sum); 3539775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getSetCC(dl, Node->getValueType(1), Sum, LHS, 3540775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOpcode () == ISD::UADDO ? 3541775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling ISD::SETULT : ISD::SETUGT)); 35424bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 35434bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 3544db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman case ISD::UMULO: 3545db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman case ISD::SMULO: { 3546e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 3547abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher EVT WideVT = EVT::getIntegerVT(*DAG.getContext(), VT.getSizeInBits() * 2); 3548db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman SDValue LHS = Node->getOperand(0); 3549db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman SDValue RHS = Node->getOperand(1); 3550db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman SDValue BottomHalf; 3551db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman SDValue TopHalf; 3552ec9d8b00470b2ddabef4e1b58b4f60d69995d8ceNuno Lopes static const unsigned Ops[2][3] = 3553db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman { { ISD::MULHU, ISD::UMUL_LOHI, ISD::ZERO_EXTEND }, 3554db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman { ISD::MULHS, ISD::SMUL_LOHI, ISD::SIGN_EXTEND }}; 3555db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman bool isSigned = Node->getOpcode() == ISD::SMULO; 3556db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman if (TLI.isOperationLegalOrCustom(Ops[isSigned][0], VT)) { 3557db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman BottomHalf = DAG.getNode(ISD::MUL, dl, VT, LHS, RHS); 3558db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = DAG.getNode(Ops[isSigned][0], dl, VT, LHS, RHS); 3559db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } else if (TLI.isOperationLegalOrCustom(Ops[isSigned][1], VT)) { 3560db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman BottomHalf = DAG.getNode(Ops[isSigned][1], dl, DAG.getVTList(VT, VT), LHS, 3561db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman RHS); 3562db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = BottomHalf.getValue(1); 356338a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher } else if (TLI.isTypeLegal(EVT::getIntegerVT(*DAG.getContext(), 356438a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher VT.getSizeInBits() * 2))) { 3565db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman LHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, LHS); 3566db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman RHS = DAG.getNode(Ops[isSigned][2], dl, WideVT, RHS); 3567db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman Tmp1 = DAG.getNode(ISD::MUL, dl, WideVT, LHS, RHS); 3568db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Tmp1, 3569db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman DAG.getIntPtrConstant(0)); 3570db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Tmp1, 3571db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman DAG.getIntPtrConstant(1)); 357238a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher } else { 357338a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher // We can fall back to a libcall with an illegal type for the MUL if we 357438a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher // have a libcall big enough. 357538a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher // Also, we can fall back to a division in some cases, but that's a big 357638a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher // performance hit in the general case. 357738a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 357838a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher if (WideVT == MVT::i16) 357938a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher LC = RTLIB::MUL_I16; 358038a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher else if (WideVT == MVT::i32) 358138a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher LC = RTLIB::MUL_I32; 358238a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher else if (WideVT == MVT::i64) 358338a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher LC = RTLIB::MUL_I64; 358438a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher else if (WideVT == MVT::i128) 358538a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher LC = RTLIB::MUL_I128; 358638a18261b97a0b7e0ed75b1c8edd81ec9bd01085Eric Christopher assert(LC != RTLIB::UNKNOWN_LIBCALL && "Cannot expand this operation!"); 3587f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 3588f316eb70743e88227b8919370fe38587ffe93512Dan Gohman // The high part is obtained by SRA'ing all but one of the bits of low 3589abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // part. 3590abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher unsigned LoSize = VT.getSizeInBits(); 3591abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue HiLHS = DAG.getNode(ISD::SRA, dl, VT, RHS, 3592abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher DAG.getConstant(LoSize-1, TLI.getPointerTy())); 3593abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue HiRHS = DAG.getNode(ISD::SRA, dl, VT, LHS, 3594abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher DAG.getConstant(LoSize-1, TLI.getPointerTy())); 3595abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher 3596abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // Here we're passing the 2 arguments explicitly as 4 arguments that are 3597abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // pre-lowered to the correct types. This all depends upon WideVT not 3598abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // being a legal type for the architecture and thus has to be split to 3599abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher // two arguments. 3600abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue Args[] = { LHS, HiLHS, RHS, HiRHS }; 3601abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher SDValue Ret = ExpandLibCall(LC, WideVT, Args, 4, isSigned, dl); 3602abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher BottomHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret, 3603abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher DAG.getIntPtrConstant(0)); 3604abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher TopHalf = DAG.getNode(ISD::EXTRACT_ELEMENT, dl, VT, Ret, 3605abbbfbd6726c7af8b27479b4311fe6bb6c40b52bEric Christopher DAG.getIntPtrConstant(1)); 3606db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } 3607f316eb70743e88227b8919370fe38587ffe93512Dan Gohman 3608db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman if (isSigned) { 360995771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson Tmp1 = DAG.getConstant(VT.getSizeInBits() - 1, 361095771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(BottomHalf.getValueType())); 3611db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman Tmp1 = DAG.getNode(ISD::SRA, dl, VT, BottomHalf, Tmp1); 3612db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), TopHalf, Tmp1, 3613db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman ISD::SETNE); 3614db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } else { 3615db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman TopHalf = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), TopHalf, 3616db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman DAG.getConstant(0, VT), ISD::SETNE); 3617db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } 3618db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman Results.push_back(BottomHalf); 3619db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman Results.push_back(TopHalf); 3620db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman break; 3621db3c169f3a3102d40352ba63fd14a75c819c7adcEli Friedman } 3622f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::BUILD_PAIR: { 3623e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PairTy = Node->getValueType(0); 3624f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, PairTy, Node->getOperand(0)); 3625f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp2 = DAG.getNode(ISD::ANY_EXTEND, dl, PairTy, Node->getOperand(1)); 3626775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp2 = DAG.getNode(ISD::SHL, dl, PairTy, Tmp2, 3627f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman DAG.getConstant(PairTy.getSizeInBits()/2, 362895771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson TLI.getShiftAmountTy(PairTy))); 3629775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(ISD::OR, dl, PairTy, Tmp1, Tmp2)); 3630f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman break; 3631f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman } 3632509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::SELECT: 3633509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = Node->getOperand(0); 3634509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2 = Node->getOperand(1); 3635509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp3 = Node->getOperand(2); 3636775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling if (Tmp1.getOpcode() == ISD::SETCC) { 3637509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = DAG.getSelectCC(dl, Tmp1.getOperand(0), Tmp1.getOperand(1), 3638509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2, Tmp3, 3639509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman cast<CondCodeSDNode>(Tmp1.getOperand(2))->get()); 3640775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } else { 3641509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = DAG.getSelectCC(dl, Tmp1, 3642509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman DAG.getConstant(0, Tmp1.getValueType()), 3643509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2, Tmp3, ISD::SETNE); 3644775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } 3645509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Results.push_back(Tmp1); 3646509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 36474bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman case ISD::BR_JT: { 36484bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Chain = Node->getOperand(0); 36494bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Table = Node->getOperand(1); 36504bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Index = Node->getOperand(2); 36514bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 3652e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT PTy = TLI.getPointerTy(); 3653071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner 3654071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner const TargetData &TD = *TLI.getTargetData(); 3655071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner unsigned EntrySize = 3656071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner DAG.getMachineFunction().getJumpTableInfo()->getEntrySize(TD); 36576e9926108a69efbc11f1cadf947e98500e4d4228Jim Grosbach 3658071c62fad0b25ad4131e7f984173a796c1e63f61Chris Lattner Index = DAG.getNode(ISD::MUL, dl, PTy, 36594bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Index, DAG.getConstant(EntrySize, PTy)); 36604bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); 36614bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman 366223b9b19b1a5a00faa9fce0788155c7dbfd00bfb1Owen Anderson EVT MemVT = EVT::getIntegerVT(*DAG.getContext(), EntrySize * 8); 3663a901129169194881a78b7fd8953e09f55b846d10Stuart Hastings SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr, 366485ca1066328639119f94c47a83b698c48b84ebb0Chris Lattner MachinePointerInfo::getJumpTable(), MemVT, 36651e559443a17d1b335f697551c6263ba60d5dd827David Greene false, false, 0); 36664bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Addr = LD; 366755e59c186303ff02c0be7429da3b1b36c347f164Dan Gohman if (TM.getRelocationModel() == Reloc::PIC_) { 36684bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // For PIC, the sequence is: 3669775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling // BRIND(load(Jumptable + index) + RelocBase) 36704bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman // RelocBase can be JumpTable, GOT or some sort of global base. 36714bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, 36724bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman TLI.getPICJumpTableRelocBase(Table, DAG)); 36734bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 3674825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Tmp1 = DAG.getNode(ISD::BRIND, dl, MVT::Other, LD.getValue(1), Addr); 36754bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman Results.push_back(Tmp1); 36764bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman break; 36774bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } 3678f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman case ISD::BRCOND: 3679f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman // Expand brcond's setcc into its constituent parts and create a BR_CC 3680f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman // Node. 3681f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1 = Node->getOperand(0); 3682f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp2 = Node->getOperand(1); 3683775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling if (Tmp2.getOpcode() == ISD::SETCC) { 3684825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Tmp1 = DAG.getNode(ISD::BR_CC, dl, MVT::Other, 3685f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp1, Tmp2.getOperand(2), 3686f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Tmp2.getOperand(0), Tmp2.getOperand(1), 3687f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Node->getOperand(2)); 3688775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } else { 368988882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings // We test only the i1 bit. Skip the AND if UNDEF. 369088882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings Tmp3 = (Tmp2.getOpcode() == ISD::UNDEF) ? Tmp2 : 369188882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings DAG.getNode(ISD::AND, dl, Tmp2.getValueType(), Tmp2, 369288882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings DAG.getConstant(1, Tmp2.getValueType())); 3693825b72b0571821bf2d378749f69d6c4cfb52d2f9Owen Anderson Tmp1 = DAG.getNode(ISD::BR_CC, dl, MVT::Other, Tmp1, 369488882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings DAG.getCondCode(ISD::SETNE), Tmp3, 369588882247d2e1bb70103062faf5bd15dd8a30b2d1Stuart Hastings DAG.getConstant(0, Tmp3.getValueType()), 3696f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Node->getOperand(2)); 3697775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } 3698f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman Results.push_back(Tmp1); 3699f6f20a7779c5308ccb3e4306552d749091a77a60Eli Friedman break; 3700ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman case ISD::SETCC: { 3701ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp1 = Node->getOperand(0); 3702ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp2 = Node->getOperand(1); 3703ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp3 = Node->getOperand(2); 3704775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling LegalizeSetCCCondCode(Node->getValueType(0), Tmp1, Tmp2, Tmp3, dl); 3705ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman 3706ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // If we expanded the SETCC into an AND/OR, return the new node 3707ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman if (Tmp2.getNode() == 0) { 3708ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Results.push_back(Tmp1); 3709ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 3710ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman } 3711ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman 3712ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // Otherwise, SETCC for the given comparison type must be completely 3713ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman // illegal; expand it into a SELECT_CC. 3714e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT VT = Node->getValueType(0); 3715ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, VT, Tmp1, Tmp2, 3716ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman DAG.getConstant(1, VT), DAG.getConstant(0, VT), Tmp3); 3717ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Results.push_back(Tmp1); 3718ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 3719ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman } 3720bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman case ISD::SELECT_CC: { 3721bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp1 = Node->getOperand(0); // LHS 3722bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp2 = Node->getOperand(1); // RHS 3723bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3 = Node->getOperand(2); // True 3724bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp4 = Node->getOperand(3); // False 3725bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman SDValue CC = Node->getOperand(4); 3726bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman 3727bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp1.getValueType()), 3728775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1, Tmp2, CC, dl); 3729bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman 3730bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman assert(!Tmp2.getNode() && "Can't legalize SELECT_CC with legal condition!"); 3731bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp2 = DAG.getConstant(0, Tmp1.getValueType()); 3732bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman CC = DAG.getCondCode(ISD::SETNE); 3733bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp1 = DAG.getNode(ISD::SELECT_CC, dl, Node->getValueType(0), Tmp1, Tmp2, 3734bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3, Tmp4, CC); 3735bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Results.push_back(Tmp1); 3736bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman break; 3737bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman } 3738bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman case ISD::BR_CC: { 3739bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp1 = Node->getOperand(0); // Chain 3740bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp2 = Node->getOperand(2); // LHS 3741bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3 = Node->getOperand(3); // RHS 3742bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp4 = Node->getOperand(1); // CC 3743bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman 3744bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman LegalizeSetCCCondCode(TLI.getSetCCResultType(Tmp2.getValueType()), 3745775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp2, Tmp3, Tmp4, dl); 3746567cac0c511c2361ddb76eb4b8d49d306107a921Stuart Hastings assert(LastCALLSEQ.size() == 1 && "branch inside CALLSEQ_BEGIN/END?"); 3747fc52163a45b9ea147db1c20a1db3edff0f0bf652Stuart Hastings setLastCALLSEQ(DAG.getEntryNode()); 3748bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman 3749bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman assert(!Tmp3.getNode() && "Can't legalize BR_CC with legal condition!"); 3750bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3 = DAG.getConstant(0, Tmp2.getValueType()); 3751bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp4 = DAG.getCondCode(ISD::SETNE); 3752bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp1 = DAG.getNode(ISD::BR_CC, dl, Node->getValueType(0), Tmp1, Tmp4, Tmp2, 3753bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Tmp3, Node->getOperand(4)); 3754bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman Results.push_back(Tmp1); 3755bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman break; 3756bbdd903c52897df78750aa0caf2fc34d55b5ead0Eli Friedman } 37573f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::GLOBAL_OFFSET_TABLE: 37583f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::GlobalAddress: 37593f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::GlobalTLSAddress: 37603f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::ExternalSymbol: 37613f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::ConstantPool: 37623f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::JumpTable: 37633f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::INTRINSIC_W_CHAIN: 37643f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::INTRINSIC_WO_CHAIN: 37653f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman case ISD::INTRINSIC_VOID: 37663f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman // FIXME: Custom lowering for these operations shouldn't return null! 37673f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 37683f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman Results.push_back(SDValue(Node, i)); 37693f727d6c1b68e90a3ab2d95ec2229f8b2c40b84bEli Friedman break; 37708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 37718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman} 37728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedmanvoid SelectionDAGLegalize::PromoteNode(SDNode *Node, 37738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SmallVectorImpl<SDValue> &Results) { 3774e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT OVT = Node->getValueType(0); 37758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOpcode() == ISD::UINT_TO_FP || 3776a64eb92fe305424ebde2e3de2b12160b8bf76047Eli Friedman Node->getOpcode() == ISD::SINT_TO_FP || 3777775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Node->getOpcode() == ISD::SETCC) { 37788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman OVT = Node->getOperand(0).getValueType(); 3779775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling } 3780e50ed30282bb5b4a9ed952580523f2dda16215acOwen Anderson EVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); 37818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DebugLoc dl = Node->getDebugLoc(); 3782509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman SDValue Tmp1, Tmp2, Tmp3; 37838c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 37848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTTZ: 37858c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTLZ: 37868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTPOP: 37878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Zero extend the argument. 37888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); 37898c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Perform the larger operation. 37909a4ba45f4cd0496c422f81e104adf6c03ebdd3baJakob Stoklund Olesen Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1); 37918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOpcode() == ISD::CTTZ) { 37928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) 37939a4ba45f4cd0496c422f81e104adf6c03ebdd3baJakob Stoklund Olesen Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(NVT), 37948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT), 37958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ISD::SETEQ); 37968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, 37978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(OVT.getSizeInBits(), NVT), Tmp1); 37988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else if (Node->getOpcode() == ISD::CTLZ) { 37998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT)) 38008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SUB, dl, NVT, Tmp1, 38018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(NVT.getSizeInBits() - 38028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman OVT.getSizeInBits(), NVT)); 38038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 3804775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(ISD::TRUNCATE, dl, OVT, Tmp1)); 38058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 38068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BSWAP: { 38078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); 3808167bea71a4bd19329a218f5e1bd8facfd90a0cf9Bill Wendling Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); 3809775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1); 3810775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, 381195771afbfd604ad003fa3723cac66c9370fed55dOwen Anderson DAG.getConstant(DiffBits, TLI.getShiftAmountTy(NVT))); 3812775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Tmp1); 38138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 38148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 38158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_UINT: 38168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_SINT: 38178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = PromoteLegalFP_TO_INT(Node->getOperand(0), Node->getValueType(0), 38188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOpcode() == ISD::FP_TO_SINT, dl); 38198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 38208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 38218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 38228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 38238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = PromoteLegalINT_TO_FP(Node->getOperand(0), Node->getValueType(0), 38248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOpcode() == ISD::SINT_TO_FP, dl); 38258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 38268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 3827f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::AND: 3828f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman case ISD::OR: 3829c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen case ISD::XOR: { 3830c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen unsigned ExtOp, TruncOp; 3831c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen if (OVT.isVector()) { 3832bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck ExtOp = ISD::BITCAST; 3833bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck TruncOp = ISD::BITCAST; 383435a389344d21178ee280c2410401b2060b5b879cChris Lattner } else { 383535a389344d21178ee280c2410401b2060b5b879cChris Lattner assert(OVT.isInteger() && "Cannot promote logic operation"); 3836c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen ExtOp = ISD::ANY_EXTEND; 3837c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen TruncOp = ISD::TRUNCATE; 3838c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen } 3839c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen // Promote each of the values to the new type. 3840c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(0)); 3841c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3842c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen // Perform the larger operation, then convert back 3843775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); 3844775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(DAG.getNode(TruncOp, dl, OVT, Tmp1)); 3845f6b23bfc79cf9f605a2e74942c90799ff4f1a17eEli Friedman break; 3846c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen } 3847c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen case ISD::SELECT: { 3848509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman unsigned ExtOp, TruncOp; 38494bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman if (Node->getValueType(0).isVector()) { 3850bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck ExtOp = ISD::BITCAST; 3851bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck TruncOp = ISD::BITCAST; 38524bc8c718218159fe410462f6e3670e7cb76c0c04Eli Friedman } else if (Node->getValueType(0).isInteger()) { 3853509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman ExtOp = ISD::ANY_EXTEND; 3854509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman TruncOp = ISD::TRUNCATE; 3855509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } else { 3856509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman ExtOp = ISD::FP_EXTEND; 3857509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman TruncOp = ISD::FP_ROUND; 3858509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 3859509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = Node->getOperand(0); 3860509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Promote each of the values to the new type. 3861509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3862509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp3 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(2)); 3863509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Perform the larger operation, then round down. 3864509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp1, Tmp2, Tmp3); 3865509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman if (TruncOp != ISD::FP_ROUND) 3866775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(TruncOp, dl, Node->getValueType(0), Tmp1); 3867509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman else 3868775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = DAG.getNode(TruncOp, dl, Node->getValueType(0), Tmp1, 3869509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman DAG.getIntPtrConstant(0)); 3870775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Results.push_back(Tmp1); 3871509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 3872c8ca3ae27b64fa785f944799a9bc133fac8f90d9Jakob Stoklund Olesen } 3873509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman case ISD::VECTOR_SHUFFLE: { 3874509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman SmallVector<int, 8> Mask; 3875509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman cast<ShuffleVectorSDNode>(Node)->getMask(Mask); 3876509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman 3877509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Cast the two input vectors. 3878bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp1 = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(0)); 3879bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp2 = DAG.getNode(ISD::BITCAST, dl, NVT, Node->getOperand(1)); 3880509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman 3881509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman // Convert the shuffle mask to the right # elements. 3882775db97a50fb56fece6fbd68e1a6f86418e8063aBill Wendling Tmp1 = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask); 3883bf17cfa3f904e488e898ac2e3af706fd1a892f08Wesley Peck Tmp1 = DAG.getNode(ISD::BITCAST, dl, OVT, Tmp1); 3884509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman Results.push_back(Tmp1); 3885509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman break; 3886509150f973ae650a57b79010a3ec36e60e40f41dEli Friedman } 3887ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman case ISD::SETCC: { 388878d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen unsigned ExtOp = ISD::FP_EXTEND; 388978d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen if (NVT.isInteger()) { 389078d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen ISD::CondCode CCCode = 389178d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen cast<CondCodeSDNode>(Node->getOperand(2))->get(); 389278d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen ExtOp = isSignedIntSetCC(CCCode) ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND; 3893ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman } 389478d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen Tmp1 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(0)); 389578d12644b905dc54cf6cf984af02a49d30d29744Jakob Stoklund Olesen Tmp2 = DAG.getNode(ExtOp, dl, NVT, Node->getOperand(1)); 3896ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Results.push_back(DAG.getNode(ISD::SETCC, dl, Node->getValueType(0), 3897ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman Tmp1, Tmp2, Node->getOperand(2))); 3898ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman break; 3899ad75460e30aab135057355fa0712141bf2cb08fcEli Friedman } 39008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 39018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman} 39028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 39033e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// SelectionDAG::Legalize - This is the entry point for the file. 39043e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// 3905975716af1b9a09274df6c2d92683449015bd8564Dan Gohmanvoid SelectionDAG::Legalize() { 39063e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// run - This is the main entry point to this class. 39073e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// 3908975716af1b9a09274df6c2d92683449015bd8564Dan Gohman SelectionDAGLegalize(*this).LegalizeDAG(); 39093e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 3910