MipsSEInstrInfo.cpp revision b1f4f120a50c392c85c6b4388d63e36251fce279
15c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//===-- MipsSEInstrInfo.cpp - Mips32/64 Instruction Information -----------===//
25c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
35c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//                     The LLVM Compiler Infrastructure
45c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
55c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This file is distributed under the University of Illinois Open Source
65c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// License. See LICENSE.TXT for details.
75c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
8116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch//===----------------------------------------------------------------------===//
95c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
105c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu// This file contains the Mips32/64 implementation of the TargetInstrInfo class.
115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//
125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu//===----------------------------------------------------------------------===//
135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch#include "MipsSEInstrInfo.h"
1546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)#include "InstPrinter/MipsInstPrinter.h"
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "MipsMachineFunction.h"
175c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "MipsTargetMachine.h"
185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/ADT/STLExtras.h"
195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/CodeGen/MachineInstrBuilder.h"
205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/CodeGen/MachineRegisterInfo.h"
215c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/Support/CommandLine.h"
225c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu#include "llvm/Support/ErrorHandling.h"
23cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)#include "llvm/Support/TargetRegistry.h"
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
25cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)using namespace llvm;
26cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
27cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)static cl::opt<bool> NoDPLoadStore("mno-ldc1-sdc1", cl::init(false),
28cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                                   cl::desc("Expand double precision loads and "
29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            "stores to their single precision "
30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch                                            "counterparts."));
315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuMipsSEInstrInfo::MipsSEInstrInfo(MipsTargetMachine &tm)
335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  : MipsInstrInfo(tm,
345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                  tm.getRelocationModel() == Reloc::PIC_ ? Mips::B : Mips::J),
355c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    RI(*tm.getSubtargetImpl()),
36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    IsN64(tm.getSubtarget<MipsSubtarget>().isABI_N64()) {}
37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
38116680a4aac90f2aa7413d9095a592090648e557Ben Murdochconst MipsRegisterInfo &MipsSEInstrInfo::getRegisterInfo() const {
39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return RI;
40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// isLoadFromStackSlot - If the specified machine instruction is a direct
43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch/// load from a stack slot, return the virtual or physical register number of
445c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/// the destination along with the FrameIndex of the loaded stack slot.  If
455c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/// not, return 0.  This predicate must return 0 if the instruction has
465c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/// any side effects other than loading from the stack slot.
475c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuunsigned MipsSEInstrInfo::
485c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuisLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const
495c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu{
505c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  unsigned Opc = MI->getOpcode();
515c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
525c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if ((Opc == Mips::LW)   || (Opc == Mips::LD)   ||
535c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      (Opc == Mips::LWC1) || (Opc == Mips::LDC1) || (Opc == Mips::LDC164)) {
545c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if ((MI->getOperand(1).isFI()) && // is a stack slot
55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        (MI->getOperand(2).isImm()) &&  // the imm is zero
56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch        (isZeroImm(MI->getOperand(2)))) {
57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      FrameIndex = MI->getOperand(1).getIndex();
58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      return MI->getOperand(0).getReg();
59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    }
60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
61116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  return 0;
63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch}
645c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
655c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/// isStoreToStackSlot - If the specified machine instruction is a direct
665c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/// store to a stack slot, return the virtual or physical register number of
675c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/// the source reg along with the FrameIndex of the loaded stack slot.  If
685c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/// not, return 0.  This predicate must return 0 if the instruction has
695c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu/// any side effects other than storing to the stack slot.
705c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuunsigned MipsSEInstrInfo::
715c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo LiuisStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const
725c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu{
735c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  unsigned Opc = MI->getOpcode();
745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if ((Opc == Mips::SW)   || (Opc == Mips::SD)   ||
765c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      (Opc == Mips::SWC1) || (Opc == Mips::SDC1) || (Opc == Mips::SDC164)) {
775c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if ((MI->getOperand(1).isFI()) && // is a stack slot
785c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        (MI->getOperand(2).isImm()) &&  // the imm is zero
795c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        (isZeroImm(MI->getOperand(2)))) {
805c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      FrameIndex = MI->getOperand(1).getIndex();
81cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)      return MI->getOperand(0).getReg();
82cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  }
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  return 0;
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu}
865c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuvoid MipsSEInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
885c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                  MachineBasicBlock::iterator I, DebugLoc DL,
895c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                  unsigned DestReg, unsigned SrcReg,
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu                                  bool KillSrc) const {
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  unsigned Opc = 0, ZeroReg = 0;
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  if (Mips::GPR32RegClass.contains(DestReg)) { // Copy to CPU Reg.
945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    if (Mips::GPR32RegClass.contains(SrcReg))
955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      Opc = Mips::ADDu, ZeroReg = Mips::ZERO;
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    else if (Mips::CCRRegClass.contains(SrcReg))
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      Opc = Mips::CFC1;
985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    else if (Mips::FGR32RegClass.contains(SrcReg))
995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MFC1;
1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::HI32RegClass.contains(SrcReg))
1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MFHI, SrcReg = 0;
1025f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::LO32RegClass.contains(SrcReg))
1035f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MFLO, SrcReg = 0;
1045f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::HI32DSPRegClass.contains(SrcReg))
1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MFHI_DSP;
1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::LO32DSPRegClass.contains(SrcReg))
1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MFLO_DSP;
1085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::DSPCCRegClass.contains(SrcReg)) {
1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      BuildMI(MBB, I, DL, get(Mips::RDDSP), DestReg).addImm(1 << 4)
1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        .addReg(SrcReg, RegState::Implicit | getKillRegState(KillSrc));
1115c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return;
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::GPR32RegClass.contains(SrcReg)) { // Copy from CPU Reg.
1155f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (Mips::CCRRegClass.contains(DestReg))
1165f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::CTC1;
1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::FGR32RegClass.contains(DestReg))
1185f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MTC1;
1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::HI32RegClass.contains(DestReg))
1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MTHI, DestReg = 0;
12146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    else if (Mips::LO32RegClass.contains(DestReg))
12246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)      Opc = Mips::MTLO, DestReg = 0;
12346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    else if (Mips::HI32DSPRegClass.contains(DestReg))
1245c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      Opc = Mips::MTHI_DSP;
12546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    else if (Mips::LO32DSPRegClass.contains(DestReg))
1265c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      Opc = Mips::MTLO_DSP;
1275c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    else if (Mips::DSPCCRegClass.contains(DestReg)) {
1285c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      BuildMI(MBB, I, DL, get(Mips::WRDSP))
1295c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        .addReg(SrcReg, getKillRegState(KillSrc)).addImm(1 << 4)
1305c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        .addReg(DestReg, RegState::ImplicitDefine);
1315c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      return;
1325c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    }
1335c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  }
1345c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::FGR32RegClass.contains(DestReg, SrcReg))
1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Opc = Mips::FMOV_S;
1365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::AFGR64RegClass.contains(DestReg, SrcReg))
1375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Opc = Mips::FMOV_D32;
1385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::FGR64RegClass.contains(DestReg, SrcReg))
1395f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Opc = Mips::FMOV_D64;
140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else if (Mips::GPR64RegClass.contains(DestReg)) { // Copy to CPU64 Reg.
141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    if (Mips::GPR64RegClass.contains(SrcReg))
142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch      Opc = Mips::DADDu, ZeroReg = Mips::ZERO_64;
1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::HI64RegClass.contains(SrcReg))
1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MFHI64, SrcReg = 0;
1455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::LO64RegClass.contains(SrcReg))
1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MFLO64, SrcReg = 0;
1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::FGR64RegClass.contains(SrcReg))
1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::DMFC1;
1495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  else if (Mips::GPR64RegClass.contains(SrcReg)) { // Copy from CPU64 Reg.
1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    if (Mips::HI64RegClass.contains(DestReg))
1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MTHI64, DestReg = 0;
1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::LO64RegClass.contains(DestReg))
1545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::MTLO64, DestReg = 0;
1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    else if (Mips::FGR64RegClass.contains(DestReg))
1565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)      Opc = Mips::DMTC1;
1575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
1585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  assert(Opc && "Cannot copy registers");
1605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc));
1625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (DestReg)
1645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MIB.addReg(DestReg, RegState::Define);
1655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (SrcReg)
1675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MIB.addReg(SrcReg, getKillRegState(KillSrc));
1685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1695f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (ZeroReg)
1705f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    MIB.addReg(ZeroReg);
1715f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)}
1725f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1735f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void MipsSEInstrInfo::
1745f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)storeRegToStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
1755f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                unsigned SrcReg, bool isKill, int FI,
1765f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
1775f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                int64_t Offset) const {
1785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  DebugLoc DL;
1795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (I != MBB.end()) DL = I->getDebugLoc();
1805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore);
1815f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1825f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  unsigned Opc = 0;
1835f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
1845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  if (Mips::GPR32RegClass.hasSubClassEq(RC))
1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Opc = Mips::SW;
186116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  else if (Mips::GPR64RegClass.hasSubClassEq(RC))
1875c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Opc = Mips::SD;
188cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)  else if (Mips::ACC64RegClass.hasSubClassEq(RC))
1895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    Opc = Mips::STORE_ACC64;
1905f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))
1915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Opc = Mips::STORE_ACC64DSP;
1925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::ACC128RegClass.hasSubClassEq(RC))
1935c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Opc = Mips::STORE_ACC128;
1945c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
1955c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Opc = Mips::STORE_CCOND_DSP;
1965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::FGR32RegClass.hasSubClassEq(RC))
1975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Opc = Mips::SWC1;
1985c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
1995c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Opc = Mips::SDC1;
2005c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  else if (Mips::FGR64RegClass.hasSubClassEq(RC))
2015c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    Opc = Mips::SDC164;
202
203  assert(Opc && "Register class not handled!");
204  BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill))
205    .addFrameIndex(FI).addImm(Offset).addMemOperand(MMO);
206}
207
208void MipsSEInstrInfo::
209loadRegFromStack(MachineBasicBlock &MBB, MachineBasicBlock::iterator I,
210                 unsigned DestReg, int FI, const TargetRegisterClass *RC,
211                 const TargetRegisterInfo *TRI, int64_t Offset) const {
212  DebugLoc DL;
213  if (I != MBB.end()) DL = I->getDebugLoc();
214  MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad);
215  unsigned Opc = 0;
216
217  if (Mips::GPR32RegClass.hasSubClassEq(RC))
218    Opc = Mips::LW;
219  else if (Mips::GPR64RegClass.hasSubClassEq(RC))
220    Opc = Mips::LD;
221  else if (Mips::ACC64RegClass.hasSubClassEq(RC))
222    Opc = Mips::LOAD_ACC64;
223  else if (Mips::ACC64DSPRegClass.hasSubClassEq(RC))
224    Opc = Mips::LOAD_ACC64DSP;
225  else if (Mips::ACC128RegClass.hasSubClassEq(RC))
226    Opc = Mips::LOAD_ACC128;
227  else if (Mips::DSPCCRegClass.hasSubClassEq(RC))
228    Opc = Mips::LOAD_CCOND_DSP;
229  else if (Mips::FGR32RegClass.hasSubClassEq(RC))
230    Opc = Mips::LWC1;
231  else if (Mips::AFGR64RegClass.hasSubClassEq(RC))
232    Opc = Mips::LDC1;
233  else if (Mips::FGR64RegClass.hasSubClassEq(RC))
234    Opc = Mips::LDC164;
235
236  assert(Opc && "Register class not handled!");
237  BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset)
238    .addMemOperand(MMO);
239}
240
241bool MipsSEInstrInfo::expandPostRAPseudo(MachineBasicBlock::iterator MI) const {
242  MachineBasicBlock &MBB = *MI->getParent();
243
244  switch(MI->getDesc().getOpcode()) {
245  default:
246    return false;
247  case Mips::RetRA:
248    expandRetRA(MBB, MI, Mips::RET);
249    break;
250  case Mips::PseudoCVT_S_W:
251    expandCvtFPInt(MBB, MI, Mips::CVT_S_W, Mips::MTC1, false);
252    break;
253  case Mips::PseudoCVT_D32_W:
254    expandCvtFPInt(MBB, MI, Mips::CVT_D32_W, Mips::MTC1, false);
255    break;
256  case Mips::PseudoCVT_S_L:
257    expandCvtFPInt(MBB, MI, Mips::CVT_S_L, Mips::DMTC1, true);
258    break;
259  case Mips::PseudoCVT_D64_W:
260    expandCvtFPInt(MBB, MI, Mips::CVT_D64_W, Mips::MTC1, true);
261    break;
262  case Mips::PseudoCVT_D64_L:
263    expandCvtFPInt(MBB, MI, Mips::CVT_D64_L, Mips::DMTC1, true);
264    break;
265  case Mips::BuildPairF64:
266    expandBuildPairF64(MBB, MI, false);
267    break;
268  case Mips::BuildPairF64_64:
269    expandBuildPairF64(MBB, MI, true);
270    break;
271  case Mips::ExtractElementF64:
272    expandExtractElementF64(MBB, MI, false);
273    break;
274  case Mips::ExtractElementF64_64:
275    expandExtractElementF64(MBB, MI, true);
276    break;
277  case Mips::PseudoLDC1:
278    expandDPLoadStore(MBB, MI, Mips::LDC1, Mips::LWC1);
279    break;
280  case Mips::PseudoSDC1:
281    expandDPLoadStore(MBB, MI, Mips::SDC1, Mips::SWC1);
282    break;
283  case Mips::MIPSeh_return32:
284  case Mips::MIPSeh_return64:
285    expandEhReturn(MBB, MI);
286    break;
287  }
288
289  MBB.erase(MI);
290  return true;
291}
292
293/// getOppositeBranchOpc - Return the inverse of the specified
294/// opcode, e.g. turning BEQ to BNE.
295unsigned MipsSEInstrInfo::getOppositeBranchOpc(unsigned Opc) const {
296  switch (Opc) {
297  default:           llvm_unreachable("Illegal opcode!");
298  case Mips::BEQ:    return Mips::BNE;
299  case Mips::BNE:    return Mips::BEQ;
300  case Mips::BGTZ:   return Mips::BLEZ;
301  case Mips::BGEZ:   return Mips::BLTZ;
302  case Mips::BLTZ:   return Mips::BGEZ;
303  case Mips::BLEZ:   return Mips::BGTZ;
304  case Mips::BEQ64:  return Mips::BNE64;
305  case Mips::BNE64:  return Mips::BEQ64;
306  case Mips::BGTZ64: return Mips::BLEZ64;
307  case Mips::BGEZ64: return Mips::BLTZ64;
308  case Mips::BLTZ64: return Mips::BGEZ64;
309  case Mips::BLEZ64: return Mips::BGTZ64;
310  case Mips::BC1T:   return Mips::BC1F;
311  case Mips::BC1F:   return Mips::BC1T;
312  }
313}
314
315/// Adjust SP by Amount bytes.
316void MipsSEInstrInfo::adjustStackPtr(unsigned SP, int64_t Amount,
317                                     MachineBasicBlock &MBB,
318                                     MachineBasicBlock::iterator I) const {
319  const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>();
320  DebugLoc DL = I != MBB.end() ? I->getDebugLoc() : DebugLoc();
321  unsigned ADDu = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
322  unsigned ADDiu = STI.isABI_N64() ? Mips::DADDiu : Mips::ADDiu;
323
324  if (isInt<16>(Amount))// addi sp, sp, amount
325    BuildMI(MBB, I, DL, get(ADDiu), SP).addReg(SP).addImm(Amount);
326  else { // Expand immediate that doesn't fit in 16-bit.
327    unsigned Reg = loadImmediate(Amount, MBB, I, DL, 0);
328    BuildMI(MBB, I, DL, get(ADDu), SP).addReg(SP).addReg(Reg, RegState::Kill);
329  }
330}
331
332/// This function generates the sequence of instructions needed to get the
333/// result of adding register REG and immediate IMM.
334unsigned
335MipsSEInstrInfo::loadImmediate(int64_t Imm, MachineBasicBlock &MBB,
336                               MachineBasicBlock::iterator II, DebugLoc DL,
337                               unsigned *NewImm) const {
338  MipsAnalyzeImmediate AnalyzeImm;
339  const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>();
340  MachineRegisterInfo &RegInfo = MBB.getParent()->getRegInfo();
341  unsigned Size = STI.isABI_N64() ? 64 : 32;
342  unsigned LUi = STI.isABI_N64() ? Mips::LUi64 : Mips::LUi;
343  unsigned ZEROReg = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
344  const TargetRegisterClass *RC = STI.isABI_N64() ?
345    &Mips::GPR64RegClass : &Mips::GPR32RegClass;
346  bool LastInstrIsADDiu = NewImm;
347
348  const MipsAnalyzeImmediate::InstSeq &Seq =
349    AnalyzeImm.Analyze(Imm, Size, LastInstrIsADDiu);
350  MipsAnalyzeImmediate::InstSeq::const_iterator Inst = Seq.begin();
351
352  assert(Seq.size() && (!LastInstrIsADDiu || (Seq.size() > 1)));
353
354  // The first instruction can be a LUi, which is different from other
355  // instructions (ADDiu, ORI and SLL) in that it does not have a register
356  // operand.
357  unsigned Reg = RegInfo.createVirtualRegister(RC);
358
359  if (Inst->Opc == LUi)
360    BuildMI(MBB, II, DL, get(LUi), Reg).addImm(SignExtend64<16>(Inst->ImmOpnd));
361  else
362    BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(ZEROReg)
363      .addImm(SignExtend64<16>(Inst->ImmOpnd));
364
365  // Build the remaining instructions in Seq.
366  for (++Inst; Inst != Seq.end() - LastInstrIsADDiu; ++Inst)
367    BuildMI(MBB, II, DL, get(Inst->Opc), Reg).addReg(Reg, RegState::Kill)
368      .addImm(SignExtend64<16>(Inst->ImmOpnd));
369
370  if (LastInstrIsADDiu)
371    *NewImm = Inst->ImmOpnd;
372
373  return Reg;
374}
375
376unsigned MipsSEInstrInfo::getAnalyzableBrOpc(unsigned Opc) const {
377  return (Opc == Mips::BEQ    || Opc == Mips::BNE    || Opc == Mips::BGTZ   ||
378          Opc == Mips::BGEZ   || Opc == Mips::BLTZ   || Opc == Mips::BLEZ   ||
379          Opc == Mips::BEQ64  || Opc == Mips::BNE64  || Opc == Mips::BGTZ64 ||
380          Opc == Mips::BGEZ64 || Opc == Mips::BLTZ64 || Opc == Mips::BLEZ64 ||
381          Opc == Mips::BC1T   || Opc == Mips::BC1F   || Opc == Mips::B      ||
382          Opc == Mips::J) ?
383         Opc : 0;
384}
385
386void MipsSEInstrInfo::expandRetRA(MachineBasicBlock &MBB,
387                                MachineBasicBlock::iterator I,
388                                unsigned Opc) const {
389  BuildMI(MBB, I, I->getDebugLoc(), get(Opc)).addReg(Mips::RA);
390}
391
392std::pair<bool, bool>
393MipsSEInstrInfo::compareOpndSize(unsigned Opc,
394                                 const MachineFunction &MF) const {
395  const MCInstrDesc &Desc = get(Opc);
396  assert(Desc.NumOperands == 2 && "Unary instruction expected.");
397  const MipsRegisterInfo *RI = &getRegisterInfo();
398  unsigned DstRegSize = getRegClass(Desc, 0, RI, MF)->getSize();
399  unsigned SrcRegSize = getRegClass(Desc, 1, RI, MF)->getSize();
400
401  return std::make_pair(DstRegSize > SrcRegSize, DstRegSize < SrcRegSize);
402}
403
404void MipsSEInstrInfo::expandCvtFPInt(MachineBasicBlock &MBB,
405                                     MachineBasicBlock::iterator I,
406                                     unsigned CvtOpc, unsigned MovOpc,
407                                     bool IsI64) const {
408  const MCInstrDesc &CvtDesc = get(CvtOpc), &MovDesc = get(MovOpc);
409  const MachineOperand &Dst = I->getOperand(0), &Src = I->getOperand(1);
410  unsigned DstReg = Dst.getReg(), SrcReg = Src.getReg(), TmpReg = DstReg;
411  unsigned KillSrc =  getKillRegState(Src.isKill());
412  DebugLoc DL = I->getDebugLoc();
413  bool DstIsLarger, SrcIsLarger;
414
415  tie(DstIsLarger, SrcIsLarger) = compareOpndSize(CvtOpc, *MBB.getParent());
416
417  if (DstIsLarger)
418    TmpReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
419
420  if (SrcIsLarger)
421    DstReg = getRegisterInfo().getSubReg(DstReg, Mips::sub_lo);
422
423  BuildMI(MBB, I, DL, MovDesc, TmpReg).addReg(SrcReg, KillSrc);
424  BuildMI(MBB, I, DL, CvtDesc, DstReg).addReg(TmpReg, RegState::Kill);
425}
426
427void MipsSEInstrInfo::expandExtractElementF64(MachineBasicBlock &MBB,
428                                              MachineBasicBlock::iterator I,
429                                              bool FP64) const {
430  unsigned DstReg = I->getOperand(0).getReg();
431  unsigned SrcReg = I->getOperand(1).getReg();
432  unsigned N = I->getOperand(2).getImm();
433  DebugLoc dl = I->getDebugLoc();
434
435  assert(N < 2 && "Invalid immediate");
436  unsigned SubIdx = N ? Mips::sub_hi : Mips::sub_lo;
437  unsigned SubReg = getRegisterInfo().getSubReg(SrcReg, SubIdx);
438
439  if (SubIdx == Mips::sub_hi && FP64)
440    BuildMI(MBB, I, dl, get(Mips::MFHC1), DstReg).addReg(SubReg);
441  else
442    BuildMI(MBB, I, dl, get(Mips::MFC1), DstReg).addReg(SubReg);
443}
444
445void MipsSEInstrInfo::expandBuildPairF64(MachineBasicBlock &MBB,
446                                         MachineBasicBlock::iterator I,
447                                         bool FP64) const {
448  unsigned DstReg = I->getOperand(0).getReg();
449  unsigned LoReg = I->getOperand(1).getReg(), HiReg = I->getOperand(2).getReg();
450  const MCInstrDesc& Mtc1Tdd = get(Mips::MTC1);
451  DebugLoc dl = I->getDebugLoc();
452  const TargetRegisterInfo &TRI = getRegisterInfo();
453
454  // mtc1 Lo, $fp
455  // mtc1 Hi, $fp + 1
456  BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_lo))
457    .addReg(LoReg);
458
459  if (FP64)
460    BuildMI(MBB, I, dl, get(Mips::MTHC1), TRI.getSubReg(DstReg, Mips::sub_hi))
461      .addReg(HiReg);
462  else
463    BuildMI(MBB, I, dl, Mtc1Tdd, TRI.getSubReg(DstReg, Mips::sub_hi))
464      .addReg(HiReg);
465}
466
467/// Add 4 to the displacement of operand MO.
468static void fixDisp(MachineOperand &MO) {
469  switch (MO.getType()) {
470  default:
471    llvm_unreachable("Unhandled operand type.");
472  case MachineOperand::MO_Immediate:
473    MO.setImm(MO.getImm() + 4);
474    break;
475  case MachineOperand::MO_GlobalAddress:
476  case MachineOperand::MO_ConstantPoolIndex:
477  case MachineOperand::MO_BlockAddress:
478  case MachineOperand::MO_TargetIndex:
479  case MachineOperand::MO_ExternalSymbol:
480    MO.setOffset(MO.getOffset() + 4);
481    break;
482  }
483}
484
485void MipsSEInstrInfo::expandDPLoadStore(MachineBasicBlock &MBB,
486                                        MachineBasicBlock::iterator I,
487                                        unsigned OpcD, unsigned OpcS) const {
488  // If NoDPLoadStore is false, just change the opcode.
489  if (!NoDPLoadStore) {
490    genInstrWithNewOpc(OpcD, I);
491    return;
492  }
493
494  // Expand a double precision FP load or store to two single precision
495  // instructions.
496
497  const TargetRegisterInfo &TRI = getRegisterInfo();
498  const MachineOperand &ValReg = I->getOperand(0);
499  unsigned LoReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_lo);
500  unsigned HiReg = TRI.getSubReg(ValReg.getReg(), Mips::sub_hi);
501
502  if (!TM.getSubtarget<MipsSubtarget>().isLittle())
503    std::swap(LoReg, HiReg);
504
505  // Create an instruction which loads from or stores to the lower memory
506  // address.
507  MachineInstrBuilder MIB = genInstrWithNewOpc(OpcS, I);
508  MIB->getOperand(0).setReg(LoReg);
509
510  // Create an instruction which loads from or stores to the higher memory
511  // address.
512  MIB = genInstrWithNewOpc(OpcS, I);
513  MIB->getOperand(0).setReg(HiReg);
514  fixDisp(MIB->getOperand(2));
515}
516
517void MipsSEInstrInfo::expandEhReturn(MachineBasicBlock &MBB,
518                                     MachineBasicBlock::iterator I) const {
519  // This pseudo instruction is generated as part of the lowering of
520  // ISD::EH_RETURN. We convert it to a stack increment by OffsetReg, and
521  // indirect jump to TargetReg
522  const MipsSubtarget &STI = TM.getSubtarget<MipsSubtarget>();
523  unsigned ADDU = STI.isABI_N64() ? Mips::DADDu : Mips::ADDu;
524  unsigned JR = STI.isABI_N64() ? Mips::JR64 : Mips::JR;
525  unsigned SP = STI.isABI_N64() ? Mips::SP_64 : Mips::SP;
526  unsigned RA = STI.isABI_N64() ? Mips::RA_64 : Mips::RA;
527  unsigned T9 = STI.isABI_N64() ? Mips::T9_64 : Mips::T9;
528  unsigned ZERO = STI.isABI_N64() ? Mips::ZERO_64 : Mips::ZERO;
529  unsigned OffsetReg = I->getOperand(0).getReg();
530  unsigned TargetReg = I->getOperand(1).getReg();
531
532  // addu $ra, $v0, $zero
533  // addu $sp, $sp, $v1
534  // jr   $ra
535  if (TM.getRelocationModel() == Reloc::PIC_)
536    BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), T9)
537        .addReg(TargetReg).addReg(ZERO);
538  BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), RA)
539      .addReg(TargetReg).addReg(ZERO);
540  BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(ADDU), SP)
541      .addReg(SP).addReg(OffsetReg);
542  BuildMI(MBB, I, I->getDebugLoc(), TM.getInstrInfo()->get(JR)).addReg(RA);
543}
544
545const MipsInstrInfo *llvm::createMipsSEInstrInfo(MipsTargetMachine &TM) {
546  return new MipsSEInstrInfo(TM);
547}
548