MBlazeInstrInfo.cpp revision 420761a0f193e87d08ee1c51b26bba23ab4bac7f
131d157ae1ac2cd9c787dc3c1d28e64c682803844Jia Liu//===-- MBlazeInstrInfo.cpp - MBlaze Instruction Information --------------===// 2a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 3a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// The LLVM Compiler Infrastructure 4a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 5a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// This file is distributed under the University of Illinois Open Source 6a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// License. See LICENSE.TXT for details. 7a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 8a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 9a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 10a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// This file contains the MBlaze implementation of the TargetInstrInfo class. 11a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// 12a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 13a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 14a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeInstrInfo.h" 15a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeTargetMachine.h" 16a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeMachineFunction.h" 17a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineInstrBuilder.h" 18a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/CodeGen/MachineRegisterInfo.h" 193d820baf195973de23d6520d692acc6bfb43bfe9Wesley Peck#include "llvm/CodeGen/ScoreboardHazardRecognizer.h" 203d820baf195973de23d6520d692acc6bfb43bfe9Wesley Peck#include "llvm/Support/CommandLine.h" 21a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "llvm/Support/ErrorHandling.h" 223e74d6fdd248e20a280f1dff3da9a6c689c2c4c3Evan Cheng#include "llvm/Support/TargetRegistry.h" 2359ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include "llvm/ADT/STLExtras.h" 2422fee2dff4c43b551aefa44a96ca74fcade6bfacEvan Cheng 254db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng#define GET_INSTRINFO_CTOR 26a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck#include "MBlazeGenInstrInfo.inc" 27a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 28a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckusing namespace llvm; 29a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 30a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckMBlazeInstrInfo::MBlazeInstrInfo(MBlazeTargetMachine &tm) 314db3cffe94a5285239cc0056f939c6b74a5ca0b6Evan Cheng : MBlazeGenInstrInfo(MBlaze::ADJCALLSTACKDOWN, MBlaze::ADJCALLSTACKUP), 32a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck TM(tm), RI(*TM.getSubtargetImpl(), *this) {} 33a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 34a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckstatic bool isZeroImm(const MachineOperand &op) { 35a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return op.isImm() && op.getImm() == 0; 36a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 37a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 38a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// isLoadFromStackSlot - If the specified machine instruction is a direct 39a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// load from a stack slot, return the virtual or physical register number of 40a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// the destination along with the FrameIndex of the loaded stack slot. If 41a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// not, return 0. This predicate must return 0 if the instruction has 42a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// any side effects other than loading from the stack slot. 43a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckunsigned MBlazeInstrInfo:: 44a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckisLoadFromStackSlot(const MachineInstr *MI, int &FrameIndex) const { 45a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (MI->getOpcode() == MBlaze::LWI) { 4641400da31ead2f61d171381c0945dceddd8fc786Wesley Peck if ((MI->getOperand(1).isFI()) && // is a stack slot 4741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck (MI->getOperand(2).isImm()) && // the imm is zero 4841400da31ead2f61d171381c0945dceddd8fc786Wesley Peck (isZeroImm(MI->getOperand(2)))) { 4941400da31ead2f61d171381c0945dceddd8fc786Wesley Peck FrameIndex = MI->getOperand(1).getIndex(); 50a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return MI->getOperand(0).getReg(); 51a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 52a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 53a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 54a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return 0; 55a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 56a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 57a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// isStoreToStackSlot - If the specified machine instruction is a direct 58a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// store to a stack slot, return the virtual or physical register number of 59a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// the source reg along with the FrameIndex of the loaded stack slot. If 60a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// not, return 0. This predicate must return 0 if the instruction has 61a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// any side effects other than storing to the stack slot. 62a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckunsigned MBlazeInstrInfo:: 63a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckisStoreToStackSlot(const MachineInstr *MI, int &FrameIndex) const { 64a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (MI->getOpcode() == MBlaze::SWI) { 6541400da31ead2f61d171381c0945dceddd8fc786Wesley Peck if ((MI->getOperand(1).isFI()) && // is a stack slot 6641400da31ead2f61d171381c0945dceddd8fc786Wesley Peck (MI->getOperand(2).isImm()) && // the imm is zero 6741400da31ead2f61d171381c0945dceddd8fc786Wesley Peck (isZeroImm(MI->getOperand(2)))) { 6841400da31ead2f61d171381c0945dceddd8fc786Wesley Peck FrameIndex = MI->getOperand(1).getIndex(); 69a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return MI->getOperand(0).getReg(); 70a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 71a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck } 72a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return 0; 73a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 74a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 75a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// insertNoop - If data hazard condition is found insert the target nop 76a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// instruction. 77a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckvoid MBlazeInstrInfo:: 78a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckinsertNoop(MachineBasicBlock &MBB, MachineBasicBlock::iterator MI) const { 79c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner DebugLoc DL; 80a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck BuildMI(MBB, MI, DL, get(MBlaze::NOP)); 81a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 82a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 83e6afcf8da2ee4b4bdef7b65b845bc66257432f4eJakob Stoklund Olesenvoid MBlazeInstrInfo:: 84e6afcf8da2ee4b4bdef7b65b845bc66257432f4eJakob Stoklund OlesencopyPhysReg(MachineBasicBlock &MBB, 85e6afcf8da2ee4b4bdef7b65b845bc66257432f4eJakob Stoklund Olesen MachineBasicBlock::iterator I, DebugLoc DL, 86e6afcf8da2ee4b4bdef7b65b845bc66257432f4eJakob Stoklund Olesen unsigned DestReg, unsigned SrcReg, 87e6afcf8da2ee4b4bdef7b65b845bc66257432f4eJakob Stoklund Olesen bool KillSrc) const { 889eb337a2b7bc24eabdba32a801c8b36d5ac9c11dWesley Peck llvm::BuildMI(MBB, I, DL, get(MBlaze::ADDK), DestReg) 89e6afcf8da2ee4b4bdef7b65b845bc66257432f4eJakob Stoklund Olesen .addReg(SrcReg, getKillRegState(KillSrc)).addReg(MBlaze::R0); 90a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 91a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 92a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckvoid MBlazeInstrInfo:: 93a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckstoreRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 94a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned SrcReg, bool isKill, int FI, 95746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterClass *RC, 96746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI) const { 97c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner DebugLoc DL; 98c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner BuildMI(MBB, I, DL, get(MBlaze::SWI)).addReg(SrcReg,getKillRegState(isKill)) 9941400da31ead2f61d171381c0945dceddd8fc786Wesley Peck .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI); 100a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 101a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 102a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckvoid MBlazeInstrInfo:: 103a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckloadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 104a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned DestReg, int FI, 105746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterClass *RC, 106746ad69e088176819981b4b2c5ac8dcd49f5e60eEvan Cheng const TargetRegisterInfo *TRI) const { 107c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner DebugLoc DL; 108c7f3ace20c325521c68335a1689645b43b06ddf0Chris Lattner BuildMI(MBB, I, DL, get(MBlaze::LWI), DestReg) 10941400da31ead2f61d171381c0945dceddd8fc786Wesley Peck .addFrameIndex(FI).addImm(0); //.addFrameIndex(FI); 110a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 111a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 112a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 113a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck// Branch Analysis 114a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck//===----------------------------------------------------------------------===// 11546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peckbool MBlazeInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, 11646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck MachineBasicBlock *&TBB, 11746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck MachineBasicBlock *&FBB, 11846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck SmallVectorImpl<MachineOperand> &Cond, 11946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck bool AllowModify) const { 12046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // If the block has no terminators, it just falls into the block after it. 12146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck MachineBasicBlock::iterator I = MBB.end(); 12246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (I == MBB.begin()) 12346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return false; 12446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck --I; 12546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck while (I->isDebugValue()) { 12646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (I == MBB.begin()) 12746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return false; 12846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck --I; 12946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck } 13046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (!isUnpredicatedTerminator(I)) 13146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return false; 13246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 13346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // Get the last instruction in the block. 13446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck MachineInstr *LastInst = I; 13546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 13646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // If there is only one terminator instruction, process it. 13746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck unsigned LastOpc = LastInst->getOpcode(); 13846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 13946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (MBlaze::isUncondBranchOpcode(LastOpc)) { 14046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck TBB = LastInst->getOperand(0).getMBB(); 14146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return false; 14246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck } 14346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (MBlaze::isCondBranchOpcode(LastOpc)) { 14446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // Block ends with fall-through condbranch. 14546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck TBB = LastInst->getOperand(1).getMBB(); 14646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 14746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck Cond.push_back(LastInst->getOperand(0)); 14846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return false; 14946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck } 15046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // Otherwise, don't know what this is. 15146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return true; 15246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck } 15346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 15446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // Get the instruction before it if it's a terminator. 15546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck MachineInstr *SecondLastInst = I; 15646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 15746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // If there are three terminators, we don't know what sort of block this is. 15846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(--I)) 15946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return true; 16046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 16146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // If the block ends with something like BEQID then BRID, handle it. 16246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (MBlaze::isCondBranchOpcode(SecondLastInst->getOpcode()) && 16346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) { 16446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck TBB = SecondLastInst->getOperand(1).getMBB(); 16546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode())); 16646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck Cond.push_back(SecondLastInst->getOperand(0)); 16746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck FBB = LastInst->getOperand(0).getMBB(); 16846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return false; 16946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck } 17046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 17146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // If the block ends with two unconditional branches, handle it. 17246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // The second one is not executed, so remove it. 17346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (MBlaze::isUncondBranchOpcode(SecondLastInst->getOpcode()) && 17446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck MBlaze::isUncondBranchOpcode(LastInst->getOpcode())) { 17546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck TBB = SecondLastInst->getOperand(0).getMBB(); 17646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck I = LastInst; 17746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (AllowModify) 17846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck I->eraseFromParent(); 17946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return false; 18046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck } 18146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 18246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // Otherwise, can't handle this. 18346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return true; 18446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck} 18546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 186a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckunsigned MBlazeInstrInfo:: 187a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley PeckInsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 188a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MachineBasicBlock *FBB, 1893bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings const SmallVectorImpl<MachineOperand> &Cond, 1903bf912593301152b65accb9d9c37a95172f1df5aStuart Hastings DebugLoc DL) const { 19146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // Shouldn't be a fall through. 19246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 19346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck assert((Cond.size() == 2 || Cond.size() == 0) && 19446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck "MBlaze branch conditions have two components!"); 19546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 19646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck unsigned Opc = MBlaze::BRID; 19746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (!Cond.empty()) 19846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck Opc = (unsigned)Cond[0].getImm(); 19946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 20046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (FBB == 0) { 20146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (Cond.empty()) // Unconditional branch 20246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck BuildMI(&MBB, DL, get(Opc)).addMBB(TBB); 20346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck else // Conditional branch 20446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB); 20546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return 1; 20646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck } 20746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 20846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck BuildMI(&MBB, DL, get(Opc)).addReg(Cond[1].getReg()).addMBB(TBB); 20946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck BuildMI(&MBB, DL, get(MBlaze::BRID)).addMBB(FBB); 21046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return 2; 21146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck} 21246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 21346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peckunsigned MBlazeInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 21446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck MachineBasicBlock::iterator I = MBB.end(); 21546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (I == MBB.begin()) return 0; 21646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck --I; 21746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck while (I->isDebugValue()) { 21846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (I == MBB.begin()) 21946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return 0; 22046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck --I; 22146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck } 22246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 22346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (!MBlaze::isUncondBranchOpcode(I->getOpcode()) && 22446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck !MBlaze::isCondBranchOpcode(I->getOpcode())) 22546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return 0; 22646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 22746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // Remove the branch. 22846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck I->eraseFromParent(); 22946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 23046a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck I = MBB.end(); 23146a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 23246a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (I == MBB.begin()) return 1; 23346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck --I; 23446a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck if (!MBlaze::isCondBranchOpcode(I->getOpcode())) 23546a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return 1; 23646a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 23746a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck // Remove the branch. 23846a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck I->eraseFromParent(); 23946a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck return 2; 240a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 241a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 2422e3441e5e583c873117530a54a6d3ea30af53b1fWesley Peckbool MBlazeInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> 2432e3441e5e583c873117530a54a6d3ea30af53b1fWesley Peck &Cond) const { 2442e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck assert(Cond.size() == 2 && "Invalid MBlaze branch opcode!"); 2452e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck switch (Cond[0].getImm()) { 2462e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck default: return true; 2472e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BEQ: Cond[0].setImm(MBlaze::BNE); return false; 2482e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BNE: Cond[0].setImm(MBlaze::BEQ); return false; 2492e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BGT: Cond[0].setImm(MBlaze::BLE); return false; 2502e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BGE: Cond[0].setImm(MBlaze::BLT); return false; 2512e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BLT: Cond[0].setImm(MBlaze::BGE); return false; 2522e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BLE: Cond[0].setImm(MBlaze::BGT); return false; 2532e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BEQI: Cond[0].setImm(MBlaze::BNEI); return false; 2542e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BNEI: Cond[0].setImm(MBlaze::BEQI); return false; 2552e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BGTI: Cond[0].setImm(MBlaze::BLEI); return false; 2562e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BGEI: Cond[0].setImm(MBlaze::BLTI); return false; 2572e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BLTI: Cond[0].setImm(MBlaze::BGEI); return false; 2582e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BLEI: Cond[0].setImm(MBlaze::BGTI); return false; 2592e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BEQD: Cond[0].setImm(MBlaze::BNED); return false; 2602e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BNED: Cond[0].setImm(MBlaze::BEQD); return false; 2612e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BGTD: Cond[0].setImm(MBlaze::BLED); return false; 2622e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BGED: Cond[0].setImm(MBlaze::BLTD); return false; 2632e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BLTD: Cond[0].setImm(MBlaze::BGED); return false; 2642e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BLED: Cond[0].setImm(MBlaze::BGTD); return false; 2652e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BEQID: Cond[0].setImm(MBlaze::BNEID); return false; 2662e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BNEID: Cond[0].setImm(MBlaze::BEQID); return false; 2672e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BGTID: Cond[0].setImm(MBlaze::BLEID); return false; 2682e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BGEID: Cond[0].setImm(MBlaze::BLTID); return false; 2692e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BLTID: Cond[0].setImm(MBlaze::BGEID); return false; 2702e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck case MBlaze::BLEID: Cond[0].setImm(MBlaze::BGTID); return false; 2712e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck } 2722e06398405c61d6d2aa99785fe34d34c33808330Wesley Peck} 27346a928b864369ba9e1b8fc055d100c2fa0f97d16Wesley Peck 274a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// getGlobalBaseReg - Return a virtual register initialized with the 275a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// the global base register value. Output instructions required to 276a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// initialize the register in the function entry block, if necessary. 277a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck/// 278a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peckunsigned MBlazeInstrInfo::getGlobalBaseReg(MachineFunction *MF) const { 279a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MBlazeFunctionInfo *MBlazeFI = MF->getInfo<MBlazeFunctionInfo>(); 280a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck unsigned GlobalBaseReg = MBlazeFI->getGlobalBaseReg(); 281a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck if (GlobalBaseReg != 0) 282a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return GlobalBaseReg; 283a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 284a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck // Insert the set of GlobalBaseReg into the first MBB of the function 285a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MachineBasicBlock &FirstMBB = MF->front(); 286a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MachineBasicBlock::iterator MBBI = FirstMBB.begin(); 287a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MachineRegisterInfo &RegInfo = MF->getRegInfo(); 288a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck const TargetInstrInfo *TII = MF->getTarget().getInstrInfo(); 289a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 290420761a0f193e87d08ee1c51b26bba23ab4bac7fCraig Topper GlobalBaseReg = RegInfo.createVirtualRegister(&MBlaze::GPRRegClass); 2913ecf1f0179b678437600da322d029ab77726409cJakob Stoklund Olesen BuildMI(FirstMBB, MBBI, DebugLoc(), TII->get(TargetOpcode::COPY), 2923ecf1f0179b678437600da322d029ab77726409cJakob Stoklund Olesen GlobalBaseReg).addReg(MBlaze::R20); 293a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck RegInfo.addLiveIn(MBlaze::R20); 294a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck 295a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck MBlazeFI->setGlobalBaseReg(GlobalBaseReg); 296a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck return GlobalBaseReg; 297a70f28ce7dc85d0075a7d86da5d7987b6e306bc6Wesley Peck} 298