LLVM API Documentation
00001 //===-- AlphaISelLowering.cpp - Alpha DAG Lowering Implementation ---------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Andrew Lenharth and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file implements the AlphaISelLowering class. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "AlphaISelLowering.h" 00015 #include "AlphaTargetMachine.h" 00016 #include "llvm/CodeGen/MachineFrameInfo.h" 00017 #include "llvm/CodeGen/MachineFunction.h" 00018 #include "llvm/CodeGen/MachineInstrBuilder.h" 00019 #include "llvm/CodeGen/SelectionDAG.h" 00020 #include "llvm/CodeGen/SSARegMap.h" 00021 #include "llvm/Constants.h" 00022 #include "llvm/Function.h" 00023 #include "llvm/Module.h" 00024 #include "llvm/Support/CommandLine.h" 00025 #include <iostream> 00026 00027 using namespace llvm; 00028 //Shamelessly adapted from PPC32 00029 // Structure used to return the necessary information to codegen an SDIV as 00030 // a multiply. 00031 struct ms { 00032 int64_t m; // magic number 00033 int64_t s; // shift amount 00034 }; 00035 00036 struct mu { 00037 uint64_t m; // magic number 00038 int64_t a; // add indicator 00039 int64_t s; // shift amount 00040 }; 00041 00042 /// magic - calculate the magic numbers required to codegen an integer sdiv as 00043 /// a sequence of multiply and shifts. Requires that the divisor not be 0, 1, 00044 /// or -1. 00045 static struct ms magic(int64_t d) { 00046 int64_t p; 00047 uint64_t ad, anc, delta, q1, r1, q2, r2, t; 00048 const uint64_t two63 = 9223372036854775808ULL; // 2^63 00049 struct ms mag; 00050 00051 ad = llabs(d); 00052 t = two63 + ((uint64_t)d >> 63); 00053 anc = t - 1 - t%ad; // absolute value of nc 00054 p = 63; // initialize p 00055 q1 = two63/anc; // initialize q1 = 2p/abs(nc) 00056 r1 = two63 - q1*anc; // initialize r1 = rem(2p,abs(nc)) 00057 q2 = two63/ad; // initialize q2 = 2p/abs(d) 00058 r2 = two63 - q2*ad; // initialize r2 = rem(2p,abs(d)) 00059 do { 00060 p = p + 1; 00061 q1 = 2*q1; // update q1 = 2p/abs(nc) 00062 r1 = 2*r1; // update r1 = rem(2p/abs(nc)) 00063 if (r1 >= anc) { // must be unsigned comparison 00064 q1 = q1 + 1; 00065 r1 = r1 - anc; 00066 } 00067 q2 = 2*q2; // update q2 = 2p/abs(d) 00068 r2 = 2*r2; // update r2 = rem(2p/abs(d)) 00069 if (r2 >= ad) { // must be unsigned comparison 00070 q2 = q2 + 1; 00071 r2 = r2 - ad; 00072 } 00073 delta = ad - r2; 00074 } while (q1 < delta || (q1 == delta && r1 == 0)); 00075 00076 mag.m = q2 + 1; 00077 if (d < 0) mag.m = -mag.m; // resulting magic number 00078 mag.s = p - 64; // resulting shift 00079 return mag; 00080 } 00081 00082 /// magicu - calculate the magic numbers required to codegen an integer udiv as 00083 /// a sequence of multiply, add and shifts. Requires that the divisor not be 0. 00084 static struct mu magicu(uint64_t d) 00085 { 00086 int64_t p; 00087 uint64_t nc, delta, q1, r1, q2, r2; 00088 struct mu magu; 00089 magu.a = 0; // initialize "add" indicator 00090 nc = - 1 - (-d)%d; 00091 p = 63; // initialize p 00092 q1 = 0x8000000000000000ull/nc; // initialize q1 = 2p/nc 00093 r1 = 0x8000000000000000ull - q1*nc; // initialize r1 = rem(2p,nc) 00094 q2 = 0x7FFFFFFFFFFFFFFFull/d; // initialize q2 = (2p-1)/d 00095 r2 = 0x7FFFFFFFFFFFFFFFull - q2*d; // initialize r2 = rem((2p-1),d) 00096 do { 00097 p = p + 1; 00098 if (r1 >= nc - r1 ) { 00099 q1 = 2*q1 + 1; // update q1 00100 r1 = 2*r1 - nc; // update r1 00101 } 00102 else { 00103 q1 = 2*q1; // update q1 00104 r1 = 2*r1; // update r1 00105 } 00106 if (r2 + 1 >= d - r2) { 00107 if (q2 >= 0x7FFFFFFFFFFFFFFFull) magu.a = 1; 00108 q2 = 2*q2 + 1; // update q2 00109 r2 = 2*r2 + 1 - d; // update r2 00110 } 00111 else { 00112 if (q2 >= 0x8000000000000000ull) magu.a = 1; 00113 q2 = 2*q2; // update q2 00114 r2 = 2*r2 + 1; // update r2 00115 } 00116 delta = d - 1 - r2; 00117 } while (p < 64 && (q1 < delta || (q1 == delta && r1 == 0))); 00118 magu.m = q2 + 1; // resulting magic number 00119 magu.s = p - 64; // resulting shift 00120 return magu; 00121 } 00122 00123 /// BuildSDIVSequence - Given an ISD::SDIV node expressing a divide by constant, 00124 /// return a DAG expression to select that will generate the same value by 00125 /// multiplying by a magic number. See: 00126 /// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html> 00127 static SDOperand BuildSDIVSequence(SDOperand N, SelectionDAG* ISelDAG) { 00128 int64_t d = (int64_t)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended(); 00129 ms magics = magic(d); 00130 // Multiply the numerator (operand 0) by the magic value 00131 SDOperand Q = ISelDAG->getNode(ISD::MULHS, MVT::i64, N.getOperand(0), 00132 ISelDAG->getConstant(magics.m, MVT::i64)); 00133 // If d > 0 and m < 0, add the numerator 00134 if (d > 0 && magics.m < 0) 00135 Q = ISelDAG->getNode(ISD::ADD, MVT::i64, Q, N.getOperand(0)); 00136 // If d < 0 and m > 0, subtract the numerator. 00137 if (d < 0 && magics.m > 0) 00138 Q = ISelDAG->getNode(ISD::SUB, MVT::i64, Q, N.getOperand(0)); 00139 // Shift right algebraic if shift value is nonzero 00140 if (magics.s > 0) 00141 Q = ISelDAG->getNode(ISD::SRA, MVT::i64, Q, 00142 ISelDAG->getConstant(magics.s, MVT::i64)); 00143 // Extract the sign bit and add it to the quotient 00144 SDOperand T = 00145 ISelDAG->getNode(ISD::SRL, MVT::i64, Q, ISelDAG->getConstant(63, MVT::i64)); 00146 return ISelDAG->getNode(ISD::ADD, MVT::i64, Q, T); 00147 } 00148 00149 /// BuildUDIVSequence - Given an ISD::UDIV node expressing a divide by constant, 00150 /// return a DAG expression to select that will generate the same value by 00151 /// multiplying by a magic number. See: 00152 /// <http://the.wall.riscom.net/books/proc/ppc/cwg/code2.html> 00153 static SDOperand BuildUDIVSequence(SDOperand N, SelectionDAG* ISelDAG) { 00154 unsigned d = 00155 (unsigned)cast<ConstantSDNode>(N.getOperand(1))->getSignExtended(); 00156 mu magics = magicu(d); 00157 // Multiply the numerator (operand 0) by the magic value 00158 SDOperand Q = ISelDAG->getNode(ISD::MULHU, MVT::i64, N.getOperand(0), 00159 ISelDAG->getConstant(magics.m, MVT::i64)); 00160 if (magics.a == 0) { 00161 Q = ISelDAG->getNode(ISD::SRL, MVT::i64, Q, 00162 ISelDAG->getConstant(magics.s, MVT::i64)); 00163 } else { 00164 SDOperand NPQ = ISelDAG->getNode(ISD::SUB, MVT::i64, N.getOperand(0), Q); 00165 NPQ = ISelDAG->getNode(ISD::SRL, MVT::i64, NPQ, 00166 ISelDAG->getConstant(1, MVT::i64)); 00167 NPQ = ISelDAG->getNode(ISD::ADD, MVT::i64, NPQ, Q); 00168 Q = ISelDAG->getNode(ISD::SRL, MVT::i64, NPQ, 00169 ISelDAG->getConstant(magics.s-1, MVT::i64)); 00170 } 00171 return Q; 00172 } 00173 00174 /// AddLiveIn - This helper function adds the specified physical register to the 00175 /// MachineFunction as a live in value. It also creates a corresponding virtual 00176 /// register for it. 00177 static unsigned AddLiveIn(MachineFunction &MF, unsigned PReg, 00178 TargetRegisterClass *RC) { 00179 assert(RC->contains(PReg) && "Not the correct regclass!"); 00180 unsigned VReg = MF.getSSARegMap()->createVirtualRegister(RC); 00181 MF.addLiveIn(PReg, VReg); 00182 return VReg; 00183 } 00184 00185 AlphaTargetLowering::AlphaTargetLowering(TargetMachine &TM) : TargetLowering(TM) { 00186 // Set up the TargetLowering object. 00187 //I am having problems with shr n ubyte 1 00188 setShiftAmountType(MVT::i64); 00189 setSetCCResultType(MVT::i64); 00190 setSetCCResultContents(ZeroOrOneSetCCResult); 00191 00192 addRegisterClass(MVT::i64, Alpha::GPRCRegisterClass); 00193 addRegisterClass(MVT::f64, Alpha::F8RCRegisterClass); 00194 addRegisterClass(MVT::f32, Alpha::F4RCRegisterClass); 00195 00196 setOperationAction(ISD::BR_CC, MVT::Other, Expand); 00197 setOperationAction(ISD::SELECT_CC, MVT::Other, Expand); 00198 00199 setOperationAction(ISD::EXTLOAD, MVT::i1, Promote); 00200 setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); 00201 00202 setOperationAction(ISD::ZEXTLOAD, MVT::i1, Promote); 00203 setOperationAction(ISD::ZEXTLOAD, MVT::i32, Expand); 00204 00205 setOperationAction(ISD::SEXTLOAD, MVT::i1, Promote); 00206 setOperationAction(ISD::SEXTLOAD, MVT::i8, Expand); 00207 setOperationAction(ISD::SEXTLOAD, MVT::i16, Expand); 00208 00209 setOperationAction(ISD::TRUNCSTORE, MVT::i1, Promote); 00210 00211 setOperationAction(ISD::FREM, MVT::f32, Expand); 00212 setOperationAction(ISD::FREM, MVT::f64, Expand); 00213 00214 setOperationAction(ISD::UINT_TO_FP, MVT::i64, Expand); 00215 setOperationAction(ISD::SINT_TO_FP, MVT::i64, Custom); 00216 setOperationAction(ISD::FP_TO_UINT, MVT::i64, Expand); 00217 setOperationAction(ISD::FP_TO_SINT, MVT::i64, Custom); 00218 00219 if (!TM.getSubtarget<AlphaSubtarget>().hasCT()) { 00220 setOperationAction(ISD::CTPOP , MVT::i64 , Expand); 00221 setOperationAction(ISD::CTTZ , MVT::i64 , Expand); 00222 setOperationAction(ISD::CTLZ , MVT::i64 , Expand); 00223 } 00224 setOperationAction(ISD::BSWAP , MVT::i64, Expand); 00225 setOperationAction(ISD::ROTL , MVT::i64, Expand); 00226 setOperationAction(ISD::ROTR , MVT::i64, Expand); 00227 00228 setOperationAction(ISD::SREM , MVT::i64, Custom); 00229 setOperationAction(ISD::UREM , MVT::i64, Custom); 00230 setOperationAction(ISD::SDIV , MVT::i64, Custom); 00231 setOperationAction(ISD::UDIV , MVT::i64, Custom); 00232 00233 setOperationAction(ISD::MEMMOVE , MVT::Other, Expand); 00234 setOperationAction(ISD::MEMSET , MVT::Other, Expand); 00235 setOperationAction(ISD::MEMCPY , MVT::Other, Expand); 00236 00237 // We don't support sin/cos/sqrt 00238 setOperationAction(ISD::FSIN , MVT::f64, Expand); 00239 setOperationAction(ISD::FCOS , MVT::f64, Expand); 00240 setOperationAction(ISD::FSIN , MVT::f32, Expand); 00241 setOperationAction(ISD::FCOS , MVT::f32, Expand); 00242 00243 setOperationAction(ISD::FSQRT, MVT::f64, Expand); 00244 setOperationAction(ISD::FSQRT, MVT::f32, Expand); 00245 00246 // FIXME: Alpha supports fcopysign natively!? 00247 setOperationAction(ISD::FCOPYSIGN, MVT::f64, Expand); 00248 setOperationAction(ISD::FCOPYSIGN, MVT::f32, Expand); 00249 00250 setOperationAction(ISD::SETCC, MVT::f32, Promote); 00251 00252 // We don't have line number support yet. 00253 setOperationAction(ISD::LOCATION, MVT::Other, Expand); 00254 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); 00255 setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); 00256 00257 // Not implemented yet. 00258 setOperationAction(ISD::STACKSAVE, MVT::Other, Expand); 00259 setOperationAction(ISD::STACKRESTORE, MVT::Other, Expand); 00260 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i64, Expand); 00261 00262 // We want to legalize GlobalAddress and ConstantPool and 00263 // ExternalSymbols nodes into the appropriate instructions to 00264 // materialize the address. 00265 setOperationAction(ISD::GlobalAddress, MVT::i64, Custom); 00266 setOperationAction(ISD::ConstantPool, MVT::i64, Custom); 00267 setOperationAction(ISD::ExternalSymbol, MVT::i64, Custom); 00268 00269 setOperationAction(ISD::VASTART, MVT::Other, Custom); 00270 setOperationAction(ISD::VAEND, MVT::Other, Expand); 00271 setOperationAction(ISD::VACOPY, MVT::Other, Custom); 00272 setOperationAction(ISD::VAARG, MVT::Other, Custom); 00273 setOperationAction(ISD::VAARG, MVT::i32, Custom); 00274 00275 setStackPointerRegisterToSaveRestore(Alpha::R30); 00276 00277 setOperationAction(ISD::ConstantFP, MVT::f64, Expand); 00278 setOperationAction(ISD::ConstantFP, MVT::f32, Expand); 00279 addLegalFPImmediate(+0.0); //F31 00280 addLegalFPImmediate(-0.0); //-F31 00281 00282 computeRegisterProperties(); 00283 00284 useITOF = TM.getSubtarget<AlphaSubtarget>().hasF2I(); 00285 } 00286 00287 const char *AlphaTargetLowering::getTargetNodeName(unsigned Opcode) const { 00288 switch (Opcode) { 00289 default: return 0; 00290 case AlphaISD::ITOFT_: return "Alpha::ITOFT_"; 00291 case AlphaISD::FTOIT_: return "Alpha::FTOIT_"; 00292 case AlphaISD::CVTQT_: return "Alpha::CVTQT_"; 00293 case AlphaISD::CVTQS_: return "Alpha::CVTQS_"; 00294 case AlphaISD::CVTTQ_: return "Alpha::CVTTQ_"; 00295 case AlphaISD::GPRelHi: return "Alpha::GPRelHi"; 00296 case AlphaISD::GPRelLo: return "Alpha::GPRelLo"; 00297 case AlphaISD::RelLit: return "Alpha::RelLit"; 00298 case AlphaISD::GlobalBaseReg: return "Alpha::GlobalBaseReg"; 00299 case AlphaISD::CALL: return "Alpha::CALL"; 00300 case AlphaISD::DivCall: return "Alpha::DivCall"; 00301 } 00302 } 00303 00304 //http://www.cs.arizona.edu/computer.help/policy/DIGITAL_unix/AA-PY8AC-TET1_html/callCH3.html#BLOCK21 00305 00306 //For now, just use variable size stack frame format 00307 00308 //In a standard call, the first six items are passed in registers $16 00309 //- $21 and/or registers $f16 - $f21. (See Section 4.1.2 for details 00310 //of argument-to-register correspondence.) The remaining items are 00311 //collected in a memory argument list that is a naturally aligned 00312 //array of quadwords. In a standard call, this list, if present, must 00313 //be passed at 0(SP). 00314 //7 ... n 0(SP) ... (n-7)*8(SP) 00315 00316 // //#define FP $15 00317 // //#define RA $26 00318 // //#define PV $27 00319 // //#define GP $29 00320 // //#define SP $30 00321 00322 std::vector<SDOperand> 00323 AlphaTargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) 00324 { 00325 MachineFunction &MF = DAG.getMachineFunction(); 00326 MachineFrameInfo *MFI = MF.getFrameInfo(); 00327 MachineBasicBlock& BB = MF.front(); 00328 std::vector<SDOperand> ArgValues; 00329 00330 unsigned args_int[] = { 00331 Alpha::R16, Alpha::R17, Alpha::R18, Alpha::R19, Alpha::R20, Alpha::R21}; 00332 unsigned args_float[] = { 00333 Alpha::F16, Alpha::F17, Alpha::F18, Alpha::F19, Alpha::F20, Alpha::F21}; 00334 00335 int count = 0; 00336 00337 GP = AddLiveIn(MF, Alpha::R29, getRegClassFor(MVT::i64)); 00338 RA = AddLiveIn(MF, Alpha::R26, getRegClassFor(MVT::i64)); 00339 00340 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) 00341 { 00342 SDOperand argt; 00343 if (count < 6) { 00344 unsigned Vreg; 00345 MVT::ValueType VT = getValueType(I->getType()); 00346 switch (VT) { 00347 default: 00348 std::cerr << "Unknown Type " << VT << "\n"; 00349 abort(); 00350 case MVT::f64: 00351 case MVT::f32: 00352 args_float[count] = AddLiveIn(MF, args_float[count], getRegClassFor(VT)); 00353 argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[count], VT); 00354 DAG.setRoot(argt.getValue(1)); 00355 break; 00356 case MVT::i1: 00357 case MVT::i8: 00358 case MVT::i16: 00359 case MVT::i32: 00360 case MVT::i64: 00361 args_int[count] = AddLiveIn(MF, args_int[count], getRegClassFor(MVT::i64)); 00362 argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[count], MVT::i64); 00363 DAG.setRoot(argt.getValue(1)); 00364 if (VT != MVT::i64) { 00365 unsigned AssertOp = 00366 I->getType()->isSigned() ? ISD::AssertSext : ISD::AssertZext; 00367 argt = DAG.getNode(AssertOp, MVT::i64, argt, 00368 DAG.getValueType(VT)); 00369 argt = DAG.getNode(ISD::TRUNCATE, VT, argt); 00370 } 00371 break; 00372 } 00373 } else { //more args 00374 // Create the frame index object for this incoming parameter... 00375 int FI = MFI->CreateFixedObject(8, 8 * (count - 6)); 00376 00377 // Create the SelectionDAG nodes corresponding to a load 00378 //from this parameter 00379 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i64); 00380 argt = DAG.getLoad(getValueType(I->getType()), 00381 DAG.getEntryNode(), FIN, DAG.getSrcValue(NULL)); 00382 } 00383 ++count; 00384 ArgValues.push_back(argt); 00385 } 00386 00387 // If the functions takes variable number of arguments, copy all regs to stack 00388 if (F.isVarArg()) { 00389 VarArgsOffset = count * 8; 00390 std::vector<SDOperand> LS; 00391 for (int i = 0; i < 6; ++i) { 00392 if (MRegisterInfo::isPhysicalRegister(args_int[i])) 00393 args_int[i] = AddLiveIn(MF, args_int[i], getRegClassFor(MVT::i64)); 00394 SDOperand argt = DAG.getCopyFromReg(DAG.getRoot(), args_int[i], MVT::i64); 00395 int FI = MFI->CreateFixedObject(8, -8 * (6 - i)); 00396 if (i == 0) VarArgsBase = FI; 00397 SDOperand SDFI = DAG.getFrameIndex(FI, MVT::i64); 00398 LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, 00399 SDFI, DAG.getSrcValue(NULL))); 00400 00401 if (MRegisterInfo::isPhysicalRegister(args_float[i])) 00402 args_float[i] = AddLiveIn(MF, args_float[i], getRegClassFor(MVT::f64)); 00403 argt = DAG.getCopyFromReg(DAG.getRoot(), args_float[i], MVT::f64); 00404 FI = MFI->CreateFixedObject(8, - 8 * (12 - i)); 00405 SDFI = DAG.getFrameIndex(FI, MVT::i64); 00406 LS.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), argt, 00407 SDFI, DAG.getSrcValue(NULL))); 00408 } 00409 00410 //Set up a token factor with all the stack traffic 00411 DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, LS)); 00412 } 00413 00414 // Finally, inform the code generator which regs we return values in. 00415 switch (getValueType(F.getReturnType())) { 00416 default: assert(0 && "Unknown type!"); 00417 case MVT::isVoid: break; 00418 case MVT::i1: 00419 case MVT::i8: 00420 case MVT::i16: 00421 case MVT::i32: 00422 case MVT::i64: 00423 MF.addLiveOut(Alpha::R0); 00424 break; 00425 case MVT::f32: 00426 case MVT::f64: 00427 MF.addLiveOut(Alpha::F0); 00428 break; 00429 } 00430 00431 //return the arguments+ 00432 return ArgValues; 00433 } 00434 00435 std::pair<SDOperand, SDOperand> 00436 AlphaTargetLowering::LowerCallTo(SDOperand Chain, 00437 const Type *RetTy, bool isVarArg, 00438 unsigned CallingConv, bool isTailCall, 00439 SDOperand Callee, ArgListTy &Args, 00440 SelectionDAG &DAG) { 00441 int NumBytes = 0; 00442 if (Args.size() > 6) 00443 NumBytes = (Args.size() - 6) * 8; 00444 00445 Chain = DAG.getCALLSEQ_START(Chain, 00446 DAG.getConstant(NumBytes, getPointerTy())); 00447 std::vector<SDOperand> args_to_use; 00448 for (unsigned i = 0, e = Args.size(); i != e; ++i) 00449 { 00450 switch (getValueType(Args[i].second)) { 00451 default: assert(0 && "Unexpected ValueType for argument!"); 00452 case MVT::i1: 00453 case MVT::i8: 00454 case MVT::i16: 00455 case MVT::i32: 00456 // Promote the integer to 64 bits. If the input type is signed use a 00457 // sign extend, otherwise use a zero extend. 00458 if (Args[i].second->isSigned()) 00459 Args[i].first = DAG.getNode(ISD::SIGN_EXTEND, MVT::i64, Args[i].first); 00460 else 00461 Args[i].first = DAG.getNode(ISD::ZERO_EXTEND, MVT::i64, Args[i].first); 00462 break; 00463 case MVT::i64: 00464 case MVT::f64: 00465 case MVT::f32: 00466 break; 00467 } 00468 args_to_use.push_back(Args[i].first); 00469 } 00470 00471 std::vector<MVT::ValueType> RetVals; 00472 MVT::ValueType RetTyVT = getValueType(RetTy); 00473 MVT::ValueType ActualRetTyVT = RetTyVT; 00474 if (RetTyVT >= MVT::i1 && RetTyVT <= MVT::i32) 00475 ActualRetTyVT = MVT::i64; 00476 00477 if (RetTyVT != MVT::isVoid) 00478 RetVals.push_back(ActualRetTyVT); 00479 RetVals.push_back(MVT::Other); 00480 00481 std::vector<SDOperand> Ops; 00482 Ops.push_back(Chain); 00483 Ops.push_back(Callee); 00484 Ops.insert(Ops.end(), args_to_use.begin(), args_to_use.end()); 00485 SDOperand TheCall = DAG.getNode(AlphaISD::CALL, RetVals, Ops); 00486 Chain = TheCall.getValue(RetTyVT != MVT::isVoid); 00487 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, 00488 DAG.getConstant(NumBytes, getPointerTy())); 00489 SDOperand RetVal = TheCall; 00490 00491 if (RetTyVT != ActualRetTyVT) { 00492 RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext : ISD::AssertZext, 00493 MVT::i64, RetVal, DAG.getValueType(RetTyVT)); 00494 RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); 00495 } 00496 00497 return std::make_pair(RetVal, Chain); 00498 } 00499 00500 void AlphaTargetLowering::restoreGP(MachineBasicBlock* BB) 00501 { 00502 BuildMI(BB, Alpha::BIS, 2, Alpha::R29).addReg(GP).addReg(GP); 00503 } 00504 void AlphaTargetLowering::restoreRA(MachineBasicBlock* BB) 00505 { 00506 BuildMI(BB, Alpha::BIS, 2, Alpha::R26).addReg(RA).addReg(RA); 00507 } 00508 00509 static int getUID() 00510 { 00511 static int id = 0; 00512 return ++id; 00513 } 00514 00515 /// LowerOperation - Provide custom lowering hooks for some operations. 00516 /// 00517 SDOperand AlphaTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { 00518 switch (Op.getOpcode()) { 00519 default: assert(0 && "Wasn't expecting to be able to lower this!"); 00520 case ISD::SINT_TO_FP: { 00521 assert(MVT::i64 == Op.getOperand(0).getValueType() && 00522 "Unhandled SINT_TO_FP type in custom expander!"); 00523 SDOperand LD; 00524 bool isDouble = MVT::f64 == Op.getValueType(); 00525 if (useITOF) { 00526 LD = DAG.getNode(AlphaISD::ITOFT_, MVT::f64, Op.getOperand(0)); 00527 } else { 00528 int FrameIdx = 00529 DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); 00530 SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i64); 00531 SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), 00532 Op.getOperand(0), FI, DAG.getSrcValue(0)); 00533 LD = DAG.getLoad(MVT::f64, ST, FI, DAG.getSrcValue(0)); 00534 } 00535 SDOperand FP = DAG.getNode(isDouble?AlphaISD::CVTQT_:AlphaISD::CVTQS_, 00536 isDouble?MVT::f64:MVT::f32, LD); 00537 return FP; 00538 } 00539 case ISD::FP_TO_SINT: { 00540 bool isDouble = MVT::f64 == Op.getOperand(0).getValueType(); 00541 SDOperand src = Op.getOperand(0); 00542 00543 if (!isDouble) //Promote 00544 src = DAG.getNode(ISD::FP_EXTEND, MVT::f64, src); 00545 00546 src = DAG.getNode(AlphaISD::CVTTQ_, MVT::f64, src); 00547 00548 if (useITOF) { 00549 return DAG.getNode(AlphaISD::FTOIT_, MVT::i64, src); 00550 } else { 00551 int FrameIdx = 00552 DAG.getMachineFunction().getFrameInfo()->CreateStackObject(8, 8); 00553 SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i64); 00554 SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), 00555 src, FI, DAG.getSrcValue(0)); 00556 return DAG.getLoad(MVT::i64, ST, FI, DAG.getSrcValue(0)); 00557 } 00558 } 00559 case ISD::ConstantPool: { 00560 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 00561 Constant *C = CP->get(); 00562 SDOperand CPI = DAG.getTargetConstantPool(C, MVT::i64, CP->getAlignment()); 00563 00564 SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi, MVT::i64, CPI, 00565 DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64)); 00566 SDOperand Lo = DAG.getNode(AlphaISD::GPRelLo, MVT::i64, CPI, Hi); 00567 return Lo; 00568 } 00569 case ISD::GlobalAddress: { 00570 GlobalAddressSDNode *GSDN = cast<GlobalAddressSDNode>(Op); 00571 GlobalValue *GV = GSDN->getGlobal(); 00572 SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i64, GSDN->getOffset()); 00573 00574 // if (!GV->hasWeakLinkage() && !GV->isExternal() && !GV->hasLinkOnceLinkage()) { 00575 if (GV->hasInternalLinkage()) { 00576 SDOperand Hi = DAG.getNode(AlphaISD::GPRelHi, MVT::i64, GA, 00577 DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64)); 00578 SDOperand Lo = DAG.getNode(AlphaISD::GPRelLo, MVT::i64, GA, Hi); 00579 return Lo; 00580 } else 00581 return DAG.getNode(AlphaISD::RelLit, MVT::i64, GA, DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64)); 00582 } 00583 case ISD::ExternalSymbol: { 00584 return DAG.getNode(AlphaISD::RelLit, MVT::i64, 00585 DAG.getTargetExternalSymbol(cast<ExternalSymbolSDNode>(Op)->getSymbol(), MVT::i64), 00586 DAG.getNode(AlphaISD::GlobalBaseReg, MVT::i64)); 00587 } 00588 00589 case ISD::UREM: 00590 case ISD::SREM: 00591 //Expand only on constant case 00592 if (Op.getOperand(1).getOpcode() == ISD::Constant) { 00593 MVT::ValueType VT = Op.Val->getValueType(0); 00594 unsigned Opc = Op.Val->getOpcode() == ISD::UREM ? ISD::UDIV : ISD::SDIV; 00595 SDOperand Tmp1 = Op.Val->getOpcode() == ISD::UREM ? 00596 BuildUDIVSequence(Op, &DAG) : 00597 BuildSDIVSequence(Op, &DAG); 00598 Tmp1 = DAG.getNode(ISD::MUL, VT, Tmp1, Op.getOperand(1)); 00599 Tmp1 = DAG.getNode(ISD::SUB, VT, Op.getOperand(0), Tmp1); 00600 return Tmp1; 00601 } 00602 //fall through 00603 case ISD::SDIV: 00604 case ISD::UDIV: 00605 if (MVT::isInteger(Op.getValueType())) { 00606 if (Op.getOperand(1).getOpcode() == ISD::Constant) 00607 return Op.getOpcode() == ISD::SDIV ? BuildSDIVSequence(Op, &DAG) : BuildUDIVSequence(Op, &DAG); 00608 const char* opstr = 0; 00609 switch(Op.getOpcode()) { 00610 case ISD::UREM: opstr = "__remqu"; break; 00611 case ISD::SREM: opstr = "__remq"; break; 00612 case ISD::UDIV: opstr = "__divqu"; break; 00613 case ISD::SDIV: opstr = "__divq"; break; 00614 } 00615 SDOperand Tmp1 = Op.getOperand(0), 00616 Tmp2 = Op.getOperand(1), 00617 Addr = DAG.getExternalSymbol(opstr, MVT::i64); 00618 return DAG.getNode(AlphaISD::DivCall, MVT::i64, Addr, Tmp1, Tmp2); 00619 } 00620 break; 00621 00622 case ISD::VAARG: { 00623 SDOperand Chain = Op.getOperand(0); 00624 SDOperand VAListP = Op.getOperand(1); 00625 SDOperand VAListS = Op.getOperand(2); 00626 00627 SDOperand Base = DAG.getLoad(MVT::i64, Chain, VAListP, VAListS); 00628 SDOperand Tmp = DAG.getNode(ISD::ADD, MVT::i64, VAListP, 00629 DAG.getConstant(8, MVT::i64)); 00630 SDOperand Offset = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Base.getValue(1), 00631 Tmp, DAG.getSrcValue(0), MVT::i32); 00632 SDOperand DataPtr = DAG.getNode(ISD::ADD, MVT::i64, Base, Offset); 00633 if (MVT::isFloatingPoint(Op.getValueType())) 00634 { 00635 //if fp && Offset < 6*8, then subtract 6*8 from DataPtr 00636 SDOperand FPDataPtr = DAG.getNode(ISD::SUB, MVT::i64, DataPtr, 00637 DAG.getConstant(8*6, MVT::i64)); 00638 SDOperand CC = DAG.getSetCC(MVT::i64, Offset, 00639 DAG.getConstant(8*6, MVT::i64), ISD::SETLT); 00640 DataPtr = DAG.getNode(ISD::SELECT, MVT::i64, CC, FPDataPtr, DataPtr); 00641 } 00642 00643 SDOperand NewOffset = DAG.getNode(ISD::ADD, MVT::i64, Offset, 00644 DAG.getConstant(8, MVT::i64)); 00645 SDOperand Update = DAG.getNode(ISD::TRUNCSTORE, MVT::Other, 00646 Offset.getValue(1), NewOffset, 00647 Tmp, DAG.getSrcValue(0), 00648 DAG.getValueType(MVT::i32)); 00649 00650 SDOperand Result; 00651 if (Op.getValueType() == MVT::i32) 00652 Result = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Update, DataPtr, 00653 DAG.getSrcValue(0), MVT::i32); 00654 else 00655 Result = DAG.getLoad(Op.getValueType(), Update, DataPtr, 00656 DAG.getSrcValue(0)); 00657 return Result; 00658 } 00659 case ISD::VACOPY: { 00660 SDOperand Chain = Op.getOperand(0); 00661 SDOperand DestP = Op.getOperand(1); 00662 SDOperand SrcP = Op.getOperand(2); 00663 SDOperand DestS = Op.getOperand(3); 00664 SDOperand SrcS = Op.getOperand(4); 00665 00666 SDOperand Val = DAG.getLoad(getPointerTy(), Chain, SrcP, SrcS); 00667 SDOperand Result = DAG.getNode(ISD::STORE, MVT::Other, Val.getValue(1), Val, 00668 DestP, DestS); 00669 SDOperand NP = DAG.getNode(ISD::ADD, MVT::i64, SrcP, 00670 DAG.getConstant(8, MVT::i64)); 00671 Val = DAG.getExtLoad(ISD::SEXTLOAD, MVT::i64, Result, NP, 00672 DAG.getSrcValue(0), MVT::i32); 00673 SDOperand NPD = DAG.getNode(ISD::ADD, MVT::i64, DestP, 00674 DAG.getConstant(8, MVT::i64)); 00675 return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, Val.getValue(1), 00676 Val, NPD, DAG.getSrcValue(0),DAG.getValueType(MVT::i32)); 00677 } 00678 case ISD::VASTART: { 00679 SDOperand Chain = Op.getOperand(0); 00680 SDOperand VAListP = Op.getOperand(1); 00681 SDOperand VAListS = Op.getOperand(2); 00682 00683 // vastart stores the address of the VarArgsBase and VarArgsOffset 00684 SDOperand FR = DAG.getFrameIndex(VarArgsBase, MVT::i64); 00685 SDOperand S1 = DAG.getNode(ISD::STORE, MVT::Other, Chain, FR, VAListP, 00686 VAListS); 00687 SDOperand SA2 = DAG.getNode(ISD::ADD, MVT::i64, VAListP, 00688 DAG.getConstant(8, MVT::i64)); 00689 return DAG.getNode(ISD::TRUNCSTORE, MVT::Other, S1, 00690 DAG.getConstant(VarArgsOffset, MVT::i64), SA2, 00691 DAG.getSrcValue(0), DAG.getValueType(MVT::i32)); 00692 } 00693 } 00694 00695 return SDOperand(); 00696 } 00697 00698 SDOperand AlphaTargetLowering::CustomPromoteOperation(SDOperand Op, 00699 SelectionDAG &DAG) { 00700 assert(Op.getValueType() == MVT::i32 && 00701 Op.getOpcode() == ISD::VAARG && 00702 "Unknown node to custom promote!"); 00703 00704 // The code in LowerOperation already handles i32 vaarg 00705 return LowerOperation(Op, DAG); 00706 }