MipsSEISelDAGToDAG.cpp revision abbcf3bd47ad8ffa70f48ebd924f99fff5c22131
1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//===-- MipsSEISelDAGToDAG.cpp - A Dag to Dag Inst Selector for MipsSE ----===// 2b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// The LLVM Compiler Infrastructure 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// This file is distributed under the University of Illinois Open Source 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// License. See LICENSE.TXT for details. 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//===----------------------------------------------------------------------===// 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Subclass of MipsDAGToDAGISel specialized for mips32/64. 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//===----------------------------------------------------------------------===// 13b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define DEBUG_TYPE "mips-isel" 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MipsSEISelDAGToDAG.h" 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "Mips.h" 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MCTargetDesc/MipsBaseInfo.h" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MipsAnalyzeImmediate.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MipsMachineFunction.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "MipsRegisterInfo.h" 21b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineConstantPool.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineFrameInfo.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineFunction.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineInstrBuilder.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/MachineRegisterInfo.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/CodeGen/SelectionDAGNodes.h" 27b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/IR/GlobalValue.h" 28b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/IR/Instructions.h" 29b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/IR/Intrinsics.h" 30b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/IR/Type.h" 31b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Support/CFG.h" 32b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Support/Debug.h" 33b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Support/ErrorHandling.h" 34b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Support/raw_ostream.h" 35b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "llvm/Target/TargetMachine.h" 36b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruusing namespace llvm; 37b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 3827f654740f2a26ad62a5c155af9199af9e69b889clairehobool MipsSEDAGToDAGISel::runOnMachineFunction(MachineFunction &MF) { 39b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Subtarget.inMips16Mode()) 4027f654740f2a26ad62a5c155af9199af9e69b889claireho return false; 4159d709d503bab6e2b61931737e662dd293b40578ccornelius return MipsDAGToDAGISel::runOnMachineFunction(MF); 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 44b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MipsSEDAGToDAGISel::addDSPCtrlRegOperands(bool IsDef, MachineInstr &MI, 45b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MachineFunction &MF) { 46b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MachineInstrBuilder MIB(MF, &MI); 47b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned Mask = MI.getOperand(1).getImm(); 48b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned Flag = IsDef ? RegState::ImplicitDefine : RegState::Implicit; 49b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 50b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Mask & 1) 51b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MIB.addReg(Mips::DSPPos, Flag); 52b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 5359d709d503bab6e2b61931737e662dd293b40578ccornelius if (Mask & 2) 5459d709d503bab6e2b61931737e662dd293b40578ccornelius MIB.addReg(Mips::DSPSCount, Flag); 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Mask & 4) 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MIB.addReg(Mips::DSPCarry, Flag); 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Mask & 8) 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MIB.addReg(Mips::DSPOutFlag, Flag); 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Mask & 16) 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MIB.addReg(Mips::DSPCCond, Flag); 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Mask & 32) 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MIB.addReg(Mips::DSPEFI, Flag); 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruunsigned MipsSEDAGToDAGISel::getMSACtrlReg(const SDValue RegIdx) const { 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (cast<ConstantSDNode>(RegIdx)->getZExtValue()) { 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 72b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru llvm_unreachable("Could not map int to register"); 73b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: return Mips::MSAIR; 74b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: return Mips::MSACSR; 75b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 2: return Mips::MSAAccess; 76b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 3: return Mips::MSASave; 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 4: return Mips::MSAModify; 78b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 5: return Mips::MSARequest; 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 6: return Mips::MSAMap; 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 7: return Mips::MSAUnmap; 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::replaceUsesWithZeroReg(MachineRegisterInfo *MRI, 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const MachineInstr& MI) { 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned DstReg = 0, ZeroReg = 0; 87b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Check if MI is "addiu $dst, $zero, 0" or "daddiu $dst, $zero, 0". 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((MI.getOpcode() == Mips::ADDiu) && 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (MI.getOperand(1).getReg() == Mips::ZERO) && 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (MI.getOperand(2).getImm() == 0)) { 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DstReg = MI.getOperand(0).getReg(); 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ZeroReg = Mips::ZERO; 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if ((MI.getOpcode() == Mips::DADDiu) && 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (MI.getOperand(1).getReg() == Mips::ZERO_64) && 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (MI.getOperand(2).getImm() == 0)) { 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DstReg = MI.getOperand(0).getReg(); 98103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius ZeroReg = Mips::ZERO_64; 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!DstReg) 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return false; 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Replace uses with ZeroReg. 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (MachineRegisterInfo::use_iterator U = MRI->use_begin(DstReg), 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru E = MRI->use_end(); U != E;) { 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MachineOperand &MO = U.getOperand(); 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned OpNo = U.getOperandNo(); 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MachineInstr *MI = MO.getParent(); 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ++U; 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Do not replace if it is a phi's operand or is tied to def operand. 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (MI->isPHI() || MI->isRegTiedToDefOperand(OpNo) || MI->isPseudo()) 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru continue; 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MO.setReg(ZeroReg); 117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return true; 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MipsSEDAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) { 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (!MipsFI->globalBaseRegSet()) 12659d709d503bab6e2b61931737e662dd293b40578ccornelius return; 12759d709d503bab6e2b61931737e662dd293b40578ccornelius 12859d709d503bab6e2b61931737e662dd293b40578ccornelius MachineBasicBlock &MBB = MF.front(); 12959d709d503bab6e2b61931737e662dd293b40578ccornelius MachineBasicBlock::iterator I = MBB.begin(); 13059d709d503bab6e2b61931737e662dd293b40578ccornelius MachineRegisterInfo &RegInfo = MF.getRegInfo(); 13159d709d503bab6e2b61931737e662dd293b40578ccornelius const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 13259d709d503bab6e2b61931737e662dd293b40578ccornelius DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 13359d709d503bab6e2b61931737e662dd293b40578ccornelius unsigned V0, V1, GlobalBaseReg = MipsFI->getGlobalBaseReg(); 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const TargetRegisterClass *RC; 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Subtarget.isABI_N64()) 13727f654740f2a26ad62a5c155af9199af9e69b889claireho RC = (const TargetRegisterClass*)&Mips::GPR64RegClass; 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RC = (const TargetRegisterClass*)&Mips::GPR32RegClass; 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru V0 = RegInfo.createVirtualRegister(RC); 142b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru V1 = RegInfo.createVirtualRegister(RC); 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Subtarget.isABI_N64()) { 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MF.getRegInfo().addLiveIn(Mips::T9_64); 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MBB.addLiveIn(Mips::T9_64); 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // lui $v0, %hi(%neg(%gp_rel(fname))) 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // daddu $v1, $v0, $t9 150b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // daddiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname))) 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const GlobalValue *FName = MF.getFunction(); 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BuildMI(MBB, I, DL, TII.get(Mips::LUi64), V0) 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BuildMI(MBB, I, DL, TII.get(Mips::DADDu), V1).addReg(V0) 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .addReg(Mips::T9_64); 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BuildMI(MBB, I, DL, TII.get(Mips::DADDiu), GlobalBaseReg).addReg(V1) 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (MF.getTarget().getRelocationModel() == Reloc::Static) { 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Set global register to __gnu_local_gp. 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // lui $v0, %hi(__gnu_local_gp) 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // addiu $globalbasereg, $v0, %lo(__gnu_local_gp) 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0) 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_HI); 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V0) 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .addExternalSymbol("__gnu_local_gp", MipsII::MO_ABS_LO); 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MF.getRegInfo().addLiveIn(Mips::T9); 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MBB.addLiveIn(Mips::T9); 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Subtarget.isABI_N32()) { 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // lui $v0, %hi(%neg(%gp_rel(fname))) 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // addu $v1, $v0, $t9 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // addiu $globalbasereg, $v1, %lo(%neg(%gp_rel(fname))) 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const GlobalValue *FName = MF.getFunction(); 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BuildMI(MBB, I, DL, TII.get(Mips::LUi), V0) 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_HI); 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BuildMI(MBB, I, DL, TII.get(Mips::ADDu), V1).addReg(V0).addReg(Mips::T9); 18427f654740f2a26ad62a5c155af9199af9e69b889claireho BuildMI(MBB, I, DL, TII.get(Mips::ADDiu), GlobalBaseReg).addReg(V1) 18527f654740f2a26ad62a5c155af9199af9e69b889claireho .addGlobalAddress(FName, 0, MipsII::MO_GPOFF_LO); 18627f654740f2a26ad62a5c155af9199af9e69b889claireho return; 18727f654740f2a26ad62a5c155af9199af9e69b889claireho } 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru assert(Subtarget.isABI_O32()); 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // For O32 ABI, the following instruction sequence is emitted to initialize 19227f654740f2a26ad62a5c155af9199af9e69b889claireho // the global base register: 193b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 194b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 0. lui $2, %hi(_gp_disp) 195b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1. addiu $2, $2, %lo(_gp_disp) 196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 2. addu $globalbasereg, $2, $t9 197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 198b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We emit only the last instruction here. 199b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 200b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // GNU linker requires that the first two instructions appear at the beginning 201b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // of a function and no instructions be inserted before or between them. 202b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The two instructions are emitted during lowering to MC layer in order to 203b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // avoid any reordering. 204b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 205b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Register $2 (Mips::V0) is added to the list of live-in registers to ensure 206b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the value instruction 1 (addiu) defines is valid when instruction 2 (addu) 207b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // reads it. 208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MF.getRegInfo().addLiveIn(Mips::V0); 209b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MBB.addLiveIn(Mips::V0); 210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru BuildMI(MBB, I, DL, TII.get(Mips::ADDu), GlobalBaseReg) 211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru .addReg(Mips::V0).addReg(Mips::T9); 212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 213b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MipsSEDAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { 215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru initGlobalBaseReg(MF); 216b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 217b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MachineRegisterInfo *MRI = &MF.getRegInfo(); 21859d709d503bab6e2b61931737e662dd293b40578ccornelius 21959d709d503bab6e2b61931737e662dd293b40578ccornelius for (MachineFunction::iterator MFI = MF.begin(), MFE = MF.end(); MFI != MFE; 22059d709d503bab6e2b61931737e662dd293b40578ccornelius ++MFI) 22159d709d503bab6e2b61931737e662dd293b40578ccornelius for (MachineBasicBlock::iterator I = MFI->begin(); I != MFI->end(); ++I) { 22259d709d503bab6e2b61931737e662dd293b40578ccornelius if (I->getOpcode() == Mips::RDDSP) 22359d709d503bab6e2b61931737e662dd293b40578ccornelius addDSPCtrlRegOperands(false, *I, MF); 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else if (I->getOpcode() == Mips::WRDSP) 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru addDSPCtrlRegOperands(true, *I, MF); 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru replaceUsesWithZeroReg(MRI, *I); 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruSDNode *MipsSEDAGToDAGISel::selectAddESubE(unsigned MOp, SDValue InFlag, 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue CmpLHS, SDLoc DL, 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDNode *Node) const { 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned Opc = InFlag.getOpcode(); (void)Opc; 235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (Opc == ISD::SUBC || Opc == ISD::SUBE)) && 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn"); 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) }; 241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue LHS = Node->getOperand(0), RHS = Node->getOperand(1); 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru EVT VT = LHS.getValueType(); 243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDNode *Carry = CurDAG->getMachineNode(Mips::SLTu, DL, VT, Ops); 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDNode *AddCarry = CurDAG->getMachineNode(Mips::ADDu, DL, VT, 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue(Carry, 0), RHS); 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, 248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue(AddCarry, 0)); 249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/// ComplexPattern used on MipsInstrInfo 252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/// Used on Mips Load/Store instructions 253f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Corneliusbool MipsSEDAGToDAGISel::selectAddrRegImm(SDValue Addr, SDValue &Base, 254f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius SDValue &Offset) const { 255f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius EVT ValTy = Addr.getValueType(); 256f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius 257f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius // if Address is FI, get the TargetFrameIndex. 258f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 259f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 260f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius Offset = CurDAG->getTargetConstant(0, ValTy); 261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return true; 262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // on PIC code Load GA 265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Addr.getOpcode() == MipsISD::Wrapper) { 266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Base = Addr.getOperand(0); 267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Offset = Addr.getOperand(1); 268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return true; 269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 270b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 271b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (TM.getRelocationModel() != Reloc::PIC_) { 272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if ((Addr.getOpcode() == ISD::TargetExternalSymbol || 273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Addr.getOpcode() == ISD::TargetGlobalAddress)) 274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return false; 275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Addresses of the form FI+const or FI|const 278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (CurDAG->isBaseWithConstantOffset(Addr)) { 279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isInt<16>(CN->getSExtValue())) { 281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 282b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If the first operand is a FI, get the TargetFI Node 283b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> 284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (Addr.getOperand(0))) 285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 286f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius else 287f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius Base = Addr.getOperand(0); 288f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius 289f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy); 290f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius return true; 291f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius } 292f760e5e9e080f32b3afdfaea0b961ce09eb052f4Craig Cornelius } 29327f654740f2a26ad62a5c155af9199af9e69b889claireho 29427f654740f2a26ad62a5c155af9199af9e69b889claireho // Operand is a result from an ADD. 29527f654740f2a26ad62a5c155af9199af9e69b889claireho if (Addr.getOpcode() == ISD::ADD) { 29627f654740f2a26ad62a5c155af9199af9e69b889claireho // When loading from constant pools, load the lower address part in 297b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the instruction itself. Example, instead of: 298b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // lui $2, %hi($CPI1_0) 299b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // addiu $2, $2, %lo($CPI1_0) 300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // lwc1 $f0, 0($2) 301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Generate: 302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // lui $2, %hi($CPI1_0) 303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // lwc1 $f0, %lo($CPI1_0)($2) 304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Addr.getOperand(1).getOpcode() == MipsISD::Lo || 305b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Addr.getOperand(1).getOpcode() == MipsISD::GPRel) { 306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue Opnd0 = Addr.getOperand(1).getOperand(0); 307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) || 308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru isa<JumpTableSDNode>(Opnd0)) { 309b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Base = Addr.getOperand(0); 31027f654740f2a26ad62a5c155af9199af9e69b889claireho Offset = Opnd0; 311b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return true; 31227f654740f2a26ad62a5c155af9199af9e69b889claireho } 313b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 314b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 316b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return false; 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::selectAddrDefault(SDValue Addr, SDValue &Base, 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue &Offset) const { 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Base = Addr; 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Offset = CurDAG->getTargetConstant(0, Addr.getValueType()); 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return true; 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::selectIntAddr(SDValue Addr, SDValue &Base, 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue &Offset) const { 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return selectAddrRegImm(Addr, Base, Offset) || 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru selectAddrDefault(Addr, Base, Offset); 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/// Used on microMIPS Load/Store unaligned instructions (12-bit offset) 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::selectAddrRegImm12(SDValue Addr, SDValue &Base, 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue &Offset) const { 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru EVT ValTy = Addr.getValueType(); 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Addresses of the form FI+const or FI|const 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (CurDAG->isBaseWithConstantOffset(Addr)) { 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (isInt<12>(CN->getSExtValue())) { 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // If the first operand is a FI, get the TargetFI Node 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru (Addr.getOperand(0))) 34527f654740f2a26ad62a5c155af9199af9e69b889claireho Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 34727f654740f2a26ad62a5c155af9199af9e69b889claireho Base = Addr.getOperand(0); 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy); 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return true; 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return false; 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querubool MipsSEDAGToDAGISel::selectIntAddrMM(SDValue Addr, SDValue &Base, 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue &Offset) const { 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return selectAddrRegImm12(Addr, Base, Offset) || 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru selectAddrDefault(Addr, Base, Offset); 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustd::pair<bool, SDNode*> MipsSEDAGToDAGISel::selectNode(SDNode *Node) { 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned Opcode = Node->getOpcode(); 365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDLoc DL(Node); 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /// 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Instruction Selection not handled by the auto-generated 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // tablegen selection should be handled here. 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /// 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDNode *Result; 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch(Opcode) { 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: break; 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case ISD::SUBE: { 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue InFlag = Node->getOperand(2); 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Result = selectAddESubE(Mips::SUBu, InFlag, InFlag.getOperand(0), DL, Node); 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, Result); 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case ISD::ADDE: { 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Subtarget.hasDSP()) // Select DSP instructions, ADDSC and ADDWC. 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue InFlag = Node->getOperand(2); 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Result = selectAddESubE(Mips::ADDu, InFlag, InFlag.getValue(0), DL, Node); 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, Result); 388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case ISD::ConstantFP: { 391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ConstantFPSDNode *CN = dyn_cast<ConstantFPSDNode>(Node); 392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Node->getValueType(0) == MVT::f64 && CN->isExactlyValue(+0.0)) { 393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Subtarget.hasMips64()) { 394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, 395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Mips::ZERO_64, MVT::i64); 396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Result = CurDAG->getMachineNode(Mips::DMTC1, DL, MVT::f64, Zero); 397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue Zero = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), DL, 399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Mips::ZERO, MVT::i32); 400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Result = CurDAG->getMachineNode(Mips::BuildPairF64, DL, MVT::f64, Zero, 401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Zero); 402b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, Result); 405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case ISD::Constant: { 410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Node); 411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned Size = CN->getValueSizeInBits(0); 412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Size == 32) 414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MipsAnalyzeImmediate AnalyzeImm; 417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int64_t Imm = CN->getSExtValue(); 418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const MipsAnalyzeImmediate::InstSeq &Seq = 420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru AnalyzeImm.Analyze(Imm, Size, false); 421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin(); 423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDLoc DL(CN); 424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDNode *RegOpnd; 425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), 426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MVT::i64); 427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The first instruction can be a LUi which is different from other 429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // instructions (ADDiu, ORI and SLL) in that it does not have a register 430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // operand. 431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (Inst->Opc == Mips::LUi64) 432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, ImmOpnd); 433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RegOpnd = 435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, 436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CurDAG->getRegister(Mips::ZERO_64, MVT::i64), 437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ImmOpnd); 438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // The remaining instructions in the sequence are handled here. 440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (++Inst; Inst != Seq.end(); ++Inst) { 441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ImmOpnd = CurDAG->getTargetConstant(SignExtend64<16>(Inst->ImmOpnd), 442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MVT::i64); 443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RegOpnd = CurDAG->getMachineNode(Inst->Opc, DL, MVT::i64, 444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue(RegOpnd, 0), ImmOpnd); 445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, RegOpnd); 448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 449b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case ISD::INTRINSIC_W_CHAIN: { 451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { 452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case Intrinsic::mips_cfcmsa: { 456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue ChainIn = Node->getOperand(0); 457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue RegIdx = Node->getOperand(2); 458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue Reg = CurDAG->getCopyFromReg(ChainIn, DL, 459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getMSACtrlReg(RegIdx), MVT::i32); 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, Reg.getNode()); 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case ISD::INTRINSIC_WO_CHAIN: { 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (cast<ConstantSDNode>(Node->getOperand(0))->getZExtValue()) { 468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 469b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case Intrinsic::mips_move_v: 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Like an assignment but will always produce a move.v even if 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // unnecessary. 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CurDAG->getMachineNode(Mips::MOVE_V, DL, 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Node->getValueType(0), 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Node->getOperand(1))); 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case ISD::INTRINSIC_VOID: { 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (cast<ConstantSDNode>(Node->getOperand(1))->getZExtValue()) { 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case Intrinsic::mips_ctcmsa: { 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue ChainIn = Node->getOperand(0); 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue RegIdx = Node->getOperand(2); 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue Value = Node->getOperand(3); 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue ChainOut = CurDAG->getCopyToReg(ChainIn, DL, 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru getMSACtrlReg(RegIdx), Value); 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, ChainOut.getNode()); 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case MipsISD::ThreadPointer: { 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru EVT PtrVT = getTargetLowering()->getPointerTy(); 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned RdhwrOpc, DestReg; 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (PtrVT == MVT::i32) { 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RdhwrOpc = Mips::RDHWR; 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DestReg = Mips::V1; 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru RdhwrOpc = Mips::RDHWR64; 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru DestReg = Mips::V1_64; 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDNode *Rdhwr = 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CurDAG->getMachineNode(RdhwrOpc, SDLoc(Node), 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Node->getValueType(0), 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CurDAG->getRegister(Mips::HWR29, MVT::i32)); 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue Chain = CurDAG->getCopyToReg(CurDAG->getEntryNode(), DL, DestReg, 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue(Rdhwr, 0)); 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue ResNode = CurDAG->getCopyFromReg(Chain, DL, DestReg, PtrVT); 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ReplaceUses(SDValue(Node, 0), ResNode); 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, ResNode.getNode()); 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case MipsISD::InsertLOHI: { 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru unsigned RCID = Subtarget.hasDSP() ? Mips::ACC64DSPRegClassID : 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Mips::ACC64RegClassID; 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue RegClass = CurDAG->getTargetConstant(RCID, MVT::i32); 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue LoIdx = CurDAG->getTargetConstant(Mips::sub_lo, MVT::i32); 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDValue HiIdx = CurDAG->getTargetConstant(Mips::sub_hi, MVT::i32); 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const SDValue Ops[] = { RegClass, Node->getOperand(0), LoIdx, 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Node->getOperand(1), HiIdx }; 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SDNode *Res = CurDAG->getMachineNode(TargetOpcode::REG_SEQUENCE, DL, 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MVT::Untyped, Ops); 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(true, Res); 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return std::make_pair(false, (SDNode*)NULL); 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruFunctionPass *llvm::createMipsSEISelDag(MipsTargetMachine &TM) { 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return new MipsSEDAGToDAGISel(TM); 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru