LLVM API Documentation
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