Mips16ISelDAGToDAG.cpp revision f283512d72757aac5bedcb270f9199194e6a12c0
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===-- Mips16ISelDAGToDAG.cpp - A Dag to Dag Inst Selector for Mips16 ----===// 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The LLVM Compiler Infrastructure 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file is distributed under the University of Illinois Open Source 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// License. See LICENSE.TXT for details. 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//===----------------------------------------------------------------------===// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Subclass of MipsDAGToDAGISel specialized for mips16. 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)//===----------------------------------------------------------------------===// 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define DEBUG_TYPE "mips-isel" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Mips16ISelDAGToDAG.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "Mips.h" 17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "MCTargetDesc/MipsBaseInfo.h" 18cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "MipsAnalyzeImmediate.h" 197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "MipsMachineFunction.h" 20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "MipsRegisterInfo.h" 21f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "llvm/CodeGen/MachineConstantPool.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineFrameInfo.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineFunction.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineInstrBuilder.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/CodeGen/MachineRegisterInfo.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/CodeGen/SelectionDAGNodes.h" 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "llvm/IR/GlobalValue.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/IR/Instructions.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/IR/Intrinsics.h" 305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/IR/Type.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/CFG.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/Debug.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/ErrorHandling.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Support/raw_ostream.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "llvm/Target/TargetMachine.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using namespace llvm; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/// Select multiply instructions. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)std::pair<SDNode*, SDNode*> 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Mips16DAGToDAGISel::selectMULT(SDNode *N, unsigned Opc, DebugLoc DL, EVT Ty, 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool HasLo, bool HasHi) { 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDNode *Lo = 0, *Hi = 0; 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDNode *Mul = CurDAG->getMachineNode(Opc, DL, MVT::Glue, N->getOperand(0), 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) N->getOperand(1)); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue InFlag = SDValue(Mul, 0); 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HasLo) { 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Opcode = Mips::Mflo16; 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Lo = CurDAG->getMachineNode(Opcode, DL, Ty, MVT::Glue, InFlag); 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InFlag = SDValue(Lo, 1); 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (HasHi) { 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Opcode = Mips::Mfhi16; 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Hi = CurDAG->getMachineNode(Opcode, DL, Ty, InFlag); 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::make_pair(Lo, Hi); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Mips16DAGToDAGISel::initGlobalBaseReg(MachineFunction &MF) { 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!MipsFI->globalBaseRegSet()) 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MachineBasicBlock &MBB = MF.front(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineBasicBlock::iterator I = MBB.begin(); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MachineRegisterInfo &RegInfo = MF.getRegInfo(); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned V0, V1, V2, GlobalBaseReg = MipsFI->getGlobalBaseReg(); 715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu const TargetRegisterClass *RC = 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (const TargetRegisterClass*)&Mips::CPU16RegsRegClass; 73cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) V0 = RegInfo.createVirtualRegister(RC); 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch V1 = RegInfo.createVirtualRegister(RC); 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch V2 = RegInfo.createVirtualRegister(RC); 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BuildMI(MBB, I, DL, TII.get(Mips::LiRxImmX16), V0) 79f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) .addExternalSymbol("_gp_disp", MipsII::MO_ABS_HI); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BuildMI(MBB, I, DL, TII.get(Mips::AddiuRxPcImmX16), V1) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) .addExternalSymbol("_gp_disp", MipsII::MO_ABS_LO); 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) BuildMI(MBB, I, DL, TII.get(Mips::SllX16), V2).addReg(V0).addImm(16); 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BuildMI(MBB, I, DL, TII.get(Mips::AdduRxRyRz16), GlobalBaseReg) 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch .addReg(V1).addReg(V2); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 86f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 87f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// Insert instructions to initialize the Mips16 SP Alias register in the 88f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)// first MBB of the function. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Mips16DAGToDAGISel::initMips16SPAliasReg(MachineFunction &MF) { 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MipsFunctionInfo *MipsFI = MF.getInfo<MipsFunctionInfo>(); 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (!MipsFI->mips16SPAliasRegSet()) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MachineBasicBlock &MBB = MF.front(); 97f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) MachineBasicBlock::iterator I = MBB.begin(); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const TargetInstrInfo &TII = *MF.getTarget().getInstrInfo(); 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc(); 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch unsigned Mips16SPAliasReg = MipsFI->getMips16SPAliasReg(); 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BuildMI(MBB, I, DL, TII.get(Mips::MoveR3216), Mips16SPAliasReg) 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) .addReg(Mips::SP); 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Mips16DAGToDAGISel::processFunctionAfterISel(MachineFunction &MF) { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initGlobalBaseReg(MF); 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch initMips16SPAliasReg(MF); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// getMips16SPAliasReg - Output the instructions required to put the 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// SP into a Mips16 accessible aliased register. 113116680a4aac90f2aa7413d9095a592090648e557Ben MurdochSDValue Mips16DAGToDAGISel::getMips16SPAliasReg() { 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch unsigned Mips16SPAliasReg = 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch MF->getInfo<MipsFunctionInfo>()->getMips16SPAliasReg(); 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return CurDAG->getRegister(Mips16SPAliasReg, TLI.getPointerTy()); 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch} 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdochvoid Mips16DAGToDAGISel::getMips16SPRefReg(SDNode *Parent, SDValue &AliasReg) { 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch SDValue AliasFPReg = CurDAG->getRegister(Mips::S0, TLI.getPointerTy()); 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (Parent) { 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch switch (Parent->getOpcode()) { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::LOAD: { 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LoadSDNode *SD = dyn_cast<LoadSDNode>(Parent); 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch switch (SD->getMemoryVT().getSizeInBits()) { 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case 8: 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case 16: 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AliasReg = TM.getFrameLowering()->hasFP(*MF)? 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AliasFPReg: getMips16SPAliasReg(); 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch break; 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case ISD::STORE: { 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch StoreSDNode *SD = dyn_cast<StoreSDNode>(Parent); 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch switch (SD->getMemoryVT().getSizeInBits()) { 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case 8: 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch case 16: 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AliasReg = TM.getFrameLowering()->hasFP(*MF)? 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch AliasFPReg: getMips16SPAliasReg(); 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return; 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) break; 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AliasReg = CurDAG->getRegister(Mips::SP, TLI.getPointerTy()); 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Mips16DAGToDAGISel::selectAddr16( 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDNode *Parent, SDValue Addr, SDValue &Base, SDValue &Offset, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue &Alias) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EVT ValTy = Addr.getValueType(); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Alias = CurDAG->getTargetConstant(0, ValTy); 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // if Address is FI, get the TargetFrameIndex. 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) { 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Offset = CurDAG->getTargetConstant(0, ValTy); 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getMips16SPRefReg(Parent, Alias); 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 165f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // on PIC code Load GA 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (Addr.getOpcode() == MipsISD::Wrapper) { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Base = Addr.getOperand(0); 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) Offset = Addr.getOperand(1); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (TM.getRelocationModel() != Reloc::PIC_) { 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if ((Addr.getOpcode() == ISD::TargetExternalSymbol || 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Addr.getOpcode() == ISD::TargetGlobalAddress)) 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Addresses of the form FI+const or FI|const 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (CurDAG->isBaseWithConstantOffset(Addr)) { 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (isInt<16>(CN->getSExtValue())) { 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If the first operand is a FI, get the TargetFI Node 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode> 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (Addr.getOperand(0))) { 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), ValTy); 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) getMips16SPRefReg(Parent, Alias); 1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) else 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Base = Addr.getOperand(0); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Offset = CurDAG->getTargetConstant(CN->getZExtValue(), ValTy); 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Operand is a result from an ADD. 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Addr.getOpcode() == ISD::ADD) { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // When loading from constant pools, load the lower address part in 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the instruction itself. Example, instead of: 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // lui $2, %hi($CPI1_0) 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // addiu $2, $2, %lo($CPI1_0) 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // lwc1 $f0, 0($2) 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Generate: 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // lui $2, %hi($CPI1_0) 2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // lwc1 $f0, %lo($CPI1_0)($2) 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Addr.getOperand(1).getOpcode() == MipsISD::Lo || 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Addr.getOperand(1).getOpcode() == MipsISD::GPRel) { 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue Opnd0 = Addr.getOperand(1).getOperand(0); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (isa<ConstantPoolSDNode>(Opnd0) || isa<GlobalAddressSDNode>(Opnd0) || 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) isa<JumpTableSDNode>(Opnd0)) { 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Base = Addr.getOperand(0); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Offset = Opnd0; 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // If an indexed floating point load/store can be emitted, return false. 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LSBaseSDNode *LS = dyn_cast<LSBaseSDNode>(Parent); 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (LS && 2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (LS->getMemoryVT() == MVT::f32 || LS->getMemoryVT() == MVT::f64) && 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Subtarget.hasFPIdx()) 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return false; 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Base = Addr; 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Offset = CurDAG->getTargetConstant(0, ValTy); 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// Select instructions not customized! Used for 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/// expanded, promoted and normal instructions 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::pair<bool, SDNode*> Mips16DAGToDAGISel::selectNode(SDNode *Node) { 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Opcode = Node->getOpcode(); 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DebugLoc DL = Node->getDebugLoc(); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Instruction Selection not handled by the auto-generated 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // tablegen selection should be handled here. 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EVT NodeTy = Node->getValueType(0); 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned MultOpc; 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) switch(Opcode) { 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) default: break; 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::SUBE: 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::ADDE: { 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue InFlag = Node->getOperand(2), CmpLHS; 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Opc = InFlag.getOpcode(); (void)Opc; 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) assert(((Opc == ISD::ADDC || Opc == ISD::ADDE) || 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) (Opc == ISD::SUBC || Opc == ISD::SUBE)) && 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "(ADD|SUB)E flag operand must come from (ADD|SUB)C/E insn"); 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned MOp; 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (Opcode == ISD::ADDE) { 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CmpLHS = InFlag.getValue(0); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MOp = Mips::AdduRxRyRz16; 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CmpLHS = InFlag.getOperand(0); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MOp = Mips::SubuRxRyRz16; 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue Ops[] = { CmpLHS, InFlag.getOperand(1) }; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue LHS = Node->getOperand(0); 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue RHS = Node->getOperand(1); 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EVT VT = LHS.getValueType(); 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Sltu_op = Mips::SltuRxRyRz16; 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDNode *Carry = CurDAG->getMachineNode(Sltu_op, DL, VT, Ops, 2); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unsigned Addu_op = Mips::AdduRxRyRz16; 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDNode *AddCarry = CurDAG->getMachineNode(Addu_op, DL, VT, 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue(Carry,0), RHS); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDNode *Result = CurDAG->SelectNodeTo(Node, MOp, VT, MVT::Glue, LHS, 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDValue(AddCarry,0)); 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::make_pair(true, Result); 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) /// Mul with two results 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::SMUL_LOHI: 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::UMUL_LOHI: { 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MultOpc = (Opcode == ISD::UMUL_LOHI ? Mips::MultuRxRy16 : Mips::MultRxRy16); 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::pair<SDNode*, SDNode*> LoHi = selectMULT(Node, MultOpc, DL, NodeTy, 2852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, true); 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!SDValue(Node, 0).use_empty()) 2872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReplaceUses(SDValue(Node, 0), SDValue(LoHi.first, 0)); 2882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!SDValue(Node, 1).use_empty()) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReplaceUses(SDValue(Node, 1), SDValue(LoHi.second, 0)); 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::make_pair(true, (SDNode*)NULL); 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::MULHS: 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) case ISD::MULHU: { 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) MultOpc = (Opcode == ISD::MULHU ? Mips::MultuRxRy16 : Mips::MultRxRy16); 2982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) SDNode *Result = selectMULT(Node, MultOpc, DL, NodeTy, false, true).second; 2992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::make_pair(true, Result); 3002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return std::make_pair(false, (SDNode*)NULL); 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)FunctionPass *llvm::createMips16ISelDag(MipsTargetMachine &TM) { 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return new Mips16DAGToDAGISel(TM); 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)