LLVM API Documentation
00001 //===-- AlphaISelDAGToDAG.cpp - Alpha 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 Alpha, 00011 // converting from a legalized dag to a Alpha dag. 00012 // 00013 //===----------------------------------------------------------------------===// 00014 00015 #include "Alpha.h" 00016 #include "AlphaTargetMachine.h" 00017 #include "AlphaISelLowering.h" 00018 #include "llvm/CodeGen/MachineInstrBuilder.h" 00019 #include "llvm/CodeGen/MachineFrameInfo.h" 00020 #include "llvm/CodeGen/MachineFunction.h" 00021 #include "llvm/CodeGen/MachineRegisterInfo.h" 00022 #include "llvm/CodeGen/SelectionDAG.h" 00023 #include "llvm/CodeGen/SelectionDAGISel.h" 00024 #include "llvm/Target/TargetOptions.h" 00025 #include "llvm/Constants.h" 00026 #include "llvm/DerivedTypes.h" 00027 #include "llvm/GlobalValue.h" 00028 #include "llvm/Intrinsics.h" 00029 #include "llvm/Support/Compiler.h" 00030 #include "llvm/Support/Debug.h" 00031 #include "llvm/Support/MathExtras.h" 00032 #include <algorithm> 00033 #include <queue> 00034 #include <set> 00035 using namespace llvm; 00036 00037 namespace { 00038 00039 //===--------------------------------------------------------------------===// 00040 /// AlphaDAGToDAGISel - Alpha specific code to select Alpha machine 00041 /// instructions for SelectionDAG operations. 00042 class AlphaDAGToDAGISel : public SelectionDAGISel { 00043 static const int64_t IMM_LOW = -32768; 00044 static const int64_t IMM_HIGH = 32767; 00045 static const int64_t IMM_MULT = 65536; 00046 static const int64_t IMM_FULLHIGH = IMM_HIGH + IMM_HIGH * IMM_MULT; 00047 static const int64_t IMM_FULLLOW = IMM_LOW + IMM_LOW * IMM_MULT; 00048 00049 static int64_t get_ldah16(int64_t x) { 00050 int64_t y = x / IMM_MULT; 00051 if (x % IMM_MULT > IMM_HIGH) 00052 ++y; 00053 return y; 00054 } 00055 00056 static int64_t get_lda16(int64_t x) { 00057 return x - get_ldah16(x) * IMM_MULT; 00058 } 00059 00060 /// get_zapImm - Return a zap mask if X is a valid immediate for a zapnot 00061 /// instruction (if not, return 0). Note that this code accepts partial 00062 /// zap masks. For example (and LHS, 1) is a valid zap, as long we know 00063 /// that the bits 1-7 of LHS are already zero. If LHS is non-null, we are 00064 /// in checking mode. If LHS is null, we assume that the mask has already 00065 /// been validated before. 00066 uint64_t get_zapImm(SDValue LHS, uint64_t Constant) { 00067 uint64_t BitsToCheck = 0; 00068 unsigned Result = 0; 00069 for (unsigned i = 0; i != 8; ++i) { 00070 if (((Constant >> 8*i) & 0xFF) == 0) { 00071 // nothing to do. 00072 } else { 00073 Result |= 1 << i; 00074 if (((Constant >> 8*i) & 0xFF) == 0xFF) { 00075 // If the entire byte is set, zapnot the byte. 00076 } else if (LHS.getNode() == 0) { 00077 // Otherwise, if the mask was previously validated, we know its okay 00078 // to zapnot this entire byte even though all the bits aren't set. 00079 } else { 00080 // Otherwise we don't know that the it's okay to zapnot this entire 00081 // byte. Only do this iff we can prove that the missing bits are 00082 // already null, so the bytezap doesn't need to really null them. 00083 BitsToCheck |= ~Constant & (0xFF << 8*i); 00084 } 00085 } 00086 } 00087 00088 // If there are missing bits in a byte (for example, X & 0xEF00), check to 00089 // see if the missing bits (0x1000) are already known zero if not, the zap 00090 // isn't okay to do, as it won't clear all the required bits. 00091 if (BitsToCheck && 00092 !CurDAG->MaskedValueIsZero(LHS, 00093 APInt(LHS.getValueSizeInBits(), 00094 BitsToCheck))) 00095 return 0; 00096 00097 return Result; 00098 } 00099 00100 static uint64_t get_zapImm(uint64_t x) { 00101 unsigned build = 0; 00102 for(int i = 0; i != 8; ++i) { 00103 if ((x & 0x00FF) == 0x00FF) 00104 build |= 1 << i; 00105 else if ((x & 0x00FF) != 0) 00106 return 0; 00107 x >>= 8; 00108 } 00109 return build; 00110 } 00111 00112 00113 static uint64_t getNearPower2(uint64_t x) { 00114 if (!x) return 0; 00115 unsigned at = CountLeadingZeros_64(x); 00116 uint64_t complow = 1 << (63 - at); 00117 uint64_t comphigh = 1 << (64 - at); 00118 //cerr << x << ":" << complow << ":" << comphigh << "\n"; 00119 if (abs(complow - x) <= abs(comphigh - x)) 00120 return complow; 00121 else 00122 return comphigh; 00123 } 00124 00125 static bool chkRemNearPower2(uint64_t x, uint64_t r, bool swap) { 00126 uint64_t y = getNearPower2(x); 00127 if (swap) 00128 return (y - x) == r; 00129 else 00130 return (x - y) == r; 00131 } 00132 00133 static bool isFPZ(SDValue N) { 00134 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); 00135 return (CN && (CN->getValueAPF().isZero())); 00136 } 00137 static bool isFPZn(SDValue N) { 00138 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); 00139 return (CN && CN->getValueAPF().isNegZero()); 00140 } 00141 static bool isFPZp(SDValue N) { 00142 ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(N); 00143 return (CN && CN->getValueAPF().isPosZero()); 00144 } 00145 00146 public: 00147 explicit AlphaDAGToDAGISel(AlphaTargetMachine &TM) 00148 : SelectionDAGISel(*TM.getTargetLowering()) 00149 {} 00150 00151 /// getI64Imm - Return a target constant with the specified value, of type 00152 /// i64. 00153 inline SDValue getI64Imm(int64_t Imm) { 00154 return CurDAG->getTargetConstant(Imm, MVT::i64); 00155 } 00156 00157 // Select - Convert the specified operand from a target-independent to a 00158 // target-specific node if it hasn't already been changed. 00159 SDNode *Select(SDValue Op); 00160 00161 /// InstructionSelect - This callback is invoked by 00162 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 00163 virtual void InstructionSelect(); 00164 00165 virtual const char *getPassName() const { 00166 return "Alpha DAG->DAG Pattern Instruction Selection"; 00167 } 00168 00169 /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for 00170 /// inline asm expressions. 00171 virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 00172 char ConstraintCode, 00173 std::vector<SDValue> &OutOps) { 00174 SDValue Op0; 00175 switch (ConstraintCode) { 00176 default: return true; 00177 case 'm': // memory 00178 Op0 = Op; 00179 AddToISelQueue(Op0); 00180 break; 00181 } 00182 00183 OutOps.push_back(Op0); 00184 return false; 00185 } 00186 00187 // Include the pieces autogenerated from the target description. 00188 #include "AlphaGenDAGISel.inc" 00189 00190 private: 00191 SDValue getGlobalBaseReg(); 00192 SDValue getGlobalRetAddr(); 00193 void SelectCALL(SDValue Op); 00194 00195 }; 00196 } 00197 00198 /// getGlobalBaseReg - Output the instructions required to put the 00199 /// GOT address into a register. 00200 /// 00201 SDValue AlphaDAGToDAGISel::getGlobalBaseReg() { 00202 unsigned GP = 0; 00203 for(MachineRegisterInfo::livein_iterator ii = RegInfo->livein_begin(), 00204 ee = RegInfo->livein_end(); ii != ee; ++ii) 00205 if (ii->first == Alpha::R29) { 00206 GP = ii->second; 00207 break; 00208 } 00209 assert(GP && "GOT PTR not in liveins"); 00210 return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 00211 GP, MVT::i64); 00212 } 00213 00214 /// getRASaveReg - Grab the return address 00215 /// 00216 SDValue AlphaDAGToDAGISel::getGlobalRetAddr() { 00217 unsigned RA = 0; 00218 for(MachineRegisterInfo::livein_iterator ii = RegInfo->livein_begin(), 00219 ee = RegInfo->livein_end(); ii != ee; ++ii) 00220 if (ii->first == Alpha::R26) { 00221 RA = ii->second; 00222 break; 00223 } 00224 assert(RA && "RA PTR not in liveins"); 00225 return CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 00226 RA, MVT::i64); 00227 } 00228 00229 /// InstructionSelect - This callback is invoked by 00230 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 00231 void AlphaDAGToDAGISel::InstructionSelect() { 00232 DEBUG(BB->dump()); 00233 00234 // Select target instructions for the DAG. 00235 SelectRoot(); 00236 CurDAG->RemoveDeadNodes(); 00237 } 00238 00239 // Select - Convert the specified operand from a target-independent to a 00240 // target-specific node if it hasn't already been changed. 00241 SDNode *AlphaDAGToDAGISel::Select(SDValue Op) { 00242 SDNode *N = Op.getNode(); 00243 if (N->isMachineOpcode()) { 00244 return NULL; // Already selected. 00245 } 00246 00247 switch (N->getOpcode()) { 00248 default: break; 00249 case AlphaISD::CALL: 00250 SelectCALL(Op); 00251 return NULL; 00252 00253 case ISD::FrameIndex: { 00254 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 00255 return CurDAG->SelectNodeTo(N, Alpha::LDA, MVT::i64, 00256 CurDAG->getTargetFrameIndex(FI, MVT::i32), 00257 getI64Imm(0)); 00258 } 00259 case ISD::GLOBAL_OFFSET_TABLE: { 00260 SDValue Result = getGlobalBaseReg(); 00261 ReplaceUses(Op, Result); 00262 return NULL; 00263 } 00264 case AlphaISD::GlobalRetAddr: { 00265 SDValue Result = getGlobalRetAddr(); 00266 ReplaceUses(Op, Result); 00267 return NULL; 00268 } 00269 00270 case AlphaISD::DivCall: { 00271 SDValue Chain = CurDAG->getEntryNode(); 00272 SDValue N0 = Op.getOperand(0); 00273 SDValue N1 = Op.getOperand(1); 00274 SDValue N2 = Op.getOperand(2); 00275 AddToISelQueue(N0); 00276 AddToISelQueue(N1); 00277 AddToISelQueue(N2); 00278 Chain = CurDAG->getCopyToReg(Chain, Alpha::R24, N1, 00279 SDValue(0,0)); 00280 Chain = CurDAG->getCopyToReg(Chain, Alpha::R25, N2, 00281 Chain.getValue(1)); 00282 Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, N0, 00283 Chain.getValue(1)); 00284 SDNode *CNode = 00285 CurDAG->getTargetNode(Alpha::JSRs, MVT::Other, MVT::Flag, 00286 Chain, Chain.getValue(1)); 00287 Chain = CurDAG->getCopyFromReg(Chain, Alpha::R27, MVT::i64, 00288 SDValue(CNode, 1)); 00289 return CurDAG->SelectNodeTo(N, Alpha::BISr, MVT::i64, Chain, Chain); 00290 } 00291 00292 case ISD::READCYCLECOUNTER: { 00293 SDValue Chain = N->getOperand(0); 00294 AddToISelQueue(Chain); //Select chain 00295 return CurDAG->getTargetNode(Alpha::RPCC, MVT::i64, MVT::Other, 00296 Chain); 00297 } 00298 00299 case ISD::Constant: { 00300 uint64_t uval = cast<ConstantSDNode>(N)->getZExtValue(); 00301 00302 if (uval == 0) { 00303 SDValue Result = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), 00304 Alpha::R31, MVT::i64); 00305 ReplaceUses(Op, Result); 00306 return NULL; 00307 } 00308 00309 int64_t val = (int64_t)uval; 00310 int32_t val32 = (int32_t)val; 00311 if (val <= IMM_HIGH + IMM_HIGH * IMM_MULT && 00312 val >= IMM_LOW + IMM_LOW * IMM_MULT) 00313 break; //(LDAH (LDA)) 00314 if ((uval >> 32) == 0 && //empty upper bits 00315 val32 <= IMM_HIGH + IMM_HIGH * IMM_MULT) 00316 // val32 >= IMM_LOW + IMM_LOW * IMM_MULT) //always true 00317 break; //(zext (LDAH (LDA))) 00318 //Else use the constant pool 00319 ConstantInt *C = ConstantInt::get(Type::Int64Ty, uval); 00320 SDValue CPI = CurDAG->getTargetConstantPool(C, MVT::i64); 00321 SDNode *Tmp = CurDAG->getTargetNode(Alpha::LDAHr, MVT::i64, CPI, 00322 getGlobalBaseReg()); 00323 return CurDAG->SelectNodeTo(N, Alpha::LDQr, MVT::i64, MVT::Other, 00324 CPI, SDValue(Tmp, 0), CurDAG->getEntryNode()); 00325 } 00326 case ISD::TargetConstantFP: 00327 case ISD::ConstantFP: { 00328 ConstantFPSDNode *CN = cast<ConstantFPSDNode>(N); 00329 bool isDouble = N->getValueType(0) == MVT::f64; 00330 MVT T = isDouble ? MVT::f64 : MVT::f32; 00331 if (CN->getValueAPF().isPosZero()) { 00332 return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYST : Alpha::CPYSS, 00333 T, CurDAG->getRegister(Alpha::F31, T), 00334 CurDAG->getRegister(Alpha::F31, T)); 00335 } else if (CN->getValueAPF().isNegZero()) { 00336 return CurDAG->SelectNodeTo(N, isDouble ? Alpha::CPYSNT : Alpha::CPYSNS, 00337 T, CurDAG->getRegister(Alpha::F31, T), 00338 CurDAG->getRegister(Alpha::F31, T)); 00339 } else { 00340 abort(); 00341 } 00342 break; 00343 } 00344 00345 case ISD::SETCC: 00346 if (N->getOperand(0).getNode()->getValueType(0).isFloatingPoint()) { 00347 ISD::CondCode CC = cast<CondCodeSDNode>(N->getOperand(2))->get(); 00348 00349 unsigned Opc = Alpha::WTF; 00350 bool rev = false; 00351 bool inv = false; 00352 switch(CC) { 00353 default: DEBUG(N->dump(CurDAG)); assert(0 && "Unknown FP comparison!"); 00354 case ISD::SETEQ: case ISD::SETOEQ: case ISD::SETUEQ: 00355 Opc = Alpha::CMPTEQ; break; 00356 case ISD::SETLT: case ISD::SETOLT: case ISD::SETULT: 00357 Opc = Alpha::CMPTLT; break; 00358 case ISD::SETLE: case ISD::SETOLE: case ISD::SETULE: 00359 Opc = Alpha::CMPTLE; break; 00360 case ISD::SETGT: case ISD::SETOGT: case ISD::SETUGT: 00361 Opc = Alpha::CMPTLT; rev = true; break; 00362 case ISD::SETGE: case ISD::SETOGE: case ISD::SETUGE: 00363 Opc = Alpha::CMPTLE; rev = true; break; 00364 case ISD::SETNE: case ISD::SETONE: case ISD::SETUNE: 00365 Opc = Alpha::CMPTEQ; inv = true; break; 00366 case ISD::SETO: 00367 Opc = Alpha::CMPTUN; inv = true; break; 00368 case ISD::SETUO: 00369 Opc = Alpha::CMPTUN; break; 00370 }; 00371 SDValue tmp1 = N->getOperand(rev?1:0); 00372 SDValue tmp2 = N->getOperand(rev?0:1); 00373 AddToISelQueue(tmp1); 00374 AddToISelQueue(tmp2); 00375 SDNode *cmp = CurDAG->getTargetNode(Opc, MVT::f64, tmp1, tmp2); 00376 if (inv) 00377 cmp = CurDAG->getTargetNode(Alpha::CMPTEQ, MVT::f64, SDValue(cmp, 0), 00378 CurDAG->getRegister(Alpha::F31, MVT::f64)); 00379 switch(CC) { 00380 case ISD::SETUEQ: case ISD::SETULT: case ISD::SETULE: 00381 case ISD::SETUNE: case ISD::SETUGT: case ISD::SETUGE: 00382 { 00383 SDNode* cmp2 = CurDAG->getTargetNode(Alpha::CMPTUN, MVT::f64, 00384 tmp1, tmp2); 00385 cmp = CurDAG->getTargetNode(Alpha::ADDT, MVT::f64, 00386 SDValue(cmp2, 0), SDValue(cmp, 0)); 00387 break; 00388 } 00389 default: break; 00390 } 00391 00392 SDNode* LD = CurDAG->getTargetNode(Alpha::FTOIT, MVT::i64, SDValue(cmp, 0)); 00393 return CurDAG->getTargetNode(Alpha::CMPULT, MVT::i64, 00394 CurDAG->getRegister(Alpha::R31, MVT::i64), 00395 SDValue(LD,0)); 00396 } 00397 break; 00398 00399 case ISD::SELECT: 00400 if (N->getValueType(0).isFloatingPoint() && 00401 (N->getOperand(0).getOpcode() != ISD::SETCC || 00402 !N->getOperand(0).getOperand(1).getValueType().isFloatingPoint())) { 00403 //This should be the condition not covered by the Patterns 00404 //FIXME: Don't have SelectCode die, but rather return something testable 00405 // so that things like this can be caught in fall though code 00406 //move int to fp 00407 bool isDouble = N->getValueType(0) == MVT::f64; 00408 SDValue cond = N->getOperand(0); 00409 SDValue TV = N->getOperand(1); 00410 SDValue FV = N->getOperand(2); 00411 AddToISelQueue(cond); 00412 AddToISelQueue(TV); 00413 AddToISelQueue(FV); 00414 00415 SDNode* LD = CurDAG->getTargetNode(Alpha::ITOFT, MVT::f64, cond); 00416 return CurDAG->getTargetNode(isDouble?Alpha::FCMOVNET:Alpha::FCMOVNES, 00417 MVT::f64, FV, TV, SDValue(LD,0)); 00418 } 00419 break; 00420 00421 case ISD::AND: { 00422 ConstantSDNode* SC = NULL; 00423 ConstantSDNode* MC = NULL; 00424 if (N->getOperand(0).getOpcode() == ISD::SRL && 00425 (MC = dyn_cast<ConstantSDNode>(N->getOperand(1))) && 00426 (SC = dyn_cast<ConstantSDNode>(N->getOperand(0).getOperand(1)))) { 00427 uint64_t sval = SC->getZExtValue(); 00428 uint64_t mval = MC->getZExtValue(); 00429 // If the result is a zap, let the autogened stuff handle it. 00430 if (get_zapImm(N->getOperand(0), mval)) 00431 break; 00432 // given mask X, and shift S, we want to see if there is any zap in the 00433 // mask if we play around with the botton S bits 00434 uint64_t dontcare = (~0ULL) >> (64 - sval); 00435 uint64_t mask = mval << sval; 00436 00437 if (get_zapImm(mask | dontcare)) 00438 mask = mask | dontcare; 00439 00440 if (get_zapImm(mask)) { 00441 AddToISelQueue(N->getOperand(0).getOperand(0)); 00442 SDValue Z = 00443 SDValue(CurDAG->getTargetNode(Alpha::ZAPNOTi, MVT::i64, 00444 N->getOperand(0).getOperand(0), 00445 getI64Imm(get_zapImm(mask))), 0); 00446 return CurDAG->getTargetNode(Alpha::SRLr, MVT::i64, Z, 00447 getI64Imm(sval)); 00448 } 00449 } 00450 break; 00451 } 00452 00453 } 00454 00455 return SelectCode(Op); 00456 } 00457 00458 void AlphaDAGToDAGISel::SelectCALL(SDValue Op) { 00459 //TODO: add flag stuff to prevent nondeturministic breakage! 00460 00461 SDNode *N = Op.getNode(); 00462 SDValue Chain = N->getOperand(0); 00463 SDValue Addr = N->getOperand(1); 00464 SDValue InFlag(0,0); // Null incoming flag value. 00465 AddToISelQueue(Chain); 00466 00467 std::vector<SDValue> CallOperands; 00468 std::vector<MVT> TypeOperands; 00469 00470 //grab the arguments 00471 for(int i = 2, e = N->getNumOperands(); i < e; ++i) { 00472 TypeOperands.push_back(N->getOperand(i).getValueType()); 00473 AddToISelQueue(N->getOperand(i)); 00474 CallOperands.push_back(N->getOperand(i)); 00475 } 00476 int count = N->getNumOperands() - 2; 00477 00478 static const unsigned args_int[] = {Alpha::R16, Alpha::R17, Alpha::R18, 00479 Alpha::R19, Alpha::R20, Alpha::R21}; 00480 static const unsigned args_float[] = {Alpha::F16, Alpha::F17, Alpha::F18, 00481 Alpha::F19, Alpha::F20, Alpha::F21}; 00482 00483 for (int i = 6; i < count; ++i) { 00484 unsigned Opc = Alpha::WTF; 00485 if (TypeOperands[i].isInteger()) { 00486 Opc = Alpha::STQ; 00487 } else if (TypeOperands[i] == MVT::f32) { 00488 Opc = Alpha::STS; 00489 } else if (TypeOperands[i] == MVT::f64) { 00490 Opc = Alpha::STT; 00491 } else 00492 assert(0 && "Unknown operand"); 00493 00494 SDValue Ops[] = { CallOperands[i], getI64Imm((i - 6) * 8), 00495 CurDAG->getCopyFromReg(Chain, Alpha::R30, MVT::i64), 00496 Chain }; 00497 Chain = SDValue(CurDAG->getTargetNode(Opc, MVT::Other, Ops, 4), 0); 00498 } 00499 for (int i = 0; i < std::min(6, count); ++i) { 00500 if (TypeOperands[i].isInteger()) { 00501 Chain = CurDAG->getCopyToReg(Chain, args_int[i], CallOperands[i], InFlag); 00502 InFlag = Chain.getValue(1); 00503 } else if (TypeOperands[i] == MVT::f32 || TypeOperands[i] == MVT::f64) { 00504 Chain = CurDAG->getCopyToReg(Chain, args_float[i], CallOperands[i], InFlag); 00505 InFlag = Chain.getValue(1); 00506 } else 00507 assert(0 && "Unknown operand"); 00508 } 00509 00510 // Finally, once everything is in registers to pass to the call, emit the 00511 // call itself. 00512 if (Addr.getOpcode() == AlphaISD::GPRelLo) { 00513 SDValue GOT = getGlobalBaseReg(); 00514 Chain = CurDAG->getCopyToReg(Chain, Alpha::R29, GOT, InFlag); 00515 InFlag = Chain.getValue(1); 00516 Chain = SDValue(CurDAG->getTargetNode(Alpha::BSR, MVT::Other, MVT::Flag, 00517 Addr.getOperand(0), Chain, InFlag), 0); 00518 } else { 00519 AddToISelQueue(Addr); 00520 Chain = CurDAG->getCopyToReg(Chain, Alpha::R27, Addr, InFlag); 00521 InFlag = Chain.getValue(1); 00522 Chain = SDValue(CurDAG->getTargetNode(Alpha::JSR, MVT::Other, MVT::Flag, 00523 Chain, InFlag), 0); 00524 } 00525 InFlag = Chain.getValue(1); 00526 00527 std::vector<SDValue> CallResults; 00528 00529 switch (N->getValueType(0).getSimpleVT()) { 00530 default: assert(0 && "Unexpected ret value!"); 00531 case MVT::Other: break; 00532 case MVT::i64: 00533 Chain = CurDAG->getCopyFromReg(Chain, Alpha::R0, MVT::i64, InFlag).getValue(1); 00534 CallResults.push_back(Chain.getValue(0)); 00535 break; 00536 case MVT::f32: 00537 Chain = CurDAG->getCopyFromReg(Chain, Alpha::F0, MVT::f32, InFlag).getValue(1); 00538 CallResults.push_back(Chain.getValue(0)); 00539 break; 00540 case MVT::f64: 00541 Chain = CurDAG->getCopyFromReg(Chain, Alpha::F0, MVT::f64, InFlag).getValue(1); 00542 CallResults.push_back(Chain.getValue(0)); 00543 break; 00544 } 00545 00546 CallResults.push_back(Chain); 00547 for (unsigned i = 0, e = CallResults.size(); i != e; ++i) 00548 ReplaceUses(Op.getValue(i), CallResults[i]); 00549 } 00550 00551 00552 /// createAlphaISelDag - This pass converts a legalized DAG into a 00553 /// Alpha-specific DAG, ready for instruction scheduling. 00554 /// 00555 FunctionPass *llvm::createAlphaISelDag(AlphaTargetMachine &TM) { 00556 return new AlphaDAGToDAGISel(TM); 00557 }