LegalizeDAG.cpp revision 8c377c7296d8a8104231442c3f6c27296249ec5f
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 143e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner#include "llvm/CodeGen/SelectionDAG.h" 153e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner#include "llvm/CodeGen/MachineFunction.h" 1645b8caf1c5a1fd8337038d64c6da8fba2d299fdfChris Lattner#include "llvm/CodeGen/MachineFrameInfo.h" 17acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey#include "llvm/CodeGen/MachineJumpTableInfo.h" 1884bc5427d6883f73cfeae3da640acd011d35c006Chris Lattner#include "llvm/CodeGen/MachineModuleInfo.h" 1983489bb7700c69b7a4a8da59365c42d3f5c8129bDevang Patel#include "llvm/CodeGen/DwarfWriter.h" 2083489bb7700c69b7a4a8da59365c42d3f5c8129bDevang Patel#include "llvm/Analysis/DebugInfo.h" 2169de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman#include "llvm/CodeGen/PseudoSourceValue.h" 2261bbbabe3da27479cc9a3a36e49091a1141ba7a3Evan Cheng#include "llvm/Target/TargetFrameInfo.h" 233e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner#include "llvm/Target/TargetLowering.h" 24e1bd822ddb0099406d9f280535461033dfeeb190Chris Lattner#include "llvm/Target/TargetData.h" 253d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng#include "llvm/Target/TargetMachine.h" 260f69b2910810b7c0971a739f18b37fae2a20eca5Chris Lattner#include "llvm/Target/TargetOptions.h" 27707e0184233f27e0e9f9aee0309f2daab8cfe7f8Dan Gohman#include "llvm/Target/TargetSubtarget.h" 28adf6a965a321372c640845407195594835921eb4Chris Lattner#include "llvm/CallingConv.h" 293e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner#include "llvm/Constants.h" 30c10305743c313558405079452138f03124e87581Reid Spencer#include "llvm/DerivedTypes.h" 3186e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling#include "llvm/Function.h" 3283489bb7700c69b7a4a8da59365c42d3f5c8129bDevang Patel#include "llvm/GlobalVariable.h" 335e46a19ec848cd4fc9649bd5170c43d9e657668cChris Lattner#include "llvm/Support/CommandLine.h" 34a4f0b3a084d120cfc5b5bb06f64b222f5cb72740Chris Lattner#include "llvm/Support/Compiler.h" 35dc84650679b6330e0fcdd4cf8bc2a351387db7caDuncan Sands#include "llvm/Support/MathExtras.h" 367971514755a08ec156a1b9c0f7f05d67919c56b7Chris Lattner#include "llvm/ADT/DenseMap.h" 37f06f35e30b4c4d7db304f717a3d4dc6595fbd078Chris Lattner#include "llvm/ADT/SmallVector.h" 3800755df36c1448ac4728a74d907aa09e3d8b2d49Chris Lattner#include "llvm/ADT/SmallPtrSet.h" 39033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng#include <map> 403e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnerusing namespace llvm; 413e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 423e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner//===----------------------------------------------------------------------===// 433e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// SelectionDAGLegalize - This takes an arbitrary SelectionDAG as input and 443e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// hacks on it until the target machine can handle it. This involves 453e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// eliminating value sizes the machine cannot handle (promoting small sizes to 463e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// large sizes or splitting up large values into small values) as well as 473e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// eliminating operations the machine cannot handle. 483e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// 493e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// This code also does a small amount of optimization and recognition of idioms 503e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// as part of its processing. For example, if a target does not support a 513e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// 'setcc' instruction efficiently, but does support 'brcc' instruction, this 523e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// will attempt merge setcc and brc instructions into brcc's. 533e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner/// 543e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnernamespace { 55360e8200ec544a3c877ff74b48f445140ac9bbd6Chris Lattnerclass VISIBILITY_HIDDEN SelectionDAGLegalize { 563e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner TargetLowering &TLI; 573e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner SelectionDAG &DAG; 5898a366d547772010e94609e4584489b3e5ce0043Bill Wendling CodeGenOpt::Level OptLevel; 593e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 606831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Libcall insertion helpers. 61fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 626831a815999dde4cf801e2076e66b4943964daf2Chris Lattner /// LastCALLSEQ_END - This keeps track of the CALLSEQ_END node that has been 636831a815999dde4cf801e2076e66b4943964daf2Chris Lattner /// legalized. We use this to ensure that calls are properly serialized 646831a815999dde4cf801e2076e66b4943964daf2Chris Lattner /// against each other, including inserted libcalls. 65475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LastCALLSEQ_END; 66fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 676831a815999dde4cf801e2076e66b4943964daf2Chris Lattner /// IsLegalizingCall - This member is used *only* for purposes of providing 68fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel /// helpful assertions that a libcall isn't created while another call is 696831a815999dde4cf801e2076e66b4943964daf2Chris Lattner /// being legalized (which could lead to non-serialized call sequences). 706831a815999dde4cf801e2076e66b4943964daf2Chris Lattner bool IsLegalizingCall; 71fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 723e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner enum LegalizeAction { 7368a17febc70d9beb5353454e0c6d136ca1e87605Chris Lattner Legal, // The target natively supports this operation. 7468a17febc70d9beb5353454e0c6d136ca1e87605Chris Lattner Promote, // This operation should be executed in a larger type. 75d74ea2bbd8bb630331f35ead42d385249bd42af8Chris Lattner Expand // Try to expand this to other ops, otherwise use a libcall. 763e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner }; 77fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 783e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// ValueTypeActions - This is a bitvector that contains two bits for each 793e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// value type, where the two bits correspond to the LegalizeAction enum. 803e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// This can be queried with "getTypeAction(VT)". 8168a17febc70d9beb5353454e0c6d136ca1e87605Chris Lattner TargetLowering::ValueTypeActionImpl ValueTypeActions; 823e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 833e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// LegalizedNodes - For nodes that are of legal width, and that have more 843e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// than one use, this map indicates what regularized operand to use. This 853e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// allows us to avoid legalizing the same thing more than once. 86475871a144eb604ddaf37503397ba0941442e5fbDan Gohman DenseMap<SDValue, SDValue> LegalizedNodes; 873e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 88475871a144eb604ddaf37503397ba0941442e5fbDan Gohman void AddLegalizedOperand(SDValue From, SDValue To) { 8969a889eb35d59a10e78a07cc26d41cbab31eddceChris Lattner LegalizedNodes.insert(std::make_pair(From, To)); 9069a889eb35d59a10e78a07cc26d41cbab31eddceChris Lattner // If someone requests legalization of the new node, return itself. 9169a889eb35d59a10e78a07cc26d41cbab31eddceChris Lattner if (From != To) 9269a889eb35d59a10e78a07cc26d41cbab31eddceChris Lattner LegalizedNodes.insert(std::make_pair(To, To)); 938afc48e44ad8868c1d41511db645e2ba1a4b894eChris Lattner } 948afc48e44ad8868c1d41511db645e2ba1a4b894eChris Lattner 953e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnerpublic: 961fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman SelectionDAGLegalize(SelectionDAG &DAG, CodeGenOpt::Level ol); 973e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 983e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// getTypeAction - Return how we should legalize values of this type, either 993e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// it is already legal or we need to expand it into multiple registers of 1003e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// smaller integer type, or we need to promote it to a larger type. 10183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands LegalizeAction getTypeAction(MVT VT) const { 10268a17febc70d9beb5353454e0c6d136ca1e87605Chris Lattner return (LegalizeAction)ValueTypeActions.getTypeAction(VT); 1033e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 1043e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 1053e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// isTypeLegal - Return true if this type is legal on this target. 1063e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// 10783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands bool isTypeLegal(MVT VT) const { 1083e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner return getTypeAction(VT) == Legal; 1093e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 1103e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 1113e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner void LegalizeDAG(); 1123e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 113456a93afcec7740c45cafa8354317f7b17987a6dChris Lattnerprivate: 1147f32156bb9c017b71971c52fac892fa7b9b06dd2Dan Gohman /// HandleOp - Legalize, Promote, or Expand the specified operand as 115c7029805ef35ce9805931067b841e6af11db382eChris Lattner /// appropriate for its type. 116475871a144eb604ddaf37503397ba0941442e5fbDan Gohman void HandleOp(SDValue Op); 117fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 118c7029805ef35ce9805931067b841e6af11db382eChris Lattner /// LegalizeOp - We know that the specified value has a legal type. 119c7029805ef35ce9805931067b841e6af11db382eChris Lattner /// Recursively ensure that the operands have legal types, then return the 120c7029805ef35ce9805931067b841e6af11db382eChris Lattner /// result. 121475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue LegalizeOp(SDValue O); 122fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1236867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// PerformInsertVectorEltInMemory - Some target cannot handle a variable 1246867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it 1256867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// is necessary to spill the vector being inserted into to memory, perform 1266867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman /// the insert there, and then read the result back. 127475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue PerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, 128bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Idx, DebugLoc dl); 129826695281344e3a4c4d44d73dd155107aafd689bDan Gohman 130f007a8b931e229eb325319c97363be8507311e2eMon P Wang /// Useful 16 element vector type that is used to pass operands for widening. 131fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel typedef SmallVector<SDValue, 16> SDValueVector; 132fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1335a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// ShuffleWithNarrowerEltType - Return a vector shuffle operation which 1345a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// performs the same shuffe in terms of order or result bytes, but on a type 1355a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// whose vector element type is narrower than the original shuffle type. 1365a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman /// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3> 1375a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman SDValue ShuffleWithNarrowerEltType(MVT NVT, MVT VT, DebugLoc dl, 1385a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman SDValue N1, SDValue N2, 1395a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman SmallVectorImpl<int> &Mask) const; 140fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 141c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner bool LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest, 14200755df36c1448ac4728a74d907aa09e3d8b2d49Chris Lattner SmallPtrSet<SDNode*, 32> &NodesLeadingTo); 1436831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 144bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen void LegalizeSetCCOperands(SDValue &LHS, SDValue &RHS, SDValue &CC, 145bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl); 146bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen void LegalizeSetCCCondCode(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, 147bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl); 148bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen void LegalizeSetCC(MVT VT, SDValue &LHS, SDValue &RHS, SDValue &CC, 149bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl) { 150bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen LegalizeSetCCOperands(LHS, RHS, CC, dl); 151bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen LegalizeSetCCCondCode(VT, LHS, RHS, CC, dl); 1527f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 153fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 154475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, bool isSigned, 155475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &Hi); 156475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 1578a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue EmitStackConvert(SDValue SrcOp, MVT SlotVT, MVT DestVT, DebugLoc dl); 158475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ExpandBUILD_VECTOR(SDNode *Node); 159475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ExpandSCALAR_TO_VECTOR(SDNode *Node); 160af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue ExpandLegalINT_TO_FP(bool isSigned, SDValue LegalOp, MVT DestVT, 161af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 162af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue PromoteLegalINT_TO_FP(SDValue LegalOp, MVT DestVT, bool isSigned, 163af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 164af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue PromoteLegalFP_TO_INT(SDValue LegalOp, MVT DestVT, bool isSigned, 165af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl); 166475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 1678a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue ExpandBSWAP(SDValue Op, DebugLoc dl); 1688a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue ExpandBitCount(unsigned Opc, SDValue Op, DebugLoc dl); 169475871a144eb604ddaf37503397ba0941442e5fbDan Gohman 1703d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue ExpandExtractFromVectorThroughStack(SDValue Op); 1718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 1728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman void ExpandNode(SDNode *Node, SmallVectorImpl<SDValue> &Results); 1738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman void PromoteNode(SDNode *Node, SmallVectorImpl<SDValue> &Results); 1743e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner}; 1753e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 1763e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 1775a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// ShuffleWithNarrowerEltType - Return a vector shuffle operation which 1785a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// performs the same shuffe in terms of order or result bytes, but on a type 1795a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman/// whose vector element type is narrower than the original shuffle type. 1809008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman/// e.g. <v4i32> <0, 1, 0, 1> -> v8i16 <0, 1, 2, 3, 0, 1, 2, 3> 1815a5ca1519e04310f585197c20e7ae584b7f2d11fNate BegemanSDValue 1825a5ca1519e04310f585197c20e7ae584b7f2d11fNate BegemanSelectionDAGLegalize::ShuffleWithNarrowerEltType(MVT NVT, MVT VT, DebugLoc dl, 1835a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman SDValue N1, SDValue N2, 1849008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVectorImpl<int> &Mask) const { 1859008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman MVT EltVT = NVT.getVectorElementType(); 1865a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman unsigned NumMaskElts = VT.getVectorNumElements(); 1875a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman unsigned NumDestElts = NVT.getVectorNumElements(); 1889008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman unsigned NumEltsGrowth = NumDestElts / NumMaskElts; 1899008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 1909008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman assert(NumEltsGrowth && "Cannot promote to vector type with fewer elts!"); 1919008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 1929008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman if (NumEltsGrowth == 1) 1939008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman return DAG.getVectorShuffle(NVT, dl, N1, N2, &Mask[0]); 1949008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 1959008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVector<int, 8> NewMask; 1965a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman for (unsigned i = 0; i != NumMaskElts; ++i) { 1979008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman int Idx = Mask[i]; 1989008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman for (unsigned j = 0; j != NumEltsGrowth; ++j) { 1999008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman if (Idx < 0) 2009008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman NewMask.push_back(-1); 2019008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman else 2029008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman NewMask.push_back(Idx * NumEltsGrowth + j); 2034352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner } 20415684b29552393553524171bff1913e750f390f8Rafael Espindola } 2055a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman assert(NewMask.size() == NumDestElts && "Non-integer NumEltsGrowth?"); 2069008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman assert(TLI.isShuffleMaskLegal(NewMask, NVT) && "Shuffle not legal?"); 2079008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman return DAG.getVectorShuffle(NVT, dl, N1, N2, &NewMask[0]); 2084352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner} 2094352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 2105aa4977fba97e816b5735f0bc53f16a46b24de63Bill WendlingSelectionDAGLegalize::SelectionDAGLegalize(SelectionDAG &dag, 2111fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman CodeGenOpt::Level ol) 212be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2bBill Wendling : TLI(dag.getTargetLoweringInfo()), DAG(dag), OptLevel(ol), 2131fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman ValueTypeActions(TLI.getValueTypeActions()) { 2146a648614e88586e85a36ceb5c1d3b84e4f55b458Nate Begeman assert(MVT::LAST_VALUETYPE <= 32 && 2153e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner "Too many value types for ValueTypeActions to hold!"); 2163e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 2173e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 2183e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattnervoid SelectionDAGLegalize::LegalizeDAG() { 2196831a815999dde4cf801e2076e66b4943964daf2Chris Lattner LastCALLSEQ_END = DAG.getEntryNode(); 2206831a815999dde4cf801e2076e66b4943964daf2Chris Lattner IsLegalizingCall = false; 221e5ab34e05d701da042619bf540046efc3c7bc41fMon P Wang 222ab510a76d6fed412f2dbbb29b3e123eef34f9c0aChris Lattner // The legalize process is inherently a bottom-up recursive process (users 223ab510a76d6fed412f2dbbb29b3e123eef34f9c0aChris Lattner // legalize their uses before themselves). Given infinite stack space, we 224ab510a76d6fed412f2dbbb29b3e123eef34f9c0aChris Lattner // could just start legalizing on the root and traverse the whole graph. In 225ab510a76d6fed412f2dbbb29b3e123eef34f9c0aChris Lattner // practice however, this causes us to run out of stack space on large basic 22632fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner // blocks. To avoid this problem, compute an ordering of the nodes where each 22732fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner // node is only legalized after all of its operands are legalized. 228f06c835f769aa1cf67801ed1f6bd366a447c18b1Dan Gohman DAG.AssignTopologicalOrder(); 229f06c835f769aa1cf67801ed1f6bd366a447c18b1Dan Gohman for (SelectionDAG::allnodes_iterator I = DAG.allnodes_begin(), 230f06c835f769aa1cf67801ed1f6bd366a447c18b1Dan Gohman E = prior(DAG.allnodes_end()); I != next(E); ++I) 231f06c835f769aa1cf67801ed1f6bd366a447c18b1Dan Gohman HandleOp(SDValue(I, 0)); 23232fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner 23332fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner // Finally, it's possible the root changed. Get the new root. 234475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue OldRoot = DAG.getRoot(); 23532fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner assert(LegalizedNodes.count(OldRoot) && "Root didn't get legalized?"); 23632fca00a23a9872c31999d054b4dd7c724276d9dChris Lattner DAG.setRoot(LegalizedNodes[OldRoot]); 2373e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 2383e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner LegalizedNodes.clear(); 2393e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 2403e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner // Remove dead nodes now. 241190a418bf6b49a4ef1c1980229a2f0d516e8a2cdChris Lattner DAG.RemoveDeadNodes(); 2423e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 2433e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 2446831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 2456831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// FindCallEndFromCallStart - Given a chained node that is part of a call 2466831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// sequence, find the CALLSEQ_END node that terminates the call sequence. 2476831a815999dde4cf801e2076e66b4943964daf2Chris Lattnerstatic SDNode *FindCallEndFromCallStart(SDNode *Node) { 2486831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (Node->getOpcode() == ISD::CALLSEQ_END) 2496831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return Node; 2506831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (Node->use_empty()) 2516831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return 0; // No CallSeqEnd 252fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2536831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // The chain is usually at the end. 254475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue TheChain(Node, Node->getNumValues()-1); 2556831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (TheChain.getValueType() != MVT::Other) { 2566831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Sometimes it's at the beginning. 257475871a144eb604ddaf37503397ba0941442e5fbDan Gohman TheChain = SDValue(Node, 0); 2586831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (TheChain.getValueType() != MVT::Other) { 2596831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Otherwise, hunt for it. 2606831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (unsigned i = 1, e = Node->getNumValues(); i != e; ++i) 2616831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (Node->getValueType(i) == MVT::Other) { 262475871a144eb604ddaf37503397ba0941442e5fbDan Gohman TheChain = SDValue(Node, i); 2636831a815999dde4cf801e2076e66b4943964daf2Chris Lattner break; 2646831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 265fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 266fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Otherwise, we walked into a node without a chain. 2676831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (TheChain.getValueType() != MVT::Other) 2686831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return 0; 2696831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 2706831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 271fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2726831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (SDNode::use_iterator UI = Node->use_begin(), 2736831a815999dde4cf801e2076e66b4943964daf2Chris Lattner E = Node->use_end(); UI != E; ++UI) { 274fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2756831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Make sure to only follow users of our token chain. 2768968450305c28444edc3c272d8752a8db0c2f34aDan Gohman SDNode *User = *UI; 2776831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (unsigned i = 0, e = User->getNumOperands(); i != e; ++i) 2786831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (User->getOperand(i) == TheChain) 2796831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (SDNode *Result = FindCallEndFromCallStart(User)) 2806831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return Result; 2816831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 2826831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return 0; 2836831a815999dde4cf801e2076e66b4943964daf2Chris Lattner} 2846831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 285fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel/// FindCallStartFromCallEnd - Given a chained node that is part of a call 2866831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// sequence, find the CALLSEQ_START node that initiates the call sequence. 2876831a815999dde4cf801e2076e66b4943964daf2Chris Lattnerstatic SDNode *FindCallStartFromCallEnd(SDNode *Node) { 2886831a815999dde4cf801e2076e66b4943964daf2Chris Lattner assert(Node && "Didn't find callseq_start for a call??"); 2896831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (Node->getOpcode() == ISD::CALLSEQ_START) return Node; 290fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2916831a815999dde4cf801e2076e66b4943964daf2Chris Lattner assert(Node->getOperand(0).getValueType() == MVT::Other && 2926831a815999dde4cf801e2076e66b4943964daf2Chris Lattner "Node doesn't have a token chain argument!"); 293ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif return FindCallStartFromCallEnd(Node->getOperand(0).getNode()); 2946831a815999dde4cf801e2076e66b4943964daf2Chris Lattner} 2956831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 2966831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// LegalizeAllNodesNotLeadingTo - Recursively walk the uses of N, looking to 297fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel/// see if any uses can reach Dest. If no dest operands can get to dest, 2986831a815999dde4cf801e2076e66b4943964daf2Chris Lattner/// legalize them, legalize ourself, and return false, otherwise, return true. 299c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner/// 300c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner/// Keep track of the nodes we fine that actually do lead to Dest in 301c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner/// NodesLeadingTo. This avoids retraversing them exponential number of times. 302c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner/// 303c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattnerbool SelectionDAGLegalize::LegalizeAllNodesNotLeadingTo(SDNode *N, SDNode *Dest, 30400755df36c1448ac4728a74d907aa09e3d8b2d49Chris Lattner SmallPtrSet<SDNode*, 32> &NodesLeadingTo) { 3056831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (N == Dest) return true; // N certainly leads to Dest :) 306fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 307c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner // If we've already processed this node and it does lead to Dest, there is no 308c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner // need to reprocess it. 309c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner if (NodesLeadingTo.count(N)) return true; 310fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3116831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // If the first result of this node has been already legalized, then it cannot 3126831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // reach N. 31374807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman if (LegalizedNodes.count(SDValue(N, 0))) return false; 314fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3156831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Okay, this node has not already been legalized. Check and legalize all 3166831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // operands. If none lead to Dest, then we can legalize this node. 3176831a815999dde4cf801e2076e66b4943964daf2Chris Lattner bool OperandsLeadToDest = false; 3186831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (unsigned i = 0, e = N->getNumOperands(); i != e; ++i) 3196831a815999dde4cf801e2076e66b4943964daf2Chris Lattner OperandsLeadToDest |= // If an operand leads to Dest, so do we. 320ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif LegalizeAllNodesNotLeadingTo(N->getOperand(i).getNode(), Dest, NodesLeadingTo); 3216831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 322c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner if (OperandsLeadToDest) { 323c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner NodesLeadingTo.insert(N); 324c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner return true; 325c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner } 3266831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 3276831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Okay, this node looks safe, legalize it and return false. 328475871a144eb604ddaf37503397ba0941442e5fbDan Gohman HandleOp(SDValue(N, 0)); 3296831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return false; 3306831a815999dde4cf801e2076e66b4943964daf2Chris Lattner} 3316831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 3320c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang/// HandleOp - Legalize, Promote, Widen, or Expand the specified operand as 333c7029805ef35ce9805931067b841e6af11db382eChris Lattner/// appropriate for its type. 334475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid SelectionDAGLegalize::HandleOp(SDValue Op) { 3351fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman // Don't touch TargetConstants 3361fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman if (Op.getOpcode() == ISD::TargetConstant) 3371fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman return; 33883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Op.getValueType(); 3391fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman // We should never see any illegal result types here. 3401fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman assert(isTypeLegal(VT) && "Illegal type introduced after type legalization?"); 34174807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman (void)LegalizeOp(Op); 342c7029805ef35ce9805931067b841e6af11db382eChris Lattner} 3436831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 3449f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng/// ExpandConstantFP - Expands the ConstantFP node to an integer constant or 3459f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng/// a load from the constant pool. 346475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanstatic SDValue ExpandConstantFP(ConstantFPSDNode *CFP, bool UseCP, 3470d137d7f35fba98f668098b3badf644efacf0e08Dan Gohman SelectionDAG &DAG, const TargetLowering &TLI) { 348004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng bool Extend = false; 34933c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen DebugLoc dl = CFP->getDebugLoc(); 350004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 351004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // If a FP immediate is precise when represented as a float and if the 352004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // target can do an extending load from float to double, we put it into 353004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng // the constant pool as a float, even if it's is statically typed as a 354aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // double. This shrinks FP constants and canonicalizes them for targets where 355aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // an FP extending load is the same cost as a normal load (such as on the x87 356aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner // fp stack or PPC FP unit). 35783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = CFP->getValueType(0); 3584fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman ConstantFP *LLVMC = const_cast<ConstantFP*>(CFP->getConstantFPValue()); 3599f87788040786b1bc6530763e4cf7e105bfb2924Evan Cheng if (!UseCP) { 360d2e936a513b01b2c5df91a9c0d80070e8c752aceChris Lattner assert((VT == MVT::f64 || VT == MVT::f32) && "Invalid type expansion"); 3617111b02c734c992b8c97d9918118768026dad79eDale Johannesen return DAG.getConstant(LLVMC->getValueAPF().bitcastToAPInt(), 362ef12057737229452c17983faa20857dba441ef05Evan Cheng (VT == MVT::f64) ? MVT::i64 : MVT::i32); 363279101eb1ac61e2d5b83d5bdcc5be56e710d2cd7Evan Cheng } 364279101eb1ac61e2d5b83d5bdcc5be56e710d2cd7Evan Cheng 36583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OrigVT = VT; 36683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT SVT = VT; 367ef12057737229452c17983faa20857dba441ef05Evan Cheng while (SVT != MVT::f32) { 36883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands SVT = (MVT::SimpleValueType)(SVT.getSimpleVT() - 1); 369ef12057737229452c17983faa20857dba441ef05Evan Cheng if (CFP->isValueValidForType(SVT, CFP->getValueAPF()) && 370ef12057737229452c17983faa20857dba441ef05Evan Cheng // Only do this if the target has a native EXTLOAD instruction from 371ef12057737229452c17983faa20857dba441ef05Evan Cheng // smaller type. 3720329466b6b4927f4e6f5d144891fef06a027fec5Evan Cheng TLI.isLoadExtLegal(ISD::EXTLOAD, SVT) && 373aa2acbbbf06348f20274f4eeb77f9761c654a589Chris Lattner TLI.ShouldShrinkFPConstant(OrigVT)) { 37483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands const Type *SType = SVT.getTypeForMVT(); 375ef12057737229452c17983faa20857dba441ef05Evan Cheng LLVMC = cast<ConstantFP>(ConstantExpr::getFPTrunc(LLVMC, SType)); 376ef12057737229452c17983faa20857dba441ef05Evan Cheng VT = SVT; 377ef12057737229452c17983faa20857dba441ef05Evan Cheng Extend = true; 378ef12057737229452c17983faa20857dba441ef05Evan Cheng } 379004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng } 380004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 381475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CPIdx = DAG.getConstantPool(LLVMC, TLI.getPointerTy()); 3821606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 383ef12057737229452c17983faa20857dba441ef05Evan Cheng if (Extend) 38433c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen return DAG.getExtLoad(ISD::EXTLOAD, dl, 38539355f9fea790c5a1b12ef0fdcfeac3f533232eaDale Johannesen OrigVT, DAG.getEntryNode(), 3863069b8743769527ce7af6cfb6591a2f0fc2faee4Dan Gohman CPIdx, PseudoSourceValue::getConstantPool(), 38750284d81f863a6576582e1a171a22eb0f012ddf3Dan Gohman 0, VT, false, Alignment); 38833c960f523f2308482d5b2816af46a7ec90a6d3dDale Johannesen return DAG.getLoad(OrigVT, dl, DAG.getEntryNode(), CPIdx, 38950284d81f863a6576582e1a171a22eb0f012ddf3Dan Gohman PseudoSourceValue::getConstantPool(), 0, false, Alignment); 390004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng} 391004952140f3cf92ee098c2c5b8cdee1449bdc2edEvan Cheng 392f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio/// ExpandUnalignedStore - Expands an unaligned store to 2 half-size stores. 393f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venanciostatic 394475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue ExpandUnalignedStore(StoreSDNode *ST, SelectionDAG &DAG, 3950d137d7f35fba98f668098b3badf644efacf0e08Dan Gohman const TargetLowering &TLI) { 396475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = ST->getChain(); 397475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ptr = ST->getBasePtr(); 398475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Val = ST->getValue(); 39983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Val.getValueType(); 400907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen int Alignment = ST->getAlignment(); 401907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen int SVOffset = ST->getSrcValueOffset(); 402bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl = ST->getDebugLoc(); 40383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (ST->getMemoryVT().isFloatingPoint() || 40483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands ST->getMemoryVT().isVector()) { 40505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MVT intVT = MVT::getIntegerVT(VT.getSizeInBits()); 40605e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (TLI.isTypeLegal(intVT)) { 40705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Expand to a bitconvert of the value to the integer type of the 40805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // same size, then a (misaligned) int store. 40905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // FIXME: Does not handle truncating floating point stores! 410bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, intVT, Val); 411bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getStore(Chain, dl, Result, Ptr, ST->getSrcValue(), 41205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SVOffset, ST->isVolatile(), Alignment); 41305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } else { 41405e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Do a (aligned) store to a stack slot, then copy from the stack slot 41505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // to the final destination using (unaligned) integer loads and stores. 41605e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MVT StoredVT = ST->getMemoryVT(); 41705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MVT RegVT = 41805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands TLI.getRegisterType(MVT::getIntegerVT(StoredVT.getSizeInBits())); 41905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands unsigned StoredBytes = StoredVT.getSizeInBits() / 8; 42005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands unsigned RegBytes = RegVT.getSizeInBits() / 8; 42105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands unsigned NumRegs = (StoredBytes + RegBytes - 1) / RegBytes; 42205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 423fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // Make sure the stack slot is also aligned for the register type. 424fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands SDValue StackPtr = DAG.CreateStackTemporary(StoredVT, RegVT); 425fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands 426fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // Perform the original store, only redirected to the stack slot. 427fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel SDValue Store = DAG.getTruncStore(Chain, dl, 428ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson Val, StackPtr, NULL, 0, StoredVT); 42905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); 43005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SmallVector<SDValue, 8> Stores; 43105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands unsigned Offset = 0; 43205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 43305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Do all but one copies using the full register width. 43405e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands for (unsigned i = 1; i < NumRegs; i++) { 43505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Load one integer register's worth from the stack slot. 436bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Load = DAG.getLoad(RegVT, dl, Store, StackPtr, NULL, 0); 43705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Store it to the final location. Remember the store. 438bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, Ptr, 43905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands ST->getSrcValue(), SVOffset + Offset, 44005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands ST->isVolatile(), 44105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MinAlign(ST->getAlignment(), Offset))); 44205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Increment the pointers. 44305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands Offset += RegBytes; 444bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 44505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands Increment); 446bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); 44705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } 44805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 449fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // The last store may be partial. Do a truncating store. On big-endian 450fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // machines this requires an extending load from the stack slot to ensure 451fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // that the bits are in the right place. 452fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands MVT MemVT = MVT::getIntegerVT(8 * (StoredBytes - Offset)); 453fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands 454fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // Load from the stack slot. 455bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Store, StackPtr, 456fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands NULL, 0, MemVT); 45705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 458bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, Ptr, 45905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands ST->getSrcValue(), SVOffset + Offset, 460fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands MemVT, ST->isVolatile(), 46105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MinAlign(ST->getAlignment(), Offset))); 46205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // The order of the stores doesn't matter - say it with a TokenFactor. 463bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], 46405e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands Stores.size()); 46505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } 466907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen } 46783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(ST->getMemoryVT().isInteger() && 46883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands !ST->getMemoryVT().isVector() && 469907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen "Unaligned store of unknown type."); 470f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Get the half-size VT 47183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NewStoredVT = 47283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands (MVT::SimpleValueType)(ST->getMemoryVT().getSimpleVT() - 1); 47383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands int NumBits = NewStoredVT.getSizeInBits(); 474f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio int IncrementSize = NumBits / 8; 475f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 476f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Divide the stored value in two parts. 477475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ShiftAmount = DAG.getConstant(NumBits, TLI.getShiftAmountTy()); 478475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo = Val; 479bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Hi = DAG.getNode(ISD::SRL, dl, VT, Val, ShiftAmount); 480f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 481f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Store the two parts 482475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Store1, Store2; 483bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Store1 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Lo:Hi, Ptr, 484f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio ST->getSrcValue(), SVOffset, NewStoredVT, 485f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio ST->isVolatile(), Alignment); 486bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 487f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 488dc84650679b6330e0fcdd4cf8bc2a351387db7caDuncan Sands Alignment = MinAlign(Alignment, IncrementSize); 489bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Store2 = DAG.getTruncStore(Chain, dl, TLI.isLittleEndian()?Hi:Lo, Ptr, 490f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio ST->getSrcValue(), SVOffset + IncrementSize, 491f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio NewStoredVT, ST->isVolatile(), Alignment); 492f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 493bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Store1, Store2); 494f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio} 495f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 496f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio/// ExpandUnalignedLoad - Expands an unaligned load to 2 half-size loads. 497f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venanciostatic 498475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue ExpandUnalignedLoad(LoadSDNode *LD, SelectionDAG &DAG, 499e9530ecae4897fe8157bd4d7616043bd8c0484e2Dan Gohman const TargetLowering &TLI) { 500f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio int SVOffset = LD->getSrcValueOffset(); 501475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = LD->getChain(); 502475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ptr = LD->getBasePtr(); 50383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = LD->getValueType(0); 50483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT LoadedVT = LD->getMemoryVT(); 505bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl = LD->getDebugLoc(); 50683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (VT.isFloatingPoint() || VT.isVector()) { 50705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MVT intVT = MVT::getIntegerVT(LoadedVT.getSizeInBits()); 50805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (TLI.isTypeLegal(intVT)) { 50905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Expand to a (misaligned) integer load of the same size, 51005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // then bitconvert to floating point or vector. 511bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue newLoad = DAG.getLoad(intVT, dl, Chain, Ptr, LD->getSrcValue(), 51205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SVOffset, LD->isVolatile(), 513907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen LD->getAlignment()); 514bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Result = DAG.getNode(ISD::BIT_CONVERT, dl, LoadedVT, newLoad); 51505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands if (VT.isFloatingPoint() && LoadedVT != VT) 516bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Result = DAG.getNode(ISD::FP_EXTEND, dl, VT, Result); 517907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen 51805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SDValue Ops[] = { Result, Chain }; 519bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getMergeValues(Ops, 2, dl); 52005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } else { 52105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Copy the value to a (aligned) stack slot using (unaligned) integer 52205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // loads and stores, then do a (aligned) load from the stack slot. 52305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MVT RegVT = TLI.getRegisterType(intVT); 52405e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands unsigned LoadedBytes = LoadedVT.getSizeInBits() / 8; 52505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands unsigned RegBytes = RegVT.getSizeInBits() / 8; 52605e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands unsigned NumRegs = (LoadedBytes + RegBytes - 1) / RegBytes; 52705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 528fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // Make sure the stack slot is also aligned for the register type. 529fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands SDValue StackBase = DAG.CreateStackTemporary(LoadedVT, RegVT); 530fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands 53105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SDValue Increment = DAG.getConstant(RegBytes, TLI.getPointerTy()); 53205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SmallVector<SDValue, 8> Stores; 53305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SDValue StackPtr = StackBase; 53405e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands unsigned Offset = 0; 53505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 53605e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Do all but one copies using the full register width. 53705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands for (unsigned i = 1; i < NumRegs; i++) { 53805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Load one integer register's worth from the original location. 539bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Load = DAG.getLoad(RegVT, dl, Chain, Ptr, LD->getSrcValue(), 54005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SVOffset + Offset, LD->isVolatile(), 54105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MinAlign(LD->getAlignment(), Offset)); 54205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Follow the load with a store to the stack slot. Remember the store. 543bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Stores.push_back(DAG.getStore(Load.getValue(1), dl, Load, StackPtr, 54405e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands NULL, 0)); 54505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Increment the pointers. 54605e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands Offset += RegBytes; 547bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, Increment); 548bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen StackPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), StackPtr, 54905e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands Increment); 55005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } 55105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 55205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // The last copy may be partial. Do an extending load. 553fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands MVT MemVT = MVT::getIntegerVT(8 * (LoadedBytes - Offset)); 554bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Load = DAG.getExtLoad(ISD::EXTLOAD, dl, RegVT, Chain, Ptr, 55505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands LD->getSrcValue(), SVOffset + Offset, 556fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands MemVT, LD->isVolatile(), 55705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands MinAlign(LD->getAlignment(), Offset)); 55805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Follow the load with a store to the stack slot. Remember the store. 559fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // On big-endian machines this requires a truncating store to ensure 560fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands // that the bits end up in the right place. 561bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Stores.push_back(DAG.getTruncStore(Load.getValue(1), dl, Load, StackPtr, 562fd6673cf7fd5c0c1e6817e5fcf460a289712ee57Duncan Sands NULL, 0, MemVT)); 56305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 56405e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // The order of the stores doesn't matter - say it with a TokenFactor. 565bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, &Stores[0], 56605e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands Stores.size()); 56705e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 56805e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Finally, perform the original load only redirected to the stack slot. 569bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Load = DAG.getExtLoad(LD->getExtensionType(), dl, VT, TF, StackBase, 57005e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands NULL, 0, LoadedVT); 57105e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands 57205e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands // Callers expect a MERGE_VALUES node. 57305e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands SDValue Ops[] = { Load, TF }; 574bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getMergeValues(Ops, 2, dl); 57505e11fab87102a230551327bfc8434ffad7a88d4Duncan Sands } 576907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen } 57783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(LoadedVT.isInteger() && !LoadedVT.isVector() && 578e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner "Unaligned load of unsupported type."); 579e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner 5808155d64c2ffab8b17e0fd8e3b7a66fcef6a8ec9dDale Johannesen // Compute the new VT that is half the size of the old one. This is an 5818155d64c2ffab8b17e0fd8e3b7a66fcef6a8ec9dDale Johannesen // integer MVT. 58283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned NumBits = LoadedVT.getSizeInBits(); 58383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NewLoadedVT; 58483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands NewLoadedVT = MVT::getIntegerVT(NumBits/2); 585e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner NumBits >>= 1; 586fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 587e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner unsigned Alignment = LD->getAlignment(); 588e400af83b3f8b69407a8963f1d2e2c82fa766f33Chris Lattner unsigned IncrementSize = NumBits / 8; 589f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio ISD::LoadExtType HiExtType = LD->getExtensionType(); 590f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 591f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If the original load is NON_EXTLOAD, the hi part load must be ZEXTLOAD. 592f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (HiExtType == ISD::NON_EXTLOAD) 593f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio HiExtType = ISD::ZEXTLOAD; 594f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 595f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // Load the value in two parts 596475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 597f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (TLI.isLittleEndian()) { 598bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(), 599f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio SVOffset, NewLoadedVT, LD->isVolatile(), Alignment); 600bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 601f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 602bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(), 603f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), 604dc84650679b6330e0fcdd4cf8bc2a351387db7caDuncan Sands MinAlign(Alignment, IncrementSize)); 605f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } else { 606bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Hi = DAG.getExtLoad(HiExtType, dl, VT, Chain, Ptr, LD->getSrcValue(), 607ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson SVOffset, NewLoadedVT, LD->isVolatile(), Alignment); 608bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ptr = DAG.getNode(ISD::ADD, dl, Ptr.getValueType(), Ptr, 609f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio DAG.getConstant(IncrementSize, TLI.getPointerTy())); 610bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, VT, Chain, Ptr, LD->getSrcValue(), 611f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio SVOffset + IncrementSize, NewLoadedVT, LD->isVolatile(), 612dc84650679b6330e0fcdd4cf8bc2a351387db7caDuncan Sands MinAlign(Alignment, IncrementSize)); 613f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 614f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 615f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // aggregate the two parts 616475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ShiftAmount = DAG.getConstant(NumBits, TLI.getShiftAmountTy()); 617bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Result = DAG.getNode(ISD::SHL, dl, VT, Hi, ShiftAmount); 618bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Result = DAG.getNode(ISD::OR, dl, VT, Result, Lo); 619f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 620bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue TF = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 621f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio Hi.getValue(1)); 622f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio 623475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[] = { Result, TF }; 624bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getMergeValues(Ops, 2, dl); 625f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio} 626912095becac923ff614d7b07728eb345ada67765Evan Cheng 627007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands/// GetFPLibCall - Return the right libcall for the given floating point type. 62883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sandsstatic RTLIB::Libcall GetFPLibCall(MVT VT, 629007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::Libcall Call_F32, 630007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::Libcall Call_F64, 631007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::Libcall Call_F80, 632007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::Libcall Call_PPCF128) { 633007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands return 634007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands VT == MVT::f32 ? Call_F32 : 635007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands VT == MVT::f64 ? Call_F64 : 636007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands VT == MVT::f80 ? Call_F80 : 637007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands VT == MVT::ppcf128 ? Call_PPCF128 : 638007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::UNKNOWN_LIBCALL; 639007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands} 640007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands 6416867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// PerformInsertVectorEltInMemory - Some target cannot handle a variable 6426867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// insertion index for the INSERT_VECTOR_ELT instruction. In this case, it 6436867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// is necessary to spill the vector being inserted into to memory, perform 6446867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman/// the insert there, and then read the result back. 645475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize:: 646bb5da918545efb54857a09c983a5a7f22a7e04d4Dale JohannesenPerformInsertVectorEltInMemory(SDValue Vec, SDValue Val, SDValue Idx, 647bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl) { 648475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1 = Vec; 649475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp2 = Val; 650475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp3 = Idx; 651fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 6526867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // If the target doesn't support this, we have to spill the input vector 6536867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // to a temporary stack slot, update the element, then reload it. This is 6546867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // badness. We could also load the value into a vector register (either 6556867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // with a "move to register" or "extload into register" instruction, then 6566867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // permute it into place, if the idx is a constant and if the idx is 6576867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // supported by the target. 65883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Tmp1.getValueType(); 65983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT EltVT = VT.getVectorElementType(); 66083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT IdxVT = Tmp3.getValueType(); 66183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PtrVT = TLI.getPointerTy(); 662475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue StackPtr = DAG.CreateStackTemporary(VT); 6636867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 664ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif int SPFI = cast<FrameIndexSDNode>(StackPtr.getNode())->getIndex(); 6656867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 6666867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Store the vector. 667bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Tmp1, StackPtr, 6680c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang PseudoSourceValue::getFixedStack(SPFI), 0); 6696867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 6706867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Truncate or zero extend offset to target pointer type. 6718e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands unsigned CastOpc = IdxVT.bitsGT(PtrVT) ? ISD::TRUNCATE : ISD::ZERO_EXTEND; 672bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Tmp3 = DAG.getNode(CastOpc, dl, PtrVT, Tmp3); 6736867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Add the offset to the index. 67483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned EltSize = EltVT.getSizeInBits()/8; 675bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Tmp3 = DAG.getNode(ISD::MUL, dl, IdxVT, Tmp3,DAG.getConstant(EltSize, IdxVT)); 676bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue StackPtr2 = DAG.getNode(ISD::ADD, dl, IdxVT, Tmp3, StackPtr); 6776867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Store the scalar value. 678bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Ch = DAG.getTruncStore(Ch, dl, Tmp2, StackPtr2, 679a54cf176613f9ae8301519a61b8935652c0fb8aeDan Gohman PseudoSourceValue::getFixedStack(SPFI), 0, EltVT); 6806867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman // Load the updated vector. 681bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen return DAG.getLoad(VT, dl, Ch, StackPtr, 682a54cf176613f9ae8301519a61b8935652c0fb8aeDan Gohman PseudoSourceValue::getFixedStack(SPFI), 0); 6836867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman} 6846867991d541d08ca95d86841eca5f7c1d5096864Nate Begeman 685e9f1015d1f184a51aaadfd03be0846bd5e7d08a2Mon P Wang 686a346615d11f0a560c6e7280c1e614301d9f93051Dan Gohman/// LegalizeOp - We know that the specified value has a legal type, and 687a346615d11f0a560c6e7280c1e614301d9f93051Dan Gohman/// that its operands are legal. Now ensure that the operation itself 688a346615d11f0a560c6e7280c1e614301d9f93051Dan Gohman/// is legal, recursively ensuring that the operands' operations remain 689a346615d11f0a560c6e7280c1e614301d9f93051Dan Gohman/// legal. 690475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::LegalizeOp(SDValue Op) { 69109ec1b058331aadb29a348091611d23892b5c492Chris Lattner if (Op.getOpcode() == ISD::TargetConstant) // Allow illegal target nodes. 69209ec1b058331aadb29a348091611d23892b5c492Chris Lattner return Op; 693fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 694ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif SDNode *Node = Op.getNode(); 6957d2ad624fa749a6d3edac0d94e9c107989c16304Dale Johannesen DebugLoc dl = Node->getDebugLoc(); 696e3304a3d24afc952d3cb415d1b504d973573c5c5Chris Lattner 6971fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 6981fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman assert(getTypeAction(Node->getValueType(i)) == Legal && 6991fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman "Unexpected illegal type!"); 7001fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman 7011fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 7021fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman assert((isTypeLegal(Node->getOperand(i).getValueType()) || 7031fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman Node->getOperand(i).getOpcode() == ISD::TargetConstant) && 7041fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman "Unexpected illegal type!"); 7053e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 70645982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner // Note that LegalizeOp may be reentered even from single-use nodes, which 70745982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner // means that we always must cache transformed nodes. 708475871a144eb604ddaf37503397ba0941442e5fbDan Gohman DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op); 709e1bd822ddb0099406d9f280535461033dfeeb190Chris Lattner if (I != LegalizedNodes.end()) return I->second; 7103e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 711475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1, Tmp2, Tmp3, Tmp4; 712475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Result = Op; 713456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner bool isCustom = false; 714fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 7158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Figure out the correct action; the way to query this varies by opcode 7168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman TargetLowering::LegalizeAction Action; 7178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman bool SimpleFinishLegalizing = true; 7183e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner switch (Node->getOpcode()) { 7198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_W_CHAIN: 7208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_WO_CHAIN: 7218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::INTRINSIC_VOID: 7228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VAARG: 7238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::STACKSAVE: 7248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), MVT::Other); 7258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 7278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 7288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_VECTOR_ELT: 7298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), 7308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0).getValueType()); 7318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7328c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND_INREG: 7338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SIGN_EXTEND_INREG: { 7348c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT InnerType = cast<VTSDNode>(Node->getOperand(1))->getVT(); 7358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), InnerType); 7368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 7388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::LOAD: 7398c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::STORE: 7408c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BR_CC: 7418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FORMAL_ARGUMENTS: 7428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CALL: 7438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CALLSEQ_START: 7448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CALLSEQ_END: 7458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SELECT_CC: 7468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SETCC: 7478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXCEPTIONADDR: 7488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EHSELECTION: 7498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // These instructions have properties that aren't modeled in the 7508c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // generic codepath 7518c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SimpleFinishLegalizing = false; 7528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7538c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_ELEMENT: 7548c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLT_ROUNDS_: 7558c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SADDO: 7568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SSUBO: 7578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UADDO: 7588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::USUBO: 7598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SMULO: 7608c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UMULO: 7618c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FPOWI: 7628c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::MERGE_VALUES: 7638c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_RETURN: 7648c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAME_TO_ARGS_OFFSET: 7658c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 7668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Action == TargetLowering::Legal) 7678c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TargetLowering::Expand; 7688c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7698c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::TRAMPOLINE: 7708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAMEADDR: 7718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::RETURNADDR: 7728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TargetLowering::Custom; 7738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7748c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BUILD_VECTOR: 7758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // A weird case: when a BUILD_VECTOR is custom-lowered, it doesn't legalize 7768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // its operands first! 7778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SimpleFinishLegalizing = false; 778948c1b1cda280c6428dbeaa03a6c2c559dbb93f4Chris Lattner break; 7793e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner default: 780d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner if (Node->getOpcode() >= ISD::BUILTIN_OP_END) { 7818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TargetLowering::Legal; 7828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else { 7838c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Action = TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0)); 7848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 7858c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 7868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 787d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner 7888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (SimpleFinishLegalizing) { 7898c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SmallVector<SDValue, 8> Ops, ResultVals; 7908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 7918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Ops.push_back(LegalizeOp(Node->getOperand(i))); 7928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 7938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman default: break; 7948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BR: 7958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BRIND: 7968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BR_JT: 7978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BR_CC: 7988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BRCOND: 7998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::RET: 8008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Branches tweak the chain to include LastCALLSEQ_END 8018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Ops[0] = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Ops[0], 8028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman LastCALLSEQ_END); 8038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Ops[0] = LegalizeOp(Ops[0]); 8048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman LastCALLSEQ_END = DAG.getEntryNode(); 8058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SHL: 8078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SRL: 8088c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SRA: 8098c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::ROTL: 8108c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::ROTR: 8118c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Legalizing shifts/rotates requires adjusting the shift amount 8128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // to the appropriate width. 8138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (!Ops[1].getValueType().isVector()) 8148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Ops[1] = LegalizeOp(DAG.getShiftAmountOperand(Ops[1])); 8158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 8188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Result = DAG.UpdateNodeOperands(Result.getValue(0), Ops.data(), 8198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Ops.size()); 8208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Action) { 8218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Legal: 822d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) 8238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals.push_back(Result.getValue(i)); 8248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Custom: 8268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // FIXME: The handling for custom lowering with multiple results is 8278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // a complete mess. 8288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = TLI.LowerOperation(Result, DAG); 8298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Tmp1.getNode()) { 8308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0, e = Node->getNumValues(); i != e; ++i) { 8318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (e == 1) 8328c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals.push_back(Tmp1); 8338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman else 8348c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals.push_back(Tmp1.getValue(i)); 8358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 8398c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // FALL THROUGH 8408c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Expand: 8418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ExpandNode(Result.getNode(), ResultVals); 8428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Promote: 8448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman PromoteNode(Result.getNode(), ResultVals); 8458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 8468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (!ResultVals.empty()) { 8488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0, e = ResultVals.size(); i != e; ++i) { 8498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (ResultVals[i] != SDValue(Node, i)) 8508c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ResultVals[i] = LegalizeOp(ResultVals[i]); 8518c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman AddLegalizedOperand(SDValue(Node, i), ResultVals[i]); 8528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8538c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman return ResultVals[Op.getResNo()]; 854d73cc5d0585e86bf6d350ab9fd9caf85bdfc8b52Chris Lattner } 8558c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 8568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 8578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 8588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman default: 859e37fe9b3a1cadceb42ac27fa0718f5a10ea2f0e6Jim Laskey#ifndef NDEBUG 86039833585556a69de12053ca1e104fe7edfd86cbdDan Gohman cerr << "NODE: "; Node->dump(&DAG); cerr << "\n"; 861e37fe9b3a1cadceb42ac27fa0718f5a10ea2f0e6Jim Laskey#endif 8623e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner assert(0 && "Do not know how to legalize this operator!"); 8633e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner abort(); 8640d3b67809ccab229a03db8c1bede852fb89eb081Lauro Ramos Venancio case ISD::GLOBAL_OFFSET_TABLE: 8653e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::GlobalAddress: 866b3a0417cad8b625acc3033bd5e24afb9ffd0b084Lauro Ramos Venancio case ISD::GlobalTLSAddress: 867056292fd738924f3f7703725d8f630983794b5a5Bill Wendling case ISD::ExternalSymbol: 86837efe6764568a3829fee26aba532283131d1a104Nate Begeman case ISD::ConstantPool: 86937efe6764568a3829fee26aba532283131d1a104Nate Begeman case ISD::JumpTable: // Nothing to do. 8700c8fbe33a4bdf7c60e0cfd5a9c86499c817d9f1aChris Lattner switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { 8710c8fbe33a4bdf7c60e0cfd5a9c86499c817d9f1aChris Lattner default: assert(0 && "This action is not supported yet!"); 872948c1b1cda280c6428dbeaa03a6c2c559dbb93f4Chris Lattner case TargetLowering::Custom: 873948c1b1cda280c6428dbeaa03a6c2c559dbb93f4Chris Lattner Tmp1 = TLI.LowerOperation(Op, DAG); 874ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 875948c1b1cda280c6428dbeaa03a6c2c559dbb93f4Chris Lattner // FALLTHROUGH if the target doesn't want to lower this op after all. 8760c8fbe33a4bdf7c60e0cfd5a9c86499c817d9f1aChris Lattner case TargetLowering::Legal: 8770c8fbe33a4bdf7c60e0cfd5a9c86499c817d9f1aChris Lattner break; 8780c8fbe33a4bdf7c60e0cfd5a9c86499c817d9f1aChris Lattner } 8793e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 8802bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey case ISD::EXCEPTIONADDR: { 8812bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey Tmp1 = LegalizeOp(Node->getOperand(0)); 88283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Node->getValueType(0); 8832bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 8842bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey default: assert(0 && "This action is not supported yet!"); 8852bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey case TargetLowering::Expand: { 8868782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey unsigned Reg = TLI.getExceptionAddressRegister(); 887c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen Result = DAG.getCopyFromReg(Tmp1, dl, Reg, VT); 8882bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey } 8892bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey break; 8902bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey case TargetLowering::Custom: 8912bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey Result = TLI.LowerOperation(Op, DAG); 892ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Result.getNode()) break; 8932bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey // Fall Thru 894eb7f34f2cb1584f155b9cefdb246b300fb2fc9c4Chris Lattner case TargetLowering::Legal: { 895475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[] = { DAG.getConstant(0, VT), Tmp1 }; 896ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getMergeValues(Ops, 2, dl); 8978782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey break; 8988782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey } 8998782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey } 900eb7f34f2cb1584f155b9cefdb246b300fb2fc9c4Chris Lattner } 901ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Result.getNode()->getNumValues() == 1) break; 902b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands 903ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif assert(Result.getNode()->getNumValues() == 2 && 904b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands "Cannot return more than two values!"); 905b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands 906b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands // Since we produced two values, make sure to remember that we 907b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands // legalized both of them. 908b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands Tmp1 = LegalizeOp(Result); 909b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands Tmp2 = LegalizeOp(Result.getValue(1)); 910b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands AddLegalizedOperand(Op.getValue(0), Tmp1); 911b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands AddLegalizedOperand(Op.getValue(1), Tmp2); 91299a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Op.getResNo() ? Tmp2 : Tmp1; 9138782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey case ISD::EHSELECTION: { 9148782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey Tmp1 = LegalizeOp(Node->getOperand(0)); 9158782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey Tmp2 = LegalizeOp(Node->getOperand(1)); 91683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Node->getValueType(0); 9178782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 9188782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey default: assert(0 && "This action is not supported yet!"); 9198782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey case TargetLowering::Expand: { 9208782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey unsigned Reg = TLI.getExceptionSelectorRegister(); 921c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen Result = DAG.getCopyFromReg(Tmp2, dl, Reg, VT); 9228782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey } 9238782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey break; 9248782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey case TargetLowering::Custom: 9258782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey Result = TLI.LowerOperation(Op, DAG); 926ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Result.getNode()) break; 9278782d481a3c720304540254a7b71d25bbe7cbf49Jim Laskey // Fall Thru 928eb7f34f2cb1584f155b9cefdb246b300fb2fc9c4Chris Lattner case TargetLowering::Legal: { 929475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ops[] = { DAG.getConstant(0, VT), Tmp2 }; 930ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getMergeValues(Ops, 2, dl); 9312bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey break; 9322bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey } 9332bc210d99f5a7322a1ae84775eba351d9ab6ea85Jim Laskey } 934eb7f34f2cb1584f155b9cefdb246b300fb2fc9c4Chris Lattner } 935ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Result.getNode()->getNumValues() == 1) break; 936b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands 937ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif assert(Result.getNode()->getNumValues() == 2 && 938b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands "Cannot return more than two values!"); 939b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands 940b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands // Since we produced two values, make sure to remember that we 941b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands // legalized both of them. 942b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands Tmp1 = LegalizeOp(Result); 943b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands Tmp2 = LegalizeOp(Result.getValue(1)); 944b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands AddLegalizedOperand(Op.getValue(0), Tmp1); 945b027fa001f16660a231a54ecea6a79f5c7855d7cDuncan Sands AddLegalizedOperand(Op.getValue(1), Tmp2); 94699a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Op.getResNo() ? Tmp2 : Tmp1; 94748b61a729df6576c8833a83893d4086bddff69a5Chris Lattner case ISD::INTRINSIC_W_CHAIN: 94848b61a729df6576c8833a83893d4086bddff69a5Chris Lattner case ISD::INTRINSIC_WO_CHAIN: 94948b61a729df6576c8833a83893d4086bddff69a5Chris Lattner case ISD::INTRINSIC_VOID: { 950475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Ops; 951d1f04d40a078d6ca7c876b16a178992a109af774Chris Lattner for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 952d1f04d40a078d6ca7c876b16a178992a109af774Chris Lattner Ops.push_back(LegalizeOp(Node->getOperand(i))); 953f06f35e30b4c4d7db304f717a3d4dc6595fbd078Chris Lattner Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size()); 954fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 95510d7fa62fffbceed580c34a00bd30f16643f6607Chris Lattner // Allow the target to custom lower its intrinsics if it wants to. 956fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel if (TLI.getOperationAction(Node->getOpcode(), MVT::Other) == 95710d7fa62fffbceed580c34a00bd30f16643f6607Chris Lattner TargetLowering::Custom) { 95810d7fa62fffbceed580c34a00bd30f16643f6607Chris Lattner Tmp3 = TLI.LowerOperation(Result, DAG); 959ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()) Result = Tmp3; 96013fc2f1d270cdedffb72b33621369cee9a2cdaaaChris Lattner } 96113fc2f1d270cdedffb72b33621369cee9a2cdaaaChris Lattner 962ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Result.getNode()->getNumValues() == 1) break; 96313fc2f1d270cdedffb72b33621369cee9a2cdaaaChris Lattner 96413fc2f1d270cdedffb72b33621369cee9a2cdaaaChris Lattner // Must have return value and chain result. 965ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif assert(Result.getNode()->getNumValues() == 2 && 96613fc2f1d270cdedffb72b33621369cee9a2cdaaaChris Lattner "Cannot return more than two values!"); 96713fc2f1d270cdedffb72b33621369cee9a2cdaaaChris Lattner 968fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Since loads produce two values, make sure to remember that we 96913fc2f1d270cdedffb72b33621369cee9a2cdaaaChris Lattner // legalized both of them. 970475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0)); 971475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1)); 97299a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Result.getValue(Op.getResNo()); 973fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel } 97436ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner 9757f460203b0c5350e9b2c592f438e40f7a7de6e45Dan Gohman case ISD::DBG_STOPPOINT: 9767f460203b0c5350e9b2c592f438e40f7a7de6e45Dan Gohman assert(Node->getNumOperands() == 1 && "Invalid DBG_STOPPOINT node!"); 97736ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the input chain. 978fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 9797f460203b0c5350e9b2c592f438e40f7a7de6e45Dan Gohman switch (TLI.getOperationAction(ISD::DBG_STOPPOINT, MVT::Other)) { 98036ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner case TargetLowering::Promote: 98136ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner default: assert(0 && "This action is not supported yet!"); 98292c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling case TargetLowering::Expand: { 98392c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling DwarfWriter *DW = DAG.getDwarfWriter(); 98492c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling bool useDEBUG_LOC = TLI.isOperationLegalOrCustom(ISD::DEBUG_LOC, 98592c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling MVT::Other); 98692c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling bool useLABEL = TLI.isOperationLegalOrCustom(ISD::DBG_LABEL, MVT::Other); 987fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 98892c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling const DbgStopPointSDNode *DSP = cast<DbgStopPointSDNode>(Node); 98992c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling GlobalVariable *CU_GV = cast<GlobalVariable>(DSP->getCompileUnit()); 99092c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling if (DW && (useDEBUG_LOC || useLABEL) && !CU_GV->isDeclaration()) { 99192c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling DICompileUnit CU(cast<GlobalVariable>(DSP->getCompileUnit())); 992fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 99392c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling unsigned Line = DSP->getLine(); 99492c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling unsigned Col = DSP->getColumn(); 99586e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling 99698a366d547772010e94609e4584489b3e5ce0043Bill Wendling if (OptLevel == CodeGenOpt::None) { 99786e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling // A bit self-referential to have DebugLoc on Debug_Loc nodes, but it 99886e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling // won't hurt anything. 99986e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling if (useDEBUG_LOC) { 100086e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling SDValue Ops[] = { Tmp1, DAG.getConstant(Line, MVT::i32), 100192c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling DAG.getConstant(Col, MVT::i32), 1002a26eae64ddf607549f9e47046d46ea5b9ec648b4Argyrios Kyrtzidis DAG.getSrcValue(CU.getGV()) }; 100386e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling Result = DAG.getNode(ISD::DEBUG_LOC, dl, MVT::Other, Ops, 4); 100486e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling } else { 1005a26eae64ddf607549f9e47046d46ea5b9ec648b4Argyrios Kyrtzidis unsigned ID = DW->RecordSourceLine(Line, Col, CU); 100686e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling Result = DAG.getLabel(ISD::DBG_LABEL, dl, Tmp1, ID); 100786e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling } 100892c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling } else { 100986e6cb924b85e7a288a4d8bfde5d1a8fb9810c88Bill Wendling Result = Tmp1; // chain 101092c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling } 101192c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling } else { 101292c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling Result = Tmp1; // chain 101392c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling } 101436ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner break; 101592c1e126473dfa93eeb4c9a124af4fedb40f0d5bBill Wendling } 10165274a4afb720858bf1ab927fc90068f1a8f12eb2Sanjiv Gupta case TargetLowering::Custom: 10175274a4afb720858bf1ab927fc90068f1a8f12eb2Sanjiv Gupta Result = TLI.LowerOperation(Op, DAG); 1018ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson if (Result.getNode()) 10195274a4afb720858bf1ab927fc90068f1a8f12eb2Sanjiv Gupta break; 102071e8685633e7938ee752004cceedccbd0d850527Evan Cheng case TargetLowering::Legal: { 102174807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman if (Tmp1 == Node->getOperand(0)) 102271e8685633e7938ee752004cceedccbd0d850527Evan Cheng break; 102371e8685633e7938ee752004cceedccbd0d850527Evan Cheng 1024475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Ops; 102571e8685633e7938ee752004cceedccbd0d850527Evan Cheng Ops.push_back(Tmp1); 102674807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman Ops.push_back(Node->getOperand(1)); // line # must be legal. 102774807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman Ops.push_back(Node->getOperand(2)); // col # must be legal. 102871e8685633e7938ee752004cceedccbd0d850527Evan Cheng Ops.push_back(Node->getOperand(3)); // filename must be legal. 102971e8685633e7938ee752004cceedccbd0d850527Evan Cheng Ops.push_back(Node->getOperand(4)); // working dir # must be legal. 103071e8685633e7938ee752004cceedccbd0d850527Evan Cheng Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size()); 103136ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner break; 103236ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner } 103371e8685633e7938ee752004cceedccbd0d850527Evan Cheng } 103436ce69195ed488034d0bb11180cc2ebd923679c8Chris Lattner break; 10353e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::ConstantFP: { 10363e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner // Spill FP immediates to the constant pool if the target cannot directly 10373e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner // codegen them. Targets often have some immediate values that can be 10383e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner // efficiently generated into an FP register without a load. We explicitly 10393e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner // leave these constants as ConstantFP nodes for the target to deal with. 10403e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner ConstantFPSDNode *CFP = cast<ConstantFPSDNode>(Node); 10413e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 10423181a771ff5b2090b7ed55f9b18a684ea8fe625aChris Lattner switch (TLI.getOperationAction(ISD::ConstantFP, CFP->getValueType(0))) { 10433181a771ff5b2090b7ed55f9b18a684ea8fe625aChris Lattner default: assert(0 && "This action is not supported yet!"); 1044e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman case TargetLowering::Legal: 1045e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman break; 10463181a771ff5b2090b7ed55f9b18a684ea8fe625aChris Lattner case TargetLowering::Custom: 10473181a771ff5b2090b7ed55f9b18a684ea8fe625aChris Lattner Tmp3 = TLI.LowerOperation(Result, DAG); 1048ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()) { 10493181a771ff5b2090b7ed55f9b18a684ea8fe625aChris Lattner Result = Tmp3; 10503181a771ff5b2090b7ed55f9b18a684ea8fe625aChris Lattner break; 10513181a771ff5b2090b7ed55f9b18a684ea8fe625aChris Lattner } 10523181a771ff5b2090b7ed55f9b18a684ea8fe625aChris Lattner // FALLTHROUGH 1053e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman case TargetLowering::Expand: { 1054e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman // Check to see if this FP immediate is already legal. 1055e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman bool isLegal = false; 1056e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman for (TargetLowering::legal_fpimm_iterator I = TLI.legal_fpimm_begin(), 1057e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman E = TLI.legal_fpimm_end(); I != E; ++I) { 1058e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman if (CFP->isExactlyValue(*I)) { 1059e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman isLegal = true; 1060e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman break; 1061e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman } 1062e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman } 1063e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman // If this is a legal constant, turn it into a TargetConstantFP node. 1064e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman if (isLegal) 1065e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman break; 1066279101eb1ac61e2d5b83d5bdcc5be56e710d2cd7Evan Cheng Result = ExpandConstantFP(CFP, true, DAG, TLI); 10673e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 1068e179584f9b740cf3a36bde70f8cab40de59b8081Nate Begeman } 10693e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 10703e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 1071fdfded55888e35b76bb70231a5bb2f60877c2f6aChris Lattner case ISD::FORMAL_ARGUMENTS: 1072f4ec817299a4187044a6162c2f520772b3ad69a0Chris Lattner case ISD::CALL: 1073fdfded55888e35b76bb70231a5bb2f60877c2f6aChris Lattner // The only option for this is to custom lower it. 1074b248e16afd105fd8c01e08d8bf997b08ff08d127Chris Lattner Tmp3 = TLI.LowerOperation(Result.getValue(0), DAG); 1075ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif assert(Tmp3.getNode() && "Target didn't custom lower this node!"); 10760ea0356dff38dfd0420b8c0a2fdf2fae7898c024Dale Johannesen // A call within a calling sequence must be legalized to something 10770ea0356dff38dfd0420b8c0a2fdf2fae7898c024Dale Johannesen // other than the normal CALLSEQ_END. Violating this gets Legalize 10780ea0356dff38dfd0420b8c0a2fdf2fae7898c024Dale Johannesen // into an infinite loop. 10790ea0356dff38dfd0420b8c0a2fdf2fae7898c024Dale Johannesen assert ((!IsLegalizingCall || 10800ea0356dff38dfd0420b8c0a2fdf2fae7898c024Dale Johannesen Node->getOpcode() != ISD::CALL || 1081ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif Tmp3.getNode()->getOpcode() != ISD::CALLSEQ_END) && 10820ea0356dff38dfd0420b8c0a2fdf2fae7898c024Dale Johannesen "Nested CALLSEQ_START..CALLSEQ_END not supported."); 10830f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling 10840f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling // The number of incoming and outgoing values should match; unless the final 10850f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling // outgoing value is a flag. 1086ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif assert((Tmp3.getNode()->getNumValues() == Result.getNode()->getNumValues() || 1087ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif (Tmp3.getNode()->getNumValues() == Result.getNode()->getNumValues() + 1 && 1088ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif Tmp3.getNode()->getValueType(Tmp3.getNode()->getNumValues() - 1) == 10890f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling MVT::Flag)) && 1090b248e16afd105fd8c01e08d8bf997b08ff08d127Chris Lattner "Lowering call/formal_arguments produced unexpected # results!"); 1091fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1092f4ec817299a4187044a6162c2f520772b3ad69a0Chris Lattner // Since CALL/FORMAL_ARGUMENTS nodes produce multiple values, make sure to 1093e2e41730ccfa9bebfabbd17ab3454aa2bb620b2aChris Lattner // remember that we legalized all of them, so it doesn't get relegalized. 1094ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif for (unsigned i = 0, e = Tmp3.getNode()->getNumValues(); i != e; ++i) { 1095ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()->getValueType(i) == MVT::Flag) 10960f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling continue; 1097b248e16afd105fd8c01e08d8bf997b08ff08d127Chris Lattner Tmp1 = LegalizeOp(Tmp3.getValue(i)); 109899a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif if (Op.getResNo() == i) 1099e2e41730ccfa9bebfabbd17ab3454aa2bb620b2aChris Lattner Tmp2 = Tmp1; 1100475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, i), Tmp1); 1101e2e41730ccfa9bebfabbd17ab3454aa2bb620b2aChris Lattner } 1102e2e41730ccfa9bebfabbd17ab3454aa2bb620b2aChris Lattner return Tmp2; 1103b2827b0901162169bb2692b77a839c9767849134Chris Lattner case ISD::BUILD_VECTOR: 1104b2827b0901162169bb2692b77a839c9767849134Chris Lattner switch (TLI.getOperationAction(ISD::BUILD_VECTOR, Node->getValueType(0))) { 11052332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner default: assert(0 && "This action is not supported yet!"); 11062332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner case TargetLowering::Custom: 11072332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner Tmp3 = TLI.LowerOperation(Result, DAG); 1108ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()) { 11092332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner Result = Tmp3; 11102332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner break; 11112332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner } 11122332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner // FALLTHROUGH 1113ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner case TargetLowering::Expand: 1114ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif Result = ExpandBUILD_VECTOR(Result.getNode()); 1115b2827b0901162169bb2692b77a839c9767849134Chris Lattner break; 11162332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner } 11172332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner break; 11182332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner case ISD::INSERT_VECTOR_ELT: 11192332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // InVec 11202332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner Tmp3 = LegalizeOp(Node->getOperand(2)); // InEltNo 11210325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman 11220325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman // The type of the value to insert may not be legal, even though the vector 11230325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman // type is legal. Legalize/Promote accordingly. We do not handle Expand 11240325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman // here. 1125957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman Tmp2 = LegalizeOp(Node->getOperand(1)); 11262332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); 1127fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 11282332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner switch (TLI.getOperationAction(ISD::INSERT_VECTOR_ELT, 11292332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner Node->getValueType(0))) { 11302332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner default: assert(0 && "This action is not supported yet!"); 11312332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner case TargetLowering::Legal: 11322332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner break; 11332332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner case TargetLowering::Custom: 11342281a991414f681c482157265461b29a923ef620Nate Begeman Tmp4 = TLI.LowerOperation(Result, DAG); 1135ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp4.getNode()) { 11362281a991414f681c482157265461b29a923ef620Nate Begeman Result = Tmp4; 11372332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner break; 11382332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner } 11392332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner // FALLTHROUGH 11400c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang case TargetLowering::Promote: 11410c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang // Fall thru for vector case 11422332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner case TargetLowering::Expand: { 11438d5a894501b7546dee94df03118b90126c420820Chris Lattner // If the insert index is a constant, codegen this as a scalar_to_vector, 11448d5a894501b7546dee94df03118b90126c420820Chris Lattner // then a shuffle that inserts it into the right position in the vector. 11458d5a894501b7546dee94df03118b90126c420820Chris Lattner if (ConstantSDNode *InsertPos = dyn_cast<ConstantSDNode>(Tmp3)) { 11460325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman // SCALAR_TO_VECTOR requires that the type of the value being inserted 1147b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands // match the element type of the vector being created, except for 1148b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands // integers in which case the inserted value can be over width. 1149b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands MVT EltVT = Op.getValueType().getVectorElementType(); 1150b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands if (Tmp2.getValueType() == EltVT || 1151b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands (EltVT.isInteger() && Tmp2.getValueType().bitsGE(EltVT))) { 1152ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue ScVec = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, 1153ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson Tmp1.getValueType(), Tmp2); 1154fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 115583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned NumElts = Tmp1.getValueType().getVectorNumElements(); 11560325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman // We generate a shuffle of InVec and ScVec, so the shuffle mask 11570325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman // should be 0,1,2,3,4,5... with the appropriate element replaced with 11580325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman // elt 0 of the RHS. 11599008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVector<int, 8> ShufOps; 11609008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman for (unsigned i = 0; i != NumElts; ++i) 11619008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman ShufOps.push_back(i != InsertPos->getZExtValue() ? i : NumElts); 11629008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 11639008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman Result = DAG.getVectorShuffle(Tmp1.getValueType(), dl, Tmp1, ScVec, 11649008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman &ShufOps[0]); 11650325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman Result = LegalizeOp(Result); 11660325d90348f33e8aa719cd70e4663e7b108297fdNate Begeman break; 11678d5a894501b7546dee94df03118b90126c420820Chris Lattner } 11688d5a894501b7546dee94df03118b90126c420820Chris Lattner } 1169bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Result = PerformInsertVectorEltInMemory(Tmp1, Tmp2, Tmp3, dl); 11702332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner break; 11712332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner } 11722332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner } 11732332b9f16fe17d1886566729b2241b8cd90f9916Chris Lattner break; 11749008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman case ISD::VECTOR_SHUFFLE: { 117587100e0b83b808757bf44dabecd1d1048255d1adChris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the input vectors, 117687100e0b83b808757bf44dabecd1d1048255d1adChris Lattner Tmp2 = LegalizeOp(Node->getOperand(1)); // but not the shuffle mask. 11779008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); 11789008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman MVT VT = Result.getValueType(); 11799008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman 11805a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman // Copy the Mask to a local SmallVector for use with isShuffleMaskLegal. 11819008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVector<int, 8> Mask; 11829008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman cast<ShuffleVectorSDNode>(Result)->getMask(Mask); 118387100e0b83b808757bf44dabecd1d1048255d1adChris Lattner 118487100e0b83b808757bf44dabecd1d1048255d1adChris Lattner // Allow targets to custom lower the SHUFFLEs they support. 11859008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman switch (TLI.getOperationAction(ISD::VECTOR_SHUFFLE, VT)) { 11864352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner default: assert(0 && "Unknown operation action!"); 11874352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner case TargetLowering::Legal: 11889008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman assert(TLI.isShuffleMaskLegal(Mask, VT) && 11894352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner "vector shuffle should not be created if not legal!"); 11904352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner break; 11914352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner case TargetLowering::Custom: 119218dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng Tmp3 = TLI.LowerOperation(Result, DAG); 1193ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()) { 119418dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng Result = Tmp3; 119518dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng break; 119618dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng } 119718dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng // FALLTHROUGH 119818dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng case TargetLowering::Expand: { 119983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT EltVT = VT.getVectorElementType(); 12005a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman unsigned NumElems = VT.getVectorNumElements(); 1201ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson SmallVector<SDValue, 8> Ops; 12025a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman for (unsigned i = 0; i != NumElems; ++i) { 12039008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman if (Mask[i] < 0) { 1204e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen Ops.push_back(DAG.getUNDEF(EltVT)); 12059008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman continue; 120618dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng } 12075a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman unsigned Idx = Mask[i]; 12089008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman if (Idx < NumElems) 12099008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp1, 12109008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman DAG.getIntPtrConstant(Idx))); 12119008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman else 12129008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, Tmp2, 12139008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman DAG.getIntPtrConstant(Idx - NumElems))); 121418dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng } 1215a87008d90b7d894cfca53d407642acfd7be2af3cEvan Cheng Result = DAG.getNode(ISD::BUILD_VECTOR, dl, VT, &Ops[0], Ops.size()); 12164352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner break; 121718dd6d0a2aeb3b827391f46996a7b40c9b1f907aEvan Cheng } 12184352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner case TargetLowering::Promote: { 12194352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // Change base type to a different vector type. 122083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OVT = Node->getValueType(0); 122183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); 12224352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 12234352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // Cast the two input vectors. 1224ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp1); 1225ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2); 1226fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 12274352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // Convert the shuffle mask to the right # elements. 12285a5ca1519e04310f585197c20e7ae584b7f2d11fNate Begeman Result = ShuffleWithNarrowerEltType(NVT, OVT, dl, Tmp1, Tmp2, Mask); 1229ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result); 12304352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner break; 12314352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner } 123287100e0b83b808757bf44dabecd1d1048255d1adChris Lattner } 123387100e0b83b808757bf44dabecd1d1048255d1adChris Lattner break; 12349008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman } 12350c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang case ISD::CONCAT_VECTORS: { 12365ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson // Legalize the operands. 12370c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang SmallVector<SDValue, 8> Ops; 12385ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) 12395ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson Ops.push_back(LegalizeOp(Node->getOperand(i))); 12405ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size()); 12415ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson 12425ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson switch (TLI.getOperationAction(ISD::CONCAT_VECTORS, 12435ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson Node->getValueType(0))) { 12445ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson default: assert(0 && "Unknown operation action!"); 12455ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson case TargetLowering::Legal: 12465ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson break; 12475ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson case TargetLowering::Custom: 12485ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson Tmp3 = TLI.LowerOperation(Result, DAG); 12495ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson if (Tmp3.getNode()) { 12505ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson Result = Tmp3; 12515ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson break; 12525ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson } 12535ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson // FALLTHROUGH 12545ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson case TargetLowering::Expand: { 12555ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson // Use extract/insert/build vector for now. We might try to be 12565ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson // more clever later. 12575ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson MVT PtrVT = TLI.getPointerTy(); 12585ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson SmallVector<SDValue, 8> Ops; 12595ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson unsigned NumOperands = Node->getNumOperands(); 12605ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson for (unsigned i=0; i < NumOperands; ++i) { 12615ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson SDValue SubOp = Node->getOperand(i); 12625ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson MVT VVT = SubOp.getNode()->getValueType(0); 12635ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson MVT EltVT = VVT.getVectorElementType(); 12645ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson unsigned NumSubElem = VVT.getVectorNumElements(); 12655ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson for (unsigned j=0; j < NumSubElem; ++j) { 12665ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson Ops.push_back(DAG.getNode(ISD::EXTRACT_VECTOR_ELT, dl, EltVT, SubOp, 12675ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson DAG.getConstant(j, PtrVT))); 12685ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson } 12690c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang } 12705ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson return LegalizeOp(DAG.getNode(ISD::BUILD_VECTOR, dl, 12715ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson Node->getValueType(0), 12725ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson &Ops[0], Ops.size())); 12730c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang } 12745ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson } 12755ee24e54d76ab86279fe196c03d6e03f5b4b3b3bBob Wilson break; 12760c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang } 12770c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang 12786831a815999dde4cf801e2076e66b4943964daf2Chris Lattner case ISD::CALLSEQ_START: { 12796831a815999dde4cf801e2076e66b4943964daf2Chris Lattner SDNode *CallEnd = FindCallEndFromCallStart(Node); 1280fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 12816831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Recursively Legalize all of the inputs of the call end that do not lead 12826831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // to this call start. This ensures that any libcalls that need be inserted 12836831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // are inserted *before* the CALLSEQ_START. 128400755df36c1448ac4728a74d907aa09e3d8b2d49Chris Lattner {SmallPtrSet<SDNode*, 32> NodesLeadingTo; 12856831a815999dde4cf801e2076e66b4943964daf2Chris Lattner for (unsigned i = 0, e = CallEnd->getNumOperands(); i != e; ++i) 1286ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif LegalizeAllNodesNotLeadingTo(CallEnd->getOperand(i).getNode(), Node, 1287c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner NodesLeadingTo); 1288c9cf4f1a7573ac7e379efd6ad15d7bd0a84a097cChris Lattner } 12896831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 12906831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Now that we legalized all of the inputs (which may have inserted 12916831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // libcalls) create the new CALLSEQ_START node. 12926831a815999dde4cf801e2076e66b4943964daf2Chris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 12936831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 12946831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Merge in the last call, to ensure that this call start after the last 12956831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // call ended. 1296c5d7d7c715f7b7a4eeea1ceaafefc3d1d6df2addChris Lattner if (LastCALLSEQ_END.getOpcode() != ISD::EntryToken) { 1297fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 1298ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1, LastCALLSEQ_END); 1299b248e16afd105fd8c01e08d8bf997b08ff08d127Chris Lattner Tmp1 = LegalizeOp(Tmp1); 1300b248e16afd105fd8c01e08d8bf997b08ff08d127Chris Lattner } 1301fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 13026831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Do not try to legalize the target-specific arguments (#1+). 13036831a815999dde4cf801e2076e66b4943964daf2Chris Lattner if (Tmp1 != Node->getOperand(0)) { 1304475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 13056831a815999dde4cf801e2076e66b4943964daf2Chris Lattner Ops[0] = Tmp1; 1306f06f35e30b4c4d7db304f717a3d4dc6595fbd078Chris Lattner Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size()); 13076831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 1308fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 13096831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Remember that the CALLSEQ_START is legalized. 13104b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner AddLegalizedOperand(Op.getValue(0), Result); 13114b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner if (Node->getNumValues() == 2) // If this has a flag result, remember it. 13124b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner AddLegalizedOperand(Op.getValue(1), Result.getValue(1)); 1313fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 13146831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Now that the callseq_start and all of the non-call nodes above this call 1315fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // sequence have been legalized, legalize the call itself. During this 13166831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // process, no libcalls can/will be inserted, guaranteeing that no calls 13176831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // can overlap. 13186831a815999dde4cf801e2076e66b4943964daf2Chris Lattner assert(!IsLegalizingCall && "Inconsistent sequentialization of calls!"); 13196831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Note that we are selecting this call! 1320475871a144eb604ddaf37503397ba0941442e5fbDan Gohman LastCALLSEQ_END = SDValue(CallEnd, 0); 13216831a815999dde4cf801e2076e66b4943964daf2Chris Lattner IsLegalizingCall = true; 1322fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 13236831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Legalize the call, starting from the CALLSEQ_END. 13246831a815999dde4cf801e2076e66b4943964daf2Chris Lattner LegalizeOp(LastCALLSEQ_END); 13256831a815999dde4cf801e2076e66b4943964daf2Chris Lattner assert(!IsLegalizingCall && "CALLSEQ_END should have cleared this!"); 13266831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return Result; 13276831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 132816cd04d26c53c6f81313cafb85f6c0e7a07cdff6Chris Lattner case ISD::CALLSEQ_END: 13296831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // If the CALLSEQ_START node hasn't been legalized first, legalize it. This 13306831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // will cause this node to be legalized as well as handling libcalls right. 1331ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (LastCALLSEQ_END.getNode() != Node) { 1332475871a144eb604ddaf37503397ba0941442e5fbDan Gohman LegalizeOp(SDValue(FindCallStartFromCallEnd(Node), 0)); 1333475871a144eb604ddaf37503397ba0941442e5fbDan Gohman DenseMap<SDValue, SDValue>::iterator I = LegalizedNodes.find(Op); 13346831a815999dde4cf801e2076e66b4943964daf2Chris Lattner assert(I != LegalizedNodes.end() && 13356831a815999dde4cf801e2076e66b4943964daf2Chris Lattner "Legalizing the call start should have legalized this node!"); 13366831a815999dde4cf801e2076e66b4943964daf2Chris Lattner return I->second; 13376831a815999dde4cf801e2076e66b4943964daf2Chris Lattner } 1338fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1339fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Otherwise, the call start has been legalized and everything is going 13406831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // according to plan. Just legalize ourselves normally here. 13413e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 134270814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner // Do not try to legalize the target-specific arguments (#1+), except for 134370814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner // an optional flag input. 134470814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner if (Node->getOperand(Node->getNumOperands()-1).getValueType() != MVT::Flag){ 134570814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner if (Tmp1 != Node->getOperand(0)) { 1346475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 134770814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Ops[0] = Tmp1; 1348f06f35e30b4c4d7db304f717a3d4dc6595fbd078Chris Lattner Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size()); 134970814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner } 135070814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner } else { 135170814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Tmp2 = LegalizeOp(Node->getOperand(Node->getNumOperands()-1)); 135270814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner if (Tmp1 != Node->getOperand(0) || 135370814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Tmp2 != Node->getOperand(Node->getNumOperands()-1)) { 1354475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Ops(Node->op_begin(), Node->op_end()); 135570814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Ops[0] = Tmp1; 135670814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner Ops.back() = Tmp2; 1357f06f35e30b4c4d7db304f717a3d4dc6595fbd078Chris Lattner Result = DAG.UpdateNodeOperands(Result, &Ops[0], Ops.size()); 135870814bc38435d61a8c7cc32f2375c09e21f12a8aChris Lattner } 13596a5428934ba6159c1acc541944332e51a6cfa59aChris Lattner } 13604b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner assert(IsLegalizingCall && "Call sequence imbalance between start/end?"); 13616831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // This finishes up call legalization. 13626831a815999dde4cf801e2076e66b4943964daf2Chris Lattner IsLegalizingCall = false; 1363fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 13644b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner // If the CALLSEQ_END node has a flag, remember that we legalized it. 1365475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Result.getValue(0)); 13664b653a0405bb16b555334d134c1eb8a97366ec3dChris Lattner if (Node->getNumValues() == 2) 1367475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Result.getValue(1)); 136899a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Result.getValue(Op.getResNo()); 1369a7dce3c6c29fb9513d215c1bc44b01865571b4c2Evan Cheng case ISD::DYNAMIC_STACKALLOC: { 137083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Node->getValueType(0); 1371fa404e8a76abfdafefb8806b35f596d288609496Chris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 1372fa404e8a76abfdafefb8806b35f596d288609496Chris Lattner Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the size. 1373fa404e8a76abfdafefb8806b35f596d288609496Chris Lattner Tmp3 = LegalizeOp(Node->getOperand(2)); // Legalize the alignment. 1374c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); 1375fa404e8a76abfdafefb8806b35f596d288609496Chris Lattner 1376c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp1 = Result.getValue(0); 13775f652295c27826f26547cf5eb4096a59d86b56b8Chris Lattner Tmp2 = Result.getValue(1); 137861bbbabe3da27479cc9a3a36e49091a1141ba7a3Evan Cheng switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 1379a7dce3c6c29fb9513d215c1bc44b01865571b4c2Evan Cheng default: assert(0 && "This action is not supported yet!"); 1380903d278a9b7398d8905c90832e587e0556c52789Chris Lattner case TargetLowering::Expand: { 1381903d278a9b7398d8905c90832e587e0556c52789Chris Lattner unsigned SPReg = TLI.getStackPointerRegisterToSaveRestore(); 1382903d278a9b7398d8905c90832e587e0556c52789Chris Lattner assert(SPReg && "Target cannot require DYNAMIC_STACKALLOC expansion and" 1383903d278a9b7398d8905c90832e587e0556c52789Chris Lattner " not tell us which reg is the stack pointer!"); 1384475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = Tmp1.getOperand(0); 13850f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling 13860f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling // Chain the dynamic stack allocation so that it doesn't modify the stack 13870f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling // pointer when other instructions are using the stack. 1388e563bbc312f8b11ecfe12b8187176f667df1dff3Chris Lattner Chain = DAG.getCALLSEQ_START(Chain, DAG.getIntPtrConstant(0, true)); 13890f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling 1390475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Size = Tmp2.getOperand(1); 1391c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen SDValue SP = DAG.getCopyFromReg(Chain, dl, SPReg, VT); 139261bbbabe3da27479cc9a3a36e49091a1141ba7a3Evan Cheng Chain = SP.getValue(1); 1393f5aeb1a8e4cf272c7348376d185ef8d8267653e0Dan Gohman unsigned Align = cast<ConstantSDNode>(Tmp3)->getZExtValue(); 139461bbbabe3da27479cc9a3a36e49091a1141ba7a3Evan Cheng unsigned StackAlign = 139561bbbabe3da27479cc9a3a36e49091a1141ba7a3Evan Cheng TLI.getTargetMachine().getFrameInfo()->getStackAlignment(); 139661bbbabe3da27479cc9a3a36e49091a1141ba7a3Evan Cheng if (Align > StackAlign) 1397ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SP = DAG.getNode(ISD::AND, dl, VT, SP, 13983e20bba5eb5df2fdd3e6655c8470084cf05032d4Evan Cheng DAG.getConstant(-(uint64_t)Align, VT)); 1399ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1 = DAG.getNode(ISD::SUB, dl, VT, SP, Size); // Value 1400c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen Chain = DAG.getCopyToReg(Chain, dl, SPReg, Tmp1); // Output chain 14010f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling 1402ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getCALLSEQ_END(Chain, DAG.getIntPtrConstant(0, true), 1403e563bbc312f8b11ecfe12b8187176f667df1dff3Chris Lattner DAG.getIntPtrConstant(0, true), SDValue()); 14040f8d9c04d9feef86cee35cf5fecfb348a6b3de50Bill Wendling 1405c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp1 = LegalizeOp(Tmp1); 1406c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp2 = LegalizeOp(Tmp2); 1407903d278a9b7398d8905c90832e587e0556c52789Chris Lattner break; 1408903d278a9b7398d8905c90832e587e0556c52789Chris Lattner } 1409903d278a9b7398d8905c90832e587e0556c52789Chris Lattner case TargetLowering::Custom: 14105f652295c27826f26547cf5eb4096a59d86b56b8Chris Lattner Tmp3 = TLI.LowerOperation(Tmp1, DAG); 1411ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()) { 1412c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp1 = LegalizeOp(Tmp3); 1413c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp2 = LegalizeOp(Tmp3.getValue(1)); 1414a7dce3c6c29fb9513d215c1bc44b01865571b4c2Evan Cheng } 1415903d278a9b7398d8905c90832e587e0556c52789Chris Lattner break; 1416a7dce3c6c29fb9513d215c1bc44b01865571b4c2Evan Cheng case TargetLowering::Legal: 1417903d278a9b7398d8905c90832e587e0556c52789Chris Lattner break; 1418a7dce3c6c29fb9513d215c1bc44b01865571b4c2Evan Cheng } 1419903d278a9b7398d8905c90832e587e0556c52789Chris Lattner // Since this op produce two values, make sure to remember that we 1420903d278a9b7398d8905c90832e587e0556c52789Chris Lattner // legalized both of them. 1421475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Tmp1); 1422475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Tmp2); 142399a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Op.getResNo() ? Tmp2 : Tmp1; 1424a7dce3c6c29fb9513d215c1bc44b01865571b4c2Evan Cheng } 14258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BR_JT: 14268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 14278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Ensure that libcalls are emitted before a branch. 14288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); 14298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = LegalizeOp(Tmp1); 14308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman LastCALLSEQ_END = DAG.getEntryNode(); 143125a022c7801b047b31d7610386e8a9ddca878cb1Chris Lattner 14328c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the jumptable node. 14338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2)); 14343d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng 1435fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel switch (TLI.getOperationAction(ISD::BR_JT, MVT::Other)) { 14363d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng default: assert(0 && "This action is not supported yet!"); 14373d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng case TargetLowering::Legal: break; 14383d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng case TargetLowering::Custom: 14393d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng Tmp1 = TLI.LowerOperation(Result, DAG); 1440ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 14413d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng break; 14423d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng case TargetLowering::Expand: { 1443475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Chain = Result.getOperand(0); 1444475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Table = Result.getOperand(1); 1445475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Index = Result.getOperand(2); 14463d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng 144783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PTy = TLI.getPointerTy(); 1448acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey MachineFunction &MF = DAG.getMachineFunction(); 1449acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey unsigned EntrySize = MF.getJumpTableInfo()->getEntrySize(); 1450fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Index= DAG.getNode(ISD::MUL, dl, PTy, 1451ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Index, DAG.getConstant(EntrySize, PTy)); 1452ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue Addr = DAG.getNode(ISD::ADD, dl, PTy, Index, Table); 1453acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey 1454712f7b3f549644190e90210a07988753f53daa0aDuncan Sands MVT MemVT = MVT::getIntegerVT(EntrySize * 8); 1455ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue LD = DAG.getExtLoad(ISD::SEXTLOAD, dl, PTy, Chain, Addr, 1456712f7b3f549644190e90210a07988753f53daa0aDuncan Sands PseudoSourceValue::getJumpTable(), 0, MemVT); 1457cc41586b9d79532172b37e1f44a9077da4b73fc9Evan Cheng Addr = LD; 1458acd80ac7bb19f8bdfa55336d567c9ecbe695c8b8Jim Laskey if (TLI.getTargetMachine().getRelocationModel() == Reloc::PIC_) { 14593d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng // For PIC, the sequence is: 14603d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng // BRIND(load(Jumptable + index) + RelocBase) 1461cc41586b9d79532172b37e1f44a9077da4b73fc9Evan Cheng // RelocBase can be JumpTable, GOT or some sort of global base. 1462ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Addr = DAG.getNode(ISD::ADD, dl, PTy, Addr, 1463cc41586b9d79532172b37e1f44a9077da4b73fc9Evan Cheng TLI.getPICJumpTableRelocBase(Table, DAG)); 14643d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng } 1465ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::BRIND, dl, MVT::Other, LD.getValue(1), Addr); 14663d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng } 14673d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng } 14683d4ce1108520a4dcf31cb01523e145d286ee64c1Evan Cheng break; 1469c18ae4cb6a263cf31283c0ef51ace24350f8d72bChris Lattner case ISD::BRCOND: 1470c18ae4cb6a263cf31283c0ef51ace24350f8d72bChris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 14716831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Ensure that libcalls are emitted before a return. 1472ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); 14736831a815999dde4cf801e2076e66b4943964daf2Chris Lattner Tmp1 = LegalizeOp(Tmp1); 14746831a815999dde4cf801e2076e66b4943964daf2Chris Lattner LastCALLSEQ_END = DAG.getEntryNode(); 14756831a815999dde4cf801e2076e66b4943964daf2Chris Lattner 1476957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the condition. 1477456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner 1478456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner // Basic block destination (Op#2) is always legal. 1479c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2)); 1480fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1481fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel switch (TLI.getOperationAction(ISD::BRCOND, MVT::Other)) { 14827cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman default: assert(0 && "This action is not supported yet!"); 1483456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Legal: break; 1484456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 1485456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = TLI.LowerOperation(Result, DAG); 1486ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 1487456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner break; 14887cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman case TargetLowering::Expand: 14897cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman // Expand brcond's setcc into its constituent parts and create a BR_CC 14907cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman // Node. 14917cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman if (Tmp2.getOpcode() == ISD::SETCC) { 1492fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getNode(ISD::BR_CC, dl, MVT::Other, 1493ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1, Tmp2.getOperand(2), 14947cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman Tmp2.getOperand(0), Tmp2.getOperand(1), 14957cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman Node->getOperand(2)); 14967cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman } else { 1497fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getNode(ISD::BR_CC, dl, MVT::Other, Tmp1, 14987cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman DAG.getCondCode(ISD::SETNE), Tmp2, 14997cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman DAG.getConstant(0, Tmp2.getValueType()), 15007cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman Node->getOperand(2)); 15017cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman } 15027cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman break; 15037cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman } 15047cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman break; 15057cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman case ISD::BR_CC: 15067cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 15076831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Ensure that libcalls are emitted before a branch. 1508ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1 = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Tmp1, LastCALLSEQ_END); 15096831a815999dde4cf801e2076e66b4943964daf2Chris Lattner Tmp1 = LegalizeOp(Tmp1); 1510fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Tmp2 = Node->getOperand(2); // LHS 1511750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp3 = Node->getOperand(3); // RHS 1512750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp4 = Node->getOperand(1); // CC 1513181b7a382fbdd3d03ce373a6ffac2204e763f9c3Chris Lattner 1514fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel LegalizeSetCC(TLI.getSetCCResultType(Tmp2.getValueType()), 1515bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Tmp2, Tmp3, Tmp4, dl); 1516722cb360690e5d7742b01a9f497fdb65bf8079d5Evan Cheng LastCALLSEQ_END = DAG.getEntryNode(); 1517722cb360690e5d7742b01a9f497fdb65bf8079d5Evan Cheng 15187f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng // If we didn't get both a LHS and RHS back from LegalizeSetCC, 1519750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman // the LHS is a legal SETCC itself. In this case, we need to compare 1520750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman // the result against zero to select between true and false values. 1521ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode() == 0) { 1522750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp3 = DAG.getConstant(0, Tmp2.getValueType()); 1523750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp4 = DAG.getCondCode(ISD::SETNE); 1524750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman } 1525fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1526fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp4, Tmp2, Tmp3, 1527750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Node->getOperand(4)); 1528fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1529181b7a382fbdd3d03ce373a6ffac2204e763f9c3Chris Lattner switch (TLI.getOperationAction(ISD::BR_CC, Tmp3.getValueType())) { 1530181b7a382fbdd3d03ce373a6ffac2204e763f9c3Chris Lattner default: assert(0 && "Unexpected action for BR_CC!"); 1531456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Legal: break; 1532456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 1533456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp4 = TLI.LowerOperation(Result, DAG); 1534ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp4.getNode()) Result = Tmp4; 1535181b7a382fbdd3d03ce373a6ffac2204e763f9c3Chris Lattner break; 15367cbd525ba85ebe440d15fa359ec940e404d14906Nate Begeman } 1537c18ae4cb6a263cf31283c0ef51ace24350f8d72bChris Lattner break; 1538f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng case ISD::LOAD: { 1539466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng LoadSDNode *LD = cast<LoadSDNode>(Node); 1540466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp1 = LegalizeOp(LD->getChain()); // Legalize the chain. 1541466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp2 = LegalizeOp(LD->getBasePtr()); // Legalize the base pointer. 15422d86ea21dd76647cb054fd5d27df9e49efc672b6Andrew Lenharth 1543466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng ISD::LoadExtType ExtType = LD->getExtensionType(); 1544466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng if (ExtType == ISD::NON_EXTLOAD) { 154583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Node->getValueType(0); 1546466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, LD->getOffset()); 1547466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp3 = Result.getValue(0); 1548466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp4 = Result.getValue(1); 1549fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1550466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 1551466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng default: assert(0 && "This action is not supported yet!"); 1552f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio case TargetLowering::Legal: 1553f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If this is an unaligned load and the target doesn't support it, 1554f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // expand it. 1555f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (!TLI.allowsUnalignedMemoryAccesses()) { 1556f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio unsigned ABIAlignment = TLI.getTargetData()-> 155783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands getABITypeAlignment(LD->getMemoryVT().getTypeForMVT()); 1558f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (LD->getAlignment() < ABIAlignment){ 1559ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif Result = ExpandUnalignedLoad(cast<LoadSDNode>(Result.getNode()), DAG, 1560f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio TLI); 1561f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio Tmp3 = Result.getOperand(0); 1562f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio Tmp4 = Result.getOperand(1); 1563907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen Tmp3 = LegalizeOp(Tmp3); 1564907f28ce3032e67c02a50095659e901de867dd3cDale Johannesen Tmp4 = LegalizeOp(Tmp4); 1565f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1566f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1567f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio break; 1568466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng case TargetLowering::Custom: 1569466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp1 = TLI.LowerOperation(Tmp3, DAG); 1570ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) { 1571466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp3 = LegalizeOp(Tmp1); 1572466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng Tmp4 = LegalizeOp(Tmp1.getValue(1)); 1573466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 1574466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 1575466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng case TargetLowering::Promote: { 1576466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // Only promote a load of vector type to another. 157783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(VT.isVector() && "Cannot promote this load!"); 1578466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // Change base type to a different vector type. 157983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), VT); 1580466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng 1581ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1 = DAG.getLoad(NVT, dl, Tmp1, Tmp2, LD->getSrcValue(), 1582d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman LD->getSrcValueOffset(), 1583d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman LD->isVolatile(), LD->getAlignment()); 1584b300d2aa3ef08b5074449e2c05804717f488f4e4Dale Johannesen Tmp3 = LegalizeOp(DAG.getNode(ISD::BIT_CONVERT, dl, VT, Tmp1)); 158541f6cbbeb21d7d4376b8c0302b9766c3e43be5f2Evan Cheng Tmp4 = LegalizeOp(Tmp1.getValue(1)); 1586466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 1587f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 1588466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 1589fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Since loads produce two values, make sure to remember that we 1590466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // legalized both of them. 1591475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Tmp3); 1592475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Tmp4); 159399a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Op.getResNo() ? Tmp4 : Tmp3; 1594466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } else { 159583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT SrcVT = LD->getMemoryVT(); 159683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned SrcWidth = SrcVT.getSizeInBits(); 1597f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands int SVOffset = LD->getSrcValueOffset(); 1598f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands unsigned Alignment = LD->getAlignment(); 1599f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands bool isVolatile = LD->isVolatile(); 1600f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 160183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (SrcWidth != SrcVT.getStoreSizeInBits() && 1602f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Some targets pretend to have an i1 loading operation, and actually 1603f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // load an i8. This trick is correct for ZEXTLOAD because the top 7 1604f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // bits are guaranteed to be zero; it helps the optimizers understand 1605f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // that these bits are zero. It is also useful for EXTLOAD, since it 1606f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // tells the optimizers that those bits are undefined. It would be 1607f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // nice to have an effective generic way of getting these benefits... 1608f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Until such a way is found, don't insist on promoting i1 here. 1609f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands (SrcVT != MVT::i1 || 16100329466b6b4927f4e6f5d144891fef06a027fec5Evan Cheng TLI.getLoadExtAction(ExtType, MVT::i1) == TargetLowering::Promote)) { 1611f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Promote to a byte-sized load if not loading an integral number of 1612f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // bytes. For example, promote EXTLOAD:i20 -> EXTLOAD:i24. 161383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned NewWidth = SrcVT.getStoreSizeInBits(); 161483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NVT = MVT::getIntegerVT(NewWidth); 1615475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Ch; 1616f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1617f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // The extra bits are guaranteed to be zero, since we stored them that 1618f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // way. A zext load from NVT thus automatically gives zext from SrcVT. 1619f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1620f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands ISD::LoadExtType NewExtType = 1621f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands ExtType == ISD::ZEXTLOAD ? ISD::ZEXTLOAD : ISD::EXTLOAD; 1622f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1623ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getExtLoad(NewExtType, dl, Node->getValueType(0), 1624f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1, Tmp2, LD->getSrcValue(), SVOffset, 1625f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands NVT, isVolatile, Alignment); 1626f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1627f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Ch = Result.getValue(1); // The chain. 1628f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1629f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands if (ExtType == ISD::SEXTLOAD) 1630f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Having the top bits zero doesn't help when sign extending. 1631fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, 1632ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result.getValueType(), 1633f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Result, DAG.getValueType(SrcVT)); 1634f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands else if (ExtType == ISD::ZEXTLOAD || NVT == Result.getValueType()) 1635f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // All the top bits are guaranteed to be zero - inform the optimizers. 1636fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getNode(ISD::AssertZext, dl, 1637ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result.getValueType(), Result, 1638f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands DAG.getValueType(SrcVT)); 1639f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1640f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1 = LegalizeOp(Result); 1641f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp2 = LegalizeOp(Ch); 1642f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } else if (SrcWidth & (SrcWidth - 1)) { 1643f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // If not loading a power-of-2 number of bits, expand as two loads. 164483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(SrcVT.isExtended() && !SrcVT.isVector() && 1645f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands "Unsupported extload!"); 1646f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands unsigned RoundWidth = 1 << Log2_32(SrcWidth); 1647f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands assert(RoundWidth < SrcWidth); 1648f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands unsigned ExtraWidth = SrcWidth - RoundWidth; 1649f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands assert(ExtraWidth < RoundWidth); 1650f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands assert(!(RoundWidth % 8) && !(ExtraWidth % 8) && 1651f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands "Load size not an integral number of bytes!"); 165283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT RoundVT = MVT::getIntegerVT(RoundWidth); 165383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT ExtraVT = MVT::getIntegerVT(ExtraWidth); 1654475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi, Ch; 1655f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands unsigned IncrementSize; 1656f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1657f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands if (TLI.isLittleEndian()) { 1658f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // EXTLOAD:i24 -> ZEXTLOAD:i16 | (shl EXTLOAD@+2:i8, 16) 1659f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Load the bottom RoundWidth bits. 1660ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, 1661ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Node->getValueType(0), Tmp1, Tmp2, 1662f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands LD->getSrcValue(), SVOffset, RoundVT, isVolatile, 1663f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Alignment); 1664f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1665f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Load the remaining ExtraWidth bits. 1666f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands IncrementSize = RoundWidth / 8; 1667ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 1668f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands DAG.getIntPtrConstant(IncrementSize)); 1669ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, 1670f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands LD->getSrcValue(), SVOffset + IncrementSize, 1671f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands ExtraVT, isVolatile, 1672f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands MinAlign(Alignment, IncrementSize)); 1673f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1674f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Build a factor node to remember that this load is independent of the 1675f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // other one. 1676ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1677f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Hi.getValue(1)); 1678f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1679f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Move the top bits to the right place. 1680ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, 1681f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands DAG.getConstant(RoundWidth, TLI.getShiftAmountTy())); 1682f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1683f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Join the hi and lo parts. 1684ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); 1685f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } else { 1686f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Big endian - avoid unaligned loads. 1687f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // EXTLOAD:i24 -> (shl EXTLOAD:i16, 8) | ZEXTLOAD@+2:i8 1688f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Load the top RoundWidth bits. 1689ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getExtLoad(ExtType, dl, Node->getValueType(0), Tmp1, Tmp2, 1690f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands LD->getSrcValue(), SVOffset, RoundVT, isVolatile, 1691f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Alignment); 1692f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1693f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Load the remaining ExtraWidth bits. 1694f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands IncrementSize = RoundWidth / 8; 1695ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 1696f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands DAG.getIntPtrConstant(IncrementSize)); 1697fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Lo = DAG.getExtLoad(ISD::ZEXTLOAD, dl, 1698ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Node->getValueType(0), Tmp1, Tmp2, 1699f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands LD->getSrcValue(), SVOffset + IncrementSize, 1700f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands ExtraVT, isVolatile, 1701f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands MinAlign(Alignment, IncrementSize)); 1702f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1703f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Build a factor node to remember that this load is independent of the 1704f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // other one. 1705ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Ch = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo.getValue(1), 1706f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Hi.getValue(1)); 1707f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1708f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Move the top bits to the right place. 1709ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getNode(ISD::SHL, dl, Hi.getValueType(), Hi, 1710f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy())); 1711f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1712f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Join the hi and lo parts. 1713ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::OR, dl, Node->getValueType(0), Lo, Hi); 1714f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } 1715f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1716f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1 = LegalizeOp(Result); 1717f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp2 = LegalizeOp(Ch); 1718f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } else { 17190329466b6b4927f4e6f5d144891fef06a027fec5Evan Cheng switch (TLI.getLoadExtAction(ExtType, SrcVT)) { 1720f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands default: assert(0 && "This action is not supported yet!"); 1721f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands case TargetLowering::Custom: 1722f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands isCustom = true; 1723f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // FALLTHROUGH 1724f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands case TargetLowering::Legal: 1725f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, LD->getOffset()); 1726f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1 = Result.getValue(0); 1727f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp2 = Result.getValue(1); 1728f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1729f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands if (isCustom) { 1730f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp3 = TLI.LowerOperation(Result, DAG); 1731ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()) { 1732f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1 = LegalizeOp(Tmp3); 1733f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp2 = LegalizeOp(Tmp3.getValue(1)); 1734f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } 1735f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } else { 1736f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // If this is an unaligned load and the target doesn't support it, 1737f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // expand it. 1738f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands if (!TLI.allowsUnalignedMemoryAccesses()) { 1739f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands unsigned ABIAlignment = TLI.getTargetData()-> 174083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands getABITypeAlignment(LD->getMemoryVT().getTypeForMVT()); 1741f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands if (LD->getAlignment() < ABIAlignment){ 1742ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif Result = ExpandUnalignedLoad(cast<LoadSDNode>(Result.getNode()), DAG, 1743f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands TLI); 1744f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1 = Result.getOperand(0); 1745f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp2 = Result.getOperand(1); 1746f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1 = LegalizeOp(Tmp1); 1747f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp2 = LegalizeOp(Tmp2); 1748f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } 1749f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1750f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1751f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands break; 1752f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands case TargetLowering::Expand: 1753f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // f64 = EXTLOAD f32 should expand to LOAD, FP_EXTEND 1754f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands if (SrcVT == MVT::f32 && Node->getValueType(0) == MVT::f64) { 1755ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue Load = DAG.getLoad(SrcVT, dl, Tmp1, Tmp2, LD->getSrcValue(), 1756f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands LD->getSrcValueOffset(), 1757f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands LD->isVolatile(), LD->getAlignment()); 1758fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getNode(ISD::FP_EXTEND, dl, 1759ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Node->getValueType(0), Load); 1760f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1 = LegalizeOp(Result); // Relegalize new nodes. 1761f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp2 = LegalizeOp(Load.getValue(1)); 1762f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands break; 1763f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands } 1764f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands assert(ExtType != ISD::EXTLOAD &&"EXTLOAD should always be supported!"); 1765f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // Turn the unsupported load into an EXTLOAD followed by an explicit 1766f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands // zero/sign extend inreg. 1767ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getExtLoad(ISD::EXTLOAD, dl, Node->getValueType(0), 1768f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1, Tmp2, LD->getSrcValue(), 1769f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands LD->getSrcValueOffset(), SrcVT, 1770f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands LD->isVolatile(), LD->getAlignment()); 1771475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue ValRes; 1772f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands if (ExtType == ISD::SEXTLOAD) 1773ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen ValRes = DAG.getNode(ISD::SIGN_EXTEND_INREG, dl, 1774ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result.getValueType(), 1775f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Result, DAG.getValueType(SrcVT)); 1776f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands else 1777ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen ValRes = DAG.getZeroExtendInReg(Result, dl, SrcVT); 1778f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp1 = LegalizeOp(ValRes); // Relegalize new nodes. 1779f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands Tmp2 = LegalizeOp(Result.getValue(1)); // Relegalize new nodes. 1780466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng break; 1781466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng } 17829d416f713e8b9e4f0c0c2b3f6f57ce2dd8993209Andrew Lenharth } 1783f9c98e650d2795b8edfae8e1560c221029df218bDuncan Sands 1784466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // Since loads produce two values, make sure to remember that we legalized 1785466685d41a9ea4905b9486fea38e83802e46f196Evan Cheng // both of them. 1786475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Tmp1); 1787475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Tmp2); 178899a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Op.getResNo() ? Tmp2 : Tmp1; 178901ff7216dd7829d4094754086baf28aa2d7149acChris Lattner } 179001ff7216dd7829d4094754086baf28aa2d7149acChris Lattner } 1791f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng case ISD::STORE: { 17928b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng StoreSDNode *ST = cast<StoreSDNode>(Node); 17938b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng Tmp1 = LegalizeOp(ST->getChain()); // Legalize the chain. 17948b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng Tmp2 = LegalizeOp(ST->getBasePtr()); // Legalize the pointer. 1795d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman int SVOffset = ST->getSrcValueOffset(); 1796d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman unsigned Alignment = ST->getAlignment(); 1797d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman bool isVolatile = ST->isVolatile(); 17988b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng 17998b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng if (!ST->isTruncatingStore()) { 1800d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner // Turn 'store float 1.0, Ptr' -> 'store int 0x12345678, Ptr' 1801d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner // FIXME: We shouldn't do this for TargetConstantFP's. 1802d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner // FIXME: move this to the DAG Combiner! Note that we can't regress due 1803d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner // to phase ordering between legalized code and the dag combiner. This 1804d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner // probably means that we need to integrate dag combiner and legalizer 1805d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner // together. 18069e3d3abd937c9bb79d56d25ec0e0724c7cbba67cDale Johannesen // We generally can't do this one for long doubles. 18072b4c279a8e203fa8b13adf7ba3a5d4c8bef70df3Chris Lattner if (ConstantFPSDNode *CFP = dyn_cast<ConstantFPSDNode>(ST->getValue())) { 1808fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel if (CFP->getValueType(0) == MVT::f32 && 18093cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner getTypeAction(MVT::i32) == Legal) { 18106cf9b8adf43b0a460fb4ba8ddbff2787f5aa9d5eDan Gohman Tmp3 = DAG.getConstant(CFP->getValueAPF(). 18117111b02c734c992b8c97d9918118768026dad79eDale Johannesen bitcastToAPInt().zextOrTrunc(32), 18123f6eb7419de437436265831fce92f62498556e08Dale Johannesen MVT::i32); 1813ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), 18149e3d3abd937c9bb79d56d25ec0e0724c7cbba67cDale Johannesen SVOffset, isVolatile, Alignment); 18159e3d3abd937c9bb79d56d25ec0e0724c7cbba67cDale Johannesen break; 18169e3d3abd937c9bb79d56d25ec0e0724c7cbba67cDale Johannesen } else if (CFP->getValueType(0) == MVT::f64) { 18173cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner // If this target supports 64-bit registers, do a single 64-bit store. 18183cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner if (getTypeAction(MVT::i64) == Legal) { 18197111b02c734c992b8c97d9918118768026dad79eDale Johannesen Tmp3 = DAG.getConstant(CFP->getValueAPF().bitcastToAPInt(). 18206cf9b8adf43b0a460fb4ba8ddbff2787f5aa9d5eDan Gohman zextOrTrunc(64), MVT::i64); 1821ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), 18223cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner SVOffset, isVolatile, Alignment); 18233cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner break; 1824d4b9c17fb705c2f58ceef4f37d789ddb56783584Duncan Sands } else if (getTypeAction(MVT::i32) == Legal && !ST->isVolatile()) { 18253cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner // Otherwise, if the target supports 32-bit registers, use 2 32-bit 18263cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner // stores. If the target supports neither 32- nor 64-bits, this 18273cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner // xform is certainly not worth it. 18287111b02c734c992b8c97d9918118768026dad79eDale Johannesen const APInt &IntVal =CFP->getValueAPF().bitcastToAPInt(); 1829475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo = DAG.getConstant(APInt(IntVal).trunc(32), MVT::i32); 1830475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Hi = DAG.getConstant(IntVal.lshr(32).trunc(32), MVT::i32); 18310753fc1850a1ca4d17acca854d830d67737fd623Duncan Sands if (TLI.isBigEndian()) std::swap(Lo, Hi); 18323cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner 1833ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Lo = DAG.getStore(Tmp1, dl, Lo, Tmp2, ST->getSrcValue(), 18343cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner SVOffset, isVolatile, Alignment); 1835ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 18360bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner DAG.getIntPtrConstant(4)); 1837ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), SVOffset+4, 1838dc84650679b6330e0fcdd4cf8bc2a351387db7caDuncan Sands isVolatile, MinAlign(Alignment, 4U)); 18393cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner 1840ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 18413cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner break; 18423cb9351e8a3691ee8cad6960601c6e3d4b293352Chris Lattner } 1843d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner } 1844d93d46ee7e0a0e539d42139b85c71b2b8c3968feChris Lattner } 1845fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1846957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman { 18478b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng Tmp3 = LegalizeOp(ST->getValue()); 1848fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2, 18498b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng ST->getOffset()); 18508b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng 185183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Tmp3.getValueType(); 18528b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng switch (TLI.getOperationAction(ISD::STORE, VT)) { 18538b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng default: assert(0 && "This action is not supported yet!"); 1854f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio case TargetLowering::Legal: 1855f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // If this is an unaligned store and the target doesn't support it, 1856f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio // expand it. 1857f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (!TLI.allowsUnalignedMemoryAccesses()) { 1858f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio unsigned ABIAlignment = TLI.getTargetData()-> 185983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands getABITypeAlignment(ST->getMemoryVT().getTypeForMVT()); 1860f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio if (ST->getAlignment() < ABIAlignment) 1861ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.getNode()), DAG, 1862f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio TLI); 1863f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 1864f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio break; 18658b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng case TargetLowering::Custom: 18668b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng Tmp1 = TLI.LowerOperation(Result, DAG); 1867ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 18688b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng break; 18698b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng case TargetLowering::Promote: 187083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(VT.isVector() && "Unknown legal promote case!"); 1871fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Tmp3 = DAG.getNode(ISD::BIT_CONVERT, dl, 18728b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng TLI.getTypeToPromoteTo(ISD::STORE, VT), Tmp3); 1873ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, 1874d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman ST->getSrcValue(), SVOffset, isVolatile, 1875d6fd1bc122ba791c698255d8be158b8ec424e248Dan Gohman Alignment); 18768b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng break; 18778b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } 18782efce0a589e2a688a1a06b5dc2ed0db32ae79924Chris Lattner break; 1879f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 18808b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } else { 1881957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman Tmp3 = LegalizeOp(ST->getValue()); 18827e857201f387d004571e6058e2ea709163500f38Duncan Sands 188383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT StVT = ST->getMemoryVT(); 188483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned StWidth = StVT.getSizeInBits(); 18857e857201f387d004571e6058e2ea709163500f38Duncan Sands 188683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (StWidth != StVT.getStoreSizeInBits()) { 18877e857201f387d004571e6058e2ea709163500f38Duncan Sands // Promote to a byte-sized store with upper bits zero if not 18887e857201f387d004571e6058e2ea709163500f38Duncan Sands // storing an integral number of bytes. For example, promote 18897e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i1 X -> TRUNCSTORE:i8 (and X, 1) 189083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NVT = MVT::getIntegerVT(StVT.getStoreSizeInBits()); 1891ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp3 = DAG.getZeroExtendInReg(Tmp3, dl, StVT); 1892ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), 18937e857201f387d004571e6058e2ea709163500f38Duncan Sands SVOffset, NVT, isVolatile, Alignment); 18947e857201f387d004571e6058e2ea709163500f38Duncan Sands } else if (StWidth & (StWidth - 1)) { 18957e857201f387d004571e6058e2ea709163500f38Duncan Sands // If not storing a power-of-2 number of bits, expand as two stores. 189683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(StVT.isExtended() && !StVT.isVector() && 18977e857201f387d004571e6058e2ea709163500f38Duncan Sands "Unsupported truncstore!"); 18987e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned RoundWidth = 1 << Log2_32(StWidth); 18997e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(RoundWidth < StWidth); 19007e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned ExtraWidth = StWidth - RoundWidth; 19017e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(ExtraWidth < RoundWidth); 19027e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(!(RoundWidth % 8) && !(ExtraWidth % 8) && 19037e857201f387d004571e6058e2ea709163500f38Duncan Sands "Store size not an integral number of bytes!"); 190483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT RoundVT = MVT::getIntegerVT(RoundWidth); 190583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT ExtraVT = MVT::getIntegerVT(ExtraWidth); 1906475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Lo, Hi; 19077e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned IncrementSize; 19087e857201f387d004571e6058e2ea709163500f38Duncan Sands 19097e857201f387d004571e6058e2ea709163500f38Duncan Sands if (TLI.isLittleEndian()) { 19107e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 X, TRUNCSTORE@+2:i8 (srl X, 16) 19117e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the bottom RoundWidth bits. 1912ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), 19137e857201f387d004571e6058e2ea709163500f38Duncan Sands SVOffset, RoundVT, 19147e857201f387d004571e6058e2ea709163500f38Duncan Sands isVolatile, Alignment); 19157e857201f387d004571e6058e2ea709163500f38Duncan Sands 19167e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the remaining ExtraWidth bits. 19177e857201f387d004571e6058e2ea709163500f38Duncan Sands IncrementSize = RoundWidth / 8; 1918ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 19197e857201f387d004571e6058e2ea709163500f38Duncan Sands DAG.getIntPtrConstant(IncrementSize)); 1920ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, 19217e857201f387d004571e6058e2ea709163500f38Duncan Sands DAG.getConstant(RoundWidth, TLI.getShiftAmountTy())); 1922ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), 19237e857201f387d004571e6058e2ea709163500f38Duncan Sands SVOffset + IncrementSize, ExtraVT, isVolatile, 19247e857201f387d004571e6058e2ea709163500f38Duncan Sands MinAlign(Alignment, IncrementSize)); 19257e857201f387d004571e6058e2ea709163500f38Duncan Sands } else { 19267e857201f387d004571e6058e2ea709163500f38Duncan Sands // Big endian - avoid unaligned stores. 19277e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i24 X -> TRUNCSTORE:i16 (srl X, 8), TRUNCSTORE@+2:i8 X 19287e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the top RoundWidth bits. 1929ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getNode(ISD::SRL, dl, Tmp3.getValueType(), Tmp3, 19307e857201f387d004571e6058e2ea709163500f38Duncan Sands DAG.getConstant(ExtraWidth, TLI.getShiftAmountTy())); 1931ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Hi = DAG.getTruncStore(Tmp1, dl, Hi, Tmp2, ST->getSrcValue(), 1932ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SVOffset, RoundVT, isVolatile, Alignment); 19337e857201f387d004571e6058e2ea709163500f38Duncan Sands 19347e857201f387d004571e6058e2ea709163500f38Duncan Sands // Store the remaining ExtraWidth bits. 19357e857201f387d004571e6058e2ea709163500f38Duncan Sands IncrementSize = RoundWidth / 8; 1936ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ADD, dl, Tmp2.getValueType(), Tmp2, 19377e857201f387d004571e6058e2ea709163500f38Duncan Sands DAG.getIntPtrConstant(IncrementSize)); 1938ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Lo = DAG.getTruncStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), 19397e857201f387d004571e6058e2ea709163500f38Duncan Sands SVOffset + IncrementSize, ExtraVT, isVolatile, 19407e857201f387d004571e6058e2ea709163500f38Duncan Sands MinAlign(Alignment, IncrementSize)); 19417e857201f387d004571e6058e2ea709163500f38Duncan Sands } 1942c7029805ef35ce9805931067b841e6af11db382eChris Lattner 19437e857201f387d004571e6058e2ea709163500f38Duncan Sands // The order of the stores doesn't matter. 1944ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, Lo, Hi); 19457e857201f387d004571e6058e2ea709163500f38Duncan Sands } else { 19467e857201f387d004571e6058e2ea709163500f38Duncan Sands if (Tmp1 != ST->getChain() || Tmp3 != ST->getValue() || 19477e857201f387d004571e6058e2ea709163500f38Duncan Sands Tmp2 != ST->getBasePtr()) 19487e857201f387d004571e6058e2ea709163500f38Duncan Sands Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp3, Tmp2, 19497e857201f387d004571e6058e2ea709163500f38Duncan Sands ST->getOffset()); 19507e857201f387d004571e6058e2ea709163500f38Duncan Sands 19517e857201f387d004571e6058e2ea709163500f38Duncan Sands switch (TLI.getTruncStoreAction(ST->getValue().getValueType(), StVT)) { 19527e857201f387d004571e6058e2ea709163500f38Duncan Sands default: assert(0 && "This action is not supported yet!"); 19537e857201f387d004571e6058e2ea709163500f38Duncan Sands case TargetLowering::Legal: 19547e857201f387d004571e6058e2ea709163500f38Duncan Sands // If this is an unaligned store and the target doesn't support it, 19557e857201f387d004571e6058e2ea709163500f38Duncan Sands // expand it. 19567e857201f387d004571e6058e2ea709163500f38Duncan Sands if (!TLI.allowsUnalignedMemoryAccesses()) { 19577e857201f387d004571e6058e2ea709163500f38Duncan Sands unsigned ABIAlignment = TLI.getTargetData()-> 195883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands getABITypeAlignment(ST->getMemoryVT().getTypeForMVT()); 19597e857201f387d004571e6058e2ea709163500f38Duncan Sands if (ST->getAlignment() < ABIAlignment) 1960ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif Result = ExpandUnalignedStore(cast<StoreSDNode>(Result.getNode()), DAG, 19617e857201f387d004571e6058e2ea709163500f38Duncan Sands TLI); 19627e857201f387d004571e6058e2ea709163500f38Duncan Sands } 19637e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 19647e857201f387d004571e6058e2ea709163500f38Duncan Sands case TargetLowering::Custom: 19657e857201f387d004571e6058e2ea709163500f38Duncan Sands Result = TLI.LowerOperation(Result, DAG); 19667e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 19677e857201f387d004571e6058e2ea709163500f38Duncan Sands case Expand: 19687e857201f387d004571e6058e2ea709163500f38Duncan Sands // TRUNCSTORE:i16 i32 -> STORE i16 19697e857201f387d004571e6058e2ea709163500f38Duncan Sands assert(isTypeLegal(StVT) && "Do not know how to expand this store!"); 1970ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp3 = DAG.getNode(ISD::TRUNCATE, dl, StVT, Tmp3); 1971ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getStore(Tmp1, dl, Tmp3, Tmp2, ST->getSrcValue(), 1972ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SVOffset, isVolatile, Alignment); 19737e857201f387d004571e6058e2ea709163500f38Duncan Sands break; 1974f3c13c82e34b8e90f1080cfe06c6f1328a2d44e1Lauro Ramos Venancio } 19758b2794aeff151be8cdbd44786c1d0f94f8f2e427Evan Cheng } 19763e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 19773e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 1978f3fd9fe20dbcb40f3dffc1518ab955a0b5d6fa23Evan Cheng } 1979140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner case ISD::STACKSAVE: 1980140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 1981c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1); 1982c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp1 = Result.getValue(0); 1983c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp2 = Result.getValue(1); 1984fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 1985140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner switch (TLI.getOperationAction(ISD::STACKSAVE, MVT::Other)) { 1986140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner default: assert(0 && "This action is not supported yet!"); 1987456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Legal: break; 1988456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 1989c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp3 = TLI.LowerOperation(Result, DAG); 1990ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp3.getNode()) { 1991c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp1 = LegalizeOp(Tmp3); 1992c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp2 = LegalizeOp(Tmp3.getValue(1)); 1993140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner } 1994456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner break; 1995140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner case TargetLowering::Expand: 1996fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Expand to CopyFromReg if the target set 19974f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner // StackPointerRegisterToSaveRestore. 19984f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) { 1999c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen Tmp1 = DAG.getCopyFromReg(Result.getOperand(0), dl, SP, 20004f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner Node->getValueType(0)); 2001c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp2 = Tmp1.getValue(1); 20024f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner } else { 2003e8d7230f480654cdb8ff1c3d0a38e1e9ab0bd55fDale Johannesen Tmp1 = DAG.getUNDEF(Node->getValueType(0)); 2004c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp2 = Node->getOperand(0); 20054f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner } 2006456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner break; 2007140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner } 2008456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner 2009456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner // Since stacksave produce two values, make sure to remember that we 2010456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner // legalized both of them. 2011475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Tmp1); 2012475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Tmp2); 201399a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Op.getResNo() ? Tmp2 : Tmp1; 2014456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner 2015140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner case ISD::STACKRESTORE: 2016140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 2017140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. 2018c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); 2019fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2020140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner switch (TLI.getOperationAction(ISD::STACKRESTORE, MVT::Other)) { 2021140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner default: assert(0 && "This action is not supported yet!"); 2022456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Legal: break; 2023456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 2024456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = TLI.LowerOperation(Result, DAG); 2025ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 2026140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner break; 2027140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner case TargetLowering::Expand: 2028fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Expand to CopyToReg if the target set 20294f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner // StackPointerRegisterToSaveRestore. 20304f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner if (unsigned SP = TLI.getStackPointerRegisterToSaveRestore()) { 2031c460ae90019ddb19d4c07b2cd2fbaecfa7adf67dDale Johannesen Result = DAG.getCopyToReg(Tmp1, dl, SP, Tmp2); 20324f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner } else { 20334f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner Result = Tmp1; 20344f0d8e4018d50c5796660a4fa167763f46259646Chris Lattner } 2035140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner break; 2036140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner } 2037140d53c99c3a70b9d3858a3c87f8ecb098994748Chris Lattner break; 20382ee743ff9be43c350075a2fa15d11a79bff36775Chris Lattner case ISD::SELECT: 2039957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the condition. 20403e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner Tmp2 = LegalizeOp(Node->getOperand(1)); // TrueVal 20412ee743ff9be43c350075a2fa15d11a79bff36775Chris Lattner Tmp3 = LegalizeOp(Node->getOperand(2)); // FalseVal 204255ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner 2043c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); 2044fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2045b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman switch (TLI.getOperationAction(ISD::SELECT, Tmp2.getValueType())) { 204655ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner default: assert(0 && "This action is not supported yet!"); 2047456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Legal: break; 2048456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: { 2049456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = TLI.LowerOperation(Result, DAG); 2050ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 2051456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner break; 2052456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner } 20539373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman case TargetLowering::Expand: 20549373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman if (Tmp1.getOpcode() == ISD::SETCC) { 2055fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getSelectCC(dl, Tmp1.getOperand(0), Tmp1.getOperand(1), 20569373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman Tmp2, Tmp3, 20579373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman cast<CondCodeSDNode>(Tmp1.getOperand(2))->get()); 20589373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman } else { 2059fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getSelectCC(dl, Tmp1, 20609373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman DAG.getConstant(0, Tmp1.getValueType()), 20619373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman Tmp2, Tmp3, ISD::SETNE); 20629373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman } 206355ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner break; 206455ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner case TargetLowering::Promote: { 206583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NVT = 206655ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner TLI.getTypeToPromoteTo(ISD::SELECT, Tmp2.getValueType()); 206755ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner unsigned ExtOp, TruncOp; 206883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (Tmp2.getValueType().isVector()) { 206941f6cbbeb21d7d4376b8c0302b9766c3e43be5f2Evan Cheng ExtOp = ISD::BIT_CONVERT; 207041f6cbbeb21d7d4376b8c0302b9766c3e43be5f2Evan Cheng TruncOp = ISD::BIT_CONVERT; 207183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands } else if (Tmp2.getValueType().isInteger()) { 2072456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner ExtOp = ISD::ANY_EXTEND; 2073456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner TruncOp = ISD::TRUNCATE; 207455ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner } else { 2075456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner ExtOp = ISD::FP_EXTEND; 2076456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner TruncOp = ISD::FP_ROUND; 207755ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner } 207855ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner // Promote each of the values to the new type. 2079ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ExtOp, dl, NVT, Tmp2); 2080ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp3 = DAG.getNode(ExtOp, dl, NVT, Tmp3); 208155ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner // Perform the larger operation, then round down. 2082ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson Result = DAG.getNode(ISD::SELECT, dl, NVT, Tmp1, Tmp2, Tmp3); 20830bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner if (TruncOp != ISD::FP_ROUND) 2084ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(TruncOp, dl, Node->getValueType(0), Result); 20850bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner else 2086ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(TruncOp, dl, Node->getValueType(0), Result, 20870bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner DAG.getIntPtrConstant(0)); 208855ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner break; 208955ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner } 209055ba8fba750ee0a51a9d74fa33b7242d24a4ff35Chris Lattner } 20913e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 2092750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman case ISD::SELECT_CC: { 2093750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp1 = Node->getOperand(0); // LHS 2094750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp2 = Node->getOperand(1); // RHS 20959373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman Tmp3 = LegalizeOp(Node->getOperand(2)); // True 20969373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman Tmp4 = LegalizeOp(Node->getOperand(3)); // False 2097475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CC = Node->getOperand(4); 2098fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2099fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel LegalizeSetCC(TLI.getSetCCResultType(Tmp1.getValueType()), 2100bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen Tmp1, Tmp2, CC, dl); 2101fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 21027f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng // If we didn't get both a LHS and RHS back from LegalizeSetCC, 2103750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman // the LHS is a legal SETCC itself. In this case, we need to compare 2104750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman // the result against zero to select between true and false values. 2105ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp2.getNode() == 0) { 2106750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp2 = DAG.getConstant(0, Tmp1.getValueType()); 2107750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman CC = DAG.getCondCode(ISD::SETNE); 2108750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman } 2109750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3, Tmp4, CC); 2110750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman 2111750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman // Everything is legal, see if we should expand this op or something. 2112750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman switch (TLI.getOperationAction(ISD::SELECT_CC, Tmp3.getValueType())) { 2113750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman default: assert(0 && "This action is not supported yet!"); 2114750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman case TargetLowering::Legal: break; 2115750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman case TargetLowering::Custom: 2116750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp1 = TLI.LowerOperation(Result, DAG); 2117ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 21189373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman break; 21199373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman } 21209373a81e53ce5f9f2c06c4209b8b886605aece08Nate Begeman break; 2121750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman } 21223e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::SETCC: 2123750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp1 = Node->getOperand(0); 2124750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp2 = Node->getOperand(1); 2125750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Tmp3 = Node->getOperand(2); 2126bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen LegalizeSetCC(Node->getValueType(0), Tmp1, Tmp2, Tmp3, dl); 2127fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2128fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // If we had to Expand the SetCC operands into a SELECT node, then it may 2129fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // not always be possible to return a true LHS & RHS. In this case, just 2130750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman // return the value we legalized, returned in the LHS 2131ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp2.getNode() == 0) { 2132750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman Result = Tmp1; 21333e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 21343e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner } 2135b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman 213673e142f2b6a3b5223de2d557d646f319ca8168cfChris Lattner switch (TLI.getOperationAction(ISD::SETCC, Tmp1.getValueType())) { 2137456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner default: assert(0 && "Cannot handle this action for SETCC yet!"); 2138456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 2139456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner isCustom = true; 2140456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner // FALLTHROUGH. 2141456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Legal: 21422b49c500838666dd0186d021389d4dd70ffda240Evan Cheng Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); 2143456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner if (isCustom) { 21442b49c500838666dd0186d021389d4dd70ffda240Evan Cheng Tmp4 = TLI.LowerOperation(Result, DAG); 2145ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp4.getNode()) Result = Tmp4; 2146456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner } 2147b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman break; 2148ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth case TargetLowering::Promote: { 2149ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth // First step, figure out the appropriate operation to use. 2150ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth // Allow SETCC to not be supported for all legal data types 2151ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth // Mostly this targets FP 215283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NewInTy = Node->getOperand(0).getValueType(); 215383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OldVT = NewInTy; OldVT = OldVT; 2154ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth 2155ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth // Scan for the appropriate larger type to use. 2156ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth while (1) { 215783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands NewInTy = (MVT::SimpleValueType)(NewInTy.getSimpleVT()+1); 2158ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth 215983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(NewInTy.isInteger() == OldVT.isInteger() && 2160ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth "Fell off of the edge of the integer world"); 216183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(NewInTy.isFloatingPoint() == OldVT.isFloatingPoint() && 2162ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth "Fell off of the edge of the floating point world"); 2163fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2164ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth // If the target supports SETCC of this type, use it. 2165f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman if (TLI.isOperationLegalOrCustom(ISD::SETCC, NewInTy)) 2166ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth break; 2167ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth } 216883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands if (NewInTy.isInteger()) 2169ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth assert(0 && "Cannot promote Legal Integer SETCC yet"); 2170ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth else { 2171ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1 = DAG.getNode(ISD::FP_EXTEND, dl, NewInTy, Tmp1); 2172ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::FP_EXTEND, dl, NewInTy, Tmp2); 2173ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth } 2174c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp1 = LegalizeOp(Tmp1); 2175c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Tmp2 = LegalizeOp(Tmp2); 21762b49c500838666dd0186d021389d4dd70ffda240Evan Cheng Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Tmp3); 2177433f8acefb78f1c8a2cf79c12b101ce7c4b20202Evan Cheng Result = LegalizeOp(Result); 21785e3efbc2ca459621400211f7370d7f121d4827d9Andrew Lenharth break; 2179ae35575957a3ab446e2766aa05d03020ced27d14Andrew Lenharth } 2180b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman case TargetLowering::Expand: 2181b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman // Expand a setcc node into a select_cc of the same condition, lhs, and 2182b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman // rhs that selects between const 1 (true) and const 0 (false). 218383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Node->getValueType(0); 2184fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getNode(ISD::SELECT_CC, dl, VT, Tmp1, Tmp2, 2185b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman DAG.getConstant(1, VT), DAG.getConstant(0, VT), 21862b49c500838666dd0186d021389d4dd70ffda240Evan Cheng Tmp3); 2187b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman break; 2188b942a3dd5f9318b2c57f137d2991440c2f0262adNate Begeman } 21893e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 21902c8086f4b9916b2d02842be5e375276023225fbaChris Lattner 21912c8086f4b9916b2d02842be5e375276023225fbaChris Lattner // Binary operators 21923e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::ADD: 21933e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::SUB: 21943e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::MUL: 2195c7c16575fea9aeffe8a63ddabe7c3c25f81ed799Nate Begeman case ISD::MULHS: 2196c7c16575fea9aeffe8a63ddabe7c3c25f81ed799Nate Begeman case ISD::MULHU: 21973e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::UDIV: 21983e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::SDIV: 21993e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::AND: 22003e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::OR: 22013e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner case ISD::XOR: 220203c0cf822e9a57109d1b4e6a2705d68852c93e1dChris Lattner case ISD::SHL: 220303c0cf822e9a57109d1b4e6a2705d68852c93e1dChris Lattner case ISD::SRL: 220403c0cf822e9a57109d1b4e6a2705d68852c93e1dChris Lattner case ISD::SRA: 220501b3d73c20f5afb8265ae943a8ba23c2238c5eeaChris Lattner case ISD::FADD: 220601b3d73c20f5afb8265ae943a8ba23c2238c5eeaChris Lattner case ISD::FSUB: 220701b3d73c20f5afb8265ae943a8ba23c2238c5eeaChris Lattner case ISD::FMUL: 220801b3d73c20f5afb8265ae943a8ba23c2238c5eeaChris Lattner case ISD::FDIV: 2209826695281344e3a4c4d44d73dd155107aafd689bDan Gohman case ISD::FPOW: 22103e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS 221192abc62399881ba9c525be80362c134ad836e2d9Duncan Sands Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS 221292abc62399881ba9c525be80362c134ad836e2d9Duncan Sands 221392abc62399881ba9c525be80362c134ad836e2d9Duncan Sands if ((Node->getOpcode() == ISD::SHL || 221492abc62399881ba9c525be80362c134ad836e2d9Duncan Sands Node->getOpcode() == ISD::SRL || 221592abc62399881ba9c525be80362c134ad836e2d9Duncan Sands Node->getOpcode() == ISD::SRA) && 221692abc62399881ba9c525be80362c134ad836e2d9Duncan Sands !Node->getValueType(0).isVector()) 221792abc62399881ba9c525be80362c134ad836e2d9Duncan Sands Tmp2 = DAG.getShiftAmountOperand(Tmp2); 221892abc62399881ba9c525be80362c134ad836e2d9Duncan Sands 2219957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman Tmp2 = LegalizeOp(Tmp2); // Legalize the RHS. 22205bc1ea0736a5785ed596d58beeff2ab23909e33dNate Begeman 2221c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); 2222aeb06d246254e4829a49164a11eacced9a43d9d4Mon P Wang 2223e8f65f1e62ea1d4f2ca9fd0137ae2e0ce20e26e1Andrew Lenharth switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { 2224bc70cf8be95f33f9aa30c8c3d0fd79e3fa636360Chris Lattner default: assert(0 && "BinOp legalize operation not supported"); 2225456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Legal: break; 2226456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 2227456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = TLI.LowerOperation(Result, DAG); 2228ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) { 22295bc1ea0736a5785ed596d58beeff2ab23909e33dNate Begeman Result = Tmp1; 22305bc1ea0736a5785ed596d58beeff2ab23909e33dNate Begeman break; 223124dc346a16397bf740d8d961cd1ebec8d2f46957Nate Begeman } 22325bc1ea0736a5785ed596d58beeff2ab23909e33dNate Begeman // Fall through if the custom lower can't deal with the operation 2233bc70cf8be95f33f9aa30c8c3d0fd79e3fa636360Chris Lattner case TargetLowering::Expand: { 223483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Op.getValueType(); 2235fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2236525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman // See if multiply or divide can be lowered using two-result operations. 2237525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman SDVTList VTs = DAG.getVTList(VT, VT); 2238525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman if (Node->getOpcode() == ISD::MUL) { 2239525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman // We just need the low half of the multiply; try both the signed 2240525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman // and unsigned forms. If the target supports both SMUL_LOHI and 2241525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman // UMUL_LOHI, form a preference by checking which forms of plain 2242525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman // MULH it supports. 2243f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman bool HasSMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT); 2244f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman bool HasUMUL_LOHI = TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT); 2245f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman bool HasMULHS = TLI.isOperationLegalOrCustom(ISD::MULHS, VT); 2246f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman bool HasMULHU = TLI.isOperationLegalOrCustom(ISD::MULHU, VT); 2247525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman unsigned OpToUse = 0; 2248525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman if (HasSMUL_LOHI && !HasMULHS) { 2249525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman OpToUse = ISD::SMUL_LOHI; 2250525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } else if (HasUMUL_LOHI && !HasMULHU) { 2251525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman OpToUse = ISD::UMUL_LOHI; 2252525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } else if (HasSMUL_LOHI) { 2253525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman OpToUse = ISD::SMUL_LOHI; 2254525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } else if (HasUMUL_LOHI) { 2255525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman OpToUse = ISD::UMUL_LOHI; 2256525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2257525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman if (OpToUse) { 2258a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands Result = DAG.getNode(OpToUse, dl, VTs, Tmp1, Tmp2); 2259525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman break; 2260525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2261525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2262525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman if (Node->getOpcode() == ISD::MULHS && 2263f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::SMUL_LOHI, VT)) { 2264fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = SDValue(DAG.getNode(ISD::SMUL_LOHI, dl, 2265ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen VTs, Tmp1, Tmp2).getNode(), 226631d7161206d7502e97a01a51a76445a8d9ac6ea5Chris Lattner 1); 2267525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman break; 2268525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2269fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel if (Node->getOpcode() == ISD::MULHU && 2270f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::UMUL_LOHI, VT)) { 2271ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = SDValue(DAG.getNode(ISD::UMUL_LOHI, dl, 2272ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen VTs, Tmp1, Tmp2).getNode(), 227331d7161206d7502e97a01a51a76445a8d9ac6ea5Chris Lattner 1); 2274525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman break; 2275525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2276525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman if (Node->getOpcode() == ISD::SDIV && 2277f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) { 2278a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands Result = DAG.getNode(ISD::SDIVREM, dl, VTs, Tmp1, Tmp2); 2279525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman break; 2280525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2281525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman if (Node->getOpcode() == ISD::UDIV && 2282f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) { 2283a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands Result = DAG.getNode(ISD::UDIVREM, dl, VTs, Tmp1, Tmp2); 2284a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands break; 2285a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands } 2286a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands if (Node->getOpcode() == ISD::SUB && 2287a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands TLI.isOperationLegalOrCustom(ISD::ADD, VT) && 2288a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands TLI.isOperationLegalOrCustom(ISD::XOR, VT)) { 2289a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands Tmp2 = DAG.getNode(ISD::XOR, dl, VT, Tmp2, 2290a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands DAG.getConstant(APInt::getAllOnesValue(VT.getSizeInBits()), VT)); 2291a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands Tmp2 = DAG.getNode(ISD::ADD, dl, VT, Tmp2, DAG.getConstant(1, VT)); 2292a9cad0e7e09e6d34de2fccb4f1294b7f0b8f3b68Duncan Sands Result = DAG.getNode(ISD::ADD, dl, VT, Tmp1, Tmp2); 2293525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman break; 2294525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 229587c8a8f304d1ee72829086ce2c41a8fa3813ba6aMon P Wang 2296826695281344e3a4c4d44d73dd155107aafd689bDan Gohman // Check to see if we have a libcall for this operator. 2297826695281344e3a4c4d44d73dd155107aafd689bDan Gohman RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 2298826695281344e3a4c4d44d73dd155107aafd689bDan Gohman bool isSigned = false; 2299826695281344e3a4c4d44d73dd155107aafd689bDan Gohman switch (Node->getOpcode()) { 2300826695281344e3a4c4d44d73dd155107aafd689bDan Gohman case ISD::UDIV: 2301826695281344e3a4c4d44d73dd155107aafd689bDan Gohman case ISD::SDIV: 2302813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov isSigned = Node->getOpcode() == ISD::SDIV; 2303813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov if (VT == MVT::i16) 2304813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov LC = (isSigned ? RTLIB::SDIV_I16 : RTLIB::UDIV_I16); 2305813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov else if (VT == MVT::i32) 2306813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov LC = (isSigned ? RTLIB::SDIV_I32 : RTLIB::UDIV_I32); 2307813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov else if (VT == MVT::i64) 2308813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov LC = (isSigned ? RTLIB::SDIV_I64 : RTLIB::UDIV_I64); 2309813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov else if (VT == MVT::i128) 2310813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov LC = (isSigned ? RTLIB::SDIV_I128 : RTLIB::UDIV_I128); 2311813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov break; 231231d7161206d7502e97a01a51a76445a8d9ac6ea5Chris Lattner case ISD::MUL: 23132f25c2c63fdc46c3b5b093b5cbdc6729f12a413aAnton Korobeynikov if (VT == MVT::i16) 23142f25c2c63fdc46c3b5b093b5cbdc6729f12a413aAnton Korobeynikov LC = RTLIB::MUL_I16; 2315813090cf891325c715b9f6fb1546e6ce67fa8c8bAnton Korobeynikov else if (VT == MVT::i32) 231631d7161206d7502e97a01a51a76445a8d9ac6ea5Chris Lattner LC = RTLIB::MUL_I32; 23179b9948507474acd3c5941ad7d33a37cb066803adNate Begeman else if (VT == MVT::i64) 2318845145f8b5f7feb8617bcfcfd3803ef80b17765dScott Michel LC = RTLIB::MUL_I64; 23192f25c2c63fdc46c3b5b093b5cbdc6729f12a413aAnton Korobeynikov else if (VT == MVT::i128) 23202f25c2c63fdc46c3b5b093b5cbdc6729f12a413aAnton Korobeynikov LC = RTLIB::MUL_I128; 232131d7161206d7502e97a01a51a76445a8d9ac6ea5Chris Lattner break; 2322826695281344e3a4c4d44d73dd155107aafd689bDan Gohman case ISD::FPOW: 2323007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands LC = GetFPLibCall(VT, RTLIB::POW_F32, RTLIB::POW_F64, RTLIB::POW_F80, 2324007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::POW_PPCF128); 2325826695281344e3a4c4d44d73dd155107aafd689bDan Gohman break; 2326d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel case ISD::FDIV: 2327d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel LC = GetFPLibCall(VT, RTLIB::DIV_F32, RTLIB::DIV_F64, RTLIB::DIV_F80, 2328d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel RTLIB::DIV_PPCF128); 2329d1e8d9c0a5dc821b6b52f7872181edeeec5df7baScott Michel break; 2330826695281344e3a4c4d44d73dd155107aafd689bDan Gohman default: break; 2331826695281344e3a4c4d44d73dd155107aafd689bDan Gohman } 2332826695281344e3a4c4d44d73dd155107aafd689bDan Gohman if (LC != RTLIB::UNKNOWN_LIBCALL) { 2333475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Dummy; 2334460a14e09c2af630fc1e840dcb3e0f725663067bDuncan Sands Result = ExpandLibCall(LC, Node, isSigned, Dummy); 233552cc1ea2a1a374b58801398460a6289723089d91Evan Cheng break; 233652cc1ea2a1a374b58801398460a6289723089d91Evan Cheng } 2337fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 233874807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman assert(0 && "Cannot expand this binary operator!"); 2339bc70cf8be95f33f9aa30c8c3d0fd79e3fa636360Chris Lattner break; 2340bc70cf8be95f33f9aa30c8c3d0fd79e3fa636360Chris Lattner } 2341cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng case TargetLowering::Promote: { 2342cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng switch (Node->getOpcode()) { 2343cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng default: assert(0 && "Do not know how to promote this BinOp!"); 2344cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng case ISD::AND: 2345cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng case ISD::OR: 2346cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng case ISD::XOR: { 234783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT OVT = Node->getValueType(0); 234883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); 234983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(OVT.isVector() && "Cannot promote this BinOp!"); 2350cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng // Bit convert each of the values to the new type. 2351ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp1); 2352ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::BIT_CONVERT, dl, NVT, Tmp2); 2353ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(Node->getOpcode(), dl, NVT, Tmp1, Tmp2); 2354cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng // Bit convert the result back the original type. 2355ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::BIT_CONVERT, dl, OVT, Result); 2356cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng break; 2357cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng } 2358cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng } 2359cc9876124e7096d050e6750dd075758320f2cdceEvan Cheng } 2360e8f65f1e62ea1d4f2ca9fd0137ae2e0ce20e26e1Andrew Lenharth } 23613e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner break; 2362a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner case ISD::FCOPYSIGN: // FCOPYSIGN does not require LHS/RHS to match type! 2363a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS 2364957bffaeca6a0e2ccc684d753df1d87e8e053fe2Eli Friedman Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the RHS. 2365fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2366a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); 2367fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2368a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { 2369a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner default: assert(0 && "Operation not supported"); 2370a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner case TargetLowering::Custom: 2371a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner Tmp1 = TLI.LowerOperation(Result, DAG); 2372ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 23738f4191d61978529e9e9d7ddc24dbcd528ef7dd4cChris Lattner break; 2374a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner case TargetLowering::Legal: break; 2375912095becac923ff614d7b07728eb345ada67765Evan Cheng case TargetLowering::Expand: { 2376ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman assert((Tmp2.getValueType() == MVT::f32 || 237757f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman Tmp2.getValueType() == MVT::f64) && 2378ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman "Ugly special-cased code!"); 2379ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman // Get the sign bit of the RHS. 238057f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman SDValue SignBit; 238157f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman MVT IVT = Tmp2.getValueType() == MVT::f64 ? MVT::i64 : MVT::i32; 238257f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman if (isTypeLegal(IVT)) { 238357f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman SignBit = DAG.getNode(ISD::BIT_CONVERT, dl, IVT, Tmp2); 238457f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman } else { 238557f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman assert(isTypeLegal(TLI.getPointerTy()) && 238657f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman (TLI.getPointerTy() == MVT::i32 || 238757f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman TLI.getPointerTy() == MVT::i64) && 238857f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman "Legal type for load?!"); 238957f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman SDValue StackPtr = DAG.CreateStackTemporary(Tmp2.getValueType()); 239057f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman SDValue StorePtr = StackPtr, LoadPtr = StackPtr; 239157f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman SDValue Ch = 239257f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman DAG.getStore(DAG.getEntryNode(), dl, Tmp2, StorePtr, NULL, 0); 239357f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman if (Tmp2.getValueType() == MVT::f64 && TLI.isLittleEndian()) 239457f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman LoadPtr = DAG.getNode(ISD::ADD, dl, StackPtr.getValueType(), 239557f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman LoadPtr, DAG.getIntPtrConstant(4)); 239657f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman SignBit = DAG.getExtLoad(ISD::SEXTLOAD, dl, TLI.getPointerTy(), 239757f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman Ch, LoadPtr, NULL, 0, MVT::i32); 239857f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman } 239957f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman SignBit = 240057f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman DAG.getSetCC(dl, TLI.getSetCCResultType(SignBit.getValueType()), 240157f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman SignBit, DAG.getConstant(0, SignBit.getValueType()), 240257f1a4bc40e9103cd41cf541b9d6a73b92f0acbaEli Friedman ISD::SETLT); 2403ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman // Get the absolute value of the result. 2404ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman SDValue AbsVal = DAG.getNode(ISD::FABS, dl, Tmp1.getValueType(), Tmp1); 2405ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman // Select between the nabs and abs value based on the sign bit of 2406ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman // the input. 2407ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman Result = DAG.getNode(ISD::SELECT, dl, AbsVal.getValueType(), SignBit, 2408ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman DAG.getNode(ISD::FNEG, dl, AbsVal.getValueType(), 2409ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman AbsVal), 2410ed2f8c557a86612ee14fea25e7be2d3c1445951aEli Friedman AbsVal); 2411912095becac923ff614d7b07728eb345ada67765Evan Cheng Result = LegalizeOp(Result); 2412a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner break; 2413a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner } 2414912095becac923ff614d7b07728eb345ada67765Evan Cheng } 2415a09f848c11c9db3c2614e0275a3256310ac26653Chris Lattner break; 2416419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman case ISD::BUILD_PAIR: { 241783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT PairTy = Node->getValueType(0); 2418419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman // TODO: handle the case where the Lo and Hi operands are not of legal type 2419419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman Tmp1 = LegalizeOp(Node->getOperand(0)); // Lo 2420419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman Tmp2 = LegalizeOp(Node->getOperand(1)); // Hi 2421419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman switch (TLI.getOperationAction(ISD::BUILD_PAIR, PairTy)) { 2422456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Promote: 2423456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 2424456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner assert(0 && "Cannot promote/custom this yet!"); 2425419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman case TargetLowering::Legal: 2426419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman if (Tmp1 != Node->getOperand(0) || Tmp2 != Node->getOperand(1)) 2427ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::BUILD_PAIR, dl, PairTy, Tmp1, Tmp2); 2428419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman break; 2429419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman case TargetLowering::Expand: 2430ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, PairTy, Tmp1); 2431ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::ANY_EXTEND, dl, PairTy, Tmp2); 2432ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp2 = DAG.getNode(ISD::SHL, dl, PairTy, Tmp2, 243383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands DAG.getConstant(PairTy.getSizeInBits()/2, 2434419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman TLI.getShiftAmountTy())); 2435ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getNode(ISD::OR, dl, PairTy, Tmp1, Tmp2); 2436419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman break; 2437419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman } 2438419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman break; 2439419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman } 2440419f8b62f73541dd783aa98c9eda6e483a487d51Nate Begeman 2441c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman case ISD::UREM: 2442c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman case ISD::SREM: 244301b3d73c20f5afb8265ae943a8ba23c2238c5eeaChris Lattner case ISD::FREM: 2444c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman Tmp1 = LegalizeOp(Node->getOperand(0)); // LHS 2445c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman Tmp2 = LegalizeOp(Node->getOperand(1)); // RHS 2446456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner 2447c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { 2448456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Promote: assert(0 && "Cannot promote this yet!"); 2449456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 2450456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner isCustom = true; 2451456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner // FALLTHROUGH 245257030e36e41ebd982a24632e7cea5b584b2d49fcAndrew Lenharth case TargetLowering::Legal: 2453c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2); 2454456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner if (isCustom) { 2455456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = TLI.LowerOperation(Result, DAG); 2456ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 2457456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner } 245857030e36e41ebd982a24632e7cea5b584b2d49fcAndrew Lenharth break; 2459525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman case TargetLowering::Expand: { 24606b5578f052c2405c0d622192ccacfd47563c99a8Evan Cheng unsigned DivOpc= (Node->getOpcode() == ISD::UREM) ? ISD::UDIV : ISD::SDIV; 246147857812e29324a9d1560796a05b53d3a9217fd9Reid Spencer bool isSigned = DivOpc == ISD::SDIV; 246283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Node->getValueType(0); 2463fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2464525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman // See if remainder can be lowered using two-result operations. 2465525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman SDVTList VTs = DAG.getVTList(VT, VT); 2466525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman if (Node->getOpcode() == ISD::SREM && 2467f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::SDIVREM, VT)) { 2468fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = SDValue(DAG.getNode(ISD::SDIVREM, dl, 2469ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen VTs, Tmp1, Tmp2).getNode(), 1); 2470525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman break; 2471525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2472525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman if (Node->getOpcode() == ISD::UREM && 2473f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::UDIVREM, VT)) { 2474ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = SDValue(DAG.getNode(ISD::UDIVREM, dl, 2475ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen VTs, Tmp1, Tmp2).getNode(), 1); 2476525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman break; 2477525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2478525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman 247958c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov if (VT.isInteger() && 248058c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov TLI.getOperationAction(DivOpc, VT) == TargetLowering::Legal) { 248158c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov // X % Y -> X-X/Y*Y 248258c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov Result = DAG.getNode(DivOpc, dl, VT, Tmp1, Tmp2); 248358c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov Result = DAG.getNode(ISD::MUL, dl, VT, Result, Tmp2); 248458c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov Result = DAG.getNode(ISD::SUB, dl, VT, Tmp1, Result); 248558c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov break; 248658c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov } 248758c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov 248858c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov // Check to see if we have a libcall for this operator. 248958c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 249058c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov switch (Node->getOpcode()) { 249158c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov default: break; 249258c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov case ISD::UREM: 249358c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov case ISD::SREM: 249458c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov if (VT == MVT::i16) 249558c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov LC = (isSigned ? RTLIB::SREM_I16 : RTLIB::UREM_I16); 249658c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov else if (VT == MVT::i32) 249758c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov LC = (isSigned ? RTLIB::SREM_I32 : RTLIB::UREM_I32); 249858c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov else if (VT == MVT::i64) 249958c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov LC = (isSigned ? RTLIB::SREM_I64 : RTLIB::UREM_I64); 250058c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov else if (VT == MVT::i128) 250158c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov LC = (isSigned ? RTLIB::SREM_I128 : RTLIB::UREM_I128); 250258c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov break; 250358c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov case ISD::FREM: 250458c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov // Floating point mod -> fmod libcall. 250558c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov LC = GetFPLibCall(VT, RTLIB::REM_F32, RTLIB::REM_F64, 250658c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov RTLIB::REM_F80, RTLIB::REM_PPCF128); 250758c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov break; 250858c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov } 250958c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov 251058c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov if (LC != RTLIB::UNKNOWN_LIBCALL) { 251158c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov SDValue Dummy; 251258c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov Result = ExpandLibCall(LC, Node, isSigned, Dummy); 251358c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov break; 2514c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman } 251558c04e149629956185cdaa3b021793189008c0d2Anton Korobeynikov 251674807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman assert(0 && "Cannot expand this binary operator!"); 2517c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman break; 2518c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman } 2519525178cdbf00720ea8bce297a7d65b0cca0ab439Dan Gohman } 2520c105e19864f2792c52bc6bb765d365308f38f461Nate Begeman break; 2521acc398c195a697795bff3245943d104eb19192b9Nate Begeman case ISD::VAARG: { 2522acc398c195a697795bff3245943d104eb19192b9Nate Begeman Tmp1 = LegalizeOp(Node->getOperand(0)); // Legalize the chain. 2523acc398c195a697795bff3245943d104eb19192b9Nate Begeman Tmp2 = LegalizeOp(Node->getOperand(1)); // Legalize the pointer. 2524acc398c195a697795bff3245943d104eb19192b9Nate Begeman 252583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Node->getValueType(0); 2526acc398c195a697795bff3245943d104eb19192b9Nate Begeman switch (TLI.getOperationAction(Node->getOpcode(), MVT::Other)) { 2527acc398c195a697795bff3245943d104eb19192b9Nate Begeman default: assert(0 && "This action is not supported yet!"); 2528456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 2529456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner isCustom = true; 2530456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner // FALLTHROUGH 2531acc398c195a697795bff3245943d104eb19192b9Nate Begeman case TargetLowering::Legal: 2532c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = DAG.UpdateNodeOperands(Result, Tmp1, Tmp2, Node->getOperand(2)); 2533c52ad4f04ea5f51a1b4c67e585acea5c0525fc3dChris Lattner Result = Result.getValue(0); 2534456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = Result.getValue(1); 2535456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner 2536456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner if (isCustom) { 2537456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp2 = TLI.LowerOperation(Result, DAG); 2538ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp2.getNode()) { 2539456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Result = LegalizeOp(Tmp2); 2540456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = LegalizeOp(Tmp2.getValue(1)); 2541456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner } 2542456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner } 2543acc398c195a697795bff3245943d104eb19192b9Nate Begeman break; 2544acc398c195a697795bff3245943d104eb19192b9Nate Begeman case TargetLowering::Expand: { 254569de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman const Value *V = cast<SrcValueSDNode>(Node->getOperand(2))->getValue(); 2546ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue VAList = DAG.getLoad(TLI.getPointerTy(), dl, Tmp1, Tmp2, V, 0); 2547acc398c195a697795bff3245943d104eb19192b9Nate Begeman // Increment the pointer, VAList, to the next vaarg 2548ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp3 = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), VAList, 2549ceb4d1aecb9deffe59b3dcdc9a783ffde8477be9Duncan Sands DAG.getConstant(TLI.getTargetData()-> 2550777d2306b36816a53bc1ae1244c0dc7d998ae691Duncan Sands getTypeAllocSize(VT.getTypeForMVT()), 2551ceb4d1aecb9deffe59b3dcdc9a783ffde8477be9Duncan Sands TLI.getPointerTy())); 2552acc398c195a697795bff3245943d104eb19192b9Nate Begeman // Store the incremented VAList to the legalized pointer 2553ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Tmp3 = DAG.getStore(VAList.getValue(1), dl, Tmp3, Tmp2, V, 0); 2554acc398c195a697795bff3245943d104eb19192b9Nate Begeman // Load the actual argument out of the pointer VAList 2555ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen Result = DAG.getLoad(VT, dl, Tmp3, VAList, NULL, 0); 2556456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = LegalizeOp(Result.getValue(1)); 2557acc398c195a697795bff3245943d104eb19192b9Nate Begeman Result = LegalizeOp(Result); 2558acc398c195a697795bff3245943d104eb19192b9Nate Begeman break; 2559acc398c195a697795bff3245943d104eb19192b9Nate Begeman } 2560acc398c195a697795bff3245943d104eb19192b9Nate Begeman } 2561fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // Since VAARG produces two values, make sure to remember that we 2562acc398c195a697795bff3245943d104eb19192b9Nate Begeman // legalized both of them. 2563475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 0), Result); 2564475871a144eb604ddaf37503397ba0941442e5fbDan Gohman AddLegalizedOperand(SDValue(Node, 1), Tmp1); 256599a6cb92d173c142073416c81efe6d3daeb80b49Gabor Greif return Op.getResNo() ? Tmp1 : Result; 2566acc398c195a697795bff3245943d104eb19192b9Nate Begeman } 25678c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Unary operators 25688c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FABS: 25698c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FNEG: 25708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FSQRT: 25718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FSIN: 25728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FCOS: 25738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLOG: 25748c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLOG2: 25758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLOG10: 25768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FEXP: 25778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FEXP2: 25788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FTRUNC: 25798c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FFLOOR: 25808c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FCEIL: 25818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRINT: 25828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FNEARBYINT: 25838c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = LegalizeOp(Node->getOperand(0)); 25848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (TLI.getOperationAction(Node->getOpcode(), Node->getValueType(0))) { 25858c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case TargetLowering::Promote: 2586456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner case TargetLowering::Custom: 25878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman isCustom = true; 25888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // FALLTHROUGH 2589acc398c195a697795bff3245943d104eb19192b9Nate Begeman case TargetLowering::Legal: 25908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Result = DAG.UpdateNodeOperands(Result, Tmp1); 2591456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner if (isCustom) { 2592456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Tmp1 = TLI.LowerOperation(Result, DAG); 2593ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (Tmp1.getNode()) Result = Tmp1; 2594456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner } 2595acc398c195a697795bff3245943d104eb19192b9Nate Begeman break; 2596acc398c195a697795bff3245943d104eb19192b9Nate Begeman case TargetLowering::Expand: 25978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 25988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman default: assert(0 && "Unreachable!"); 25998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FNEG: 26008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Expand Y = FNEG(X) -> Y = SUB -0.0, X 26018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp2 = DAG.getConstantFP(-0.0, Node->getValueType(0)); 26028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Result = DAG.getNode(ISD::FSUB, dl, Node->getValueType(0), Tmp2, Tmp1); 26038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 26048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FABS: { 26058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Expand Y = FABS(X) -> Y = (X >u 0.0) ? X : fneg(X). 26068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT VT = Node->getValueType(0); 26078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp2 = DAG.getConstantFP(0.0, VT); 26088c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), 26098c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1, Tmp2, ISD::SETUGT); 26108c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp3 = DAG.getNode(ISD::FNEG, dl, VT, Tmp1); 26118c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Result = DAG.getNode(ISD::SELECT, dl, VT, Tmp2, Tmp1, Tmp3); 26128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 2613456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner } 26148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FSQRT: 26158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FSIN: 26168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FCOS: 26178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLOG: 26188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLOG2: 26198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLOG10: 26208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FEXP: 26218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FEXP2: 26228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FTRUNC: 26238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FFLOOR: 26248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FCEIL: 26258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRINT: 26268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FNEARBYINT: { 26278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT VT = Node->getValueType(0); 2628acc398c195a697795bff3245943d104eb19192b9Nate Begeman 26298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman assert(!VT.isVector() && "Vector shouldn't get here!"); 2630826695281344e3a4c4d44d73dd155107aafd689bDan Gohman 263156966225d1eed9f9a6951d2167bfbbec9628c8d6Evan Cheng RTLIB::Libcall LC = RTLIB::UNKNOWN_LIBCALL; 2632f76e7dc8d8ac1855ef59698e82c757548ef4ca65Chris Lattner switch(Node->getOpcode()) { 263356966225d1eed9f9a6951d2167bfbbec9628c8d6Evan Cheng case ISD::FSQRT: 2634007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands LC = GetFPLibCall(VT, RTLIB::SQRT_F32, RTLIB::SQRT_F64, 2635007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::SQRT_F80, RTLIB::SQRT_PPCF128); 263656966225d1eed9f9a6951d2167bfbbec9628c8d6Evan Cheng break; 263756966225d1eed9f9a6951d2167bfbbec9628c8d6Evan Cheng case ISD::FSIN: 2638007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands LC = GetFPLibCall(VT, RTLIB::SIN_F32, RTLIB::SIN_F64, 2639007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::SIN_F80, RTLIB::SIN_PPCF128); 264056966225d1eed9f9a6951d2167bfbbec9628c8d6Evan Cheng break; 264156966225d1eed9f9a6951d2167bfbbec9628c8d6Evan Cheng case ISD::FCOS: 2642007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands LC = GetFPLibCall(VT, RTLIB::COS_F32, RTLIB::COS_F64, 2643007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::COS_F80, RTLIB::COS_PPCF128); 264456966225d1eed9f9a6951d2167bfbbec9628c8d6Evan Cheng break; 26457794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case ISD::FLOG: 26467794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen LC = GetFPLibCall(VT, RTLIB::LOG_F32, RTLIB::LOG_F64, 26477794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen RTLIB::LOG_F80, RTLIB::LOG_PPCF128); 26487794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 26497794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case ISD::FLOG2: 26507794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen LC = GetFPLibCall(VT, RTLIB::LOG2_F32, RTLIB::LOG2_F64, 26517794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen RTLIB::LOG2_F80, RTLIB::LOG2_PPCF128); 26527794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 26537794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case ISD::FLOG10: 26547794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen LC = GetFPLibCall(VT, RTLIB::LOG10_F32, RTLIB::LOG10_F64, 26557794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen RTLIB::LOG10_F80, RTLIB::LOG10_PPCF128); 26567794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 26577794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case ISD::FEXP: 26587794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen LC = GetFPLibCall(VT, RTLIB::EXP_F32, RTLIB::EXP_F64, 26597794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen RTLIB::EXP_F80, RTLIB::EXP_PPCF128); 26607794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 26617794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen case ISD::FEXP2: 26627794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen LC = GetFPLibCall(VT, RTLIB::EXP2_F32, RTLIB::EXP2_F64, 26637794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen RTLIB::EXP2_F80, RTLIB::EXP2_PPCF128); 26647794f2a3a7778bdbc9bdd861db1fe914450e0470Dale Johannesen break; 26652bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman case ISD::FTRUNC: 26662bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman LC = GetFPLibCall(VT, RTLIB::TRUNC_F32, RTLIB::TRUNC_F64, 26672bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman RTLIB::TRUNC_F80, RTLIB::TRUNC_PPCF128); 26682bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman break; 26692bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman case ISD::FFLOOR: 26702bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman LC = GetFPLibCall(VT, RTLIB::FLOOR_F32, RTLIB::FLOOR_F64, 26712bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman RTLIB::FLOOR_F80, RTLIB::FLOOR_PPCF128); 26722bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman break; 26732bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman case ISD::FCEIL: 26742bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman LC = GetFPLibCall(VT, RTLIB::CEIL_F32, RTLIB::CEIL_F64, 26752bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman RTLIB::CEIL_F80, RTLIB::CEIL_PPCF128); 26762bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman break; 26772bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman case ISD::FRINT: 26782bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman LC = GetFPLibCall(VT, RTLIB::RINT_F32, RTLIB::RINT_F64, 26792bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman RTLIB::RINT_F80, RTLIB::RINT_PPCF128); 26802bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman break; 26812bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman case ISD::FNEARBYINT: 26822bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman LC = GetFPLibCall(VT, RTLIB::NEARBYINT_F32, RTLIB::NEARBYINT_F64, 26832bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman RTLIB::NEARBYINT_F80, RTLIB::NEARBYINT_PPCF128); 26842bb1e3eede14dd8a965506465e2876fb1ae765c2Dan Gohman break; 26859d24ac56e1f9f1025a473d6b013557431fd05b7cEvan Cheng break; 2686f76e7dc8d8ac1855ef59698e82c757548ef4ca65Chris Lattner default: assert(0 && "Unreachable!"); 2687f76e7dc8d8ac1855ef59698e82c757548ef4ca65Chris Lattner } 2688475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Dummy; 2689460a14e09c2af630fc1e840dcb3e0f725663067bDuncan Sands Result = ExpandLibCall(LC, Node, false/*sign irrelevant*/, Dummy); 2690f76e7dc8d8ac1855ef59698e82c757548ef4ca65Chris Lattner break; 2691f76e7dc8d8ac1855ef59698e82c757548ef4ca65Chris Lattner } 26922c8086f4b9916b2d02842be5e375276023225fbaChris Lattner } 26932c8086f4b9916b2d02842be5e375276023225fbaChris Lattner break; 26942c8086f4b9916b2d02842be5e375276023225fbaChris Lattner } 26952c8086f4b9916b2d02842be5e375276023225fbaChris Lattner break; 26966ddf8ed6fe2d0aa5e15f7b9ad7e5049e2223bbd1Chris Lattner case ISD::FPOWI: { 269783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Node->getValueType(0); 2698826695281344e3a4c4d44d73dd155107aafd689bDan Gohman 2699826695281344e3a4c4d44d73dd155107aafd689bDan Gohman // Expand unsupported unary vector operators by unrolling them. 270074807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman assert(!VT.isVector() && "Vector shouldn't get here!"); 2701826695281344e3a4c4d44d73dd155107aafd689bDan Gohman 2702826695281344e3a4c4d44d73dd155107aafd689bDan Gohman // We always lower FPOWI into a libcall. No target support for it yet. 2703007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::Libcall LC = GetFPLibCall(VT, RTLIB::POWI_F32, RTLIB::POWI_F64, 2704007f9847c44ddbe7fd04cba362b4ec0f0f40964bDuncan Sands RTLIB::POWI_F80, RTLIB::POWI_PPCF128); 2705475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Dummy; 2706460a14e09c2af630fc1e840dcb3e0f725663067bDuncan Sands Result = ExpandLibCall(LC, Node, false/*sign irrelevant*/, Dummy); 27076ddf8ed6fe2d0aa5e15f7b9ad7e5049e2223bbd1Chris Lattner break; 27086ddf8ed6fe2d0aa5e15f7b9ad7e5049e2223bbd1Chris Lattner } 270974c376529101acbe141a256d0bf23a44eb454c84Bill Wendling case ISD::SADDO: 271074c376529101acbe141a256d0bf23a44eb454c84Bill Wendling case ISD::SSUBO: { 2711c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling MVT VT = Node->getValueType(0); 2712c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 2713c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling default: assert(0 && "This action not supported for this op yet!"); 2714c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling case TargetLowering::Custom: 2715c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling Result = TLI.LowerOperation(Op, DAG); 2716c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling if (Result.getNode()) break; 2717c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling // FALLTHROUGH 2718c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling case TargetLowering::Legal: { 2719c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling SDValue LHS = LegalizeOp(Node->getOperand(0)); 2720c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling SDValue RHS = LegalizeOp(Node->getOperand(1)); 2721c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling 2722fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::SADDO ? 2723ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 272474c376529101acbe141a256d0bf23a44eb454c84Bill Wendling LHS, RHS); 2725c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling MVT OType = Node->getValueType(1); 2726c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling 2727a6af91ae124d0713cfabcea8c5f508091dd7a556Bill Wendling SDValue Zero = DAG.getConstant(0, LHS.getValueType()); 2728c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling 2729740464e6164e503f3c01d2b13a52c0261042abe0Bill Wendling // LHSSign -> LHS >= 0 2730740464e6164e503f3c01d2b13a52c0261042abe0Bill Wendling // RHSSign -> RHS >= 0 2731740464e6164e503f3c01d2b13a52c0261042abe0Bill Wendling // SumSign -> Sum >= 0 2732740464e6164e503f3c01d2b13a52c0261042abe0Bill Wendling // 273374c376529101acbe141a256d0bf23a44eb454c84Bill Wendling // Add: 2734740464e6164e503f3c01d2b13a52c0261042abe0Bill Wendling // Overflow -> (LHSSign == RHSSign) && (LHSSign != SumSign) 273574c376529101acbe141a256d0bf23a44eb454c84Bill Wendling // Sub: 273674c376529101acbe141a256d0bf23a44eb454c84Bill Wendling // Overflow -> (LHSSign != RHSSign) && (LHSSign != SumSign) 2737740464e6164e503f3c01d2b13a52c0261042abe0Bill Wendling // 2738ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue LHSSign = DAG.getSetCC(dl, OType, LHS, Zero, ISD::SETGE); 2739ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue RHSSign = DAG.getSetCC(dl, OType, RHS, Zero, ISD::SETGE); 2740fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel SDValue SignsMatch = DAG.getSetCC(dl, OType, LHSSign, RHSSign, 2741fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Node->getOpcode() == ISD::SADDO ? 274274c376529101acbe141a256d0bf23a44eb454c84Bill Wendling ISD::SETEQ : ISD::SETNE); 2743740464e6164e503f3c01d2b13a52c0261042abe0Bill Wendling 2744ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue SumSign = DAG.getSetCC(dl, OType, Sum, Zero, ISD::SETGE); 2745ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue SumSignNE = DAG.getSetCC(dl, OType, LHSSign, SumSign, ISD::SETNE); 2746740464e6164e503f3c01d2b13a52c0261042abe0Bill Wendling 2747ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue Cmp = DAG.getNode(ISD::AND, dl, OType, SignsMatch, SumSignNE); 2748c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling 2749c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling MVT ValueVTs[] = { LHS.getValueType(), OType }; 2750c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling SDValue Ops[] = { Sum, Cmp }; 2751c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling 2752fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getNode(ISD::MERGE_VALUES, dl, 2753ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen DAG.getVTList(&ValueVTs[0], 2), 2754aaffa05d0a652dd3eae76a941d02d6b0469fa821Duncan Sands &Ops[0], 2); 2755c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling SDNode *RNode = Result.getNode(); 2756c23e4968790395053f3f52aeb3342637fcaafdbfDan Gohman DAG.ReplaceAllUsesWith(Node, RNode); 2757c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling break; 2758c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling } 2759c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling } 2760c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling 2761c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling break; 2762c0062fb7557c9f4eb66b7d8fa7b6b0c765e579b8Bill Wendling } 276374c376529101acbe141a256d0bf23a44eb454c84Bill Wendling case ISD::UADDO: 276474c376529101acbe141a256d0bf23a44eb454c84Bill Wendling case ISD::USUBO: { 276541ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling MVT VT = Node->getValueType(0); 276641ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling switch (TLI.getOperationAction(Node->getOpcode(), VT)) { 276741ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling default: assert(0 && "This action not supported for this op yet!"); 276841ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling case TargetLowering::Custom: 276941ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling Result = TLI.LowerOperation(Op, DAG); 277041ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling if (Result.getNode()) break; 277141ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling // FALLTHROUGH 277241ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling case TargetLowering::Legal: { 277341ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling SDValue LHS = LegalizeOp(Node->getOperand(0)); 277441ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling SDValue RHS = LegalizeOp(Node->getOperand(1)); 277541ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling 277674c376529101acbe141a256d0bf23a44eb454c84Bill Wendling SDValue Sum = DAG.getNode(Node->getOpcode() == ISD::UADDO ? 2777ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen ISD::ADD : ISD::SUB, dl, LHS.getValueType(), 277874c376529101acbe141a256d0bf23a44eb454c84Bill Wendling LHS, RHS); 277941ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling MVT OType = Node->getValueType(1); 2780ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen SDValue Cmp = DAG.getSetCC(dl, OType, Sum, LHS, 2781fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Node->getOpcode () == ISD::UADDO ? 278274c376529101acbe141a256d0bf23a44eb454c84Bill Wendling ISD::SETULT : ISD::SETUGT); 278341ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling 278441ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling MVT ValueVTs[] = { LHS.getValueType(), OType }; 278541ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling SDValue Ops[] = { Sum, Cmp }; 278641ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling 2787fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Result = DAG.getNode(ISD::MERGE_VALUES, dl, 2788ca57b84729303d6f0c5abf951563efcde97010cdDale Johannesen DAG.getVTList(&ValueVTs[0], 2), 2789aaffa05d0a652dd3eae76a941d02d6b0469fa821Duncan Sands &Ops[0], 2); 279041ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling SDNode *RNode = Result.getNode(); 2791c23e4968790395053f3f52aeb3342637fcaafdbfDan Gohman DAG.ReplaceAllUsesWith(Node, RNode); 279241ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling break; 279341ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling } 279441ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling } 279541ea7e7eb3a6a269f2bfed0bdc191ea046d18e5eBill Wendling 27968ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling break; 27978ac0d4b4fb10406278cd600214cd3ee6d76620cdBill Wendling } 279845b8caf1c5a1fd8337038d64c6da8fba2d299fdfChris Lattner } 2799fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 28004ddd283f6928fc337c1bf3277566d7b31526e8d9Chris Lattner assert(Result.getValueType() == Op.getValueType() && 28014ddd283f6928fc337c1bf3277566d7b31526e8d9Chris Lattner "Bad legalization!"); 2802fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2803456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner // Make sure that the generated code is itself legal. 2804456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner if (Result != Op) 2805456a93afcec7740c45cafa8354317f7b17987a6dChris Lattner Result = LegalizeOp(Result); 28063e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 280745982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner // Note that LegalizeOp may be reentered even from single-use nodes, which 280845982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner // means that we always must cache transformed nodes. 280945982dad53cd184fe8947a1b0206b0b16964f359Chris Lattner AddLegalizedOperand(Op, Result); 28103e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner return Result; 28113e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 28123e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 28133d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli FriedmanSDValue SelectionDAGLegalize::ExpandExtractFromVectorThroughStack(SDValue Op) { 28143d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue Vec = Op.getOperand(0); 28153d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue Idx = Op.getOperand(1); 28163d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman DebugLoc dl = Op.getDebugLoc(); 28173d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman // Store the value to a temporary stack slot, then LOAD the returned part. 28183d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue StackPtr = DAG.CreateStackTemporary(Vec.getValueType()); 28193d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman SDValue Ch = DAG.getStore(DAG.getEntryNode(), dl, Vec, StackPtr, NULL, 0); 28203d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 28213d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman // Add the offset to the index. 28222a35b1c54ba55a917e01e0043efcf67e20505953Eli Friedman unsigned EltSize = 28232a35b1c54ba55a917e01e0043efcf67e20505953Eli Friedman Vec.getValueType().getVectorElementType().getSizeInBits()/8; 28243d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::MUL, dl, Idx.getValueType(), Idx, 28253d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman DAG.getConstant(EltSize, Idx.getValueType())); 28263d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 28273d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman if (Idx.getValueType().bitsGT(TLI.getPointerTy())) 28283d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::TRUNCATE, dl, TLI.getPointerTy(), Idx); 28293d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman else 28303d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman Idx = DAG.getNode(ISD::ZERO_EXTEND, dl, TLI.getPointerTy(), Idx); 28313d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 28323d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman StackPtr = DAG.getNode(ISD::ADD, dl, Idx.getValueType(), Idx, StackPtr); 28333d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 28343d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman return DAG.getLoad(Op.getValueType(), dl, Ch, StackPtr, NULL, 0); 28353d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman} 28363d43b3f6d7e1d3516052f20bf2d14727ebddb8ffEli Friedman 2837750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman/// LegalizeSetCCOperands - Attempts to create a legal LHS and RHS for a SETCC 2838750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman/// with condition CC on the current target. This usually involves legalizing 2839750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman/// or promoting the arguments. In the case where LHS and RHS must be expanded, 2840750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman/// there may be no choice but to create a new SetCC node to represent the 2841750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman/// legalized value of setcc lhs, rhs. In this case, the value is returned in 2842475871a144eb604ddaf37503397ba0941442e5fbDan Gohman/// LHS, and the SDValue returned in RHS has a nil SDNode value. 2843475871a144eb604ddaf37503397ba0941442e5fbDan Gohmanvoid SelectionDAGLegalize::LegalizeSetCCOperands(SDValue &LHS, 2844475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue &RHS, 2845bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue &CC, 2846bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl) { 284774807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman LHS = LegalizeOp(LHS); 284874807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman RHS = LegalizeOp(RHS); 284974807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman} 2850750ac1bdfa6f09bddfd9efce1d6360dde8fa74c0Nate Begeman 28517f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng/// LegalizeSetCCCondCode - Legalize a SETCC with given LHS and RHS and 28527f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng/// condition code CC on the current target. This routine assumes LHS and rHS 28537f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng/// have already been legalized by LegalizeSetCCOperands. It expands SETCC with 28547f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng/// illegal condition code into AND / OR of multiple SETCC values. 28557f042681764c6f8eae22781d8b4cb4c218a86b76Evan Chengvoid SelectionDAGLegalize::LegalizeSetCCCondCode(MVT VT, 28567f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng SDValue &LHS, SDValue &RHS, 2857bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue &CC, 2858bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen DebugLoc dl) { 28597f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng MVT OpVT = LHS.getValueType(); 28607f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng ISD::CondCode CCCode = cast<CondCodeSDNode>(CC)->get(); 28617f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng switch (TLI.getCondCodeAction(CCCode, OpVT)) { 28627f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng default: assert(0 && "Unknown condition code action!"); 28637f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng case TargetLowering::Legal: 28647f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng // Nothing to do. 28657f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng break; 28667f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng case TargetLowering::Expand: { 28677f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng ISD::CondCode CC1 = ISD::SETCC_INVALID, CC2 = ISD::SETCC_INVALID; 28687f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng unsigned Opc = 0; 28697f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng switch (CCCode) { 28707f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng default: assert(0 && "Don't know how to expand this condition!"); abort(); 2871e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETO; Opc = ISD::AND; break; 2872e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOGT: CC1 = ISD::SETGT; CC2 = ISD::SETO; Opc = ISD::AND; break; 2873e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOGE: CC1 = ISD::SETGE; CC2 = ISD::SETO; Opc = ISD::AND; break; 2874e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOLT: CC1 = ISD::SETLT; CC2 = ISD::SETO; Opc = ISD::AND; break; 2875e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETOLE: CC1 = ISD::SETLE; CC2 = ISD::SETO; Opc = ISD::AND; break; 2876e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETONE: CC1 = ISD::SETNE; CC2 = ISD::SETO; Opc = ISD::AND; break; 2877e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUEQ: CC1 = ISD::SETEQ; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2878e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUGT: CC1 = ISD::SETGT; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2879e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUGE: CC1 = ISD::SETGE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2880e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETULT: CC1 = ISD::SETLT; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2881e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETULE: CC1 = ISD::SETLE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 2882e7d238ea239e6ab8a2c60ecd27468f3cfc1bb08bDan Gohman case ISD::SETUNE: CC1 = ISD::SETNE; CC2 = ISD::SETUO; Opc = ISD::OR; break; 28837f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng // FIXME: Implement more expansions. 28847f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 28857f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng 2886bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue SetCC1 = DAG.getSetCC(dl, VT, LHS, RHS, CC1); 2887bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen SDValue SetCC2 = DAG.getSetCC(dl, VT, LHS, RHS, CC2); 2888bb5da918545efb54857a09c983a5a7f22a7e04d4Dale Johannesen LHS = DAG.getNode(Opc, dl, VT, SetCC1, SetCC2); 28897f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng RHS = SDValue(); 28907f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng CC = SDValue(); 28917f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng break; 28927f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 28937f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng } 28947f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng} 28957f042681764c6f8eae22781d8b4cb4c218a86b76Evan Cheng 28961401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// EmitStackConvert - Emit a store/load combination to the stack. This stores 28971401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// SrcOp to a stack slot of type SlotVT, truncating it if needed. It then does 28981401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// a load from the stack slot to DestVT, extending it if needed. 28991401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner/// The resultant code need not be legal. 2900475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::EmitStackConvert(SDValue SrcOp, 2901475871a144eb604ddaf37503397ba0941442e5fbDan Gohman MVT SlotVT, 29028a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen MVT DestVT, 29038a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl) { 290435481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner // Create the stack frame object. 2905ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson unsigned SrcAlign = 2906ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson TLI.getTargetData()->getPrefTypeAlignment(SrcOp.getValueType(). 2907ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson getTypeForMVT()); 2908475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue FIPtr = DAG.CreateStackTemporary(SlotVT, SrcAlign); 2909fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2910bbbbb9c3dd4160990f856854d16a3beaead1f354Dan Gohman FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(FIPtr); 291169de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman int SPFI = StackPtrFI->getIndex(); 291215b3830bcda4f9958abf1c65e6e1c64c5cbb484dDan Gohman const Value *SV = PseudoSourceValue::getFixedStack(SPFI); 291315b3830bcda4f9958abf1c65e6e1c64c5cbb484dDan Gohman 291483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned SrcSize = SrcOp.getValueType().getSizeInBits(); 291583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned SlotSize = SlotVT.getSizeInBits(); 291683ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned DestSize = DestVT.getSizeInBits(); 2917ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson unsigned DestAlign = 2918ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson TLI.getTargetData()->getPrefTypeAlignment(DestVT.getTypeForMVT()); 2919fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 29201401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner // Emit a store to the stack slot. Use a truncstore if the input value is 29211401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner // later than DestVT. 2922475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Store; 2923fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 29241401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner if (SrcSize > SlotSize) 29258a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Store = DAG.getTruncStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, 292615b3830bcda4f9958abf1c65e6e1c64c5cbb484dDan Gohman SV, 0, SlotVT, false, SrcAlign); 29271401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner else { 29281401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner assert(SrcSize == SlotSize && "Invalid store"); 29298a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Store = DAG.getStore(DAG.getEntryNode(), dl, SrcOp, FIPtr, 293015b3830bcda4f9958abf1c65e6e1c64c5cbb484dDan Gohman SV, 0, false, SrcAlign); 29311401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner } 2932fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 293335481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner // Result is a load from the stack slot. 29341401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner if (SlotSize == DestSize) 29358a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getLoad(DestVT, dl, Store, FIPtr, SV, 0, false, DestAlign); 2936fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 29371401d15c99b284ead81b8476a6db95328c5f28fdChris Lattner assert(SlotSize < DestSize && "Unknown extension!"); 29388a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, Store, FIPtr, SV, 0, SlotVT, 2939364d73ddab43b699ab90240f11b7a2eb5cf69bd8Mon P Wang false, DestAlign); 294035481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner} 294135481892da1e5634bf497c8a0cabb1bb5a8b8fefChris Lattner 2942475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandSCALAR_TO_VECTOR(SDNode *Node) { 29438a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl = Node->getDebugLoc(); 29444352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // Create a vector sized/aligned stack slot, store the value to element #0, 29454352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner // then load the whole vector back out. 2946475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue StackPtr = DAG.CreateStackTemporary(Node->getValueType(0)); 294769de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman 2948bbbbb9c3dd4160990f856854d16a3beaead1f354Dan Gohman FrameIndexSDNode *StackPtrFI = cast<FrameIndexSDNode>(StackPtr); 294969de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman int SPFI = StackPtrFI->getIndex(); 295069de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman 2951b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands SDValue Ch = DAG.getTruncStore(DAG.getEntryNode(), dl, Node->getOperand(0), 2952b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands StackPtr, 2953b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands PseudoSourceValue::getFixedStack(SPFI), 0, 2954b10b5ac8d9da43ca2db61401a20af6b676c98438Duncan Sands Node->getValueType(0).getVectorElementType()); 29558a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getLoad(Node->getValueType(0), dl, Ch, StackPtr, 2956a54cf176613f9ae8301519a61b8935652c0fb8aeDan Gohman PseudoSourceValue::getFixedStack(SPFI), 0); 29574352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner} 29584352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 29594352cc9e217e4482ad53f5a7b92c3543f569eb6eChris Lattner 2960ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner/// ExpandBUILD_VECTOR - Expand a BUILD_VECTOR node on targets that don't 296107a96765daedf180a7102d39fe56c499878312b7Dan Gohman/// support the operation, but do support the resultant vector type. 2962475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandBUILD_VECTOR(SDNode *Node) { 296326cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson unsigned NumElems = Node->getNumOperands(); 296426cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson SDValue SplatValue = Node->getOperand(0); 296526cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson DebugLoc dl = Node->getDebugLoc(); 296626cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson MVT VT = Node->getValueType(0); 296726cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson MVT OpVT = SplatValue.getValueType(); 296826cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson MVT EltVT = VT.getVectorElementType(); 2969fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2970fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // If the only non-undef value is the low element, turn this into a 297187100e0b83b808757bf44dabecd1d1048255d1adChris Lattner // SCALAR_TO_VECTOR node. If this is { X, X, X, X }, determine X. 2972ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner bool isOnlyLowElement = true; 2973fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2974475871a144eb604ddaf37503397ba0941442e5fbDan Gohman // FIXME: it would be far nicer to change this into map<SDValue,uint64_t> 2975f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner // and use a bitmask instead of a list of elements. 29769008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman // FIXME: this doesn't treat <0, u, 0, u> for example, as a splat. 2977475871a144eb604ddaf37503397ba0941442e5fbDan Gohman std::map<SDValue, std::vector<unsigned> > Values; 2978033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng Values[SplatValue].push_back(0); 29792eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner bool isConstant = true; 29802eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner if (!isa<ConstantFPSDNode>(SplatValue) && !isa<ConstantSDNode>(SplatValue) && 29812eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner SplatValue.getOpcode() != ISD::UNDEF) 29822eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner isConstant = false; 2983fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2984033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng for (unsigned i = 1; i < NumElems; ++i) { 2985475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue V = Node->getOperand(i); 298689a1b380a475cbe477e50ff4b94335596b37f21aChris Lattner Values[V].push_back(i); 2987033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng if (V.getOpcode() != ISD::UNDEF) 2988ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner isOnlyLowElement = false; 2989033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng if (SplatValue != V) 2990ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson SplatValue = SDValue(0, 0); 29912eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner 29922eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // If this isn't a constant element or an undef, we can't use a constant 29932eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // pool load. 29942eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner if (!isa<ConstantFPSDNode>(V) && !isa<ConstantSDNode>(V) && 29952eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner V.getOpcode() != ISD::UNDEF) 29962eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner isConstant = false; 2997ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 2998fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 2999ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner if (isOnlyLowElement) { 3000ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // If the low element is an undef too, then this whole things is an undef. 3001ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner if (Node->getOperand(0).getOpcode() == ISD::UNDEF) 300226cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson return DAG.getUNDEF(VT); 3003ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // Otherwise, turn this into a scalar_to_vector node. 300426cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson return DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Node->getOperand(0)); 3005ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 3006fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 30072eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // If all elements are constants, create a load from the constant pool. 3008ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner if (isConstant) { 3009ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner std::vector<Constant*> CV; 3010033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng for (unsigned i = 0, e = NumElems; i != e; ++i) { 3011fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel if (ConstantFPSDNode *V = 3012ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner dyn_cast<ConstantFPSDNode>(Node->getOperand(i))) { 30134fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman CV.push_back(const_cast<ConstantFP *>(V->getConstantFPValue())); 3014fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel } else if (ConstantSDNode *V = 3015ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson dyn_cast<ConstantSDNode>(Node->getOperand(i))) { 30164fbd796a1251a27e6590765a0a34876f436a0af9Dan Gohman CV.push_back(const_cast<ConstantInt *>(V->getConstantIntValue())); 3017ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } else { 3018ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner assert(Node->getOperand(i).getOpcode() == ISD::UNDEF); 301926cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson const Type *OpNTy = OpVT.getTypeForMVT(); 3020ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner CV.push_back(UndefValue::get(OpNTy)); 3021ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 3022ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 30239d6565a5b1fbc4286d6ee638d8f47a3171a9ed7eReid Spencer Constant *CP = ConstantVector::get(CV); 3024475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CPIdx = DAG.getConstantPool(CP, TLI.getPointerTy()); 30251606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 30268a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getLoad(VT, dl, DAG.getEntryNode(), CPIdx, 302750284d81f863a6576582e1a171a22eb0f012ddf3Dan Gohman PseudoSourceValue::getConstantPool(), 0, 302850284d81f863a6576582e1a171a22eb0f012ddf3Dan Gohman false, Alignment); 3029ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 3030fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3031ba36cb5242eb02b12b277f82b9efe497f7da4d7fGabor Greif if (SplatValue.getNode()) { // Splat of one value? 30322eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // Build the shuffle constant vector: <0, 0, 0, 0> 30339008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVector<int, 8> ZeroVec(NumElems, 0); 3034033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng 30352eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // If the target supports VECTOR_SHUFFLE and this shuffle mask, use it. 30369008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman if (TLI.isShuffleMaskLegal(ZeroVec, Node->getValueType(0))) { 30372eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // Get the splatted value into the low element of a vector register. 3038fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel SDValue LowValVec = 303926cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, SplatValue); 3040fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 30412eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner // Return shuffle(LowValVec, undef, <0,0,0,0>) 30429008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman return DAG.getVectorShuffle(VT, dl, LowValVec, DAG.getUNDEF(VT), 30439008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman &ZeroVec[0]); 30442eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner } 30452eb8653157ccd318b357af74bfd517c76ef166b8Chris Lattner } 3046fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3047033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng // If there are only two unique elements, we may be able to turn this into a 3048033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng // vector shuffle. 3049033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng if (Values.size() == 2) { 3050f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner // Get the two values in deterministic order. 3051475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Val1 = Node->getOperand(1); 3052475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Val2; 3053475871a144eb604ddaf37503397ba0941442e5fbDan Gohman std::map<SDValue, std::vector<unsigned> >::iterator MI = Values.begin(); 3054f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner if (MI->first != Val1) 3055f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner Val2 = MI->first; 3056f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner else 3057f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner Val2 = (++MI)->first; 3058fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3059ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson // If Val1 is an undef, make sure it ends up as Val2, to ensure that our 3060f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner // vector shuffle has the undef vector on the RHS. 3061f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner if (Val1.getOpcode() == ISD::UNDEF) 3062f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner std::swap(Val1, Val2); 3063fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3064033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng // Build the shuffle constant vector: e.g. <0, 4, 0, 4> 30659008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman SmallVector<int, 8> ShuffleMask(NumElems, -1); 3066f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner 3067f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner // Set elements of the shuffle mask for Val1. 3068f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner std::vector<unsigned> &Val1Elts = Values[Val1]; 3069f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner for (unsigned i = 0, e = Val1Elts.size(); i != e; ++i) 30709008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman ShuffleMask[Val1Elts[i]] = 0; 3071f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner 3072f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner // Set elements of the shuffle mask for Val2. 3073f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner std::vector<unsigned> &Val2Elts = Values[Val2]; 3074f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner for (unsigned i = 0, e = Val2Elts.size(); i != e; ++i) 3075f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner if (Val2.getOpcode() != ISD::UNDEF) 30769008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman ShuffleMask[Val2Elts[i]] = NumElems; 3077033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng 3078f9d95c8835bc4f9072c33e1f9ebaa581a4d3268dChris Lattner // If the target supports SCALAR_TO_VECTOR and this shuffle mask, use it. 307926cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson if (TLI.isOperationLegalOrCustom(ISD::SCALAR_TO_VECTOR, VT) && 30809008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman TLI.isShuffleMaskLegal(ShuffleMask, VT)) { 308126cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson Val1 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Val1); 308226cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson Val2 = DAG.getNode(ISD::SCALAR_TO_VECTOR, dl, VT, Val2); 30839008ca6b6b4f638cfafccb593cbc5b1d3f5ab877Nate Begeman return DAG.getVectorShuffle(VT, dl, Val1, Val2, &ShuffleMask[0]); 3084033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng } 3085033e6816668da71ff0866a61f5c0a7e7e795d069Evan Cheng } 3086fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3087ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // Otherwise, we can't handle this case efficiently. Allocate a sufficiently 3088ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // aligned object on the stack, store each element into it, then load 3089ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // the result as a vector. 3090ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // Create the stack frame object. 3091475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue FIPtr = DAG.CreateStackTemporary(VT); 309215b3830bcda4f9958abf1c65e6e1c64c5cbb484dDan Gohman int FI = cast<FrameIndexSDNode>(FIPtr.getNode())->getIndex(); 309315b3830bcda4f9958abf1c65e6e1c64c5cbb484dDan Gohman const Value *SV = PseudoSourceValue::getFixedStack(FI); 309415b3830bcda4f9958abf1c65e6e1c64c5cbb484dDan Gohman 3095ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // Emit a store of each element to the stack slot. 3096475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SmallVector<SDValue, 8> Stores; 309726cbf9eb99c779b8992f4865c6cf308318d39723Bob Wilson unsigned TypeByteSize = OpVT.getSizeInBits() / 8; 3098ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // Store (in the right endianness) the elements to memory. 3099ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 3100ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // Ignore undef elements. 3101ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner if (Node->getOperand(i).getOpcode() == ISD::UNDEF) continue; 3102fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3103841c882f5dae8c953ea99b5824108313549cfaf8Chris Lattner unsigned Offset = TypeByteSize*i; 3104fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3105475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Idx = DAG.getConstant(Offset, FIPtr.getValueType()); 31068a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Idx = DAG.getNode(ISD::ADD, dl, FIPtr.getValueType(), FIPtr, Idx); 3107fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 31088a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Stores.push_back(DAG.getStore(DAG.getEntryNode(), dl, Node->getOperand(i), 31098a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Idx, SV, Offset)); 3110ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner } 3111fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3112475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue StoreChain; 3113ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner if (!Stores.empty()) // Not all undef elements? 31148a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen StoreChain = DAG.getNode(ISD::TokenFactor, dl, MVT::Other, 3115bd564bfc63163e31f320c3da9749db70992dc35eChris Lattner &Stores[0], Stores.size()); 3116ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner else 3117ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner StoreChain = DAG.getEntryNode(); 3118fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 3119ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner // Result is a load from the stack slot. 31208a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getLoad(VT, dl, StoreChain, FIPtr, SV, 0); 3121ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner} 3122ce87215131efcc68dcf7fca61055ad783a7aeb0eChris Lattner 312377e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// ExpandLibCall - Expand a node into a call to a libcall. If the result value 312477e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// does not fit into a register, return the lo part and set the hi part to the 312577e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// by-reg argument. If it does fit into a single register, return the result 312677e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner// and leave the Hi part unset. 3127475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandLibCall(RTLIB::Libcall LC, SDNode *Node, 3128475871a144eb604ddaf37503397ba0941442e5fbDan Gohman bool isSigned, SDValue &Hi) { 31296831a815999dde4cf801e2076e66b4943964daf2Chris Lattner assert(!IsLegalizingCall && "Cannot overlap legalization of calls!"); 3130fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel // The input chain to this libcall is the entry node of the function. 31316831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Legalizing the call will automatically add the previous call to the 31326831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // dependence. 3133475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InChain = DAG.getEntryNode(); 3134fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 313577e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner TargetLowering::ArgListTy Args; 313647857812e29324a9d1560796a05b53d3a9217fd9Reid Spencer TargetLowering::ArgListEntry Entry; 313777e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner for (unsigned i = 0, e = Node->getNumOperands(); i != e; ++i) { 313883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT ArgVT = Node->getOperand(i).getValueType(); 313983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands const Type *ArgTy = ArgVT.getTypeForMVT(); 3140fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Entry.Node = Node->getOperand(i); Entry.Ty = ArgTy; 3141d0b82b301d700217a716526f9329bb031e0d6578Anton Korobeynikov Entry.isSExt = isSigned; 314200fee65fd21f9615d1a604b8b7d42cd16a3f6b47Duncan Sands Entry.isZExt = !isSigned; 314347857812e29324a9d1560796a05b53d3a9217fd9Reid Spencer Args.push_back(Entry); 314477e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner } 3145056292fd738924f3f7703725d8f630983794b5a5Bill Wendling SDValue Callee = DAG.getExternalSymbol(TLI.getLibcallName(LC), 31460c39719bfc7d0b3e61fbd55e1115184a1d5f6ae7Mon P Wang TLI.getPointerTy()); 3147edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 31480d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner // Splice the libcall in wherever FindInputOutputChains tells us to. 314983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands const Type *RetTy = Node->getValueType(0).getTypeForMVT(); 3150ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson std::pair<SDValue, SDValue> CallInfo = 315186098bd6a63d2cdf0c9be9ef3151bd2728281fd7Dale Johannesen TLI.LowerCallTo(InChain, RetTy, isSigned, !isSigned, false, false, 31527d2ad624fa749a6d3edac0d94e9c107989c16304Dale Johannesen CallingConv::C, false, Callee, Args, DAG, 31537d2ad624fa749a6d3edac0d94e9c107989c16304Dale Johannesen Node->getDebugLoc()); 31540d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner 31556831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // Legalize the call sequence, starting with the chain. This will advance 31566831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // the LastCALLSEQ_END to the legalized version of the CALLSEQ_END node that 31576831a815999dde4cf801e2076e66b4943964daf2Chris Lattner // was added by LowerCallTo (guaranteeing proper serialization of calls). 31586831a815999dde4cf801e2076e66b4943964daf2Chris Lattner LegalizeOp(CallInfo.second); 315974807f2520715056be399a2bc59dfc8b6f8f3eb2Eli Friedman return CallInfo.first; 316022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 316122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 316222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandLegalINT_TO_FP - This function is responsible for legalizing a 316322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// INT_TO_FP operation of the specified operand when the target requests that 316422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we expand it. At this point, we know that the result and operand types are 316522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target. 3166475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::ExpandLegalINT_TO_FP(bool isSigned, 3167475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0, 3168af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen MVT DestVT, 3169af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 317022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (Op0.getValueType() == MVT::i32) { 317122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // simple 32-bit [signed|unsigned] integer to float/double expansion 3172fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 317323594d4537fb88a963c6d6993af5027eac9bfbacChris Lattner // Get the stack frame index of a 8 byte buffer. 3174475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue StackSlot = DAG.CreateStackTemporary(MVT::f64); 3175fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 317622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // word offset constant for Hi/Lo address computation 3177475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue WordOff = DAG.getConstant(sizeof(int), TLI.getPointerTy()); 317822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // set up Hi and Lo (into buffer) address based on endian 3179475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Hi = StackSlot; 3180fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel SDValue Lo = DAG.getNode(ISD::ADD, dl, 3181ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson TLI.getPointerTy(), StackSlot, WordOff); 3182408c428096df3a3970a8387f9dd258ae948663a6Chris Lattner if (TLI.isLittleEndian()) 3183408c428096df3a3970a8387f9dd258ae948663a6Chris Lattner std::swap(Hi, Lo); 3184fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 318522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // if signed map to unsigned space 3186475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Op0Mapped; 318722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (isSigned) { 318822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // constant used to invert sign bit (signed to unsigned mapping) 3189475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue SignBit = DAG.getConstant(0x80000000u, MVT::i32); 3190af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen Op0Mapped = DAG.getNode(ISD::XOR, dl, MVT::i32, Op0, SignBit); 319122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } else { 319222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner Op0Mapped = Op0; 319322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 319422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // store the lo of the constructed double - based on integer input 3195af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Store1 = DAG.getStore(DAG.getEntryNode(), dl, 3196ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson Op0Mapped, Lo, NULL, 0); 319722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // initial hi portion of constructed double 3198475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue InitialHi = DAG.getConstant(0x43300000u, MVT::i32); 319922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // store the hi of the constructed double - biased exponent 3200af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Store2=DAG.getStore(Store1, dl, InitialHi, Hi, NULL, 0); 320122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // load the constructed double 3202af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Load = DAG.getLoad(MVT::f64, dl, Store2, StackSlot, NULL, 0); 320322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // FP constant to bias correct the final result 3204475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Bias = DAG.getConstantFP(isSigned ? 3205ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson BitsToDouble(0x4330000080000000ULL) : 3206ec15bbfd2f8a3667313dcfa0f9a11497ae6732b8Bob Wilson BitsToDouble(0x4330000000000000ULL), 320722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner MVT::f64); 320822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // subtract the bias 3209af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Sub = DAG.getNode(ISD::FSUB, dl, MVT::f64, Load, Bias); 321022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // final result 3211475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Result; 321222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // handle final rounding 321322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (DestVT == MVT::f64) { 321422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // do nothing 321522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner Result = Sub; 32168e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands } else if (DestVT.bitsLT(MVT::f64)) { 3217af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen Result = DAG.getNode(ISD::FP_ROUND, dl, DestVT, Sub, 32180bd4893a0726889b942405262e53d06cf3fe3be8Chris Lattner DAG.getIntPtrConstant(0)); 32198e4eb09b1e3571965f49edcdfb56b1375b1b7551Duncan Sands } else if (DestVT.bitsGT(MVT::f64)) { 3220af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen Result = DAG.getNode(ISD::FP_EXTEND, dl, DestVT, Sub); 322122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 322222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner return Result; 322322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 322422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner assert(!isSigned && "Legalize cannot Expand SINT_TO_FP for i64 yet"); 3225af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Tmp1 = DAG.getNode(ISD::SINT_TO_FP, dl, DestVT, Op0); 322622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 3227af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue SignSet = DAG.getSetCC(dl, TLI.getSetCCResultType(Op0.getValueType()), 32285480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands Op0, DAG.getConstant(0, Op0.getValueType()), 32295480c0469e5c0323ffb12f1ead2abd169d6cc0e7Duncan Sands ISD::SETLT); 3230475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Zero = DAG.getIntPtrConstant(0), Four = DAG.getIntPtrConstant(4); 3231af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue CstOffset = DAG.getNode(ISD::SELECT, dl, Zero.getValueType(), 323222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner SignSet, Four, Zero); 323322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 323422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the sign bit of the integer is set, the large number will be treated 323522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // as a negative number. To counteract this, the dynamic code adds an 323622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // offset depending on the data type. 323722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner uint64_t FF; 323883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands switch (Op0.getValueType().getSimpleVT()) { 323922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner default: assert(0 && "Unsupported integer type!"); 324022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case MVT::i8 : FF = 0x43800000ULL; break; // 2^8 (as a float) 324122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case MVT::i16: FF = 0x47800000ULL; break; // 2^16 (as a float) 324222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case MVT::i32: FF = 0x4F800000ULL; break; // 2^32 (as a float) 324322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case MVT::i64: FF = 0x5F800000ULL; break; // 2^64 (as a float) 324422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 324522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (TLI.isLittleEndian()) FF <<= 32; 3246d2e936a513b01b2c5df91a9c0d80070e8c752aceChris Lattner Constant *FudgeFactor = ConstantInt::get(Type::Int64Ty, FF); 324722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 3248475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue CPIdx = DAG.getConstantPool(FudgeFactor, TLI.getPointerTy()); 32491606e8e4cd937e6de6681f686c266cf61722d972Evan Cheng unsigned Alignment = cast<ConstantPoolSDNode>(CPIdx)->getAlignment(); 3250af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen CPIdx = DAG.getNode(ISD::ADD, dl, TLI.getPointerTy(), CPIdx, CstOffset); 325187a0f10dc7eff8cf5e83a754f75adf9cb3991435Dan Gohman Alignment = std::min(Alignment, 4u); 3252475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue FudgeInReg; 325322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (DestVT == MVT::f32) 3254af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen FudgeInReg = DAG.getLoad(MVT::f32, dl, DAG.getEntryNode(), CPIdx, 325550284d81f863a6576582e1a171a22eb0f012ddf3Dan Gohman PseudoSourceValue::getConstantPool(), 0, 325650284d81f863a6576582e1a171a22eb0f012ddf3Dan Gohman false, Alignment); 325722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner else { 325869de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman FudgeInReg = 3259af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen LegalizeOp(DAG.getExtLoad(ISD::EXTLOAD, dl, DestVT, 326069de1932b350d7cdfc0ed1f4198d6f78c7822a02Dan Gohman DAG.getEntryNode(), CPIdx, 32613069b8743769527ce7af6cfb6591a2f0fc2faee4Dan Gohman PseudoSourceValue::getConstantPool(), 0, 326250284d81f863a6576582e1a171a22eb0f012ddf3Dan Gohman MVT::f32, false, Alignment)); 326322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 326422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 3265af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen return DAG.getNode(ISD::FADD, dl, DestVT, Tmp1, FudgeInReg); 326622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 326722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 326822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// PromoteLegalINT_TO_FP - This function is responsible for legalizing a 326922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// *INT_TO_FP operation of the specified operand when the target requests that 327022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we promote it. At this point, we know that the result and operand types are 327122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target, and that there is a legal UINT_TO_FP or SINT_TO_FP 327222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// operation that takes a larger input. 3273475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::PromoteLegalINT_TO_FP(SDValue LegalOp, 3274475871a144eb604ddaf37503397ba0941442e5fbDan Gohman MVT DestVT, 3275af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen bool isSigned, 3276af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 327722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // First step, figure out the appropriate *INT_TO_FP operation to use. 327883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NewInTy = LegalOp.getValueType(); 327922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 328022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner unsigned OpToUse = 0; 328122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 328222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Scan for the appropriate larger type to use. 328322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner while (1) { 328483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands NewInTy = (MVT::SimpleValueType)(NewInTy.getSimpleVT()+1); 328583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(NewInTy.isInteger() && "Ran out of possibilities!"); 328622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 328722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the target supports SINT_TO_FP of this type, use it. 328822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner switch (TLI.getOperationAction(ISD::SINT_TO_FP, NewInTy)) { 328922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner default: break; 329022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case TargetLowering::Legal: 329122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (!TLI.isTypeLegal(NewInTy)) 329222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; // Can't use this datatype. 329322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // FALL THROUGH. 329422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case TargetLowering::Custom: 329522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner OpToUse = ISD::SINT_TO_FP; 329622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; 329722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 329822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (OpToUse) break; 329922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (isSigned) continue; 330022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 330122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the target supports UINT_TO_FP of this type, use it. 330222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner switch (TLI.getOperationAction(ISD::UINT_TO_FP, NewInTy)) { 330322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner default: break; 330422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case TargetLowering::Legal: 330522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (!TLI.isTypeLegal(NewInTy)) 330622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; // Can't use this datatype. 330722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // FALL THROUGH. 330822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case TargetLowering::Custom: 330922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner OpToUse = ISD::UINT_TO_FP; 331022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; 331122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 331222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (OpToUse) break; 331322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 331422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Otherwise, try a larger type. 331522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 331622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 331722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Okay, we found the operation and type to use. Zero extend our input to the 331822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // desired type then run the operation on it. 3319af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen return DAG.getNode(OpToUse, dl, DestVT, 332022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner DAG.getNode(isSigned ? ISD::SIGN_EXTEND : ISD::ZERO_EXTEND, 3321af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen dl, NewInTy, LegalOp)); 332277e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner} 332377e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner 332422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// PromoteLegalFP_TO_INT - This function is responsible for legalizing a 332522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// FP_TO_*INT operation of the specified operand when the target requests that 332622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// we promote it. At this point, we know that the result and operand types are 332722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// legal for the target, and that there is a legal FP_TO_UINT or FP_TO_SINT 332822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// operation that returns a larger result. 3329475871a144eb604ddaf37503397ba0941442e5fbDan GohmanSDValue SelectionDAGLegalize::PromoteLegalFP_TO_INT(SDValue LegalOp, 3330475871a144eb604ddaf37503397ba0941442e5fbDan Gohman MVT DestVT, 3331af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen bool isSigned, 3332af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen DebugLoc dl) { 333322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // First step, figure out the appropriate FP_TO*INT operation to use. 333483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT NewOutTy = DestVT; 33359c32d3b798dc6caeebe6cea2effe80ca5e84e66eChris Lattner 333622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner unsigned OpToUse = 0; 3337e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner 333822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Scan for the appropriate larger type to use. 333922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner while (1) { 334083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands NewOutTy = (MVT::SimpleValueType)(NewOutTy.getSimpleVT()+1); 334183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands assert(NewOutTy.isInteger() && "Ran out of possibilities!"); 334266de05b606cf31f1f23ed0c4eb1f097738cd1506Chris Lattner 334322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the target supports FP_TO_SINT returning this type, use it. 334422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner switch (TLI.getOperationAction(ISD::FP_TO_SINT, NewOutTy)) { 334522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner default: break; 334622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case TargetLowering::Legal: 334722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (!TLI.isTypeLegal(NewOutTy)) 334822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; // Can't use this datatype. 334922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // FALL THROUGH. 335022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case TargetLowering::Custom: 335122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner OpToUse = ISD::FP_TO_SINT; 335222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; 335322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 335422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (OpToUse) break; 3355e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner 335622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If the target supports FP_TO_UINT of this type, use it. 335722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner switch (TLI.getOperationAction(ISD::FP_TO_UINT, NewOutTy)) { 335822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner default: break; 335922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case TargetLowering::Legal: 336022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (!TLI.isTypeLegal(NewOutTy)) 336122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; // Can't use this datatype. 336222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // FALL THROUGH. 336322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case TargetLowering::Custom: 336422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner OpToUse = ISD::FP_TO_UINT; 336522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner break; 3366e9c35e7309a8293852ba71d874fa4dc99e07e6feChris Lattner } 336722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner if (OpToUse) break; 33680d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner 336922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // Otherwise, try a larger type. 3370a88a260dbd874a3bdd3e47f4f15ab0d7c7803044Chris Lattner } 3371a88a260dbd874a3bdd3e47f4f15ab0d7c7803044Chris Lattner 3372fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel 337327a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // Okay, we found the operation and type to use. 3374af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen SDValue Operation = DAG.getNode(OpToUse, dl, NewOutTy, LegalOp); 3375126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands 337627a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // If the operation produces an invalid type, it must be custom lowered. Use 337727a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // the target lowering hooks to expand it. Just keep the low part of the 337827a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // expanded operation, we know that we're truncating anyway. 337927a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner if (getTypeAction(NewOutTy) == Expand) { 33801607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands SmallVector<SDValue, 2> Results; 33811607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands TLI.ReplaceNodeResults(Operation.getNode(), Results, DAG); 33821607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands assert(Results.size() == 1 && "Incorrect FP_TO_XINT lowering!"); 33831607f05cb7d77d01ce521a30232faa389dbed4e2Duncan Sands Operation = Results[0]; 338427a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner } 3385126d90770bdb17e6925b2fe26de99aa079b7b9b3Duncan Sands 338627a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // Truncate the result of the extended FP_TO_*INT operation to the desired 338727a6c7380fa4dfc8e1837a8dd67967d063b26544Chris Lattner // size. 3388af435274e56af687b51f33b5bc6f005fe99ad46fDale Johannesen return DAG.getNode(ISD::TRUNCATE, dl, DestVT, Operation); 338922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 339013689e2009e71f7982d1313ed699e0e6a50157d0Chris Lattner 339122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandBSWAP - Open code the operations for BSWAP of the specified operation. 339222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// 33938a782a2a8c2f0c82f292d03a3f707232b0bae27bDale JohannesenSDValue SelectionDAGLegalize::ExpandBSWAP(SDValue Op, DebugLoc dl) { 339483ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Op.getValueType(); 339583ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT SHVT = TLI.getShiftAmountTy(); 3396475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp1, Tmp2, Tmp3, Tmp4, Tmp5, Tmp6, Tmp7, Tmp8; 339783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands switch (VT.getSimpleVT()) { 339822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner default: assert(0 && "Unhandled Expand type in BSWAP!"); abort(); 339922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case MVT::i16: 34008a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 34018a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 34028a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp1, Tmp2); 340322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case MVT::i32: 34048a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); 34058a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 34068a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 34078a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); 34088a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(0xFF0000, VT)); 34098a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(0xFF00, VT)); 34108a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); 34118a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); 34128a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); 341322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case MVT::i64: 34148a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(56, SHVT)); 34158a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp7 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(40, SHVT)); 34168a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(24, SHVT)); 34178a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp5 = DAG.getNode(ISD::SHL, dl, VT, Op, DAG.getConstant(8, SHVT)); 34188a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(8, SHVT)); 34198a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(24, SHVT)); 34208a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(40, SHVT)); 34218a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp1 = DAG.getNode(ISD::SRL, dl, VT, Op, DAG.getConstant(56, SHVT)); 34228a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp7 = DAG.getNode(ISD::AND, dl, VT, Tmp7, DAG.getConstant(255ULL<<48, VT)); 34238a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::AND, dl, VT, Tmp6, DAG.getConstant(255ULL<<40, VT)); 34248a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp5 = DAG.getNode(ISD::AND, dl, VT, Tmp5, DAG.getConstant(255ULL<<32, VT)); 34258a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::AND, dl, VT, Tmp4, DAG.getConstant(255ULL<<24, VT)); 34268a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp3 = DAG.getNode(ISD::AND, dl, VT, Tmp3, DAG.getConstant(255ULL<<16, VT)); 34278a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::AND, dl, VT, Tmp2, DAG.getConstant(255ULL<<8 , VT)); 34288a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp7); 34298a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp6 = DAG.getNode(ISD::OR, dl, VT, Tmp6, Tmp5); 34308a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp3); 34318a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2 = DAG.getNode(ISD::OR, dl, VT, Tmp2, Tmp1); 34328a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp8 = DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp6); 34338a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp4 = DAG.getNode(ISD::OR, dl, VT, Tmp4, Tmp2); 34348a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::OR, dl, VT, Tmp8, Tmp4); 34350d67f0c80f0295aa44f826ec1402ea73d6b4bd22Chris Lattner } 343677e77a6aa0ab25a812947aed477220dd11220a18Chris Lattner} 3437edf128a7fa90f2b0b7ee24741a04a7ae1ecd6f7eMisha Brukman 343822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// ExpandBitCount - Expand the specified bitcount instruction into operations. 343922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner/// 3440fdc40a0a696c658d550d894ea03772e5f8af2c94Scott MichelSDValue SelectionDAGLegalize::ExpandBitCount(unsigned Opc, SDValue Op, 34418a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DebugLoc dl) { 344222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner switch (Opc) { 344322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner default: assert(0 && "Cannot expand this yet!"); 344422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTPOP: { 344522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner static const uint64_t mask[6] = { 344622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 0x5555555555555555ULL, 0x3333333333333333ULL, 344722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 0x0F0F0F0F0F0F0F0FULL, 0x00FF00FF00FF00FFULL, 344822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner 0x0000FFFF0000FFFFULL, 0x00000000FFFFFFFFULL 344922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner }; 345083ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Op.getValueType(); 345183ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT ShVT = TLI.getShiftAmountTy(); 345283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned len = VT.getSizeInBits(); 345322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { 345422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner //x = (x & mask[i][len/8]) + (x >> (1 << i) & mask[i][len/8]) 3455b0d5cdd52e8448f769cd71aaee6a4b8592dc08b1Duncan Sands unsigned EltSize = VT.isVector() ? 3456b0d5cdd52e8448f769cd71aaee6a4b8592dc08b1Duncan Sands VT.getVectorElementType().getSizeInBits() : len; 3457b0d5cdd52e8448f769cd71aaee6a4b8592dc08b1Duncan Sands SDValue Tmp2 = DAG.getConstant(APInt(EltSize, mask[i]), VT); 3458475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); 3459fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Op = DAG.getNode(ISD::ADD, dl, VT, 3460e72c5964d5263f2489bf2c7e9d32f71271d205fcDale Johannesen DAG.getNode(ISD::AND, dl, VT, Op, Tmp2), 34618a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNode(ISD::AND, dl, VT, 34628a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNode(ISD::SRL, dl, VT, Op, Tmp3), 34638a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Tmp2)); 346422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 346522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner return Op; 346622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 346722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTLZ: { 346822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // for now, we do this: 346922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >> 1); 347022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >> 2); 347122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // ... 347222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >>16); 347322cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // x = x | (x >>32); // for 64-bit input 347422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // return popcount(~x); 347522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // 347622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // but see also: http://www.hackersdelight.org/HDcode/nlz.cc 347783ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Op.getValueType(); 347883ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT ShVT = TLI.getShiftAmountTy(); 347983ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands unsigned len = VT.getSizeInBits(); 348022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner for (unsigned i = 0; (1U << i) <= (len / 2); ++i) { 3481475871a144eb604ddaf37503397ba0941442e5fbDan Gohman SDValue Tmp3 = DAG.getConstant(1ULL << i, ShVT); 3482fdc40a0a696c658d550d894ea03772e5f8af2c94Scott Michel Op = DAG.getNode(ISD::OR, dl, VT, Op, 3483e72c5964d5263f2489bf2c7e9d32f71271d205fcDale Johannesen DAG.getNode(ISD::SRL, dl, VT, Op, Tmp3)); 348422cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 34858a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen Op = DAG.getNOT(dl, Op, VT); 34868a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::CTPOP, dl, VT, Op); 348722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 348822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner case ISD::CTTZ: { 348922cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // for now, we use: { return popcount(~x & (x - 1)); } 349022cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // unless the target has ctlz but not ctpop, in which case we use: 349122cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // { return 32 - nlz(~x & (x-1)); } 349222cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // see also http://www.hackersdelight.org/HDcode/ntz.cc 349383ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands MVT VT = Op.getValueType(); 34948a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen SDValue Tmp3 = DAG.getNode(ISD::AND, dl, VT, 34958a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNOT(dl, Op, VT), 34968a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNode(ISD::SUB, dl, VT, Op, 34977581bfa2757a3149c6d17c0fe592e5c3808aa843Bill Wendling DAG.getConstant(1, VT))); 349822cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner // If ISD::CTLZ is legal and CTPOP isn't, then do that instead. 3499f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman if (!TLI.isOperationLegalOrCustom(ISD::CTPOP, VT) && 3500f560ffae1f1f6591859c7b70636a3eca6c03f083Dan Gohman TLI.isOperationLegalOrCustom(ISD::CTLZ, VT)) 35018a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::SUB, dl, VT, 350283ec4b6711980242ef3c55a4fa36b2d7a39c1bfbDuncan Sands DAG.getConstant(VT.getSizeInBits(), VT), 35038a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen DAG.getNode(ISD::CTLZ, dl, VT, Tmp3)); 35048a782a2a8c2f0c82f292d03a3f707232b0bae27bDale Johannesen return DAG.getNode(ISD::CTPOP, dl, VT, Tmp3); 350522cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 350622cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner } 350722cde6a518782cafc2115ad8d8233f79c9e9d52eChris Lattner} 3508e34b396ab7d28469bf3d9679a748b643d8e30458Chris Lattner 35098c377c7296d8a8104231442c3f6c27296249ec5fEli Friedmanvoid SelectionDAGLegalize::ExpandNode(SDNode *Node, 35108c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SmallVectorImpl<SDValue> &Results) { 35118c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DebugLoc dl = Node->getDebugLoc(); 35128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SDValue Tmp1, Tmp2; 35138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 35148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTPOP: 35158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTLZ: 35168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTTZ: 35178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandBitCount(Node->getOpcode(), Node->getOperand(0), dl); 35188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 35198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BSWAP: 35218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(ExpandBSWAP(Node->getOperand(0), dl)); 35228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAMEADDR: 35248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::RETURNADDR: 35258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FRAME_TO_ARGS_OFFSET: 35268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(0, Node->getValueType(0))); 35278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FLT_ROUNDS_: 35298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(1, Node->getValueType(0))); 35308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_RETURN: 35328c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::DECLARE: 35338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::DBG_LABEL: 35348c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EH_LABEL: 35358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::PREFETCH: 35368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::MEMBARRIER: 35378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VAEND: 35388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Node->getOperand(0)); 35398c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35408c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::MERGE_VALUES: 35418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman for (unsigned i = 0; i < Node->getNumValues(); i++) 35428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Node->getOperand(i)); 35438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UNDEF: { 35458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT VT = Node->getValueType(0); 35468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (VT.isInteger()) 35478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstant(0, VT)); 35488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman else if (VT.isFloatingPoint()) 35498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(DAG.getConstantFP(0, VT)); 35508c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman else 35518c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman assert(0 && "Unknown value type!"); 35528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35538c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 35548c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::TRAP: { 35558c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // If this operation is not supported, lower it to 'abort()' call 35568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman TargetLowering::ArgListTy Args; 35578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman std::pair<SDValue, SDValue> CallResult = 35588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman TLI.LowerCallTo(Node->getOperand(0), Type::VoidTy, 35598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman false, false, false, false, CallingConv::C, false, 35608c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getExternalSymbol("abort", TLI.getPointerTy()), 35618c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Args, DAG, dl); 35628c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(CallResult.second); 35638c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35648c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 35658c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND: 35668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BIT_CONVERT: 35678c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), Node->getValueType(0), 35688c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 35698c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 35708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_EXTEND: 35728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), 35738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0).getValueType(), 35748c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 35758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 35768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SIGN_EXTEND_INREG: { 35788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // NOTE: we could fall back on load/store here too for targets without 35798c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // SAR. However, it is doubtful that any exist. 35808c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); 35818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman unsigned BitsDiff = Node->getValueType(0).getSizeInBits() - 35828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ExtraVT.getSizeInBits(); 35838c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SDValue ShiftCst = DAG.getConstant(BitsDiff, TLI.getShiftAmountTy()); 35848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SHL, dl, Node->getValueType(0), 35858c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), ShiftCst); 35868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SRA, dl, Node->getValueType(0), Tmp1, ShiftCst); 35878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 35888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 35898c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 35908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_ROUND_INREG: { 35918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // The only way we can lower this is to turn it into a TRUNCSTORE, 35928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // EXTLOAD pair, targetting a temporary location (a stack slot). 35938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 35948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // NOTE: there is a choice here between constantly creating new stack 35958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // slots and always reusing the same one. We currently always create 35968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // new ones, as reuse may inhibit scheduling. 35978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT ExtraVT = cast<VTSDNode>(Node->getOperand(1))->getVT(); 35988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = EmitStackConvert(Node->getOperand(0), ExtraVT, 35998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getValueType(0), dl); 36008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 36018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 36028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 36038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 36048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 36058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandLegalINT_TO_FP(Node->getOpcode() == ISD::SINT_TO_FP, 36068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), Node->getValueType(0), dl); 36078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 36088c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 36098c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_UINT: { 36108c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SDValue True, False; 36118c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT VT = Node->getOperand(0).getValueType(); 36128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT NVT = Node->getValueType(0); 36138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman const uint64_t zero[] = {0, 0}; 36148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman APFloat apf = APFloat(APInt(VT.getSizeInBits(), 2, zero)); 36158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman APInt x = APInt::getSignBit(NVT.getSizeInBits()); 36168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman (void)apf.convertFromAPInt(x, false, APFloat::rmNearestTiesToEven); 36178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getConstantFP(apf, VT); 36188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(VT), 36198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), 36208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1, ISD::SETLT); 36218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman True = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, Node->getOperand(0)); 36228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman False = DAG.getNode(ISD::FP_TO_SINT, dl, NVT, 36238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getNode(ISD::FSUB, dl, VT, 36248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0), Tmp1)); 36258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman False = DAG.getNode(ISD::XOR, dl, NVT, False, 36268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(x, NVT)); 36278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, True, False); 36288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 36298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 36308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 36318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::VACOPY: { 36328c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // This defaults to loading a pointer from the input and storing it to the 36338c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // output, returning the chain. 36348c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman const Value *VD = cast<SrcValueSDNode>(Node->getOperand(3))->getValue(); 36358c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman const Value *VS = cast<SrcValueSDNode>(Node->getOperand(4))->getValue(); 36368c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getLoad(TLI.getPointerTy(), dl, Node->getOperand(0), 36378c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(2), VS, 0); 36388c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getStore(Tmp1.getValue(1), dl, Tmp1, Node->getOperand(1), VD, 0); 36398c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 36408c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 36418c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 36428c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_VECTOR_ELT: 36438c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOperand(0).getValueType().getVectorNumElements() == 1) 36448c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // This must be an access of the only element. Return it. 36458c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::BIT_CONVERT, dl, Node->getValueType(0), 36468c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0)); 36478c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman else 36488c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = ExpandExtractFromVectorThroughStack(SDValue(Node, 0)); 36498c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 36508c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 36518c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_SUBVECTOR: 36528c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(ExpandExtractFromVectorThroughStack(SDValue(Node, 0))); 36538c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 36548c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SCALAR_TO_VECTOR: 36558c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(ExpandSCALAR_TO_VECTOR(Node)); 36568c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 36578c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::EXTRACT_ELEMENT: { 36588c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT OpTy = Node->getOperand(0).getValueType(); 36598c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { 36608c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // 1 -> Hi 36618c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SRL, dl, OpTy, Node->getOperand(0), 36628c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(OpTy.getSizeInBits()/2, 36638c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman TLI.getShiftAmountTy())); 36648c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), Tmp1); 36658c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else { 36668c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // 0 -> Lo 36678c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::TRUNCATE, dl, Node->getValueType(0), 36688c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOperand(0)); 36698c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 36708c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 36718c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 36728c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 36738c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 36748c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman} 36758c377c7296d8a8104231442c3f6c27296249ec5fEli Friedmanvoid SelectionDAGLegalize::PromoteNode(SDNode *Node, 36768c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SmallVectorImpl<SDValue> &Results) { 36778c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT OVT = Node->getValueType(0); 36788c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOpcode() == ISD::UINT_TO_FP || 36798c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOpcode() == ISD::SINT_TO_FP) { 36808c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman OVT = Node->getOperand(0).getValueType(); 36818c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 36828c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman MVT NVT = TLI.getTypeToPromoteTo(Node->getOpcode(), OVT); 36838c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DebugLoc dl = Node->getDebugLoc(); 36848c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman SDValue Tmp1, Tmp2; 36858c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman switch (Node->getOpcode()) { 36868c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTTZ: 36878c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTLZ: 36888c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::CTPOP: 36898c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Zero extend the argument. 36908c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Node->getOperand(0)); 36918c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Perform the larger operation. 36928c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(Node->getOpcode(), dl, Node->getValueType(0), Tmp1); 36938c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman if (Node->getOpcode() == ISD::CTTZ) { 36948c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman //if Tmp1 == sizeinbits(NVT) then Tmp1 = sizeinbits(Old VT) 36958c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp2 = DAG.getSetCC(dl, TLI.getSetCCResultType(Tmp1.getValueType()), 36968c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1, DAG.getConstant(NVT.getSizeInBits(), NVT), 36978c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman ISD::SETEQ); 36988c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SELECT, dl, NVT, Tmp2, 36998c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(OVT.getSizeInBits(), NVT), Tmp1); 37008c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } else if (Node->getOpcode() == ISD::CTLZ) { 37018c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman // Tmp1 = Tmp1 - (sizeinbits(NVT) - sizeinbits(Old VT)) 37028c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SUB, dl, NVT, Tmp1, 37038c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(NVT.getSizeInBits() - 37048c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman OVT.getSizeInBits(), NVT)); 37058c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 37068c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 37078c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 37088c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::BSWAP: { 37098c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman unsigned DiffBits = NVT.getSizeInBits() - OVT.getSizeInBits(); 37108c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::ZERO_EXTEND, dl, NVT, Tmp1); 37118c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::BSWAP, dl, NVT, Tmp1); 37128c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = DAG.getNode(ISD::SRL, dl, NVT, Tmp1, 37138c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman DAG.getConstant(DiffBits, TLI.getShiftAmountTy())); 37148c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 37158c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 37168c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 37178c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_UINT: 37188c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::FP_TO_SINT: 37198c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = PromoteLegalFP_TO_INT(Node->getOperand(0), Node->getValueType(0), 37208c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOpcode() == ISD::FP_TO_SINT, dl); 37218c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 37228c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 37238c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::UINT_TO_FP: 37248c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman case ISD::SINT_TO_FP: 37258c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Tmp1 = PromoteLegalINT_TO_FP(Node->getOperand(0), Node->getValueType(0), 37268c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Node->getOpcode() == ISD::SINT_TO_FP, dl); 37278c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman Results.push_back(Tmp1); 37288c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman break; 37298c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman } 37308c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman} 37318c377c7296d8a8104231442c3f6c27296249ec5fEli Friedman 37323e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// SelectionDAG::Legalize - This is the entry point for the file. 37333e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner// 373498a366d547772010e94609e4584489b3e5ce0043Bill Wendlingvoid SelectionDAG::Legalize(bool TypesNeedLegalizing, 373598a366d547772010e94609e4584489b3e5ce0043Bill Wendling CodeGenOpt::Level OptLevel) { 37363e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// run - This is the main entry point to this class. 37373e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner /// 37381fde9c5f771922f12fefc903850c4eca303297d9Eli Friedman SelectionDAGLegalize(*this, OptLevel).LegalizeDAG(); 37393e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner} 37403e928bbd6153eb08641cbd0ad7d8487378a8b12aChris Lattner 3741