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