LLVM API Documentation

IA64ISelDAGToDAG.cpp

Go to the documentation of this file.
00001 //===---- IA64ISelDAGToDAG.cpp - IA64 pattern matching inst selector ------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by Duraid Madina and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines a pattern matching instruction selector for IA64,
00011 // converting a legalized dag to an IA64 dag.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #include "IA64.h"
00016 #include "IA64TargetMachine.h"
00017 #include "IA64ISelLowering.h"
00018 #include "llvm/CodeGen/MachineInstrBuilder.h"
00019 #include "llvm/CodeGen/MachineFunction.h"
00020 #include "llvm/CodeGen/SSARegMap.h"
00021 #include "llvm/CodeGen/SelectionDAG.h"
00022 #include "llvm/CodeGen/SelectionDAGISel.h"
00023 #include "llvm/Target/TargetOptions.h"
00024 #include "llvm/ADT/Statistic.h"
00025 #include "llvm/Constants.h"
00026 #include "llvm/GlobalValue.h"
00027 #include "llvm/Intrinsics.h"
00028 #include "llvm/Support/Debug.h"
00029 #include "llvm/Support/MathExtras.h"
00030 #include <iostream>
00031 #include <set>
00032 using namespace llvm;
00033 
00034 namespace {
00035   Statistic<> FusedFP ("ia64-codegen", "Number of fused fp operations");
00036   Statistic<> FrameOff("ia64-codegen", "Number of frame idx offsets collapsed");
00037     
00038   //===--------------------------------------------------------------------===//
00039   /// IA64DAGToDAGISel - IA64 specific code to select IA64 machine
00040   /// instructions for SelectionDAG operations.
00041   ///
00042   class IA64DAGToDAGISel : public SelectionDAGISel {
00043     IA64TargetLowering IA64Lowering;
00044     unsigned GlobalBaseReg;
00045   public:
00046     IA64DAGToDAGISel(IA64TargetMachine &TM)
00047       : SelectionDAGISel(IA64Lowering), IA64Lowering(*TM.getTargetLowering()) {}
00048     
00049     virtual bool runOnFunction(Function &Fn) {
00050       // Make sure we re-emit a set of the global base reg if necessary
00051       GlobalBaseReg = 0;
00052       return SelectionDAGISel::runOnFunction(Fn);
00053     }
00054  
00055     /// getI64Imm - Return a target constant with the specified value, of type
00056     /// i64.
00057     inline SDOperand getI64Imm(uint64_t Imm) {
00058       return CurDAG->getTargetConstant(Imm, MVT::i64);
00059     }
00060 
00061     /// getGlobalBaseReg - insert code into the entry mbb to materialize the PIC
00062     /// base register.  Return the virtual register that holds this value.
00063     // SDOperand getGlobalBaseReg(); TODO: hmm
00064     
00065     // Select - Convert the specified operand from a target-independent to a
00066     // target-specific node if it hasn't already been changed.
00067     void Select(SDOperand &Result, SDOperand N);
00068     
00069     SDNode *SelectIntImmediateExpr(SDOperand LHS, SDOperand RHS,
00070                                    unsigned OCHi, unsigned OCLo,
00071                                    bool IsArithmetic = false,
00072                                    bool Negate = false);
00073     SDNode *SelectBitfieldInsert(SDNode *N);
00074 
00075     /// SelectCC - Select a comparison of the specified values with the
00076     /// specified condition code, returning the CR# of the expression.
00077     SDOperand SelectCC(SDOperand LHS, SDOperand RHS, ISD::CondCode CC);
00078 
00079     /// SelectAddr - Given the specified address, return the two operands for a
00080     /// load/store instruction, and return true if it should be an indexed [r+r]
00081     /// operation.
00082     bool SelectAddr(SDOperand Addr, SDOperand &Op1, SDOperand &Op2);
00083 
00084     SDOperand BuildSDIVSequence(SDNode *N);
00085     SDOperand BuildUDIVSequence(SDNode *N);
00086     
00087     /// InstructionSelectBasicBlock - This callback is invoked by
00088     /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
00089     virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
00090     
00091     virtual const char *getPassName() const {
00092       return "IA64 (Itanium) DAG->DAG Instruction Selector";
00093     } 
00094 
00095 // Include the pieces autogenerated from the target description.
00096 #include "IA64GenDAGISel.inc"
00097     
00098 private:
00099     SDOperand SelectDIV(SDOperand Op);
00100   };
00101 }
00102 
00103 /// InstructionSelectBasicBlock - This callback is invoked by
00104 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
00105 void IA64DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
00106   DEBUG(BB->dump());
00107   
00108   // The selection process is inherently a bottom-up recursive process (users
00109   // select their uses before themselves).  Given infinite stack space, we
00110   // could just start selecting on the root and traverse the whole graph.  In
00111   // practice however, this causes us to run out of stack space on large basic
00112   // blocks.  To avoid this problem, select the entry node, then all its uses,
00113   // iteratively instead of recursively.
00114   std::vector<SDOperand> Worklist;
00115   Worklist.push_back(DAG.getEntryNode());
00116   
00117   // Note that we can do this in the IA64 target (scanning forward across token
00118   // chain edges) because no nodes ever get folded across these edges.  On a
00119   // target like X86 which supports load/modify/store operations, this would
00120   // have to be more careful.
00121   while (!Worklist.empty()) {
00122     SDOperand Node = Worklist.back();
00123     Worklist.pop_back();
00124     
00125     // Chose from the least deep of the top two nodes.
00126     if (!Worklist.empty() &&
00127         Worklist.back().Val->getNodeDepth() < Node.Val->getNodeDepth())
00128       std::swap(Worklist.back(), Node);
00129     
00130     if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
00131          Node.Val->getOpcode() < IA64ISD::FIRST_NUMBER) ||
00132         CodeGenMap.count(Node)) continue;
00133     
00134     for (SDNode::use_iterator UI = Node.Val->use_begin(),
00135          E = Node.Val->use_end(); UI != E; ++UI) {
00136       // Scan the values.  If this use has a value that is a token chain, add it
00137       // to the worklist.
00138       SDNode *User = *UI;
00139       for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
00140         if (User->getValueType(i) == MVT::Other) {
00141           Worklist.push_back(SDOperand(User, i));
00142           break; 
00143         }
00144     }
00145 
00146     // Finally, legalize this node.
00147     SDOperand Dummy;
00148     Select(Dummy, Node);
00149   }
00150     
00151   // Select target instructions for the DAG.
00152   DAG.setRoot(SelectRoot(DAG.getRoot()));
00153   CodeGenMap.clear();
00154   DAG.RemoveDeadNodes();
00155   
00156   // Emit machine code to BB. 
00157   ScheduleAndEmitDAG(DAG);
00158 }
00159 
00160 SDOperand IA64DAGToDAGISel::SelectDIV(SDOperand Op) {
00161   SDNode *N = Op.Val;
00162   SDOperand Chain, Tmp1, Tmp2;
00163   Select(Chain, N->getOperand(0));
00164 
00165   Select(Tmp1, N->getOperand(0));
00166   Select(Tmp2, N->getOperand(1));
00167 
00168   bool isFP=false;
00169 
00170   if(MVT::isFloatingPoint(Tmp1.getValueType()))
00171     isFP=true;
00172     
00173   bool isModulus=false; // is it a division or a modulus?
00174   bool isSigned=false;
00175 
00176   switch(N->getOpcode()) {
00177     case ISD::FDIV:
00178     case ISD::SDIV:  isModulus=false; isSigned=true;  break;
00179     case ISD::UDIV:  isModulus=false; isSigned=false; break;
00180     case ISD::FREM:
00181     case ISD::SREM:  isModulus=true;  isSigned=true;  break;
00182     case ISD::UREM:  isModulus=true;  isSigned=false; break;
00183   }
00184 
00185   // TODO: check for integer divides by powers of 2 (or other simple patterns?)
00186 
00187     SDOperand TmpPR, TmpPR2;
00188     SDOperand TmpF1, TmpF2, TmpF3, TmpF4, TmpF5, TmpF6, TmpF7, TmpF8;
00189     SDOperand TmpF9, TmpF10,TmpF11,TmpF12,TmpF13,TmpF14,TmpF15;
00190     SDNode *Result;
00191 
00192     // we'll need copies of F0 and F1
00193     SDOperand F0 = CurDAG->getRegister(IA64::F0, MVT::f64);
00194     SDOperand F1 = CurDAG->getRegister(IA64::F1, MVT::f64);
00195     
00196     // OK, emit some code:
00197 
00198     if(!isFP) {
00199       // first, load the inputs into FP regs.
00200       TmpF1 =
00201         SDOperand(CurDAG->getTargetNode(IA64::SETFSIG, MVT::f64, Tmp1), 0);
00202       Chain = TmpF1.getValue(1);
00203       TmpF2 =
00204         SDOperand(CurDAG->getTargetNode(IA64::SETFSIG, MVT::f64, Tmp2), 0);
00205       Chain = TmpF2.getValue(1);
00206       
00207       // next, convert the inputs to FP
00208       if(isSigned) {
00209         TmpF3 =
00210           SDOperand(CurDAG->getTargetNode(IA64::FCVTXF, MVT::f64, TmpF1), 0);
00211         Chain = TmpF3.getValue(1);
00212         TmpF4 =
00213           SDOperand(CurDAG->getTargetNode(IA64::FCVTXF, MVT::f64, TmpF2), 0);
00214         Chain = TmpF4.getValue(1);
00215       } else { // is unsigned
00216         TmpF3 =
00217           SDOperand(CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF1), 0);
00218         Chain = TmpF3.getValue(1);
00219         TmpF4 =
00220           SDOperand(CurDAG->getTargetNode(IA64::FCVTXUFS1, MVT::f64, TmpF2), 0);
00221         Chain = TmpF4.getValue(1);
00222       }
00223 
00224     } else { // this is an FP divide/remainder, so we 'leak' some temp
00225              // regs and assign TmpF3=Tmp1, TmpF4=Tmp2
00226       TmpF3=Tmp1;
00227       TmpF4=Tmp2;
00228     }
00229 
00230     // we start by computing an approximate reciprocal (good to 9 bits?)
00231     // note, this instruction writes _both_ TmpF5 (answer) and TmpPR (predicate)
00232     if(isFP)
00233       TmpF5 = SDOperand(CurDAG->getTargetNode(IA64::FRCPAS0, MVT::f64, MVT::i1,
00234                                               TmpF3, TmpF4), 0);
00235     else
00236       TmpF5 = SDOperand(CurDAG->getTargetNode(IA64::FRCPAS1, MVT::f64, MVT::i1,
00237                                               TmpF3, TmpF4), 0);
00238                                   
00239     TmpPR = TmpF5.getValue(1);
00240     Chain = TmpF5.getValue(2);
00241 
00242     SDOperand minusB;
00243     if(isModulus) { // for remainders, it'll be handy to have
00244                              // copies of -input_b
00245       minusB = SDOperand(CurDAG->getTargetNode(IA64::SUB, MVT::i64,
00246                   CurDAG->getRegister(IA64::r0, MVT::i64), Tmp2), 0);
00247       Chain = minusB.getValue(1);
00248     }
00249     
00250     SDOperand TmpE0, TmpY1, TmpE1, TmpY2;
00251     
00252     TmpE0 = SDOperand(CurDAG->getTargetNode(IA64::CFNMAS1, MVT::f64,
00253                                             TmpF4, TmpF5, F1, TmpPR), 0);
00254     Chain = TmpE0.getValue(1);
00255     TmpY1 = SDOperand(CurDAG->getTargetNode(IA64::CFMAS1, MVT::f64,
00256                                             TmpF5, TmpE0, TmpF5, TmpPR), 0);
00257     Chain = TmpY1.getValue(1);
00258     TmpE1 = SDOperand(CurDAG->getTargetNode(IA64::CFMAS1, MVT::f64,
00259                                             TmpE0, TmpE0, F0, TmpPR), 0);
00260     Chain = TmpE1.getValue(1);
00261     TmpY2 = SDOperand(CurDAG->getTargetNode(IA64::CFMAS1, MVT::f64,
00262                                             TmpY1, TmpE1, TmpY1, TmpPR), 0);
00263     Chain = TmpY2.getValue(1);
00264     
00265     if(isFP) { // if this is an FP divide, we finish up here and exit early
00266       if(isModulus)
00267         assert(0 && "Sorry, try another FORTRAN compiler.");
00268  
00269       SDOperand TmpE2, TmpY3, TmpQ0, TmpR0;
00270       
00271       TmpE2 = SDOperand(CurDAG->getTargetNode(IA64::CFMAS1, MVT::f64,
00272                                               TmpE1, TmpE1, F0, TmpPR), 0);
00273       Chain = TmpE2.getValue(1);
00274       TmpY3 = SDOperand(CurDAG->getTargetNode(IA64::CFMAS1, MVT::f64,
00275                                               TmpY2, TmpE2, TmpY2, TmpPR), 0);
00276       Chain = TmpY3.getValue(1);
00277       TmpQ0 =
00278         SDOperand(CurDAG->getTargetNode(IA64::CFMADS1, MVT::f64, // double prec!
00279                                         Tmp1, TmpY3, F0, TmpPR), 0);
00280       Chain = TmpQ0.getValue(1);
00281       TmpR0 =
00282         SDOperand(CurDAG->getTargetNode(IA64::CFNMADS1, MVT::f64, // double prec!
00283                                         Tmp2, TmpQ0, Tmp1, TmpPR), 0);
00284       Chain = TmpR0.getValue(1);
00285 
00286 // we want Result to have the same target register as the frcpa, so
00287 // we two-address hack it. See the comment "for this to work..." on
00288 // page 48 of Intel application note #245415
00289       Result = CurDAG->getTargetNode(IA64::TCFMADS0, MVT::f64, // d.p. s0 rndg!
00290                                      TmpF5, TmpY3, TmpR0, TmpQ0, TmpPR);
00291       Chain = SDOperand(Result, 1);
00292       return SDOperand(Result, 0); // XXX: early exit!
00293     } else { // this is *not* an FP divide, so there's a bit left to do:
00294     
00295       SDOperand TmpQ2, TmpR2, TmpQ3, TmpQ;
00296       
00297       TmpQ2 = SDOperand(CurDAG->getTargetNode(IA64::CFMAS1, MVT::f64,
00298                                               TmpF3, TmpY2, F0, TmpPR), 0);
00299       Chain = TmpQ2.getValue(1);
00300       TmpR2 = SDOperand(CurDAG->getTargetNode(IA64::CFNMAS1, MVT::f64,
00301                                               TmpF4, TmpQ2, TmpF3, TmpPR), 0);
00302       Chain = TmpR2.getValue(1);
00303       
00304 // we want TmpQ3 to have the same target register as the frcpa? maybe we
00305 // should two-address hack it. See the comment "for this to work..." on page
00306 // 48 of Intel application note #245415
00307       TmpQ3 = SDOperand(CurDAG->getTargetNode(IA64::TCFMAS1, MVT::f64,
00308                                          TmpF5, TmpR2, TmpY2, TmpQ2, TmpPR), 0);
00309       Chain = TmpQ3.getValue(1);
00310 
00311       // STORY: without these two-address instructions (TCFMAS1 and TCFMADS0)
00312       // the FPSWA won't be able to help out in the case of large/tiny
00313       // arguments. Other fun bugs may also appear, e.g. 0/x = x, not 0.
00314       
00315       if(isSigned)
00316         TmpQ = SDOperand(CurDAG->getTargetNode(IA64::FCVTFXTRUNCS1,
00317                                                MVT::f64, TmpQ3), 0);
00318       else
00319         TmpQ = SDOperand(CurDAG->getTargetNode(IA64::FCVTFXUTRUNCS1,
00320                                                MVT::f64, TmpQ3), 0);
00321       
00322       Chain = TmpQ.getValue(1);
00323 
00324       if(isModulus) {
00325         SDOperand FPminusB =
00326           SDOperand(CurDAG->getTargetNode(IA64::SETFSIG, MVT::f64, minusB), 0);
00327         Chain = FPminusB.getValue(1);
00328         SDOperand Remainder =
00329           SDOperand(CurDAG->getTargetNode(IA64::XMAL, MVT::f64,
00330                                           TmpQ, FPminusB, TmpF1), 0);
00331         Chain = Remainder.getValue(1);
00332         Result = CurDAG->getTargetNode(IA64::GETFSIG, MVT::i64, Remainder);
00333         Chain = SDOperand(Result, 1);
00334       } else { // just an integer divide
00335         Result = CurDAG->getTargetNode(IA64::GETFSIG, MVT::i64, TmpQ);
00336         Chain = SDOperand(Result, 1);
00337       }
00338 
00339       return SDOperand(Result, 0);
00340     } // wasn't an FP divide
00341 }
00342 
00343 // Select - Convert the specified operand from a target-independent to a
00344 // target-specific node if it hasn't already been changed.
00345 void IA64DAGToDAGISel::Select(SDOperand &Result, SDOperand Op) {
00346   SDNode *N = Op.Val;
00347   if (N->getOpcode() >= ISD::BUILTIN_OP_END &&
00348       N->getOpcode() < IA64ISD::FIRST_NUMBER) {
00349     Result = Op;
00350     return;   // Already selected.
00351   }
00352 
00353   // If this has already been converted, use it.
00354   std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op);
00355   if (CGMI != CodeGenMap.end()) {
00356     Result = CGMI->second;
00357     return;
00358   }
00359   
00360   switch (N->getOpcode()) {
00361   default: break;
00362 
00363   case IA64ISD::BRCALL: { // XXX: this is also a hack!
00364     SDOperand Chain;
00365     SDOperand InFlag;  // Null incoming flag value.
00366 
00367     Select(Chain, N->getOperand(0));
00368     if(N->getNumOperands()==3) // we have an incoming chain, callee and flag
00369       Select(InFlag, N->getOperand(2));
00370 
00371     unsigned CallOpcode;
00372     SDOperand CallOperand;
00373     
00374     // if we can call directly, do so
00375     if (GlobalAddressSDNode *GASD =
00376       dyn_cast<GlobalAddressSDNode>(N->getOperand(1))) {
00377       CallOpcode = IA64::BRCALL_IPREL_GA;
00378       CallOperand = CurDAG->getTargetGlobalAddress(GASD->getGlobal(), MVT::i64);
00379     } else if (ExternalSymbolSDNode *ESSDN = // FIXME: we currently NEED this
00380                              // case for correctness, to avoid
00381            // "non-pic code with imm reloc.n
00382            // against dynamic symbol" errors
00383              dyn_cast<ExternalSymbolSDNode>(N->getOperand(1))) {
00384     CallOpcode = IA64::BRCALL_IPREL_ES;
00385     CallOperand = N->getOperand(1);
00386   } else {
00387     // otherwise we need to load the function descriptor,
00388     // load the branch target (function)'s entry point and GP,
00389     // branch (call) then restore the GP
00390     SDOperand FnDescriptor;
00391     Select(FnDescriptor, N->getOperand(1));
00392    
00393     // load the branch target's entry point [mem] and 
00394     // GP value [mem+8]
00395     SDOperand targetEntryPoint=
00396       SDOperand(CurDAG->getTargetNode(IA64::LD8, MVT::i64, FnDescriptor), 0);
00397     Chain = targetEntryPoint.getValue(1);
00398     SDOperand targetGPAddr=
00399       SDOperand(CurDAG->getTargetNode(IA64::ADDS, MVT::i64, 
00400         FnDescriptor, CurDAG->getConstant(8, MVT::i64)), 0);
00401     Chain = targetGPAddr.getValue(1);
00402     SDOperand targetGP=
00403       SDOperand(CurDAG->getTargetNode(IA64::LD8, MVT::i64, targetGPAddr), 0);
00404     Chain = targetGP.getValue(1);
00405 
00406     Chain = CurDAG->getCopyToReg(Chain, IA64::r1, targetGP, InFlag);
00407     InFlag = Chain.getValue(1);
00408     Chain = CurDAG->getCopyToReg(Chain, IA64::B6, targetEntryPoint, InFlag); // FLAG these?
00409     InFlag = Chain.getValue(1);
00410     
00411     CallOperand = CurDAG->getRegister(IA64::B6, MVT::i64);
00412     CallOpcode = IA64::BRCALL_INDIRECT;
00413   }
00414  
00415    // Finally, once everything is setup, emit the call itself
00416    if(InFlag.Val)
00417      Chain = SDOperand(CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag,
00418                                              CallOperand, InFlag), 0);
00419    else // there might be no arguments
00420      Chain = SDOperand(CurDAG->getTargetNode(CallOpcode, MVT::Other, MVT::Flag,
00421                                              CallOperand, Chain), 0);
00422    InFlag = Chain.getValue(1);
00423 
00424    std::vector<SDOperand> CallResults;
00425 
00426    CallResults.push_back(Chain);
00427    CallResults.push_back(InFlag);
00428 
00429    for (unsigned i = 0, e = CallResults.size(); i != e; ++i)
00430      CodeGenMap[Op.getValue(i)] = CallResults[i];
00431    Result = CallResults[Op.ResNo];
00432    return;
00433   }
00434   
00435   case IA64ISD::GETFD: {
00436     SDOperand Input;
00437     Select(Input, N->getOperand(0));
00438     Result = SDOperand(CurDAG->getTargetNode(IA64::GETFD, MVT::i64, Input), 0);
00439     CodeGenMap[Op] = Result;
00440     return;
00441   } 
00442   
00443   case ISD::FDIV:
00444   case ISD::SDIV:
00445   case ISD::UDIV:
00446   case ISD::SREM:
00447   case ISD::UREM:
00448     Result = SelectDIV(Op);
00449     return;
00450  
00451   case ISD::TargetConstantFP: {
00452     SDOperand Chain = CurDAG->getEntryNode(); // this is a constant, so..
00453 
00454     if (cast<ConstantFPSDNode>(N)->isExactlyValue(+0.0)) {
00455       Result = CurDAG->getCopyFromReg(Chain, IA64::F0, MVT::f64);
00456     } else if (cast<ConstantFPSDNode>(N)->isExactlyValue(+1.0)) {
00457       Result = CurDAG->getCopyFromReg(Chain, IA64::F1, MVT::f64);
00458     } else
00459       assert(0 && "Unexpected FP constant!");
00460     return;
00461   }
00462 
00463   case ISD::FrameIndex: { // TODO: reduce creepyness
00464     int FI = cast<FrameIndexSDNode>(N)->getIndex();
00465     if (N->hasOneUse())
00466       Result = CurDAG->SelectNodeTo(N, IA64::MOV, MVT::i64,
00467                                   CurDAG->getTargetFrameIndex(FI, MVT::i64));
00468     else
00469       Result = CodeGenMap[Op] = SDOperand(CurDAG->getTargetNode(IA64::MOV, MVT::i64,
00470                                 CurDAG->getTargetFrameIndex(FI, MVT::i64)), 0);
00471     return;
00472   }
00473 
00474   case ISD::ConstantPool: { // TODO: nuke the constant pool
00475           //       (ia64 doesn't need one)
00476     ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(N);
00477     Constant *C = CP->get();
00478     SDOperand CPI = CurDAG->getTargetConstantPool(C, MVT::i64,
00479                                                   CP->getAlignment());
00480     Result = SDOperand(CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, // ?
00481                         CurDAG->getRegister(IA64::r1, MVT::i64), CPI), 0);
00482     return;
00483   }
00484 
00485   case ISD::GlobalAddress: {
00486     GlobalValue *GV = cast<GlobalAddressSDNode>(N)->getGlobal();
00487     SDOperand GA = CurDAG->getTargetGlobalAddress(GV, MVT::i64);
00488     SDOperand Tmp = SDOperand(CurDAG->getTargetNode(IA64::ADDL_GA, MVT::i64, 
00489                             CurDAG->getRegister(IA64::r1, MVT::i64), GA), 0);
00490     Result = SDOperand(CurDAG->getTargetNode(IA64::LD8, MVT::i64, Tmp), 0);
00491     return;
00492   }
00493   
00494 /* XXX  case ISD::ExternalSymbol: {
00495     SDOperand EA = CurDAG->getTargetExternalSymbol(cast<ExternalSymbolSDNode>(N)->getSymbol(),
00496     MVT::i64);
00497     SDOperand Tmp = CurDAG->getTargetNode(IA64::ADDL_EA, MVT::i64, 
00498                             CurDAG->getRegister(IA64::r1, MVT::i64), EA);
00499     return CurDAG->getTargetNode(IA64::LD8, MVT::i64, Tmp);
00500  }
00501 */
00502 
00503   case ISD::LOAD:
00504   case ISD::EXTLOAD: // FIXME: load -1, not 1, for bools?
00505   case ISD::ZEXTLOAD: {
00506     SDOperand Chain, Address;
00507     Select(Chain, N->getOperand(0));
00508     Select(Address, N->getOperand(1));
00509 
00510     MVT::ValueType TypeBeingLoaded = (N->getOpcode() == ISD::LOAD) ?
00511       N->getValueType(0) : cast<VTSDNode>(N->getOperand(3))->getVT();
00512     unsigned Opc;
00513     switch (TypeBeingLoaded) {
00514     default: N->dump(); assert(0 && "Cannot load this type!");
00515     case MVT::i1: { // this is a bool
00516       Opc = IA64::LD1; // first we load a byte, then compare for != 0
00517       if(N->getValueType(0) == MVT::i1) { // XXX: early exit!
00518         Result = CurDAG->SelectNodeTo(N, IA64::CMPNE, MVT::i1, MVT::Other, 
00519                     SDOperand(CurDAG->getTargetNode(Opc, MVT::i64, Address), 0),
00520                                   CurDAG->getRegister(IA64::r0, MVT::i64), 
00521                                   Chain).getValue(Op.ResNo);
00522         return;
00523       }
00524       /* otherwise, we want to load a bool into something bigger: LD1
00525          will do that for us, so we just fall through */
00526     }
00527     case MVT::i8:  Opc = IA64::LD1; break;
00528     case MVT::i16: Opc = IA64::LD2; break;
00529     case MVT::i32: Opc = IA64::LD4; break;
00530     case MVT::i64: Opc = IA64::LD8; break;
00531     
00532     case MVT::f32: Opc = IA64::LDF4; break;
00533     case MVT::f64: Opc = IA64::LDF8; break;
00534     }
00535 
00536     // TODO: comment this
00537     Result = CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
00538                                 Address, Chain).getValue(Op.ResNo);
00539     return;
00540   }
00541   
00542   case ISD::TRUNCSTORE:
00543   case ISD::STORE: {
00544     SDOperand Address, Chain;
00545     Select(Address, N->getOperand(2));
00546     Select(Chain, N->getOperand(0));
00547    
00548     unsigned Opc;
00549     if (N->getOpcode() == ISD::STORE) {
00550       switch (N->getOperand(1).getValueType()) {
00551       default: assert(0 && "unknown type in store");
00552       case MVT::i1: { // this is a bool
00553         Opc = IA64::ST1; // we store either 0 or 1 as a byte 
00554   // first load zero!
00555   SDOperand Initial = CurDAG->getCopyFromReg(Chain, IA64::r0, MVT::i64);
00556   Chain = Initial.getValue(1);
00557   // then load 1 into the same reg iff the predicate to store is 1
00558         SDOperand Tmp;
00559         Select(Tmp, N->getOperand(1));
00560         Tmp = SDOperand(CurDAG->getTargetNode(IA64::TPCADDS, MVT::i64, Initial,
00561                                               CurDAG->getConstant(1, MVT::i64),
00562                                               Tmp), 0);
00563         Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, Address, Tmp, Chain);
00564         return;
00565       }
00566       case MVT::i64: Opc = IA64::ST8;  break;
00567       case MVT::f64: Opc = IA64::STF8; break;
00568       }
00569     } else { //ISD::TRUNCSTORE
00570       switch(cast<VTSDNode>(N->getOperand(4))->getVT()) {
00571       default: assert(0 && "unknown type in truncstore");
00572       case MVT::i8:  Opc = IA64::ST1;  break;
00573       case MVT::i16: Opc = IA64::ST2;  break;
00574       case MVT::i32: Opc = IA64::ST4;  break;
00575       case MVT::f32: Opc = IA64::STF4; break;
00576       }
00577     }
00578     
00579     SDOperand N1, N2;
00580     Select(N1, N->getOperand(1));
00581     Select(N2, N->getOperand(2));
00582     Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, N2, N1, Chain);
00583     return;
00584   }
00585 
00586   case ISD::BRCOND: {
00587     SDOperand Chain, CC;
00588     Select(Chain, N->getOperand(0));
00589     Select(CC, N->getOperand(1));
00590     MachineBasicBlock *Dest =
00591       cast<BasicBlockSDNode>(N->getOperand(2))->getBasicBlock();
00592     //FIXME - we do NOT need long branches all the time
00593     Result = CurDAG->SelectNodeTo(N, IA64::BRLCOND_NOTCALL, MVT::Other, CC, 
00594                                 CurDAG->getBasicBlock(Dest), Chain);
00595     return;
00596   }
00597 
00598   case ISD::CALLSEQ_START:
00599   case ISD::CALLSEQ_END: {
00600     int64_t Amt = cast<ConstantSDNode>(N->getOperand(1))->getValue();
00601     unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ?
00602                        IA64::ADJUSTCALLSTACKDOWN : IA64::ADJUSTCALLSTACKUP;
00603     SDOperand N0;
00604     Select(N0, N->getOperand(0));
00605     Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, getI64Imm(Amt), N0);
00606     return;
00607   }
00608 
00609   case ISD::BR:
00610      // FIXME: we don't need long branches all the time!
00611     SDOperand N0;
00612     Select(N0, N->getOperand(0));
00613     Result = CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other, 
00614                                 N->getOperand(1), N0);
00615     return;
00616   }
00617   
00618   SelectCode(Result, Op);
00619 }
00620 
00621 
00622 /// createIA64DAGToDAGInstructionSelector - This pass converts a legalized DAG
00623 /// into an IA64-specific DAG, ready for instruction scheduling.
00624 ///
00625 FunctionPass
00626 *llvm::createIA64DAGToDAGInstructionSelector(IA64TargetMachine &TM) {
00627   return new IA64DAGToDAGISel(TM);
00628 }
00629