SparcISelDAGToDAG.cpp revision 384e5efc0e0b23a0d6c51f991a1b382be0414a8c
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 41 Hi, Lo, // Hi/Lo operations, typically on a global address. 42 43 FTOI, // FP to Int within a FP register. 44 ITOF, // Int to FP within a FP register. 45 46 SELECT_ICC, // Select between two values using the current ICC flags. 47 SELECT_FCC, // Select between two values using the current FCC flags. 48 }; 49} 50 51namespace { 52 class SparcV8TargetLowering : public TargetLowering { 53 public: 54 SparcV8TargetLowering(TargetMachine &TM); 55 virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); 56 virtual std::vector<SDOperand> 57 LowerArguments(Function &F, SelectionDAG &DAG); 58 virtual std::pair<SDOperand, SDOperand> 59 LowerCallTo(SDOperand Chain, const Type *RetTy, bool isVarArg, 60 unsigned CC, 61 bool isTailCall, SDOperand Callee, ArgListTy &Args, 62 SelectionDAG &DAG); 63 64 virtual SDOperand LowerReturnTo(SDOperand Chain, SDOperand Op, 65 SelectionDAG &DAG); 66 virtual SDOperand LowerVAStart(SDOperand Chain, SDOperand VAListP, 67 Value *VAListV, SelectionDAG &DAG); 68 virtual std::pair<SDOperand,SDOperand> 69 LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, 70 const Type *ArgTy, SelectionDAG &DAG); 71 virtual std::pair<SDOperand, SDOperand> 72 LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, 73 SelectionDAG &DAG); 74 virtual MachineBasicBlock *InsertAtEndOfBasicBlock(MachineInstr *MI, 75 MachineBasicBlock *MBB); 76 }; 77} 78 79SparcV8TargetLowering::SparcV8TargetLowering(TargetMachine &TM) 80 : TargetLowering(TM) { 81 82 // Set up the register classes. 83 addRegisterClass(MVT::i32, V8::IntRegsRegisterClass); 84 addRegisterClass(MVT::f32, V8::FPRegsRegisterClass); 85 addRegisterClass(MVT::f64, V8::DFPRegsRegisterClass); 86 87 // Custom legalize GlobalAddress nodes into LO/HI parts. 88 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 89 setOperationAction(ISD::ConstantPool , MVT::i32, Custom); 90 91 // Sparc doesn't have sext_inreg, replace them with shl/sra 92 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i16, Expand); 93 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i8 , Expand); 94 setOperationAction(ISD::SIGN_EXTEND_INREG, MVT::i1 , Expand); 95 96 // Sparc has no REM operation. 97 setOperationAction(ISD::UREM, MVT::i32, Expand); 98 setOperationAction(ISD::SREM, MVT::i32, Expand); 99 100 // Custom expand fp<->sint 101 setOperationAction(ISD::FP_TO_SINT, MVT::i32, Custom); 102 setOperationAction(ISD::SINT_TO_FP, MVT::i32, Custom); 103 104 // Expand fp<->uint 105 setOperationAction(ISD::FP_TO_UINT, MVT::i32, Expand); 106 setOperationAction(ISD::UINT_TO_FP, MVT::i32, Expand); 107 108 setOperationAction(ISD::EXTLOAD, MVT::f32, Expand); 109 110 // Sparc has no select or setcc: expand to SELECT_CC. 111 setOperationAction(ISD::SELECT, MVT::i32, Expand); 112 setOperationAction(ISD::SELECT, MVT::f32, Expand); 113 setOperationAction(ISD::SELECT, MVT::f64, Expand); 114 setOperationAction(ISD::SETCC, MVT::i32, Expand); 115 setOperationAction(ISD::SETCC, MVT::f32, Expand); 116 setOperationAction(ISD::SETCC, MVT::f64, Expand); 117 118 // Sparc doesn't have BRCOND either, it has BR_CC. 119 setOperationAction(ISD::BRCOND, MVT::Other, Expand); 120 setOperationAction(ISD::BRCONDTWOWAY, MVT::Other, Expand); 121 setOperationAction(ISD::BRTWOWAY_CC, MVT::Other, Expand); 122 setOperationAction(ISD::BR_CC, MVT::i32, Custom); 123 setOperationAction(ISD::BR_CC, MVT::f32, Custom); 124 setOperationAction(ISD::BR_CC, MVT::f64, Custom); 125 126 setOperationAction(ISD::SELECT_CC, MVT::i32, Custom); 127 setOperationAction(ISD::SELECT_CC, MVT::f32, Custom); 128 setOperationAction(ISD::SELECT_CC, MVT::f64, Custom); 129 130 computeRegisterProperties(); 131} 132 133/// LowerArguments - V8 uses a very simple ABI, where all values are passed in 134/// either one or two GPRs, including FP values. TODO: we should pass FP values 135/// in FP registers for fastcc functions. 136std::vector<SDOperand> 137SparcV8TargetLowering::LowerArguments(Function &F, SelectionDAG &DAG) { 138 MachineFunction &MF = DAG.getMachineFunction(); 139 SSARegMap *RegMap = MF.getSSARegMap(); 140 std::vector<SDOperand> ArgValues; 141 142 static const unsigned ArgRegs[] = { 143 V8::I0, V8::I1, V8::I2, V8::I3, V8::I4, V8::I5 144 }; 145 146 const unsigned *CurArgReg = ArgRegs, *ArgRegEnd = ArgRegs+6; 147 unsigned ArgOffset = 68; 148 149 SDOperand Root = DAG.getRoot(); 150 std::vector<SDOperand> OutChains; 151 152 for (Function::arg_iterator I = F.arg_begin(), E = F.arg_end(); I != E; ++I) { 153 MVT::ValueType ObjectVT = getValueType(I->getType()); 154 155 switch (ObjectVT) { 156 default: assert(0 && "Unhandled argument type!"); 157 // TODO: FP 158 case MVT::i1: 159 case MVT::i8: 160 case MVT::i16: 161 case MVT::i32: 162 if (I->use_empty()) { // Argument is dead. 163 if (CurArgReg < ArgRegEnd) ++CurArgReg; 164 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); 165 } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR 166 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 167 MF.addLiveIn(*CurArgReg++, VReg); 168 SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32); 169 if (ObjectVT != MVT::i32) { 170 unsigned AssertOp = I->getType()->isSigned() ? ISD::AssertSext 171 : ISD::AssertZext; 172 Arg = DAG.getNode(AssertOp, MVT::i32, Arg, 173 DAG.getValueType(ObjectVT)); 174 Arg = DAG.getNode(ISD::TRUNCATE, ObjectVT, Arg); 175 } 176 ArgValues.push_back(Arg); 177 } else { 178 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); 179 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 180 SDOperand Load; 181 if (ObjectVT == MVT::i32) { 182 Load = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0)); 183 } else { 184 unsigned LoadOp = 185 I->getType()->isSigned() ? ISD::SEXTLOAD : ISD::ZEXTLOAD; 186 187 Load = DAG.getExtLoad(LoadOp, MVT::i32, Root, FIPtr, 188 DAG.getSrcValue(0), ObjectVT); 189 } 190 ArgValues.push_back(Load); 191 } 192 193 ArgOffset += 4; 194 break; 195 case MVT::f32: 196 if (I->use_empty()) { // Argument is dead. 197 if (CurArgReg < ArgRegEnd) ++CurArgReg; 198 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); 199 } else if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR 200 // FP value is passed in an integer register. 201 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 202 MF.addLiveIn(*CurArgReg++, VReg); 203 SDOperand Arg = DAG.getCopyFromReg(Root, VReg, MVT::i32); 204 205 // We use the stack space that is already reserved for this reg. 206 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); 207 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 208 209 SDOperand SV = DAG.getSrcValue(0); 210 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Root, 211 Arg, FIPtr, SV); 212 ArgValues.push_back(DAG.getLoad(MVT::f32, Store, FIPtr, SV)); 213 } 214 ArgOffset += 4; 215 break; 216 217 case MVT::i64: 218 case MVT::f64: 219 if (I->use_empty()) { // Argument is dead. 220 if (CurArgReg < ArgRegEnd) ++CurArgReg; 221 if (CurArgReg < ArgRegEnd) ++CurArgReg; 222 ArgValues.push_back(DAG.getNode(ISD::UNDEF, ObjectVT)); 223 } else if (CurArgReg == ArgRegEnd && ObjectVT == MVT::f64 && 224 ((CurArgReg-ArgRegs) & 1) == 0) { 225 // If this is a double argument and the whole thing lives on the stack, 226 // and the argument is aligned, load the double straight from the stack. 227 // We can't do a load in cases like void foo([6ints], int,double), 228 // because the double wouldn't be aligned! 229 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(8, ArgOffset); 230 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 231 ArgValues.push_back(DAG.getLoad(MVT::f64, Root, FIPtr, 232 DAG.getSrcValue(0))); 233 } else { 234 SDOperand HiVal; 235 if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR 236 unsigned VRegHi = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 237 MF.addLiveIn(*CurArgReg++, VRegHi); 238 HiVal = DAG.getCopyFromReg(Root, VRegHi, MVT::i32); 239 } else { 240 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); 241 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 242 HiVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0)); 243 } 244 245 SDOperand LoVal; 246 if (CurArgReg < ArgRegEnd) { // Lives in an incoming GPR 247 unsigned VRegLo = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 248 MF.addLiveIn(*CurArgReg++, VRegLo); 249 LoVal = DAG.getCopyFromReg(Root, VRegLo, MVT::i32); 250 } else { 251 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset+4); 252 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 253 LoVal = DAG.getLoad(MVT::i32, Root, FIPtr, DAG.getSrcValue(0)); 254 } 255 256 // Compose the two halves together into an i64 unit. 257 SDOperand WholeValue = 258 DAG.getNode(ISD::BUILD_PAIR, MVT::i64, LoVal, HiVal); 259 260 if (ObjectVT == MVT::i64) { 261 // If we are emitting an i64, this is what we want. 262 ArgValues.push_back(WholeValue); 263 } else { 264 assert(ObjectVT == MVT::f64); 265 // Otherwise, emit a store to the stack and reload into FPR. 266 int FrameIdx = MF.getFrameInfo()->CreateStackObject(8, 8); 267 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 268 SDOperand SV = DAG.getSrcValue(0); 269 SDOperand Store = DAG.getNode(ISD::STORE, MVT::Other, Root, 270 WholeValue, FIPtr, SV); 271 ArgValues.push_back(DAG.getLoad(MVT::f64, Store, FIPtr, SV)); 272 } 273 } 274 ArgOffset += 8; 275 break; 276 } 277 } 278 279 // Store remaining ArgRegs to the stack if this is a varargs function. 280 if (F.getFunctionType()->isVarArg()) { 281 for (; CurArgReg != ArgRegEnd; ++CurArgReg) { 282 unsigned VReg = RegMap->createVirtualRegister(&V8::IntRegsRegClass); 283 MF.addLiveIn(*CurArgReg, VReg); 284 SDOperand Arg = DAG.getCopyFromReg(DAG.getRoot(), VReg, MVT::i32); 285 286 int FrameIdx = MF.getFrameInfo()->CreateFixedObject(4, ArgOffset); 287 SDOperand FIPtr = DAG.getFrameIndex(FrameIdx, MVT::i32); 288 289 OutChains.push_back(DAG.getNode(ISD::STORE, MVT::Other, DAG.getRoot(), 290 Arg, FIPtr, DAG.getSrcValue(0))); 291 ArgOffset += 4; 292 } 293 } 294 295 if (!OutChains.empty()) 296 DAG.setRoot(DAG.getNode(ISD::TokenFactor, MVT::Other, OutChains)); 297 298 // Finally, inform the code generator which regs we return values in. 299 switch (getValueType(F.getReturnType())) { 300 default: assert(0 && "Unknown type!"); 301 case MVT::isVoid: break; 302 case MVT::i1: 303 case MVT::i8: 304 case MVT::i16: 305 case MVT::i32: 306 MF.addLiveOut(V8::I0); 307 break; 308 case MVT::i64: 309 MF.addLiveOut(V8::I0); 310 MF.addLiveOut(V8::I1); 311 break; 312 case MVT::f32: 313 MF.addLiveOut(V8::F0); 314 break; 315 case MVT::f64: 316 MF.addLiveOut(V8::D0); 317 break; 318 } 319 320 return ArgValues; 321} 322 323std::pair<SDOperand, SDOperand> 324SparcV8TargetLowering::LowerCallTo(SDOperand Chain, const Type *RetTy, 325 bool isVarArg, unsigned CC, 326 bool isTailCall, SDOperand Callee, 327 ArgListTy &Args, SelectionDAG &DAG) { 328 assert(0 && "Unimp"); 329 abort(); 330} 331 332SDOperand SparcV8TargetLowering::LowerReturnTo(SDOperand Chain, SDOperand Op, 333 SelectionDAG &DAG) { 334 if (Op.getValueType() == MVT::i64) { 335 SDOperand Hi = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 336 DAG.getConstant(1, MVT::i32)); 337 SDOperand Lo = DAG.getNode(ISD::EXTRACT_ELEMENT, MVT::i32, Op, 338 DAG.getConstant(0, MVT::i32)); 339 return DAG.getNode(ISD::RET, MVT::Other, Chain, Lo, Hi); 340 } else { 341 return DAG.getNode(ISD::RET, MVT::Other, Chain, Op); 342 } 343} 344 345SDOperand SparcV8TargetLowering:: 346LowerVAStart(SDOperand Chain, SDOperand VAListP, Value *VAListV, 347 SelectionDAG &DAG) { 348 349 assert(0 && "Unimp"); 350 abort(); 351} 352 353std::pair<SDOperand,SDOperand> SparcV8TargetLowering:: 354LowerVAArg(SDOperand Chain, SDOperand VAListP, Value *VAListV, 355 const Type *ArgTy, SelectionDAG &DAG) { 356 assert(0 && "Unimp"); 357 abort(); 358} 359 360std::pair<SDOperand, SDOperand> SparcV8TargetLowering:: 361LowerFrameReturnAddress(bool isFrameAddr, SDOperand Chain, unsigned Depth, 362 SelectionDAG &DAG) { 363 assert(0 && "Unimp"); 364 abort(); 365} 366 367SDOperand SparcV8TargetLowering:: 368LowerOperation(SDOperand Op, SelectionDAG &DAG) { 369 switch (Op.getOpcode()) { 370 default: assert(0 && "Should not custom lower this!"); 371 case ISD::GlobalAddress: { 372 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 373 SDOperand GA = DAG.getTargetGlobalAddress(GV, MVT::i32); 374 SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, GA); 375 SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, GA); 376 return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); 377 } 378 case ISD::ConstantPool: { 379 Constant *C = cast<ConstantPoolSDNode>(Op)->get(); 380 SDOperand CP = DAG.getTargetConstantPool(C, MVT::i32); 381 SDOperand Hi = DAG.getNode(V8ISD::Hi, MVT::i32, CP); 382 SDOperand Lo = DAG.getNode(V8ISD::Lo, MVT::i32, CP); 383 return DAG.getNode(ISD::ADD, MVT::i32, Lo, Hi); 384 } 385 case ISD::FP_TO_SINT: { 386 // Convert the fp value to integer in an FP register. 387 Op = DAG.getNode(V8ISD::FTOI, Op.getOperand(0).getValueType(), 388 Op.getOperand(0)); 389 int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8; 390 int FrameIdx = 391 DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size); 392 SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); 393 SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), 394 Op, FI, DAG.getSrcValue(0)); 395 return DAG.getLoad(MVT::i32, ST, FI, DAG.getSrcValue(0)); 396 } 397 case ISD::SINT_TO_FP: { 398 int Size = Op.getOperand(0).getValueType() == MVT::f32 ? 4 : 8; 399 int FrameIdx = 400 DAG.getMachineFunction().getFrameInfo()->CreateStackObject(Size, Size); 401 SDOperand FI = DAG.getFrameIndex(FrameIdx, MVT::i32); 402 SDOperand ST = DAG.getNode(ISD::STORE, MVT::Other, DAG.getEntryNode(), 403 Op.getOperand(0), FI, DAG.getSrcValue(0)); 404 405 Op = DAG.getLoad(Op.getValueType(), ST, FI, DAG.getSrcValue(0)); 406 407 // Convert the int value to FP in an FP register. 408 return DAG.getNode(V8ISD::ITOF, Op.getValueType(), Op); 409 } 410 case ISD::BR_CC: { 411 SDOperand Chain = Op.getOperand(0); 412 SDOperand CC = Op.getOperand(1); 413 SDOperand LHS = Op.getOperand(2); 414 SDOperand RHS = Op.getOperand(3); 415 SDOperand Dest = Op.getOperand(4); 416 417 // Get the condition flag. 418 if (LHS.getValueType() == MVT::i32) { 419 SDOperand Cond = DAG.getNode(V8ISD::CMPICC, MVT::Flag, LHS, RHS); 420 return DAG.getNode(V8ISD::BRICC, MVT::Other, Chain, Dest, CC, Cond); 421 } else { 422 SDOperand Cond = DAG.getNode(V8ISD::CMPFCC, MVT::Flag, LHS, RHS); 423 return DAG.getNode(V8ISD::BRFCC, MVT::Other, Chain, Dest, CC, Cond); 424 } 425 } 426 case ISD::SELECT_CC: { 427 SDOperand LHS = Op.getOperand(0); 428 SDOperand RHS = Op.getOperand(1); 429 unsigned CC = cast<CondCodeSDNode>(Op.getOperand(4))->get(); 430 SDOperand TrueVal = Op.getOperand(2); 431 SDOperand FalseVal = Op.getOperand(3); 432 433 unsigned Opc; 434 Opc = LHS.getValueType() == MVT::i32 ? V8ISD::CMPICC : V8ISD::CMPFCC; 435 SDOperand CompareFlag = DAG.getNode(Opc, MVT::Flag, LHS, RHS); 436 437 Opc = LHS.getValueType() == MVT::i32 ? 438 V8ISD::SELECT_ICC : V8ISD::SELECT_FCC; 439 return DAG.getNode(Opc, TrueVal.getValueType(), TrueVal, FalseVal, 440 DAG.getConstant(CC, MVT::i32), CompareFlag); 441 } 442 } 443} 444 445MachineBasicBlock * 446SparcV8TargetLowering::InsertAtEndOfBasicBlock(MachineInstr *MI, 447 MachineBasicBlock *BB) { 448 unsigned BROpcode; 449 // Figure out the conditional branch opcode to use for this select_cc. 450 switch (MI->getOpcode()) { 451 default: assert(0 && "Unknown SELECT_CC!"); 452 case V8::SELECT_CC_Int_ICC: 453 case V8::SELECT_CC_FP_ICC: 454 case V8::SELECT_CC_DFP_ICC: 455 // Integer compare. 456 switch ((ISD::CondCode)MI->getOperand(3).getImmedValue()) { 457 default: assert(0 && "Unknown integer condition code!"); 458 case ISD::SETEQ: BROpcode = V8::BE; break; 459 case ISD::SETNE: BROpcode = V8::BNE; break; 460 case ISD::SETLT: BROpcode = V8::BL; break; 461 case ISD::SETGT: BROpcode = V8::BG; break; 462 case ISD::SETLE: BROpcode = V8::BLE; break; 463 case ISD::SETGE: BROpcode = V8::BGE; break; 464 case ISD::SETULT: BROpcode = V8::BCS; break; 465 case ISD::SETULE: BROpcode = V8::BLEU; break; 466 case ISD::SETUGT: BROpcode = V8::BGU; break; 467 case ISD::SETUGE: BROpcode = V8::BCC; break; 468 } 469 break; 470 case V8::SELECT_CC_Int_FCC: 471 case V8::SELECT_CC_FP_FCC: 472 case V8::SELECT_CC_DFP_FCC: 473 // FP compare. 474 switch ((ISD::CondCode)MI->getOperand(3).getImmedValue()) { 475 default: assert(0 && "Unknown fp condition code!"); 476 case ISD::SETEQ: BROpcode = V8::FBE; break; 477 case ISD::SETNE: BROpcode = V8::FBNE; break; 478 case ISD::SETLT: BROpcode = V8::FBL; break; 479 case ISD::SETGT: BROpcode = V8::FBG; break; 480 case ISD::SETLE: BROpcode = V8::FBLE; break; 481 case ISD::SETGE: BROpcode = V8::FBGE; break; 482 case ISD::SETULT: BROpcode = V8::FBUL; break; 483 case ISD::SETULE: BROpcode = V8::FBULE; break; 484 case ISD::SETUGT: BROpcode = V8::FBUG; break; 485 case ISD::SETUGE: BROpcode = V8::FBUGE; break; 486 case ISD::SETUO: BROpcode = V8::FBU; break; 487 case ISD::SETO: BROpcode = V8::FBO; break; 488 case ISD::SETONE: BROpcode = V8::FBLG; break; 489 case ISD::SETUEQ: BROpcode = V8::FBUE; break; 490 } 491 break; 492 } 493 494 // To "insert" a SELECT_CC instruction, we actually have to insert the diamond 495 // control-flow pattern. The incoming instruction knows the destination vreg 496 // to set, the condition code register to branch on, the true/false values to 497 // select between, and a branch opcode to use. 498 const BasicBlock *LLVM_BB = BB->getBasicBlock(); 499 ilist<MachineBasicBlock>::iterator It = BB; 500 ++It; 501 502 // thisMBB: 503 // ... 504 // TrueVal = ... 505 // [f]bCC copy1MBB 506 // fallthrough --> copy0MBB 507 MachineBasicBlock *thisMBB = BB; 508 MachineBasicBlock *copy0MBB = new MachineBasicBlock(LLVM_BB); 509 MachineBasicBlock *sinkMBB = new MachineBasicBlock(LLVM_BB); 510 BuildMI(BB, BROpcode, 1).addMBB(sinkMBB); 511 MachineFunction *F = BB->getParent(); 512 F->getBasicBlockList().insert(It, copy0MBB); 513 F->getBasicBlockList().insert(It, sinkMBB); 514 // Update machine-CFG edges 515 BB->addSuccessor(copy0MBB); 516 BB->addSuccessor(sinkMBB); 517 518 // copy0MBB: 519 // %FalseValue = ... 520 // # fallthrough to sinkMBB 521 BB = copy0MBB; 522 523 // Update machine-CFG edges 524 BB->addSuccessor(sinkMBB); 525 526 // sinkMBB: 527 // %Result = phi [ %FalseValue, copy0MBB ], [ %TrueValue, thisMBB ] 528 // ... 529 BB = sinkMBB; 530 BuildMI(BB, V8::PHI, 4, MI->getOperand(0).getReg()) 531 .addReg(MI->getOperand(2).getReg()).addMBB(copy0MBB) 532 .addReg(MI->getOperand(1).getReg()).addMBB(thisMBB); 533 534 delete MI; // The pseudo instruction is gone now. 535 return BB; 536} 537 538//===----------------------------------------------------------------------===// 539// Instruction Selector Implementation 540//===----------------------------------------------------------------------===// 541 542//===--------------------------------------------------------------------===// 543/// SparcV8DAGToDAGISel - PPC specific code to select Sparc V8 machine 544/// instructions for SelectionDAG operations. 545/// 546namespace { 547class SparcV8DAGToDAGISel : public SelectionDAGISel { 548 SparcV8TargetLowering V8Lowering; 549public: 550 SparcV8DAGToDAGISel(TargetMachine &TM) 551 : SelectionDAGISel(V8Lowering), V8Lowering(TM) {} 552 553 SDOperand Select(SDOperand Op); 554 555 // Complex Pattern Selectors. 556 bool SelectADDRrr(SDOperand N, SDOperand &R1, SDOperand &R2); 557 bool SelectADDRri(SDOperand N, SDOperand &Base, SDOperand &Offset); 558 559 /// InstructionSelectBasicBlock - This callback is invoked by 560 /// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 561 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 562 563 virtual const char *getPassName() const { 564 return "PowerPC DAG->DAG Pattern Instruction Selection"; 565 } 566 567 // Include the pieces autogenerated from the target description. 568#include "SparcV8GenDAGISel.inc" 569}; 570} // end anonymous namespace 571 572/// InstructionSelectBasicBlock - This callback is invoked by 573/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 574void SparcV8DAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { 575 DEBUG(BB->dump()); 576 577 // Select target instructions for the DAG. 578 DAG.setRoot(Select(DAG.getRoot())); 579 CodeGenMap.clear(); 580 DAG.RemoveDeadNodes(); 581 582 // Emit machine code to BB. 583 ScheduleAndEmitDAG(DAG); 584} 585 586bool SparcV8DAGToDAGISel::SelectADDRri(SDOperand Addr, SDOperand &Base, 587 SDOperand &Offset) { 588 if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 589 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 590 Offset = CurDAG->getTargetConstant(0, MVT::i32); 591 return true; 592 } 593 594 if (Addr.getOpcode() == ISD::ADD) { 595 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1))) { 596 if (Predicate_simm13(CN)) { 597 if (FrameIndexSDNode *FIN = 598 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) { 599 // Constant offset from frame ref. 600 Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), MVT::i32); 601 } else { 602 Base = Select(Addr.getOperand(0)); 603 } 604 Offset = CurDAG->getTargetConstant(CN->getValue(), MVT::i32); 605 return true; 606 } 607 } 608 if (Addr.getOperand(0).getOpcode() == V8ISD::Lo) { 609 Base = Select(Addr.getOperand(1)); 610 Offset = Addr.getOperand(0).getOperand(0); 611 return true; 612 } 613 if (Addr.getOperand(1).getOpcode() == V8ISD::Lo) { 614 Base = Select(Addr.getOperand(0)); 615 Offset = Addr.getOperand(1).getOperand(0); 616 return true; 617 } 618 } 619 Base = Select(Addr); 620 Offset = CurDAG->getTargetConstant(0, MVT::i32); 621 return true; 622} 623 624bool SparcV8DAGToDAGISel::SelectADDRrr(SDOperand Addr, SDOperand &R1, 625 SDOperand &R2) { 626 if (Addr.getOpcode() == ISD::FrameIndex) return false; 627 if (Addr.getOpcode() == ISD::ADD) { 628 if (isa<ConstantSDNode>(Addr.getOperand(1)) && 629 Predicate_simm13(Addr.getOperand(1).Val)) 630 return false; // Let the reg+imm pattern catch this! 631 if (Addr.getOperand(0).getOpcode() == V8ISD::Lo || 632 Addr.getOperand(1).getOpcode() == V8ISD::Lo) 633 return false; // Let the reg+imm pattern catch this! 634 R1 = Select(Addr.getOperand(0)); 635 R2 = Select(Addr.getOperand(1)); 636 return true; 637 } 638 639 R1 = Select(Addr); 640 R2 = CurDAG->getRegister(V8::G0, MVT::i32); 641 return true; 642} 643 644SDOperand SparcV8DAGToDAGISel::Select(SDOperand Op) { 645 SDNode *N = Op.Val; 646 if (N->getOpcode() >= ISD::BUILTIN_OP_END && 647 N->getOpcode() < V8ISD::FIRST_NUMBER) 648 return Op; // Already selected. 649 // If this has already been converted, use it. 650 std::map<SDOperand, SDOperand>::iterator CGMI = CodeGenMap.find(Op); 651 if (CGMI != CodeGenMap.end()) return CGMI->second; 652 653 switch (N->getOpcode()) { 654 default: break; 655 case ISD::BasicBlock: return CodeGenMap[Op] = Op; 656 case ISD::FrameIndex: { 657 int FI = cast<FrameIndexSDNode>(N)->getIndex(); 658 if (N->hasOneUse()) 659 return CurDAG->SelectNodeTo(N, V8::ADDri, MVT::i32, 660 CurDAG->getTargetFrameIndex(FI, MVT::i32), 661 CurDAG->getTargetConstant(0, MVT::i32)); 662 return CodeGenMap[Op] = 663 CurDAG->getTargetNode(V8::ADDri, MVT::i32, 664 CurDAG->getTargetFrameIndex(FI, MVT::i32), 665 CurDAG->getTargetConstant(0, MVT::i32)); 666 } 667 case V8ISD::CMPICC: { 668 // FIXME: Handle compare with immediate. 669 SDOperand LHS = Select(N->getOperand(0)); 670 SDOperand RHS = Select(N->getOperand(1)); 671 SDOperand Result = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag, 672 LHS, RHS); 673 return CodeGenMap[Op] = Result.getValue(1); 674 } 675 case ISD::ADD_PARTS: { 676 SDOperand LHSL = Select(N->getOperand(0)); 677 SDOperand LHSH = Select(N->getOperand(1)); 678 SDOperand RHSL = Select(N->getOperand(2)); 679 SDOperand RHSH = Select(N->getOperand(3)); 680 // FIXME, handle immediate RHS. 681 SDOperand Low = CurDAG->getTargetNode(V8::ADDCCrr, MVT::i32, MVT::Flag, 682 LHSL, RHSL); 683 SDOperand Hi = CurDAG->getTargetNode(V8::ADDXrr, MVT::i32, LHSH, RHSH, 684 Low.getValue(1)); 685 CodeGenMap[SDOperand(N, 0)] = Low; 686 CodeGenMap[SDOperand(N, 1)] = Hi; 687 return Op.ResNo ? Hi : Low; 688 } 689 case ISD::SUB_PARTS: { 690 SDOperand LHSL = Select(N->getOperand(0)); 691 SDOperand LHSH = Select(N->getOperand(1)); 692 SDOperand RHSL = Select(N->getOperand(2)); 693 SDOperand RHSH = Select(N->getOperand(3)); 694 // FIXME, handle immediate RHS. 695 SDOperand Low = CurDAG->getTargetNode(V8::SUBCCrr, MVT::i32, MVT::Flag, 696 LHSL, RHSL); 697 SDOperand Hi = CurDAG->getTargetNode(V8::SUBXrr, MVT::i32, LHSH, RHSH, 698 Low.getValue(1)); 699 CodeGenMap[SDOperand(N, 0)] = Low; 700 CodeGenMap[SDOperand(N, 1)] = Hi; 701 return Op.ResNo ? Hi : Low; 702 } 703 case ISD::SDIV: 704 case ISD::UDIV: { 705 // FIXME: should use a custom expander to expose the SRA to the dag. 706 SDOperand DivLHS = Select(N->getOperand(0)); 707 SDOperand DivRHS = Select(N->getOperand(1)); 708 709 // Set the Y register to the high-part. 710 SDOperand TopPart; 711 if (N->getOpcode() == ISD::SDIV) { 712 TopPart = CurDAG->getTargetNode(V8::SRAri, MVT::i32, DivLHS, 713 CurDAG->getTargetConstant(31, MVT::i32)); 714 } else { 715 TopPart = CurDAG->getRegister(V8::G0, MVT::i32); 716 } 717 TopPart = CurDAG->getTargetNode(V8::WRYrr, MVT::Flag, TopPart, 718 CurDAG->getRegister(V8::G0, MVT::i32)); 719 720 // FIXME: Handle div by immediate. 721 unsigned Opcode = N->getOpcode() == ISD::SDIV ? V8::SDIVrr : V8::UDIVrr; 722 return CurDAG->SelectNodeTo(N, Opcode, MVT::i32, DivLHS, DivRHS, TopPart); 723 } 724 case ISD::MULHU: 725 case ISD::MULHS: { 726 // FIXME: Handle mul by immediate. 727 SDOperand MulLHS = Select(N->getOperand(0)); 728 SDOperand MulRHS = Select(N->getOperand(1)); 729 unsigned Opcode = N->getOpcode() == ISD::MULHU ? V8::UMULrr : V8::SMULrr; 730 SDOperand Mul = CurDAG->getTargetNode(Opcode, MVT::i32, MVT::Flag, 731 MulLHS, MulRHS); 732 // The high part is in the Y register. 733 return CurDAG->SelectNodeTo(N, V8::RDY, MVT::i32, Mul.getValue(1)); 734 } 735 736 case ISD::RET: { 737 if (N->getNumOperands() == 2) { 738 SDOperand Chain = Select(N->getOperand(0)); // Token chain. 739 SDOperand Val = Select(N->getOperand(1)); 740 if (N->getOperand(1).getValueType() == MVT::i32) { 741 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Val); 742 } else if (N->getOperand(1).getValueType() == MVT::f32) { 743 Chain = CurDAG->getCopyToReg(Chain, V8::F0, Val); 744 } else { 745 assert(N->getOperand(1).getValueType() == MVT::f64); 746 Chain = CurDAG->getCopyToReg(Chain, V8::D0, Val); 747 } 748 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain); 749 } else if (N->getNumOperands() > 1) { 750 SDOperand Chain = Select(N->getOperand(0)); // Token chain. 751 assert(N->getOperand(1).getValueType() == MVT::i32 && 752 N->getOperand(2).getValueType() == MVT::i32 && 753 N->getNumOperands() == 3 && "Unknown two-register ret value!"); 754 Chain = CurDAG->getCopyToReg(Chain, V8::I1, Select(N->getOperand(1))); 755 Chain = CurDAG->getCopyToReg(Chain, V8::I0, Select(N->getOperand(2))); 756 return CurDAG->SelectNodeTo(N, V8::RETL, MVT::Other, Chain); 757 } 758 break; // Generated code handles the void case. 759 } 760 } 761 762 return SelectCode(Op); 763} 764 765 766/// createPPCISelDag - This pass converts a legalized DAG into a 767/// PowerPC-specific DAG, ready for instruction scheduling. 768/// 769FunctionPass *llvm::createSparcV8ISelDag(TargetMachine &TM) { 770 return new SparcV8DAGToDAGISel(TM); 771} 772