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     /// InstructionSelectBasicBlock - This callback is invoked by
00085     /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
00086     virtual void InstructionSelectBasicBlock(SelectionDAG &DAG);
00087     
00088     virtual const char *getPassName() const {
00089       return "IA64 (Itanium) DAG->DAG Instruction Selector";
00090     } 
00091 
00092 // Include the pieces autogenerated from the target description.
00093 #include "IA64GenDAGISel.inc"
00094     
00095 private:
00096     SDOperand SelectDIV(SDOperand Op);
00097   };
00098 }
00099 
00100 /// InstructionSelectBasicBlock - This callback is invoked by
00101 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen.
00102 void IA64DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) {
00103   DEBUG(BB->dump());
00104   
00105   // The selection process is inherently a bottom-up recursive process (users
00106   // select their uses before themselves).  Given infinite stack space, we
00107   // could just start selecting on the root and traverse the whole graph.  In
00108   // practice however, this causes us to run out of stack space on large basic
00109   // blocks.  To avoid this problem, select the entry node, then all its uses,
00110   // iteratively instead of recursively.
00111   std::vector<SDOperand> Worklist;
00112   Worklist.push_back(DAG.getEntryNode());
00113   
00114   // Note that we can do this in the IA64 target (scanning forward across token
00115   // chain edges) because no nodes ever get folded across these edges.  On a
00116   // target like X86 which supports load/modify/store operations, this would
00117   // have to be more careful.
00118   while (!Worklist.empty()) {
00119     SDOperand Node = Worklist.back();
00120     Worklist.pop_back();
00121     
00122     // Chose from the least deep of the top two nodes.
00123     if (!Worklist.empty() &&
00124         Worklist.back().Val->getNodeDepth() < Node.Val->getNodeDepth())
00125       std::swap(Worklist.back(), Node);
00126     
00127     if ((Node.Val->getOpcode() >= ISD::BUILTIN_OP_END &&
00128          Node.Val->getOpcode() < IA64ISD::FIRST_NUMBER) ||
00129         CodeGenMap.count(Node)) continue;
00130     
00131     for (SDNode::use_iterator UI = Node.Val->use_begin(),
00132          E = Node.Val->use_end(); UI != E; ++UI) {
00133       // Scan the values.  If this use has a value that is a token chain, add it
00134       // to the worklist.
00135       SDNode *User = *UI;
00136       for (unsigned i = 0, e = User->getNumValues(); i != e; ++i)
00137         if (User->getValueType(i) == MVT::Other) {
00138           Worklist.push_back(SDOperand(User, i));
00139           break; 
00140         }
00141     }
00142 
00143     // Finally, legalize this node.
00144     SDOperand Dummy;
00145     Select(Dummy, Node);
00146   }
00147     
00148   // Select target instructions for the DAG.
00149   DAG.setRoot(SelectRoot(DAG.getRoot()));
00150   assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!");
00151   CodeGenMap.clear();
00152   HandleMap.clear();
00153   ReplaceMap.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:
00515 #ifndef NDEBUG
00516       N->dump();
00517 #endif
00518       assert(0 && "Cannot load this type!");
00519     case MVT::i1: { // this is a bool
00520       Opc = IA64::LD1; // first we load a byte, then compare for != 0
00521       if(N->getValueType(0) == MVT::i1) { // XXX: early exit!
00522         Result = CurDAG->SelectNodeTo(N, IA64::CMPNE, MVT::i1, MVT::Other, 
00523                     SDOperand(CurDAG->getTargetNode(Opc, MVT::i64, Address), 0),
00524                                   CurDAG->getRegister(IA64::r0, MVT::i64), 
00525                                   Chain).getValue(Op.ResNo);
00526         return;
00527       }
00528       /* otherwise, we want to load a bool into something bigger: LD1
00529          will do that for us, so we just fall through */
00530     }
00531     case MVT::i8:  Opc = IA64::LD1; break;
00532     case MVT::i16: Opc = IA64::LD2; break;
00533     case MVT::i32: Opc = IA64::LD4; break;
00534     case MVT::i64: Opc = IA64::LD8; break;
00535     
00536     case MVT::f32: Opc = IA64::LDF4; break;
00537     case MVT::f64: Opc = IA64::LDF8; break;
00538     }
00539 
00540     // TODO: comment this
00541     Result = CurDAG->SelectNodeTo(N, Opc, N->getValueType(0), MVT::Other,
00542                                 Address, Chain).getValue(Op.ResNo);
00543     return;
00544   }
00545   
00546   case ISD::TRUNCSTORE:
00547   case ISD::STORE: {
00548     SDOperand Address, Chain;
00549     Select(Address, N->getOperand(2));
00550     Select(Chain, N->getOperand(0));
00551    
00552     unsigned Opc;
00553     if (N->getOpcode() == ISD::STORE) {
00554       switch (N->getOperand(1).getValueType()) {
00555       default: assert(0 && "unknown type in store");
00556       case MVT::i1: { // this is a bool
00557         Opc = IA64::ST1; // we store either 0 or 1 as a byte 
00558   // first load zero!
00559   SDOperand Initial = CurDAG->getCopyFromReg(Chain, IA64::r0, MVT::i64);
00560   Chain = Initial.getValue(1);
00561   // then load 1 into the same reg iff the predicate to store is 1
00562         SDOperand Tmp;
00563         Select(Tmp, N->getOperand(1));
00564         Tmp = SDOperand(CurDAG->getTargetNode(IA64::TPCADDS, MVT::i64, Initial,
00565                                               CurDAG->getConstant(1, MVT::i64),
00566                                               Tmp), 0);
00567         Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, Address, Tmp, Chain);
00568         return;
00569       }
00570       case MVT::i64: Opc = IA64::ST8;  break;
00571       case MVT::f64: Opc = IA64::STF8; break;
00572       }
00573     } else { //ISD::TRUNCSTORE
00574       switch(cast<VTSDNode>(N->getOperand(4))->getVT()) {
00575       default: assert(0 && "unknown type in truncstore");
00576       case MVT::i8:  Opc = IA64::ST1;  break;
00577       case MVT::i16: Opc = IA64::ST2;  break;
00578       case MVT::i32: Opc = IA64::ST4;  break;
00579       case MVT::f32: Opc = IA64::STF4; break;
00580       }
00581     }
00582     
00583     SDOperand N1, N2;
00584     Select(N1, N->getOperand(1));
00585     Select(N2, N->getOperand(2));
00586     Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, N2, N1, Chain);
00587     return;
00588   }
00589 
00590   case ISD::BRCOND: {
00591     SDOperand Chain, CC;
00592     Select(Chain, N->getOperand(0));
00593     Select(CC, N->getOperand(1));
00594     MachineBasicBlock *Dest =
00595       cast<BasicBlockSDNode>(N->getOperand(2))->getBasicBlock();
00596     //FIXME - we do NOT need long branches all the time
00597     Result = CurDAG->SelectNodeTo(N, IA64::BRLCOND_NOTCALL, MVT::Other, CC, 
00598                                 CurDAG->getBasicBlock(Dest), Chain);
00599     return;
00600   }
00601 
00602   case ISD::CALLSEQ_START:
00603   case ISD::CALLSEQ_END: {
00604     int64_t Amt = cast<ConstantSDNode>(N->getOperand(1))->getValue();
00605     unsigned Opc = N->getOpcode() == ISD::CALLSEQ_START ?
00606                        IA64::ADJUSTCALLSTACKDOWN : IA64::ADJUSTCALLSTACKUP;
00607     SDOperand N0;
00608     Select(N0, N->getOperand(0));
00609     Result = CurDAG->SelectNodeTo(N, Opc, MVT::Other, getI64Imm(Amt), N0);
00610     return;
00611   }
00612 
00613   case ISD::BR:
00614      // FIXME: we don't need long branches all the time!
00615     SDOperand N0;
00616     Select(N0, N->getOperand(0));
00617     Result = CurDAG->SelectNodeTo(N, IA64::BRL_NOTCALL, MVT::Other, 
00618                                 N->getOperand(1), N0);
00619     return;
00620   }
00621   
00622   SelectCode(Result, Op);
00623 }
00624 
00625 
00626 /// createIA64DAGToDAGInstructionSelector - This pass converts a legalized DAG
00627 /// into an IA64-specific DAG, ready for instruction scheduling.
00628 ///
00629 FunctionPass
00630 *llvm::createIA64DAGToDAGInstructionSelector(IA64TargetMachine &TM) {
00631   return new IA64DAGToDAGISel(TM);
00632 }
00633