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)