SparcISelDAGToDAG.cpp revision b8973bd8f50d7321635e1e07b81a880a0828d185
1//===-- SparcV8ISelDAGToDAG.cpp - A dag to dag inst selector for SparcV8 --===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an instruction selector for the V8 target 11// 12//===----------------------------------------------------------------------===// 13 14#include "SparcV8.h" 15#include "SparcV8TargetMachine.h" 16#include "llvm/DerivedTypes.h" 17#include "llvm/Function.h" 18#include "llvm/CodeGen/MachineFrameInfo.h" 19#include "llvm/CodeGen/MachineFunction.h" 20#include "llvm/CodeGen/MachineInstrBuilder.h" 21#include "llvm/CodeGen/SelectionDAG.h" 22#include "llvm/CodeGen/SelectionDAGISel.h" 23#include "llvm/CodeGen/SSARegMap.h" 24#include "llvm/Target/TargetLowering.h" 25#include "llvm/Support/Debug.h" 26#include <iostream> 27using namespace llvm; 28 29//===----------------------------------------------------------------------===// 30// TargetLowering Implementation 31//===----------------------------------------------------------------------===// 32 33namespace V8ISD { 34 enum { 35 FIRST_NUMBER = ISD::BUILTIN_OP_END+V8::INSTRUCTION_LIST_END, 36 CMPICC, // Compare two GPR operands, set icc. 37 CMPFCC, // Compare two FP operands, set fcc. 38 BRICC, // Branch to dest on icc condition 39 BRFCC, // Branch to dest on fcc condition 40 SELECT_ICC, // Select between two values using the current ICC flags. 41 SELECT_FCC, // Select between two values using the current FCC flags. 42 43 Hi, Lo, // Hi/Lo operations, typically on a global address. 44 45 FTOI, // FP to Int within a FP register. 46 ITOF, // Int to FP within a FP register. 47 48 CALL, // A V8 call instruction. 49 RET_FLAG, // Return with a flag operand. 50 }; 51} 52 53/// IntCondCCodeToICC - Convert a DAG integer condition code to a SPARC ICC 54/// condition. 55static V8CC::CondCodes IntCondCCodeToICC(ISD::CondCode CC) { 56 switch (CC) { 57 default: assert(0 && "Unknown integer condition code!"); 58 case ISD::SETEQ: return V8CC::ICC_E; 59 case ISD::SETNE: return V8CC::ICC_NE; 60 case ISD::SETLT: return V8CC::ICC_L; 61 case ISD::SETGT: return V8CC::ICC_G; 62 case ISD::SETLE: return V8CC::ICC_LE; 63 case ISD::SETGE: return V8CC::ICC_GE; 64 case ISD::SETULT: return V8CC::ICC_CS; 65 case ISD::SETULE: return V8CC::ICC_LEU; 66 case ISD::SETUGT: return V8CC::ICC_GU; 67 case ISD::SETUGE: return V8CC::ICC_CC; 68 } 69} 70 71/// FPCondCCodeToFCC - Convert a DAG floatingp oint condition code to a SPARC 72/// FCC condition. 73static V8CC::CondCodes FPCondCCodeToFCC(ISD::CondCode CC) { 74 switch (CC) { 75 default: assert(0 && "Unknown fp condition code!"); 76 case ISD::SETEQ: return V8CC::FCC_E; 77 case ISD::SETNE: return V8CC::FCC_NE; 78 case ISD::SETLT: return V8CC::FCC_L; 79 case ISD::SETGT: return V8CC::FCC_G; 80 case ISD::SETLE: return V8CC::FCC_LE; 81 case ISD::SETGE: return V8CC::FCC_GE; 82 case ISD::SETULT: return V8CC::FCC_UL; 83 case ISD::SETULE: return V8CC::FCC_ULE; 84 case ISD::SETUGT: return V8CC::FCC_UG; 85 case ISD::SETUGE: return V8CC::FCC_UGE; 86 case ISD::SETUO: return V8CC::FCC_U; 87 case ISD::SETO: return V8CC::FCC_O; 88 case ISD::SETONE: return V8CC::FCC_LG; 89 case ISD::SETUEQ: return V8CC::FCC_UE; 90 } 91} 92 93namespace { 94 class SparcV8TargetLowering : public TargetLowering { 95 int VarArgsFrameOffset; // Frame offset to start of varargs area. 96 public: 97 SparcV8TargetLowering(TargetMachine &TM); 98 virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); 99 100 /// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to 101 /// be zero. Op is expected to be a target specific node. Used by DAG 102 /// combiner. 103 virtual bool isMaskedValueZeroForTargetNode(const SDOperand &Op, 104 uint64_t Mask) const; 105 106 virtual std::vector<SDOperand> 107 LowerArguments(Function &F, SelectionDAG &DAG); 108 virtual std::pair<SDOperand, SDOperand> 109 LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, 110 unsigned CC, 111 bool isTailCall, SDOperand Callee, ArgListTy &Args, 112 SelectionDAG &DAG); 113 virtual std::pair<SDOperand, SDOperand> 114 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, 115 SelectionDAG &DAG); 116 virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, 117 MachineBasicBlock *MBB); 118 119 virtual const char *getTargetNodeName(unsigned Opcode) const; 120 }; 121} 122 123SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) 124 : TargetLowering(TM) { 125 126 // Set up the register classes. 127 addRegisterClass(MVT::i32, V8::IntRegsRegisterClass); 128 addRegisterClass(MVT::f32, V8::FPRegsRegisterClass); 129 addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass); 130 131 // Custom legalize GlobalAddress nodes into LO/HI parts. 132 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 133 setOperationAction(ISD::ConstantPool , MVT::i32, Custom); 134 135 // Sparc doesn't have sext_inreg, replace them with shl/sra 136 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); 137 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); 138 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); 139 140 // Sparc has no REM operation. 141 setOperationAction(ISD::UREM, MVT::i32, Expand); 142 setOperationAction(ISD::SREM, MVT::i32, Expand); 143 144 // Custom expand fp<->sint 145 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 146 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); 147 148 // Expand fp<->uint 149 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); 150 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); 151 152 setOperationAction(ISD::BIT_CONVERT, MVT::f32, Expand); 153 setOperationAction(ISD::BIT_CONVERT, MVT::i32, Expand); 154 155 // Turn FP extload into load/fextend 156 setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); 157 158 // Sparc has no select or setcc: expand to SELECT_CC. 159 setOperationAction(ISD::SELECT, MVT::i32, Expand); 160 setOperationAction(ISD::SELECT, MVT::f32, Expand); 161 setOperationAction(ISD::SELECT, MVT::f64, Expand); 162 setOperationAction(ISD::SETCC, MVT::i32, Expand); 163 setOperationAction(ISD::SETCC, MVT::f32, Expand); 164 setOperationAction(ISD::SETCC, MVT::f64, Expand); 165 166 // Sparc doesn't have BRCOND either, it has BR_CC. 167 setOperationAction(ISD::BRCOND, MVT::Other, Expand); 168 setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); 169 setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand); 170 setOperationAction(ISD::BR_CC, MVT::i32, Custom); 171 setOperationAction(ISD::BR_CC, MVT::f32, Custom); 172 setOperationAction(ISD::BR_CC, MVT::f64, Custom); 173 174 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 175 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 176 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 177 178 // V8 has no intrinsics for these particular operations. 179 setOperationAction(ISD::MEMMOVE, MVT::Other, Expand); 180 setOperationAction(ISD::MEMSET, MVT::Other, Expand); 181 setOperationAction(ISD::MEMCPY, MVT::Other, Expand); 182 183 setOperationAction(ISD::FSIN , MVT::f64, Expand); 184 setOperationAction(ISD::FCOS , MVT::f64, Expand); 185 setOperationAction(ISD::FSIN , MVT::f32, Expand); 186 setOperationAction(ISD::FCOS , MVT::f32, Expand); 187 setOperationAction(ISD::CTPOP, MVT::i32, Expand); 188 setOperationAction(ISD::CTTZ , MVT::i32, Expand); 189 setOperationAction(ISD::CTLZ , MVT::i32, Expand); 190 setOperationAction(ISD::ROTL , MVT::i32, Expand); 191 setOperationAction(ISD::ROTR , MVT::i32, Expand); 192 setOperationAction(ISD::BSWAP, MVT::i32, Expand); 193 194 setOperationAction(ISD::SHL_PARTS, MVT::i32, Expand); 195 setOperationAction(ISD::SRA_PARTS, MVT::i32, Expand); 196 setOperationAction(ISD::SRL_PARTS, MVT::i32, Expand); 197 198 // We don't have line number support yet. 199 setOperationAction(ISD::LOCATION, MVT::Other, Expand); 200 setOperationAction(ISD::DEBUG_LOC, MVT::Other, Expand); 201 setOperationAction(ISD::DEBUG_LABEL, MVT::Other, Expand); 202 203 // RET must be custom lowered, to meet ABI requirements 204 setOperationAction(ISD::RET , MVT::Other, Custom); 205 206 // VASTART needs to be custom lowered to use the VarArgsFrameIndex 207 setOperationAction(ISD::VASTART , MVT::Other, Custom); 208 209 // Use the default implementation. 210 setOperationAction(ISD::VAARG , MVT::Other, Expand); 211 setOperationAction(ISD::VACOPY , MVT::Other, Expand); 212 setOperationAction(ISD::VAEND , MVT::Other, Expand); 213 setOperationAction(ISD::STACKSAVE , MVT::Other, Expand); 214 setOperationAction(ISD::STACKRESTORE , MVT::Other, Expand); 215 setOperationAction(ISD::DYNAMIC_STACKALLOC, MVT::i32 , Expand); 216 217 setOperationAction(ISD::ConstantFP, MVT::f64, Expand); 218 setOperationAction(ISD::ConstantFP, MVT::f32, Expand); 219 220 setStackPointerRegisterToSaveRestore(V8::O6); 221 222 if (TM.getSubtarget<SparcV8Subtarget>().isV9()) { 223 setOperationAction(ISD::CTPOP, MVT::i32, Legal); 224 } 225 226 computeRegisterProperties(); 227} 228 229const char *SparcV8TargetLowering::getTargetNodeName(unsigned Opcode) const { 230 switch (Opcode) { 231 default: return 0; 232 case V8ISD::CMPICC: return "V8ISD::CMPICC"; 233 case V8ISD::CMPFCC: return "V8ISD::CMPFCC"; 234 case V8ISD::BRICC: return "V8ISD::BRICC"; 235 case V8ISD::BRFCC: return "V8ISD::BRFCC"; 236 case V8ISD::SELECT_ICC: return "V8ISD::SELECT_ICC"; 237 case V8ISD::SELECT_FCC: return "V8ISD::SELECT_FCC"; 238 case V8ISD::Hi: return "V8ISD::Hi"; 239 case V8ISD::Lo: return "V8ISD::Lo"; 240 case V8ISD::FTOI: return "V8ISD::FTOI"; 241 case V8ISD::ITOF: return "V8ISD::ITOF"; 242 case V8ISD::CALL: return "V8ISD::CALL"; 243 case V8ISD::RET_FLAG: return "V8ISD::RET_FLAG"; 244 } 245} 246 247/// isMaskedValueZeroForTargetNode - Return true if 'Op & Mask' is known to 248/// be zero. Op is expected to be a target specific node. Used by DAG 249/// combiner. 250bool SparcV8TargetLowering:: 251isMaskedValueZeroForTargetNode(const SDOperand &Op, uint64_t Mask) const { 252 switch (Op.getOpcode()) { 253 default: return false; 254 case V8ISD::SELECT_ICC: 255 case V8ISD::SELECT_FCC: 256 assert(MVT::isInteger(Op.getValueType()) && "Not an integer select!"); 257 // These operations are masked zero if both the left and the right are zero. 258 return MaskedValueIsZero(Op.getOperand(0), Mask) && 259 MaskedValueIsZero(Op.getOperand(1), Mask); 260 } 261} 262 263 264/// LowerArguments - V8 uses a very simple ABI, where all values are passed in 265/// either one or two GPRs, including FP values. TODO: we should pass FP values 266/// in FP registers for fastcc functions. 267std::vector<SDOperand> 268SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { 269 MachineFunction &MF = DAG.getMachineFunction(); 270 SSARegMap *RegMap = MF.getSSARegMap(); 271 std::vector<SDOperand> ArgValues; 272 273 static const unsigned ArgRegs[] = { 274 V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 275 }; 276 277 const unsigned *CurArgReg = ArgRegs, *ArgRegEnd = ArgRegs+6; 278 unsigned ArgOffset = 68; 279 280 SDOperand Root = DAG.getRoot(); 281 std::vector<SDOperand> OutChains; 282 283 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { 284 MVT::ValueType ObjectVT = getValueType(I->getType()); 285 286 switch (ObjectVT) { 287 default: assert(0 && "Unhandled argument type!"); 288 case MVT::i1: 289 case MVT::i8: 290 case MVT::i16: 291 case MVT::i32: 292 if (I->use_empty()) { // Argument is dead. 293 if (CurArgReg < ArgRegEnd) ++CurArgReg; 294 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); 295 } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR 296 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 297 MF.addLiveIn(*CurArgReg++, VReg); 298 SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32); 299 if (ObjectVT != MVT::i32) { 300 unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 301 : ISD::AssertZext; 302 Arg = DAG.getNode(AssertOp, MVT::i32, Arg, 303 DAG.getValueType(ObjectVT)); 304 Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg); 305 } 306 ArgValues.push_back(Arg); 307 } else { 308 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); 309 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 310 SDOperand Load; 311 if (ObjectVT == MVT::i32) { 312 Load = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0)); 313 } else { 314 unsigned LoadOp = 315 I->getType()->isSigned() ? ISD::SEXTLOAD : ISD::ZEXTLOAD; 316 317 // Sparc is big endian, so add an offset based on the ObjectVT. 318 unsigned Offset = 4-std::max(1U, MVT::getSizeInBits(ObjectVT)/8); 319 FIPtr = DAG.getNode(ISD::ADD, MVT::i32, FIPtr, 320 DAG.getConstant(Offset, MVT::i32)); 321 Load = DAG.getExtLoad(LoadOp, MVT::i32, Root, FIPtr, 322 DAG.getSrcValue(0), ObjectVT); 323 Load = DAG.getNode(ISD::TRUNCATE, ObjectVT, Load); 324 } 325 ArgValues.push_back(Load); 326 } 327 328 ArgOffset += 4; 329 break; 330 case MVT::f32: 331 if (I->use_empty()) { // Argument is dead. 332 if (CurArgReg < ArgRegEnd) ++CurArgReg; 333 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); 334 } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR 335 // FP value is passed in an integer register. 336 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 337 MF.addLiveIn(*CurArgReg++, VReg); 338 SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32); 339 340 Arg = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Arg); 341 ArgValues.push_back(Arg); 342 } else { 343 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); 344 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 345 SDOperand Load = DAG.getLoad(MVT::f32, Root, FIPtr, DAG.getSrcValue(0)); 346 ArgValues.push_back(Load); 347 } 348 ArgOffset += 4; 349 break; 350 351 case MVT::i64: 352 case MVT::f64: 353 if (I->use_empty()) { // Argument is dead. 354 if (CurArgReg < ArgRegEnd) ++CurArgReg; 355 if (CurArgReg < ArgRegEnd) ++CurArgReg; 356 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); 357 } else if (/* FIXME: Apparently this isn't safe?? */ 358 0 && CurArgReg == ArgRegEnd && ObjectVT == MVT::f64 && 359 ((CurArgReg-ArgRegs) & 1) == 0) { 360 // If this is a double argument and the whole thing lives on the stack, 361 // and the argument is aligned, load the double straight from the stack. 362 // We can't do a load in cases like void foo([6ints], int,double), 363 // because the double wouldn't be aligned! 364 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset); 365 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 366 ArgValues.push_back(DAG.getLoad(MVT::f64, Root, FIPtr, 367 DAG.getSrcValue(0))); 368 } else { 369 SDOperand HiVal; 370 if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR 371 unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 372 MF.addLiveIn(*CurArgReg++, VRegHi); 373 HiVal = DAG.getCopyFromReg(Root, VRegHi, MVT::i32); 374 } else { 375 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); 376 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 377 HiVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0)); 378 } 379 380 SDOperand LoVal; 381 if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR 382 unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 383 MF.addLiveIn(*CurArgReg++, VRegLo); 384 LoVal = DAG.getCopyFromReg(Root, VRegLo, MVT::i32); 385 } else { 386 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4); 387 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 388 LoVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0)); 389 } 390 391 // Compose the two halves together into an i64 unit. 392 SDOperand WholeValue = 393 DAG.getNode(ISD::BUILD_PAIR, MVT::i64, LoVal, HiVal); 394 395 // If we want a double, do a bit convert. 396 if (ObjectVT == MVT::f64) 397 WholeValue = DAG.getNode(ISD::BIT_CONVERT, MVT::f64, WholeValue); 398 399 ArgValues.push_back(WholeValue); 400 } 401 ArgOffset += 8; 402 break; 403 } 404 } 405 406 // Store remaining ArgRegs to the stack if this is a varargs function. 407 if (F.getFunctionType()->isVarArg()) { 408 // Remember the vararg offset for the va_start implementation. 409 VarArgsFrameOffset = ArgOffset; 410 411 for (; CurArgReg != ArgRegEnd; ++CurArgReg) { 412 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 413 MF.addLiveIn(*CurArgReg, VReg); 414 SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 415 416 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); 417 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 418 419 OutChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), 420 Arg, FIPtr, DAG.getSrcValue(0))); 421 ArgOffset += 4; 422 } 423 } 424 425 if (!OutChains.empty()) 426 DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains)); 427 428 // Finally, inform the code generator which regs we return values in. 429 switch (getValueType(F.getReturnType())) { 430 default: assert(0 && "Unknown type!"); 431 case MVT::isVoid: break; 432 case MVT::i1: 433 case MVT::i8: 434 case MVT::i16: 435 case MVT::i32: 436 MF.addLiveOut(V8::I0); 437 break; 438 case MVT::i64: 439 MF.addLiveOut(V8::I0); 440 MF.addLiveOut(V8::I1); 441 break; 442 case MVT::f32: 443 MF.addLiveOut(V8::F0); 444 break; 445 case MVT::f64: 446 MF.addLiveOut(V8::D0); 447 break; 448 } 449 450 return ArgValues; 451} 452 453std::pair<SDOperand, SDOperand> 454SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, 455 bool isVarArg, unsigned CC, 456 bool isTailCall, SDOperand Callee, 457 ArgListTy &Args, SelectionDAG &DAG) { 458 MachineFunction &MF = DAG.getMachineFunction(); 459 // Count the size of the outgoing arguments. 460 unsigned ArgsSize = 0; 461 for (unsigned i = 0, e = Args.size(); i != e; ++i) { 462 switch (getValueType(Args[i].second)) { 463 default: assert(0 && "Unknown value type!"); 464 case MVT::i1: 465 case MVT::i8: 466 case MVT::i16: 467 case MVT::i32: 468 case MVT::f32: 469 ArgsSize += 4; 470 break; 471 case MVT::i64: 472 case MVT::f64: 473 ArgsSize += 8; 474 break; 475 } 476 } 477 if (ArgsSize > 4*6) 478 ArgsSize -= 4*6; // Space for first 6 arguments is prereserved. 479 else 480 ArgsSize = 0; 481 482 // Keep stack frames 8-byte aligned. 483 ArgsSize = (ArgsSize+7) & ~7; 484 485 Chain = DAG.getNode(ISD::CALLSEQ_START, MVT::Other, Chain, 486 DAG.getConstant(ArgsSize, getPointerTy())); 487 488 SDOperand StackPtr, NullSV; 489 std::vector<SDOperand> Stores; 490 std::vector<SDOperand> RegValuesToPass; 491 unsigned ArgOffset = 68; 492 for (unsigned i = 0, e = Args.size(); i != e; ++i) { 493 SDOperand Val = Args[i].first; 494 MVT::ValueType ObjectVT = Val.getValueType(); 495 SDOperand ValToStore(0, 0); 496 unsigned ObjSize; 497 switch (ObjectVT) { 498 default: assert(0 && "Unhandled argument type!"); 499 case MVT::i1: 500 case MVT::i8: 501 case MVT::i16: 502 // Promote the integer to 32-bits. If the input type is signed, use a 503 // sign extend, otherwise use a zero extend. 504 if (Args[i].second->isSigned()) 505 Val = DAG.getNode(ISD::SIGN_EXTEND, MVT::i32, Val); 506 else 507 Val = DAG.getNode(ISD::ZERO_EXTEND, MVT::i32, Val); 508 // FALL THROUGH 509 case MVT::i32: 510 ObjSize = 4; 511 512 if (RegValuesToPass.size() >= 6) { 513 ValToStore = Val; 514 } else { 515 RegValuesToPass.push_back(Val); 516 } 517 break; 518 case MVT::f32: 519 ObjSize = 4; 520 if (RegValuesToPass.size() >= 6) { 521 ValToStore = Val; 522 } else { 523 // Convert this to a FP value in an int reg. 524 Val = DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Val); 525 RegValuesToPass.push_back(Val); 526 } 527 break; 528 case MVT::f64: 529 ObjSize = 8; 530 // If we can store this directly into the outgoing slot, do so. We can 531 // do this when all ArgRegs are used and if the outgoing slot is aligned. 532 // FIXME: McGill/misr fails with this. 533 if (0 && RegValuesToPass.size() >= 6 && ((ArgOffset-68) & 7) == 0) { 534 ValToStore = Val; 535 break; 536 } 537 538 // Otherwise, convert this to a FP value in int regs. 539 Val = DAG.getNode(ISD::BIT_CONVERT, MVT::i64, Val); 540 // FALL THROUGH 541 case MVT::i64: 542 ObjSize = 8; 543 if (RegValuesToPass.size() >= 6) { 544 ValToStore = Val; // Whole thing is passed in memory. 545 break; 546 } 547 548 // Split the value into top and bottom part. Top part goes in a reg. 549 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val, 550 DAG.getConstant(1, MVT::i32)); 551 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Val, 552 DAG.getConstant(0, MVT::i32)); 553 RegValuesToPass.push_back(Hi); 554 555 if (RegValuesToPass.size() >= 6) { 556 ValToStore = Lo; 557 ArgOffset += 4; 558 ObjSize = 4; 559 } else { 560 RegValuesToPass.push_back(Lo); 561 } 562 break; 563 } 564 565 if (ValToStore.Val) { 566 if (!StackPtr.Val) { 567 StackPtr = DAG.getRegister(V8::O6, MVT::i32); 568 NullSV = DAG.getSrcValue(NULL); 569 } 570 SDOperand PtrOff = DAG.getConstant(ArgOffset, getPointerTy()); 571 PtrOff = DAG.getNode(ISD::ADD, MVT::i32, StackPtr, PtrOff); 572 Stores.push_back(DAG.getNode(ISD::STORE, MVT::Other, Chain, 573 ValToStore, PtrOff, NullSV)); 574 } 575 ArgOffset += ObjSize; 576 } 577 578 // Emit all stores, make sure the occur before any copies into physregs. 579 if (!Stores.empty()) 580 Chain = DAG.getNode(ISD::TokenFactor, MVT::Other, Stores); 581 582 static const unsigned ArgRegs[] = { 583 V8::O0, V8::O1, V8::O2, V8::O3, V8::O4, V8::O5 584 }; 585 586 // Build a sequence of copy-to-reg nodes chained together with token chain 587 // and flag operands which copy the outgoing args into O[0-5]. 588 SDOperand InFlag; 589 for (unsigned i = 0, e = RegValuesToPass.size(); i != e; ++i) { 590 Chain = DAG.getCopyToReg(Chain, ArgRegs[i], RegValuesToPass[i], InFlag); 591 InFlag = Chain.getValue(1); 592 } 593 594 // If the callee is a GlobalAddress node (quite common, every direct call is) 595 // turn it into a TargetGlobalAddress node so that legalize doesn't hack it. 596 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 597 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), MVT::i32); 598 599 std::vector<MVT::ValueType> NodeTys; 600 NodeTys.push_back(MVT::Other); // Returns a chain 601 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. 602 std::vector<SDOperand> Ops; 603 Ops.push_back(Chain); 604 Ops.push_back(Callee); 605 if (InFlag.Val) 606 Ops.push_back(InFlag); 607 Chain = DAG.getNode(V8ISD::CALL, NodeTys, Ops); 608 InFlag = Chain.getValue(1); 609 610 MVT::ValueType RetTyVT = getValueType(RetTy); 611 SDOperand RetVal; 612 if (RetTyVT != MVT::isVoid) { 613 switch (RetTyVT) { 614 default: assert(0 && "Unknown value type to return!"); 615 case MVT::i1: 616 case MVT::i8: 617 case MVT::i16: 618 RetVal = DAG.getCopyFromReg(Chain, V8::O0, MVT::i32, InFlag); 619 Chain = RetVal.getValue(1); 620 621 // Add a note to keep track of whether it is sign or zero extended. 622 RetVal = DAG.getNode(RetTy->isSigned() ? ISD::AssertSext :ISD::AssertZext, 623 MVT::i32, RetVal, DAG.getValueType(RetTyVT)); 624 RetVal = DAG.getNode(ISD::TRUNCATE, RetTyVT, RetVal); 625 break; 626 case MVT::i32: 627 RetVal = DAG.getCopyFromReg(Chain, V8::O0, MVT::i32, InFlag); 628 Chain = RetVal.getValue(1); 629 break; 630 case MVT::f32: 631 RetVal = DAG.getCopyFromReg(Chain, V8::F0, MVT::f32, InFlag); 632 Chain = RetVal.getValue(1); 633 break; 634 case MVT::f64: 635 RetVal = DAG.getCopyFromReg(Chain, V8::D0, MVT::f64, InFlag); 636 Chain = RetVal.getValue(1); 637 break; 638 case MVT::i64: 639 SDOperand Lo = DAG.getCopyFromReg(Chain, V8::O1, MVT::i32, InFlag); 640 SDOperand Hi = DAG.getCopyFromReg(Lo.getValue(1), V8::O0, MVT::i32, 641 Lo.getValue(2)); 642 RetVal = DAG.getNode(ISD::BUILD_PAIR, MVT::i64, Lo, Hi); 643 Chain = Hi.getValue(1); 644 break; 645 } 646 } 647 648 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, 649 DAG.getConstant(ArgsSize, getPointerTy())); 650 651 return std::make_pair(RetVal, Chain); 652} 653 654std::pair<SDOperand, SDOperand> SparcV8TargetLowering:: 655LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, 656 SelectionDAG &DAG) { 657 assert(0 && "Unimp"); 658 abort(); 659} 660 661// Look at LHS/RHS/CC and see if they are a lowered V8 setcc instruction. If so 662// set LHS/RHS and V8CC to the LHS/RHS of the setcc and V8CC to the condition. 663static void LookThroughSetCC(SDOperand &LHS, SDOperand &RHS, 664 ISD::CondCode CC, unsigned &V8CC) { 665 if (isa<ConstantSDNode>(RHS) && cast<ConstantSDNode>(RHS)->getValue() == 0 && 666 CC == ISD::SETNE && 667 ((LHS.getOpcode() == V8ISD::SELECT_ICC && 668 LHS.getOperand(3).getOpcode() == V8ISD::CMPICC) || 669 (LHS.getOpcode() == V8ISD::SELECT_FCC && 670 LHS.getOperand(3).getOpcode() == V8ISD::CMPFCC)) && 671 isa<ConstantSDNode>(LHS.getOperand(0)) && 672 isa<ConstantSDNode>(LHS.getOperand(1)) && 673 cast<ConstantSDNode>(LHS.getOperand(0))->getValue() == 1 && 674 cast<ConstantSDNode>(LHS.getOperand(1))->getValue() == 0) { 675 SDOperand CMPCC = LHS.getOperand(3); 676 V8CC = cast<ConstantSDNode>(LHS.getOperand(2))->getValue(); 677 LHS = CMPCC.getOperand(0); 678 RHS = CMPCC.getOperand(1); 679 } 680} 681 682 683SDOperand SparcV8TargetLowering:: 684LowerOperation(SDOperand Op, SelectionDAG &DAG) { 685 switch (Op.getOpcode()) { 686 default: assert(0 && "Should not custom lower this!"); 687 case ISD::GlobalAddress: { 688 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 689 SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32); 690 SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, GA); 691 SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, GA); 692 return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); 693 } 694 case ISD::ConstantPool: { 695 Constant *C = cast<ConstantPoolSDNode>(Op)->get(); 696 SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32, 697 cast<ConstantPoolSDNode>(Op)->getAlignment()); 698 SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, CP); 699 SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP); 700 return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); 701 } 702 case ISD::FP_TO_SINT: 703 // Convert the fp value to integer in an FP register. 704 assert(Op.getValueType() == MVT::i32); 705 Op = DAG.getNode(V8ISD::FTOI, MVT::f32, Op.getOperand(0)); 706 return DAG.getNode(ISD::BIT_CONVERT, MVT::i32, Op); 707 case ISD::SINT_TO_FP: { 708 assert(Op.getOperand(0).getValueType() == MVT::i32); 709 SDOperand Tmp = DAG.getNode(ISD::BIT_CONVERT, MVT::f32, Op.getOperand(0)); 710 // Convert the int value to FP in an FP register. 711 return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Tmp); 712 } 713 case ISD::BR_CC: { 714 SDOperand Chain = Op.getOperand(0); 715 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(1))->get(); 716 SDOperand LHS = Op.getOperand(2); 717 SDOperand RHS = Op.getOperand(3); 718 SDOperand Dest = Op.getOperand(4); 719 unsigned Opc, V8CC = ~0U; 720 721 // If this is a br_cc of a "setcc", and if the setcc got lowered into 722 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. 723 LookThroughSetCC(LHS, RHS, CC, V8CC); 724 725 // Get the condition flag. 726 SDOperand CompareFlag; 727 if (LHS.getValueType() == MVT::i32) { 728 std::vector<MVT::ValueType> VTs; 729 VTs.push_back(MVT::i32); 730 VTs.push_back(MVT::Flag); 731 std::vector<SDOperand> Ops; 732 Ops.push_back(LHS); 733 Ops.push_back(RHS); 734 CompareFlag = DAG.getNode(V8ISD::CMPICC, VTs, Ops).getValue(1); 735 if (V8CC == ~0U) V8CC = IntCondCCodeToICC(CC); 736 Opc = V8ISD::BRICC; 737 } else { 738 CompareFlag = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); 739 if (V8CC == ~0U) V8CC = FPCondCCodeToFCC(CC); 740 Opc = V8ISD::BRFCC; 741 } 742 return DAG.getNode(Opc, MVT::Other, Chain, Dest, 743 DAG.getConstant(V8CC, MVT::i32), CompareFlag); 744 } 745 case ISD::SELECT_CC: { 746 SDOperand LHS = Op.getOperand(0); 747 SDOperand RHS = Op.getOperand(1); 748 ISD::CondCode CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 749 SDOperand TrueVal = Op.getOperand(2); 750 SDOperand FalseVal = Op.getOperand(3); 751 unsigned Opc, V8CC = ~0U; 752 753 // If this is a select_cc of a "setcc", and if the setcc got lowered into 754 // an CMP[IF]CC/SELECT_[IF]CC pair, find the original compared values. 755 LookThroughSetCC(LHS, RHS, CC, V8CC); 756 757 SDOperand CompareFlag; 758 if (LHS.getValueType() == MVT::i32) { 759 std::vector<MVT::ValueType> VTs; 760 VTs.push_back(LHS.getValueType()); // subcc returns a value 761 VTs.push_back(MVT::Flag); 762 std::vector<SDOperand> Ops; 763 Ops.push_back(LHS); 764 Ops.push_back(RHS); 765 CompareFlag = DAG.getNode(V8ISD::CMPICC, VTs, Ops).getValue(1); 766 Opc = V8ISD::SELECT_ICC; 767 if (V8CC == ~0U) V8CC = IntCondCCodeToICC(CC); 768 } else { 769 CompareFlag = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); 770 Opc = V8ISD::SELECT_FCC; 771 if (V8CC == ~0U) V8CC = FPCondCCodeToFCC(CC); 772 } 773 return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal, 774 DAG.getConstant(V8CC, MVT::i32), CompareFlag); 775 } 776 case ISD::VASTART: { 777 // vastart just stores the address of the VarArgsFrameIndex slot into the 778 // memory location argument. 779 SDOperand Offset = DAG.getNode(ISD::ADD, MVT::i32, 780 DAG.getRegister(V8::I6, MVT::i32), 781 DAG.getConstant(VarArgsFrameOffset, MVT::i32)); 782 return DAG.getNode(ISD::STORE, MVT::Other, Op.getOperand(0), Offset, 783 Op.getOperand(1), Op.getOperand(2)); 784 } 785 case ISD::RET: { 786 SDOperand Copy; 787 788 switch(Op.getNumOperands()) { 789 default: 790 assert(0 && "Do not know how to return this many arguments!"); 791 abort(); 792 case 1: 793 return SDOperand(); // ret void is legal 794 case 2: { 795 unsigned ArgReg; 796 switch(Op.getOperand(1).getValueType()) { 797 default: assert(0 && "Unknown type to return!"); 798 case MVT::i32: ArgReg = V8::I0; break; 799 case MVT::f32: ArgReg = V8::F0; break; 800 case MVT::f64: ArgReg = V8::D0; break; 801 } 802 Copy = DAG.getCopyToReg(Op.getOperand(0), ArgReg, Op.getOperand(1), 803 SDOperand()); 804 break; 805 } 806 case 3: 807 Copy = DAG.getCopyToReg(Op.getOperand(0), V8::I0, Op.getOperand(2), 808 SDOperand()); 809 Copy = DAG.getCopyToReg(Copy, V8::I1, Op.getOperand(1), Copy.getValue(1)); 810 break; 811 } 812 return DAG.getNode(V8ISD::RET_FLAG, MVT::Other, Copy, Copy.getValue(1)); 813 } 814 } 815} 816 817MachineBasicBlock * 818SparcV8TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, 819 MachineBasicBlock *BB) { 820 unsigned BROpcode; 821 unsigned CC; 822 // Figure out the conditional branch opcode to use for this select_cc. 823 switch (MI->getOpcode()) { 824 default: assert(0 && "Unknown SELECT_CC!"); 825 case V8::SELECT_CC_Int_ICC: 826 case V8::SELECT_CC_FP_ICC: 827 case V8::SELECT_CC_DFP_ICC: 828 BROpcode = V8::BCOND; 829 break; 830 case V8::SELECT_CC_Int_FCC: 831 case V8::SELECT_CC_FP_FCC: 832 case V8::SELECT_CC_DFP_FCC: 833 BROpcode = V8::FBCOND; 834 break; 835 } 836 837 CC = (V8CC::CondCodes)MI->getOperand(3).getImmedValue(); 838 839 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 840 // control-flow pattern. The incoming instruction knows the destination vreg 841 // to set, the condition code register to branch on, the true/false values to 842 // select between, and a branch opcode to use. 843 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 844 ilist<MachineBasicBlock>::iterator It = BB; 845 ++It; 846 847 // thisMBB: 848 // ... 849 // TrueVal = ... 850 // [f]bCC copy1MBB 851 // fallthrough --> copy0MBB 852 MachineBasicBlock *thisMBB = BB; 853 MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); 854 MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); 855 BuildMI(BB, BROpcode, 2).addMBB(sinkMBB).addImm(CC); 856 MachineFunction *F = BB->getParent(); 857 F->getBasicBlockList().insert(It, copy0MBB); 858 F->getBasicBlockList().insert(It, sinkMBB); 859 // Update machine-CFG edges 860 BB->addSuccessor(copy0MBB); 861 BB->addSuccessor(sinkMBB); 862 863 // copy0MBB: 864 // %FalseValue = ... 865 // # fallthrough to sinkMBB 866 BB = copy0MBB; 867 868 // Update machine-CFG edges 869 BB->addSuccessor(sinkMBB); 870 871 // sinkMBB: 872 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 873 // ... 874 BB = sinkMBB; 875 BuildMI(BB, V8::PHI, 4, MI->getOperand(0).getReg()) 876 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 877 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 878 879 delete MI; // The pseudo instruction is gone now. 880 return BB; 881} 882 883//===----------------------------------------------------------------------===// 884// Instruction Selector Implementation 885//===----------------------------------------------------------------------===// 886 887//===--------------------------------------------------------------------===// 888/// SparcV8DAGToDAGISel - SPARC specific code to select Sparc V8 machine 889/// instructions for SelectionDAG operations. 890/// 891namespace { 892class SparcV8DAGToDAGISel : public SelectionDAGISel { 893 SparcV8TargetLowering V8Lowering; 894 895 /// Subtarget - Keep a pointer to the Sparc Subtarget around so that we can 896 /// make the right decision when generating code for different targets. 897 const SparcV8Subtarget &Subtarget; 898public: 899 SparcV8DAGToDAGISel(TargetMachine &TM) 900 : SelectionDAGISel(V8Lowering), V8Lowering(TM), 901 Subtarget(TM.getSubtarget<SparcV8Subtarget>()) { 902 } 903 904 SDOperand Select(SDOperand Op); 905 906 // Complex Pattern Selectors. 907 bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2); 908 bool SelectADDRri(SDOperand N, SDOperand &Base, SDOperand &Offset); 909 910 /// InstructionSelectBasicBlock - This callback is invoked by 911 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 912 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 913 914 virtual const char *getPassName() const { 915 return "SparcV8 DAG->DAG Pattern Instruction Selection"; 916 } 917 918 // Include the pieces autogenerated from the target description. 919#include "SparcV8GenDAGISel.inc" 920}; 921} // end anonymous namespace 922 923/// InstructionSelectBasicBlock - This callback is invoked by 924/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 925void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { 926 DEBUG(BB->dump()); 927 928 // Select target instructions for the DAG. 929 DAG.setRoot(Select(DAG.getRoot())); 930 CodeGenMap.clear(); 931 DAG.RemoveDeadNodes(); 932 933 // Emit machine code to BB. 934 ScheduleAndEmitDAG(DAG); 935} 936 937bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base, 938 SDOperand &Offset) { 939 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 940 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 941 Offset = CurDAG->getTargetConstant(0, MVT::i32); 942 return true; 943 } 944 945 if (Addr.getOpcode() == ISD::ADD) { 946 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { 947 if (Predicate_simm13(CN)) { 948 if (FrameIndexSDNode *FIN = 949 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) { 950 // Constant offset from frame ref. 951 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 952 } else { 953 Base = Select(Addr.getOperand(0)); 954 } 955 Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32); 956 return true; 957 } 958 } 959 if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) { 960 Base = Select(Addr.getOperand(1)); 961 Offset = Addr.getOperand(0).getOperand(0); 962 return true; 963 } 964 if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) { 965 Base = Select(Addr.getOperand(0)); 966 Offset = Addr.getOperand(1).getOperand(0); 967 return true; 968 } 969 } 970 Base = Select(Addr); 971 Offset = CurDAG->getTargetConstant(0, MVT::i32); 972 return true; 973} 974 975bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 976 SDOperand &R2) { 977 if (Addr.getOpcode() == ISD::FrameIndex) return false; 978 if (Addr.getOpcode() == ISD::ADD) { 979 if (isa<ConstantSDNode>(Addr.getOperand(1)) && 980 Predicate_simm13(Addr.getOperand(1).Val)) 981 return false; // Let the reg+imm pattern catch this! 982 if (Addr.getOperand(0).getOpcode() == V8ISD::Lo || 983 Addr.getOperand(1).getOpcode() == V8ISD::Lo) 984 return false; // Let the reg+imm pattern catch this! 985 R1 = Select(Addr.getOperand(0)); 986 R2 = Select(Addr.getOperand(1)); 987 return true; 988 } 989 990 R1 = Select(Addr); 991 R2 = CurDAG->getRegister(V8::G0, MVT::i32); 992 return true; 993} 994 995SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { 996 SDNode *N = Op.Val; 997 if (N->getOpcode() >= ISD::BUILTIN_OP_END && 998 N->getOpcode() < V8ISD::FIRST_NUMBER) 999 return Op; // Already selected. 1000 // If this has already been converted, use it. 1001 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op); 1002 if (CGMI != CodeGenMap.end()) return CGMI->second; 1003 1004 switch (N->getOpcode()) { 1005 default: break; 1006 case ISD::FrameIndex: { 1007 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 1008 if (N->hasOneUse()) 1009 return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32, 1010 CurDAG->getTargetFrameIndex(FI, MVT::i32), 1011 CurDAG->getTargetConstant(0, MVT::i32)); 1012 return CodeGenMap[Op] = 1013 CurDAG->getTargetNode(V8::ADDri, MVT::i32, 1014 CurDAG->getTargetFrameIndex(FI, MVT::i32), 1015 CurDAG->getTargetConstant(0, MVT::i32)); 1016 } 1017 case ISD::ADD_PARTS: { 1018 SDOperand LHSL = Select(N->getOperand(0)); 1019 SDOperand LHSH = Select(N->getOperand(1)); 1020 SDOperand RHSL = Select(N->getOperand(2)); 1021 SDOperand RHSH = Select(N->getOperand(3)); 1022 // FIXME, handle immediate RHS. 1023 SDOperand Low = CurDAG->getTargetNode(V8::ADDCCrr, MVT::i32, MVT::Flag, 1024 LHSL, RHSL); 1025 SDOperand Hi = CurDAG->getTargetNode(V8::ADDXrr, MVT::i32, LHSH, RHSH, 1026 Low.getValue(1)); 1027 CodeGenMap[SDOperand(N, 0)] = Low; 1028 CodeGenMap[SDOperand(N, 1)] = Hi; 1029 return Op.ResNo ? Hi : Low; 1030 } 1031 case ISD::SUB_PARTS: { 1032 SDOperand LHSL = Select(N->getOperand(0)); 1033 SDOperand LHSH = Select(N->getOperand(1)); 1034 SDOperand RHSL = Select(N->getOperand(2)); 1035 SDOperand RHSH = Select(N->getOperand(3)); 1036 // FIXME, handle immediate RHS. 1037 SDOperand Low = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag, 1038 LHSL, RHSL); 1039 SDOperand Hi = CurDAG->getTargetNode(V8::SUBXrr, MVT::i32, LHSH, RHSH, 1040 Low.getValue(1)); 1041 CodeGenMap[SDOperand(N, 0)] = Low; 1042 CodeGenMap[SDOperand(N, 1)] = Hi; 1043 return Op.ResNo ? Hi : Low; 1044 } 1045 case ISD::SDIV: 1046 case ISD::UDIV: { 1047 // FIXME: should use a custom expander to expose the SRA to the dag. 1048 SDOperand DivLHS = Select(N->getOperand(0)); 1049 SDOperand DivRHS = Select(N->getOperand(1)); 1050 1051 // Set the Y register to the high-part. 1052 SDOperand TopPart; 1053 if (N->getOpcode() == ISD::SDIV) { 1054 TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS, 1055 CurDAG->getTargetConstant(31, MVT::i32)); 1056 } else { 1057 TopPart = CurDAG->getRegister(V8::G0, MVT::i32); 1058 } 1059 TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart, 1060 CurDAG->getRegister(V8::G0, MVT::i32)); 1061 1062 // FIXME: Handle div by immediate. 1063 unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr; 1064 return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart); 1065 } 1066 case ISD::MULHU: 1067 case ISD::MULHS: { 1068 // FIXME: Handle mul by immediate. 1069 SDOperand MulLHS = Select(N->getOperand(0)); 1070 SDOperand MulRHS = Select(N->getOperand(1)); 1071 unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr; 1072 SDOperand Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag, 1073 MulLHS, MulRHS); 1074 // The high part is in the Y register. 1075 return CurDAG->SelectNodeTo(N, V8::RDY, MVT::i32, Mul.getValue(1)); 1076 } 1077 case V8ISD::CALL: 1078 // FIXME: This is a workaround for a bug in tblgen. 1079 { // Pattern #47: (call:Flag (tglobaladdr:i32):$dst, ICC:Flag) 1080 // Emits: (CALL:void (tglobaladdr:i32):$dst) 1081 // Pattern complexity = 2 cost = 1 1082 SDOperand N1 = N->getOperand(1); 1083 if (N1.getOpcode() != ISD::TargetGlobalAddress && 1084 N1.getOpcode() != ISD::ExternalSymbol) goto P47Fail; 1085 SDOperand InFlag = SDOperand(0, 0); 1086 SDOperand Chain = N->getOperand(0); 1087 SDOperand Tmp0 = N1; 1088 Chain = Select(Chain); 1089 SDOperand Result; 1090 if (N->getNumOperands() == 3) { 1091 InFlag = Select(N->getOperand(2)); 1092 Result = CurDAG->getTargetNode(V8::CALL, MVT::Other, MVT::Flag, Tmp0, 1093 Chain, InFlag); 1094 } else { 1095 Result = CurDAG->getTargetNode(V8::CALL, MVT::Other, MVT::Flag, Tmp0, 1096 Chain); 1097 } 1098 Chain = CodeGenMap[SDOperand(N, 0)] = Result.getValue(0); 1099 CodeGenMap[SDOperand(N, 1)] = Result.getValue(1); 1100 return Result.getValue(Op.ResNo); 1101 } 1102 P47Fail:; 1103 1104 } 1105 1106 return SelectCode(Op); 1107} 1108 1109 1110/// createSparcV8ISelDag - This pass converts a legalized DAG into a 1111/// SPARC-specific DAG, ready for instruction scheduling. 1112/// 1113FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) { 1114 return new SparcV8DAGToDAGISel(TM); 1115} 1116