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