MipsISelDAGToDAG.cpp revision 243830
1234353Sdim//===-- MipsISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips --------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file defines an instruction selector for the MIPS target. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#define DEBUG_TYPE "mips-isel" 15193323Sed#include "Mips.h" 16234353Sdim#include "MipsAnalyzeImmediate.h" 17193323Sed#include "MipsMachineFunction.h" 18193323Sed#include "MipsRegisterInfo.h" 19193323Sed#include "MipsSubtarget.h" 20193323Sed#include "MipsTargetMachine.h" 21234353Sdim#include "MCTargetDesc/MipsBaseInfo.h" 22193323Sed#include "llvm/GlobalValue.h" 23193323Sed#include "llvm/Instructions.h" 24193323Sed#include "llvm/Intrinsics.h" 25193323Sed#include "llvm/Support/CFG.h" 26193323Sed#include "llvm/Type.h" 27193323Sed#include "llvm/CodeGen/MachineConstantPool.h" 28193323Sed#include "llvm/CodeGen/MachineFunction.h" 29193323Sed#include "llvm/CodeGen/MachineFrameInfo.h" 30193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 31193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h" 32193323Sed#include "llvm/CodeGen/SelectionDAGISel.h" 33234353Sdim#include "llvm/CodeGen/SelectionDAGNodes.h" 34193323Sed#include "llvm/Target/TargetMachine.h" 35193323Sed#include "llvm/Support/Debug.h" 36198090Srdivacky#include "llvm/Support/ErrorHandling.h" 37198090Srdivacky#include "llvm/Support/raw_ostream.h" 38193323Sedusing namespace llvm; 39193323Sed 40193323Sed//===----------------------------------------------------------------------===// 41193323Sed// Instruction Selector Implementation 42193323Sed//===----------------------------------------------------------------------===// 43193323Sed 44193323Sed//===----------------------------------------------------------------------===// 45193323Sed// MipsDAGToDAGISel - MIPS specific code to select MIPS machine 46193323Sed// instructions for SelectionDAG operations. 47193323Sed//===----------------------------------------------------------------------===// 48193323Sednamespace { 49193323Sed 50198892Srdivackyclass MipsDAGToDAGISel : public SelectionDAGISel { 51193323Sed 52193323Sed /// TM - Keep a reference to MipsTargetMachine. 53193323Sed MipsTargetMachine &TM; 54193323Sed 55193323Sed /// Subtarget - Keep a pointer to the MipsSubtarget around so that we can 56193323Sed /// make the right decision when generating code for different targets. 57193323Sed const MipsSubtarget &Subtarget; 58221345Sdim 59193323Sedpublic: 60193323Sed explicit MipsDAGToDAGISel(MipsTargetMachine &tm) : 61193323Sed SelectionDAGISel(tm), 62193323Sed TM(tm), Subtarget(tm.getSubtarget<MipsSubtarget>()) {} 63221345Sdim 64193323Sed // Pass Name 65193323Sed virtual const char *getPassName() const { 66193323Sed return "MIPS DAG->DAG Pattern Instruction Selection"; 67221345Sdim } 68193323Sed 69234353Sdim virtual bool runOnMachineFunction(MachineFunction &MF); 70221345Sdim 71221345Sdimprivate: 72193323Sed // Include the pieces autogenerated from the target description. 73193323Sed #include "MipsGenDAGISel.inc" 74193323Sed 75193399Sed /// getTargetMachine - Return a reference to the TargetMachine, casted 76193399Sed /// to the target-specific type. 77193399Sed const MipsTargetMachine &getTargetMachine() { 78193399Sed return static_cast<const MipsTargetMachine &>(TM); 79193399Sed } 80193399Sed 81193399Sed /// getInstrInfo - Return a reference to the TargetInstrInfo, casted 82193399Sed /// to the target-specific type. 83193399Sed const MipsInstrInfo *getInstrInfo() { 84193399Sed return getTargetMachine().getInstrInfo(); 85193399Sed } 86193399Sed 87193399Sed SDNode *getGlobalBaseReg(); 88234353Sdim 89243830Sdim SDValue getMips16SPAliasReg(); 90243830Sdim 91243830Sdim void getMips16SPRefReg(SDNode *parent, SDValue &AliasReg); 92243830Sdim 93234353Sdim std::pair<SDNode*, SDNode*> SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, 94234353Sdim EVT Ty, bool HasLo, bool HasHi); 95234353Sdim 96202375Srdivacky SDNode *Select(SDNode *N); 97193323Sed 98193323Sed // Complex Pattern. 99234353Sdim bool SelectAddr(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Offset); 100193323Sed 101243830Sdim bool SelectAddr16(SDNode *Parent, SDValue N, SDValue &Base, SDValue &Offset, 102243830Sdim SDValue &Alias); 103243830Sdim 104234353Sdim // getImm - Return a target constant with the specified value. 105234353Sdim inline SDValue getImm(const SDNode *Node, unsigned Imm) { 106234353Sdim return CurDAG->getTargetConstant(Imm, Node->getValueType(0)); 107193323Sed } 108224145Sdim 109234353Sdim void ProcessFunctionAfterISel(MachineFunction &MF); 110234353Sdim bool ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI, const MachineInstr&); 111234353Sdim void InitGlobalBaseReg(MachineFunction &MF); 112243830Sdim void InitMips16SPAliasReg(MachineFunction &MF); 113234353Sdim 114224145Sdim virtual bool SelectInlineAsmMemoryOperand(const SDValue &Op, 115224145Sdim char ConstraintCode, 116224145Sdim std::vector<SDValue> &OutOps); 117193323Sed}; 118193323Sed 119193323Sed} 120193323Sed 121234353Sdim// Insert instructions to initialize the global base register in the 122234353Sdim// first MBB of the function. When the ABI is O32 and the relocation model is 123234353Sdim// PIC, the necessary instructions are emitted later to prevent optimization 124234353Sdim// passes from moving them. 125234353Sdimvoid MipsDAGToDAGISel::InitGlobalBaseReg(MachineFunction &MF) { 126234353Sdim MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 127193323Sed 128234353Sdim if (!MipsFI->globalBaseRegSet()) 129234353Sdim return; 130234353Sdim 131234353Sdim MachineBasicBlock &MBB = MF.front(); 132234353Sdim MachineBasicBlock::iterator I = MBB.begin(); 133234353Sdim MachineRegisterInfo &RegInfo = MF.getRegInfo(); 134234353Sdim const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 135234353Sdim DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 136239462Sdim unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg(); 137239462Sdim const TargetRegisterClass *RC; 138234353Sdim 139239462Sdim if (Subtarget.isABI_N64()) 140239462Sdim RC = (const TargetRegisterClass*)&Mips::CPU64RegsRegClass; 141239462Sdim else if (Subtarget.inMips16Mode()) 142239462Sdim RC = (const TargetRegisterClass*)&Mips::CPU16RegsRegClass; 143239462Sdim else 144239462Sdim RC = (const TargetRegisterClass*)&Mips::CPURegsRegClass; 145234353Sdim 146239462Sdim V0 = RegInfo.createVirtualRegister(RC); 147239462Sdim V1 = RegInfo.createVirtualRegister(RC); 148239462Sdim V2 = RegInfo.createVirtualRegister(RC); 149234353Sdim 150234353Sdim if (Subtarget.isABI_N64()) { 151234353Sdim MF.getRegInfo().addLiveIn(Mips::T9_64); 152234353Sdim MBB.addLiveIn(Mips::T9_64); 153234353Sdim 154234353Sdim // lui $v0, %hi(%neg(%gp_rel(fname))) 155234353Sdim // daddu $v1, $v0, $t9 156234353Sdim // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname))) 157234353Sdim const GlobalValue *FName = MF.getFunction(); 158234353Sdim BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0) 159234353Sdim .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); 160239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0) 161239462Sdim .addReg(Mips::T9_64); 162234353Sdim BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1) 163234353Sdim .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); 164239462Sdim return; 165239462Sdim } 166239462Sdim 167239462Sdim if (Subtarget.inMips16Mode()) { 168239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0) 169239462Sdim .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI); 170239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), V1) 171239462Sdim .addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); 172239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16); 173239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg) 174239462Sdim .addReg(V1).addReg(V2); 175239462Sdim return; 176239462Sdim } 177239462Sdim 178239462Sdim if (MF.getTarget().getRelocationModel() == Reloc::Static) { 179234353Sdim // Set global register to __gnu_local_gp. 180234353Sdim // 181234353Sdim // lui $v0, %hi(__gnu_local_gp) 182234353Sdim // addiu $globalbasereg, $v0, %lo(__gnu_local_gp) 183234353Sdim BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0) 184234353Sdim .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI); 185234353Sdim BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0) 186234353Sdim .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO); 187239462Sdim return; 188239462Sdim } 189234353Sdim 190239462Sdim MF.getRegInfo().addLiveIn(Mips::T9); 191239462Sdim MBB.addLiveIn(Mips::T9); 192234353Sdim 193239462Sdim if (Subtarget.isABI_N32()) { 194239462Sdim // lui $v0, %hi(%neg(%gp_rel(fname))) 195239462Sdim // addu $v1, $v0, $t9 196239462Sdim // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname))) 197239462Sdim const GlobalValue *FName = MF.getFunction(); 198239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0) 199239462Sdim .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); 200239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9); 201239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1) 202239462Sdim .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); 203239462Sdim return; 204234353Sdim } 205239462Sdim 206239462Sdim assert(Subtarget.isABI_O32()); 207239462Sdim 208239462Sdim // For O32 ABI, the following instruction sequence is emitted to initialize 209239462Sdim // the global base register: 210239462Sdim // 211239462Sdim // 0. lui $2, %hi(_gp_disp) 212239462Sdim // 1. addiu $2, $2, %lo(_gp_disp) 213239462Sdim // 2. addu $globalbasereg, $2, $t9 214239462Sdim // 215239462Sdim // We emit only the last instruction here. 216239462Sdim // 217239462Sdim // GNU linker requires that the first two instructions appear at the beginning 218239462Sdim // of a function and no instructions be inserted before or between them. 219239462Sdim // The two instructions are emitted during lowering to MC layer in order to 220239462Sdim // avoid any reordering. 221239462Sdim // 222239462Sdim // Register $2 (Mips::V0) is added to the list of live-in registers to ensure 223239462Sdim // the value instruction 1 (addiu) defines is valid when instruction 2 (addu) 224239462Sdim // reads it. 225239462Sdim MF.getRegInfo().addLiveIn(Mips::V0); 226239462Sdim MBB.addLiveIn(Mips::V0); 227239462Sdim BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg) 228239462Sdim .addReg(Mips::V0).addReg(Mips::T9); 229234353Sdim} 230234353Sdim 231243830Sdim// Insert instructions to initialize the Mips16 SP Alias register in the 232243830Sdim// first MBB of the function. 233243830Sdim// 234243830Sdimvoid MipsDAGToDAGISel::InitMips16SPAliasReg(MachineFunction &MF) { 235243830Sdim MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 236243830Sdim 237243830Sdim if (!MipsFI->mips16SPAliasRegSet()) 238243830Sdim return; 239243830Sdim 240243830Sdim MachineBasicBlock &MBB = MF.front(); 241243830Sdim MachineBasicBlock::iterator I = MBB.begin(); 242243830Sdim const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 243243830Sdim DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 244243830Sdim unsigned Mips16SPAliasReg = MipsFI->getMips16SPAliasReg(); 245243830Sdim 246243830Sdim BuildMI(MBB, I, DL, TII.get(Mips::MoveR3216), Mips16SPAliasReg) 247243830Sdim .addReg(Mips::SP); 248243830Sdim} 249243830Sdim 250243830Sdim 251234353Sdimbool MipsDAGToDAGISel::ReplaceUsesWithZeroReg(MachineRegisterInfo *MRI, 252234353Sdim const MachineInstr& MI) { 253234353Sdim unsigned DstReg = 0, ZeroReg = 0; 254234353Sdim 255234353Sdim // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0". 256234353Sdim if ((MI.getOpcode() == Mips::ADDiu) && 257234353Sdim (MI.getOperand(1).getReg() == Mips::ZERO) && 258234353Sdim (MI.getOperand(2).getImm() == 0)) { 259234353Sdim DstReg = MI.getOperand(0).getReg(); 260234353Sdim ZeroReg = Mips::ZERO; 261234353Sdim } else if ((MI.getOpcode() == Mips::DADDiu) && 262234353Sdim (MI.getOperand(1).getReg() == Mips::ZERO_64) && 263234353Sdim (MI.getOperand(2).getImm() == 0)) { 264234353Sdim DstReg = MI.getOperand(0).getReg(); 265234353Sdim ZeroReg = Mips::ZERO_64; 266234353Sdim } 267234353Sdim 268234353Sdim if (!DstReg) 269234353Sdim return false; 270234353Sdim 271234353Sdim // Replace uses with ZeroReg. 272234353Sdim for (MachineRegisterInfo::use_iterator U = MRI->use_begin(DstReg), 273239462Sdim E = MRI->use_end(); U != E;) { 274234353Sdim MachineOperand &MO = U.getOperand(); 275239462Sdim unsigned OpNo = U.getOperandNo(); 276234353Sdim MachineInstr *MI = MO.getParent(); 277239462Sdim ++U; 278234353Sdim 279234353Sdim // Do not replace if it is a phi's operand or is tied to def operand. 280239462Sdim if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo()) 281234353Sdim continue; 282234353Sdim 283234353Sdim MO.setReg(ZeroReg); 284234353Sdim } 285234353Sdim 286234353Sdim return true; 287234353Sdim} 288234353Sdim 289234353Sdimvoid MipsDAGToDAGISel::ProcessFunctionAfterISel(MachineFunction &MF) { 290234353Sdim InitGlobalBaseReg(MF); 291243830Sdim InitMips16SPAliasReg(MF); 292234353Sdim 293234353Sdim MachineRegisterInfo *MRI = &MF.getRegInfo(); 294234353Sdim 295234353Sdim for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE; 296234353Sdim ++MFI) 297234353Sdim for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) 298234353Sdim ReplaceUsesWithZeroReg(MRI, *I); 299234353Sdim} 300234353Sdim 301234353Sdimbool MipsDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { 302234353Sdim bool Ret = SelectionDAGISel::runOnMachineFunction(MF); 303234353Sdim 304234353Sdim ProcessFunctionAfterISel(MF); 305234353Sdim 306234353Sdim return Ret; 307234353Sdim} 308234353Sdim 309193323Sed/// getGlobalBaseReg - Output the instructions required to put the 310193323Sed/// GOT address into a register. 311193399SedSDNode *MipsDAGToDAGISel::getGlobalBaseReg() { 312234353Sdim unsigned GlobalBaseReg = MF->getInfo<MipsFunctionInfo>()->getGlobalBaseReg(); 313193399Sed return CurDAG->getRegister(GlobalBaseReg, TLI.getPointerTy()).getNode(); 314193323Sed} 315193323Sed 316243830Sdim/// getMips16SPAliasReg - Output the instructions required to put the 317243830Sdim/// SP into a Mips16 accessible aliased register. 318243830SdimSDValue MipsDAGToDAGISel::getMips16SPAliasReg() { 319243830Sdim unsigned Mips16SPAliasReg = 320243830Sdim MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg(); 321243830Sdim return CurDAG->getRegister(Mips16SPAliasReg, TLI.getPointerTy()); 322243830Sdim} 323243830Sdim 324193323Sed/// ComplexPattern used on MipsInstrInfo 325193323Sed/// Used on Mips Load/Store instructions 326193323Sedbool MipsDAGToDAGISel:: 327234353SdimSelectAddr(SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset) { 328226633Sdim EVT ValTy = Addr.getValueType(); 329226633Sdim 330193323Sed // if Address is FI, get the TargetFrameIndex. 331193323Sed if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 332226633Sdim Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 333226633Sdim Offset = CurDAG->getTargetConstant(0, ValTy); 334193323Sed return true; 335193323Sed } 336221345Sdim 337193323Sed // on PIC code Load GA 338234353Sdim if (Addr.getOpcode() == MipsISD::Wrapper) { 339234353Sdim Base = Addr.getOperand(0); 340234353Sdim Offset = Addr.getOperand(1); 341234353Sdim return true; 342234353Sdim } 343234353Sdim 344234353Sdim if (TM.getRelocationModel() != Reloc::PIC_) { 345193323Sed if ((Addr.getOpcode() == ISD::TargetExternalSymbol || 346193323Sed Addr.getOpcode() == ISD::TargetGlobalAddress)) 347193323Sed return false; 348221345Sdim } 349221345Sdim 350223017Sdim // Addresses of the form FI+const or FI|const 351223017Sdim if (CurDAG->isBaseWithConstantOffset(Addr)) { 352223017Sdim ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 353223017Sdim if (isInt<16>(CN->getSExtValue())) { 354193323Sed 355223017Sdim // If the first operand is a FI, get the TargetFI Node 356223017Sdim if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> 357223017Sdim (Addr.getOperand(0))) 358226633Sdim Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 359223017Sdim else 360223017Sdim Base = Addr.getOperand(0); 361193323Sed 362226633Sdim Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy); 363223017Sdim return true; 364193323Sed } 365223017Sdim } 366199481Srdivacky 367223017Sdim // Operand is a result from an ADD. 368223017Sdim if (Addr.getOpcode() == ISD::ADD) { 369199481Srdivacky // When loading from constant pools, load the lower address part in 370199989Srdivacky // the instruction itself. Example, instead of: 371199481Srdivacky // lui $2, %hi($CPI1_0) 372199481Srdivacky // addiu $2, $2, %lo($CPI1_0) 373199481Srdivacky // lwc1 $f0, 0($2) 374199481Srdivacky // Generate: 375199481Srdivacky // lui $2, %hi($CPI1_0) 376199481Srdivacky // lwc1 $f0, %lo($CPI1_0)($2) 377243830Sdim if (Addr.getOperand(1).getOpcode() == MipsISD::Lo || 378243830Sdim Addr.getOperand(1).getOpcode() == MipsISD::GPRel) { 379243830Sdim SDValue Opnd0 = Addr.getOperand(1).getOperand(0); 380239462Sdim if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) || 381239462Sdim isa<JumpTableSDNode>(Opnd0)) { 382199989Srdivacky Base = Addr.getOperand(0); 383239462Sdim Offset = Opnd0; 384199989Srdivacky return true; 385199481Srdivacky } 386199481Srdivacky } 387234353Sdim 388234353Sdim // If an indexed floating point load/store can be emitted, return false. 389239462Sdim const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent); 390239462Sdim 391239462Sdim if (LS && 392239462Sdim (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) && 393234353Sdim Subtarget.hasMips32r2Or64()) 394234353Sdim return false; 395193323Sed } 396193323Sed 397193323Sed Base = Addr; 398226633Sdim Offset = CurDAG->getTargetConstant(0, ValTy); 399193323Sed return true; 400193323Sed} 401193323Sed 402243830Sdimvoid MipsDAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) { 403243830Sdim SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI.getPointerTy()); 404243830Sdim if (Parent) { 405243830Sdim switch (Parent->getOpcode()) { 406243830Sdim case ISD::LOAD: { 407243830Sdim LoadSDNode *SD = dyn_cast<LoadSDNode>(Parent); 408243830Sdim switch (SD->getMemoryVT().getSizeInBits()) { 409243830Sdim case 8: 410243830Sdim case 16: 411243830Sdim AliasReg = TM.getFrameLowering()->hasFP(*MF)? 412243830Sdim AliasFPReg: getMips16SPAliasReg(); 413243830Sdim return; 414243830Sdim } 415243830Sdim break; 416243830Sdim } 417243830Sdim case ISD::STORE: { 418243830Sdim StoreSDNode *SD = dyn_cast<StoreSDNode>(Parent); 419243830Sdim switch (SD->getMemoryVT().getSizeInBits()) { 420243830Sdim case 8: 421243830Sdim case 16: 422243830Sdim AliasReg = TM.getFrameLowering()->hasFP(*MF)? 423243830Sdim AliasFPReg: getMips16SPAliasReg(); 424243830Sdim return; 425243830Sdim } 426243830Sdim break; 427243830Sdim } 428243830Sdim } 429243830Sdim } 430243830Sdim AliasReg = CurDAG->getRegister(Mips::SP, TLI.getPointerTy()); 431243830Sdim return; 432243830Sdim 433243830Sdim} 434243830Sdimbool MipsDAGToDAGISel::SelectAddr16( 435243830Sdim SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset, 436243830Sdim SDValue &Alias) { 437243830Sdim EVT ValTy = Addr.getValueType(); 438243830Sdim 439243830Sdim Alias = CurDAG->getTargetConstant(0, ValTy); 440243830Sdim 441243830Sdim // if Address is FI, get the TargetFrameIndex. 442243830Sdim if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 443243830Sdim Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 444243830Sdim Offset = CurDAG->getTargetConstant(0, ValTy); 445243830Sdim getMips16SPRefReg(Parent, Alias); 446243830Sdim return true; 447243830Sdim } 448243830Sdim // on PIC code Load GA 449243830Sdim if (Addr.getOpcode() == MipsISD::Wrapper) { 450243830Sdim Base = Addr.getOperand(0); 451243830Sdim Offset = Addr.getOperand(1); 452243830Sdim return true; 453243830Sdim } 454243830Sdim if (TM.getRelocationModel() != Reloc::PIC_) { 455243830Sdim if ((Addr.getOpcode() == ISD::TargetExternalSymbol || 456243830Sdim Addr.getOpcode() == ISD::TargetGlobalAddress)) 457243830Sdim return false; 458243830Sdim } 459243830Sdim // Addresses of the form FI+const or FI|const 460243830Sdim if (CurDAG->isBaseWithConstantOffset(Addr)) { 461243830Sdim ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 462243830Sdim if (isInt<16>(CN->getSExtValue())) { 463243830Sdim 464243830Sdim // If the first operand is a FI, get the TargetFI Node 465243830Sdim if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> 466243830Sdim (Addr.getOperand(0))) { 467243830Sdim Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 468243830Sdim getMips16SPRefReg(Parent, Alias); 469243830Sdim } 470243830Sdim else 471243830Sdim Base = Addr.getOperand(0); 472243830Sdim 473243830Sdim Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy); 474243830Sdim return true; 475243830Sdim } 476243830Sdim } 477243830Sdim // Operand is a result from an ADD. 478243830Sdim if (Addr.getOpcode() == ISD::ADD) { 479243830Sdim // When loading from constant pools, load the lower address part in 480243830Sdim // the instruction itself. Example, instead of: 481243830Sdim // lui $2, %hi($CPI1_0) 482243830Sdim // addiu $2, $2, %lo($CPI1_0) 483243830Sdim // lwc1 $f0, 0($2) 484243830Sdim // Generate: 485243830Sdim // lui $2, %hi($CPI1_0) 486243830Sdim // lwc1 $f0, %lo($CPI1_0)($2) 487243830Sdim if (Addr.getOperand(1).getOpcode() == MipsISD::Lo || 488243830Sdim Addr.getOperand(1).getOpcode() == MipsISD::GPRel) { 489243830Sdim SDValue Opnd0 = Addr.getOperand(1).getOperand(0); 490243830Sdim if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) || 491243830Sdim isa<JumpTableSDNode>(Opnd0)) { 492243830Sdim Base = Addr.getOperand(0); 493243830Sdim Offset = Opnd0; 494243830Sdim return true; 495243830Sdim } 496243830Sdim } 497243830Sdim 498243830Sdim // If an indexed floating point load/store can be emitted, return false. 499243830Sdim const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent); 500243830Sdim 501243830Sdim if (LS && 502243830Sdim (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) && 503243830Sdim Subtarget.hasMips32r2Or64()) 504243830Sdim return false; 505243830Sdim } 506243830Sdim Base = Addr; 507243830Sdim Offset = CurDAG->getTargetConstant(0, ValTy); 508243830Sdim return true; 509243830Sdim} 510243830Sdim 511234353Sdim/// Select multiply instructions. 512234353Sdimstd::pair<SDNode*, SDNode*> 513234353SdimMipsDAGToDAGISel::SelectMULT(SDNode *N, unsigned Opc, DebugLoc dl, EVT Ty, 514234353Sdim bool HasLo, bool HasHi) { 515234353Sdim SDNode *Lo = 0, *Hi = 0; 516234353Sdim SDNode *Mul = CurDAG->getMachineNode(Opc, dl, MVT::Glue, N->getOperand(0), 517234353Sdim N->getOperand(1)); 518234353Sdim SDValue InFlag = SDValue(Mul, 0); 519234353Sdim 520234353Sdim if (HasLo) { 521243830Sdim unsigned Opcode = Subtarget.inMips16Mode() ? Mips::Mflo16 : 522243830Sdim (Ty == MVT::i32 ? Mips::MFLO : Mips::MFLO64); 523243830Sdim Lo = CurDAG->getMachineNode(Opcode, dl, Ty, MVT::Glue, InFlag); 524234353Sdim InFlag = SDValue(Lo, 1); 525234353Sdim } 526243830Sdim if (HasHi) { 527243830Sdim unsigned Opcode = Subtarget.inMips16Mode() ? Mips::Mfhi16 : 528243830Sdim (Ty == MVT::i32 ? Mips::MFHI : Mips::MFHI64); 529243830Sdim Hi = CurDAG->getMachineNode(Opcode, dl, Ty, InFlag); 530243830Sdim } 531234353Sdim return std::make_pair(Lo, Hi); 532234353Sdim} 533234353Sdim 534234353Sdim 535193323Sed/// Select instructions not customized! Used for 536193323Sed/// expanded, promoted and normal instructions 537202375SrdivackySDNode* MipsDAGToDAGISel::Select(SDNode *Node) { 538193323Sed unsigned Opcode = Node->getOpcode(); 539193323Sed DebugLoc dl = Node->getDebugLoc(); 540193323Sed 541193323Sed // Dump information about the Node being selected 542204642Srdivacky DEBUG(errs() << "Selecting: "; Node->dump(CurDAG); errs() << "\n"); 543193323Sed 544193323Sed // If we have a custom node, we already have selected! 545193323Sed if (Node->isMachineOpcode()) { 546204642Srdivacky DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n"); 547193323Sed return NULL; 548193323Sed } 549193323Sed 550193323Sed /// 551221345Sdim // Instruction Selection not handled by the auto-generated 552193323Sed // tablegen selection should be handled here. 553221345Sdim /// 554234353Sdim EVT NodeTy = Node->getValueType(0); 555234353Sdim unsigned MultOpc; 556234353Sdim 557193323Sed switch(Opcode) { 558234353Sdim default: break; 559193323Sed 560234353Sdim case ISD::SUBE: 561234353Sdim case ISD::ADDE: { 562243830Sdim bool inMips16Mode = Subtarget.inMips16Mode(); 563234353Sdim SDValue InFlag = Node->getOperand(2), CmpLHS; 564234353Sdim unsigned Opc = InFlag.getOpcode(); (void)Opc; 565234353Sdim assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || 566234353Sdim (Opc == ISD::SUBC || Opc == ISD::SUBE)) && 567234353Sdim "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn"); 568193323Sed 569234353Sdim unsigned MOp; 570234353Sdim if (Opcode == ISD::ADDE) { 571234353Sdim CmpLHS = InFlag.getValue(0); 572243830Sdim if (inMips16Mode) 573243830Sdim MOp = Mips::AdduRxRyRz16; 574243830Sdim else 575243830Sdim MOp = Mips::ADDu; 576234353Sdim } else { 577234353Sdim CmpLHS = InFlag.getOperand(0); 578243830Sdim if (inMips16Mode) 579243830Sdim MOp = Mips::SubuRxRyRz16; 580243830Sdim else 581243830Sdim MOp = Mips::SUBu; 582234353Sdim } 583193323Sed 584234353Sdim SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) }; 585193323Sed 586234353Sdim SDValue LHS = Node->getOperand(0); 587234353Sdim SDValue RHS = Node->getOperand(1); 588193323Sed 589234353Sdim EVT VT = LHS.getValueType(); 590243830Sdim 591243830Sdim unsigned Sltu_op = inMips16Mode? Mips::SltuRxRyRz16: Mips::SLTu; 592243830Sdim SDNode *Carry = CurDAG->getMachineNode(Sltu_op, dl, VT, Ops, 2); 593243830Sdim unsigned Addu_op = inMips16Mode? Mips::AdduRxRyRz16 : Mips::ADDu; 594243830Sdim SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, dl, VT, 595234353Sdim SDValue(Carry,0), RHS); 596193323Sed 597234353Sdim return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, 598234353Sdim LHS, SDValue(AddCarry,0)); 599234353Sdim } 600193323Sed 601234353Sdim /// Mul with two results 602234353Sdim case ISD::SMUL_LOHI: 603234353Sdim case ISD::UMUL_LOHI: { 604243830Sdim if (NodeTy == MVT::i32) { 605243830Sdim if (Subtarget.inMips16Mode()) 606243830Sdim MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 : 607243830Sdim Mips::MultRxRy16); 608243830Sdim else 609243830Sdim MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MULTu : Mips::MULT); 610243830Sdim } 611234353Sdim else 612234353Sdim MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::DMULTu : Mips::DMULT); 613193323Sed 614234353Sdim std::pair<SDNode*, SDNode*> LoHi = SelectMULT(Node, MultOpc, dl, NodeTy, 615234353Sdim true, true); 616193323Sed 617234353Sdim if (!SDValue(Node, 0).use_empty()) 618234353Sdim ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0)); 619193323Sed 620234353Sdim if (!SDValue(Node, 1).use_empty()) 621234353Sdim ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0)); 622193323Sed 623234353Sdim return NULL; 624234353Sdim } 625193323Sed 626234353Sdim /// Special Muls 627234353Sdim case ISD::MUL: { 628234353Sdim // Mips32 has a 32-bit three operand mul instruction. 629234353Sdim if (Subtarget.hasMips32() && NodeTy == MVT::i32) 630234353Sdim break; 631234353Sdim return SelectMULT(Node, NodeTy == MVT::i32 ? Mips::MULT : Mips::DMULT, 632234353Sdim dl, NodeTy, true, false).first; 633234353Sdim } 634234353Sdim case ISD::MULHS: 635234353Sdim case ISD::MULHU: { 636243830Sdim if (NodeTy == MVT::i32) { 637243830Sdim if (Subtarget.inMips16Mode()) 638243830Sdim MultOpc = (Opcode == ISD::MULHU ? 639243830Sdim Mips::MultuRxRy16 : Mips::MultRxRy16); 640243830Sdim else 641243830Sdim MultOpc = (Opcode == ISD::MULHU ? Mips::MULTu : Mips::MULT); 642243830Sdim } 643234353Sdim else 644234353Sdim MultOpc = (Opcode == ISD::MULHU ? Mips::DMULTu : Mips::DMULT); 645193323Sed 646234353Sdim return SelectMULT(Node, MultOpc, dl, NodeTy, false, true).second; 647234353Sdim } 648234353Sdim 649234353Sdim // Get target GOT address. 650234353Sdim case ISD::GLOBAL_OFFSET_TABLE: 651234353Sdim return getGlobalBaseReg(); 652234353Sdim 653234353Sdim case ISD::ConstantFP: { 654234353Sdim ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node); 655234353Sdim if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { 656234353Sdim if (Subtarget.hasMips64()) { 657234353Sdim SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, 658234353Sdim Mips::ZERO_64, MVT::i64); 659234353Sdim return CurDAG->getMachineNode(Mips::DMTC1, dl, MVT::f64, Zero); 660234353Sdim } 661234353Sdim 662234353Sdim SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), dl, 663234353Sdim Mips::ZERO, MVT::i32); 664234353Sdim return CurDAG->getMachineNode(Mips::BuildPairF64, dl, MVT::f64, Zero, 665234353Sdim Zero); 666193323Sed } 667234353Sdim break; 668234353Sdim } 669193323Sed 670234353Sdim case ISD::Constant: { 671234353Sdim const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node); 672234353Sdim unsigned Size = CN->getValueSizeInBits(0); 673193323Sed 674234353Sdim if (Size == 32) 675234353Sdim break; 676193323Sed 677234353Sdim MipsAnalyzeImmediate AnalyzeImm; 678234353Sdim int64_t Imm = CN->getSExtValue(); 679193323Sed 680234353Sdim const MipsAnalyzeImmediate::InstSeq &Seq = 681234353Sdim AnalyzeImm.Analyze(Imm, Size, false); 682234353Sdim 683234353Sdim MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); 684234353Sdim DebugLoc DL = CN->getDebugLoc(); 685234353Sdim SDNode *RegOpnd; 686234353Sdim SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), 687234353Sdim MVT::i64); 688234353Sdim 689234353Sdim // The first instruction can be a LUi which is different from other 690234353Sdim // instructions (ADDiu, ORI and SLL) in that it does not have a register 691234353Sdim // operand. 692234353Sdim if (Inst->Opc == Mips::LUi64) 693234353Sdim RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd); 694234353Sdim else 695234353Sdim RegOpnd = 696234353Sdim CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, 697234353Sdim CurDAG->getRegister(Mips::ZERO_64, MVT::i64), 698234353Sdim ImmOpnd); 699234353Sdim 700234353Sdim // The remaining instructions in the sequence are handled here. 701234353Sdim for (++Inst; Inst != Seq.end(); ++Inst) { 702234353Sdim ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), 703234353Sdim MVT::i64); 704234353Sdim RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, 705234353Sdim SDValue(RegOpnd, 0), ImmOpnd); 706193323Sed } 707193323Sed 708234353Sdim return RegOpnd; 709234353Sdim } 710193323Sed 711243830Sdim#ifndef NDEBUG 712243830Sdim case ISD::LOAD: 713243830Sdim case ISD::STORE: 714243830Sdim assert(cast<MemSDNode>(Node)->getMemoryVT().getSizeInBits() / 8 <= 715243830Sdim cast<MemSDNode>(Node)->getAlignment() && 716243830Sdim "Unexpected unaligned loads/stores."); 717243830Sdim break; 718243830Sdim#endif 719243830Sdim 720234353Sdim case MipsISD::ThreadPointer: { 721234353Sdim EVT PtrVT = TLI.getPointerTy(); 722234353Sdim unsigned RdhwrOpc, SrcReg, DestReg; 723234353Sdim 724234353Sdim if (PtrVT == MVT::i32) { 725234353Sdim RdhwrOpc = Mips::RDHWR; 726234353Sdim SrcReg = Mips::HWR29; 727234353Sdim DestReg = Mips::V1; 728234353Sdim } else { 729234353Sdim RdhwrOpc = Mips::RDHWR64; 730234353Sdim SrcReg = Mips::HWR29_64; 731234353Sdim DestReg = Mips::V1_64; 732199481Srdivacky } 733199481Srdivacky 734234353Sdim SDNode *Rdhwr = 735234353Sdim CurDAG->getMachineNode(RdhwrOpc, Node->getDebugLoc(), 736234353Sdim Node->getValueType(0), 737234353Sdim CurDAG->getRegister(SrcReg, PtrVT)); 738234353Sdim SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), dl, DestReg, 739234353Sdim SDValue(Rdhwr, 0)); 740234353Sdim SDValue ResNode = CurDAG->getCopyFromReg(Chain, dl, DestReg, PtrVT); 741234353Sdim ReplaceUses(SDValue(Node, 0), ResNode); 742234353Sdim return ResNode.getNode(); 743193323Sed } 744234353Sdim } 745193323Sed 746193323Sed // Select the default instruction 747202375Srdivacky SDNode *ResNode = SelectCode(Node); 748193323Sed 749204642Srdivacky DEBUG(errs() << "=> "); 750202375Srdivacky if (ResNode == NULL || ResNode == Node) 751202375Srdivacky DEBUG(Node->dump(CurDAG)); 752193323Sed else 753193323Sed DEBUG(ResNode->dump(CurDAG)); 754198090Srdivacky DEBUG(errs() << "\n"); 755193323Sed return ResNode; 756193323Sed} 757193323Sed 758224145Sdimbool MipsDAGToDAGISel:: 759224145SdimSelectInlineAsmMemoryOperand(const SDValue &Op, char ConstraintCode, 760224145Sdim std::vector<SDValue> &OutOps) { 761224145Sdim assert(ConstraintCode == 'm' && "unexpected asm memory constraint"); 762224145Sdim OutOps.push_back(Op); 763224145Sdim return false; 764224145Sdim} 765224145Sdim 766221345Sdim/// createMipsISelDag - This pass converts a legalized DAG into a 767193323Sed/// MIPS-specific DAG, ready for instruction scheduling. 768193323SedFunctionPass *llvm::createMipsISelDag(MipsTargetMachine &TM) { 769193323Sed return new MipsDAGToDAGISel(TM); 770193323Sed} 771