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