1894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===- SPUInstrInfo.cpp - Cell SPU Instruction Information ----------------===// 2894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 3894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// The LLVM Compiler Infrastructure 4894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 5894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file is distributed under the University of Illinois Open Source 6894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// License. See LICENSE.TXT for details. 7894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 8894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 9894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 10894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// This file contains the Cell SPU implementation of the TargetInstrInfo class. 11894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman// 12894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//===----------------------------------------------------------------------===// 13894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 14894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUInstrInfo.h" 15894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUInstrBuilder.h" 16894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "SPUTargetMachine.h" 1719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "SPUHazardRecognizers.h" 18894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/CodeGen/MachineInstrBuilder.h" 1919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/MC/MCContext.h" 20894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/Debug.h" 21894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/ErrorHandling.h" 2219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "llvm/Support/TargetRegistry.h" 23894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman#include "llvm/Support/raw_ostream.h" 24894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 2519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#define GET_INSTRINFO_CTOR 2619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman#include "SPUGenInstrInfo.inc" 2719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 28894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanusing namespace llvm; 29894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 30894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumannamespace { 31894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Predicate for an unconditional branch instruction 32894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman inline bool isUncondBranch(const MachineInstr *I) { 33894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned opc = I->getOpcode(); 34894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 35894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return (opc == SPU::BR 36894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BRA 37894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BI); 38894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 39894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman //! Predicate for a conditional branch instruction 41894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman inline bool isCondBranch(const MachineInstr *I) { 42894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned opc = I->getOpcode(); 43894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 44894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return (opc == SPU::BRNZr32 45894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BRNZv4i32 46894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BRZr32 47894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BRZv4i32 48894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BRHNZr16 49894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BRHNZv8i16 50894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BRHZr16 51894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman || opc == SPU::BRHZv8i16); 52894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 53894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 54894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 55894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::SPUInstrInfo(SPUTargetMachine &tm) 5619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman : SPUGenInstrInfo(SPU::ADJCALLSTACKDOWN, SPU::ADJCALLSTACKUP), 57894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TM(tm), 58894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman RI(*TM.getSubtargetImpl(), *this) 59894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ /* NOP */ } 60894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 6119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// CreateTargetHazardRecognizer - Return the hazard recognizer to use for 6219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/// this target when scheduling the DAG. 6319bac1e08be200c31efd26f0f5fd144c9b3eefd3John BaumanScheduleHazardRecognizer *SPUInstrInfo::CreateTargetHazardRecognizer( 6419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetMachine *TM, 6519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const ScheduleDAG *DAG) const { 6619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman const TargetInstrInfo *TII = TM->getInstrInfo(); 6719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman assert(TII && "No InstrInfo?"); 6819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return new SPUHazardRecognizer(*TII); 6919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 7019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 71894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned 72894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::isLoadFromStackSlot(const MachineInstr *MI, 73894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int &FrameIndex) const { 74894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (MI->getOpcode()) { 75894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: break; 76894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDv16i8: 77894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDv8i16: 78894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDv4i32: 79894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDv4f32: 80894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDv2f64: 81894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDr128: 82894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDr64: 83894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDr32: 84894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::LQDr16: { 85894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MachineOperand MOp1 = MI->getOperand(1); 86894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MachineOperand MOp2 = MI->getOperand(2); 87894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MOp1.isImm() && MOp2.isFI()) { 88894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndex = MOp2.getIndex(); 89894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MI->getOperand(0).getReg(); 90894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 91894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 92894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 93894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 94894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 95894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 96894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 97894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned 98894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::isStoreToStackSlot(const MachineInstr *MI, 99894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman int &FrameIndex) const { 100894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman switch (MI->getOpcode()) { 101894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman default: break; 102894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDv16i8: 103894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDv8i16: 104894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDv4i32: 105894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDv4f32: 106894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDv2f64: 107894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDr128: 108894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDr64: 109894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDr32: 110894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDr16: 111894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman case SPU::STQDr8: { 112894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MachineOperand MOp1 = MI->getOperand(1); 113894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const MachineOperand MOp2 = MI->getOperand(2); 114894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MOp1.isImm() && MOp2.isFI()) { 115894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FrameIndex = MOp2.getIndex(); 116894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return MI->getOperand(0).getReg(); 117894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 118894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman break; 119894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 120894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 121894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 122894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 123894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 124894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid SPUInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 125894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I, DebugLoc DL, 126894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DestReg, unsigned SrcReg, 127894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool KillSrc) const 128894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 129894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // We support cross register class moves for our aliases, such as R3 in any 130894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // reg class to any other reg class containing R3. This is required because 131894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // we instruction select bitconvert i64 -> f64 as a noop for example, so our 132894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // types have no specific meaning. 133894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 134894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman BuildMI(MBB, I, DL, get(SPU::LRr128), DestReg) 135894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(SrcReg, getKillRegState(KillSrc)); 136894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 137894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 138894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid 139894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 140894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator MI, 141894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned SrcReg, bool isKill, int FrameIdx, 142894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC, 143894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterInfo *TRI) const 144894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 145894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned opc; 14619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isValidFrameIdx = (FrameIdx < SPUFrameLowering::maxFrameOffset()); 147894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RC == SPU::GPRCRegisterClass) { 148894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::STQDr128 : SPU::STQXr128); 149894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R64CRegisterClass) { 150894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::STQDr64 : SPU::STQXr64); 151894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R64FPRegisterClass) { 152894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::STQDr64 : SPU::STQXr64); 153894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R32CRegisterClass) { 154894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::STQDr32 : SPU::STQXr32); 155894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R32FPRegisterClass) { 156894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::STQDr32 : SPU::STQXr32); 157894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R16CRegisterClass) { 158894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::STQDr16 : SPU::STQXr16); 159894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R8CRegisterClass) { 160894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::STQDr8 : SPU::STQXr8); 161894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::VECREGRegisterClass) { 162894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx) ? SPU::STQDv16i8 : SPU::STQXv16i8; 163894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 164894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Unknown regclass!"); 165894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 166894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 167894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc DL; 168894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MI != MBB.end()) DL = MI->getDebugLoc(); 169894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addFrameReference(BuildMI(MBB, MI, DL, get(opc)) 170894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman .addReg(SrcReg, getKillRegState(isKill)), FrameIdx); 171894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 172894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 173894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanvoid 174894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 175894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator MI, 176894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned DestReg, int FrameIdx, 177894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterClass *RC, 178894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const TargetRegisterInfo *TRI) const 179894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman{ 180894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned opc; 18119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool isValidFrameIdx = (FrameIdx < SPUFrameLowering::maxFrameOffset()); 182894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (RC == SPU::GPRCRegisterClass) { 183894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::LQDr128 : SPU::LQXr128); 184894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R64CRegisterClass) { 185894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::LQDr64 : SPU::LQXr64); 186894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R64FPRegisterClass) { 187894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::LQDr64 : SPU::LQXr64); 188894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R32CRegisterClass) { 189894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::LQDr32 : SPU::LQXr32); 190894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R32FPRegisterClass) { 191894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::LQDr32 : SPU::LQXr32); 192894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R16CRegisterClass) { 193894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::LQDr16 : SPU::LQXr16); 194894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::R8CRegisterClass) { 195894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx ? SPU::LQDr8 : SPU::LQXr8); 196894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (RC == SPU::VECREGRegisterClass) { 197894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman opc = (isValidFrameIdx) ? SPU::LQDv16i8 : SPU::LQXv16i8; 198894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 199894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman llvm_unreachable("Unknown regclass in loadRegFromStackSlot!"); 200894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 201894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 202894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc DL; 203894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (MI != MBB.end()) DL = MI->getDebugLoc(); 204894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman addFrameReference(BuildMI(MBB, MI, DL, get(opc), DestReg), FrameIdx); 205894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 206894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 207894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Branch analysis 208894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman/*! 209894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman \note This code was kiped from PPC. There may be more branch analysis for 210894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman CellSPU than what's currently done here. 211894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman */ 212894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 213894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, 214894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock *&FBB, 215894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman SmallVectorImpl<MachineOperand> &Cond, 216894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman bool AllowModify) const { 217894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the block has no terminators, it just falls into the block after it. 218894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I = MBB.end(); 219894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I == MBB.begin()) 220894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 221894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --I; 222894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (I->isDebugValue()) { 223894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I == MBB.begin()) 224894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 225894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --I; 226894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 227894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isUnpredicatedTerminator(I)) 228894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 229894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 230894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the last instruction in the block. 231894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineInstr *LastInst = I; 232894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 233894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If there is only one terminator instruction, process it. 234894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I == MBB.begin() || !isUnpredicatedTerminator(--I)) { 235894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isUncondBranch(LastInst)) { 236894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Check for jump tables 237894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!LastInst->getOperand(0).isMBB()) 238894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 239894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TBB = LastInst->getOperand(0).getMBB(); 240894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 241894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else if (isCondBranch(LastInst)) { 242894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Block ends with fall-through condbranch. 243894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TBB = LastInst->getOperand(1).getMBB(); 244894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Pushing LastInst: "); 245894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(LastInst->dump()); 246894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Cond.push_back(MachineOperand::CreateImm(LastInst->getOpcode())); 247894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Cond.push_back(LastInst->getOperand(0)); 248894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 249894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 250894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, don't know what this is. 251894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 252894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 253894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 254894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Get the instruction before it if it's a terminator. 255894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineInstr *SecondLastInst = I; 256894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 257894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If there are three terminators, we don't know what sort of block this is. 258894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (SecondLastInst && I != MBB.begin() && 259894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman isUnpredicatedTerminator(--I)) 260894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 261894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 262894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the block ends with a conditional and unconditional branch, handle it. 263894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isCondBranch(SecondLastInst) && isUncondBranch(LastInst)) { 264894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TBB = SecondLastInst->getOperand(1).getMBB(); 265894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Pushing SecondLastInst: "); 266894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(SecondLastInst->dump()); 267894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Cond.push_back(MachineOperand::CreateImm(SecondLastInst->getOpcode())); 268894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Cond.push_back(SecondLastInst->getOperand(0)); 269894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman FBB = LastInst->getOperand(0).getMBB(); 270894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 271894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 272894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 273894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // If the block ends with two unconditional branches, handle it. The second 274894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // one is not executed, so remove it. 275894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (isUncondBranch(SecondLastInst) && isUncondBranch(LastInst)) { 276894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman TBB = SecondLastInst->getOperand(0).getMBB(); 277894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = LastInst; 278894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (AllowModify) 279894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I->eraseFromParent(); 280894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 281894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 282894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 283894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Otherwise, can't handle this. 284894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 285894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 286894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 28719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman// search MBB for branch hint labels and branch hit ops 28819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic void removeHBR( MachineBasicBlock &MBB) { 28919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I){ 29019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (I->getOpcode() == SPU::HBRA || 29119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I->getOpcode() == SPU::HBR_LABEL){ 29219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman I=MBB.erase(I); 29319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (I == MBB.end()) 29419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman break; 29519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 29619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 29719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 29819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 299894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned 300894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 301894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock::iterator I = MBB.end(); 30219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman removeHBR(MBB); 303894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I == MBB.begin()) 304894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 305894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --I; 306894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman while (I->isDebugValue()) { 307894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I == MBB.begin()) 308894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 309894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --I; 310894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 311894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!isCondBranch(I) && !isUncondBranch(I)) 312894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 0; 313894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 314894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Remove the first branch. 315894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Removing branch: "); 316894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(I->dump()); 317894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I->eraseFromParent(); 318894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I = MBB.end(); 319894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (I == MBB.begin()) 320894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 1; 321894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 322894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman --I; 323894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (!(isCondBranch(I) || isUncondBranch(I))) 324894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 1; 325894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 326894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Remove the second branch. 327894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Removing second branch: "); 328894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(I->dump()); 329894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman I->eraseFromParent(); 330894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 2; 331894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 332894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 33319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman/** Find the optimal position for a hint branch instruction in a basic block. 33419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * This should take into account: 33519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * -the branch hint delays 33619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * -congestion of the memory bus 33719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * -dual-issue scheduling (i.e. avoid insertion of nops) 33819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman * Current implementation is rather simplistic. 33919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman */ 34019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Baumanstatic MachineBasicBlock::iterator findHBRPosition(MachineBasicBlock &MBB) 34119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman{ 34219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineBasicBlock::iterator J = MBB.end(); 34319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman for( int i=0; i<8; i++) { 34419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if( J == MBB.begin() ) return J; 34519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman J--; 34619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 34719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman return J; 34819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman} 34919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 350894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanunsigned 351894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, 352894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineBasicBlock *FBB, 353894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const SmallVectorImpl<MachineOperand> &Cond, 354894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DebugLoc DL) const { 355894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Shouldn't be a fall through. 356894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 357894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman assert((Cond.size() == 2 || Cond.size() == 0) && 358894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman "SPU branch conditions have two components!"); 359894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 36019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MachineInstrBuilder MIB; 36119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman //TODO: make a more accurate algorithm. 36219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman bool haveHBR = MBB.size()>8; 36319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 36419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman removeHBR(MBB); 36519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MCSymbol *branchLabel = MBB.getParent()->getContext().CreateTempSymbol(); 36619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // Add a label just before the branch 36719bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (haveHBR) 36819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB = BuildMI(&MBB, DL, get(SPU::HBR_LABEL)).addSym(branchLabel); 36919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 370894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // One-way branch. 371894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (FBB == 0) { 372894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (Cond.empty()) { 373894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Unconditional branch 37419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB = BuildMI(&MBB, DL, get(SPU::BR)); 375894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MIB.addMBB(TBB); 376894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 377894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Inserted one-way uncond branch: "); 378894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG((*MIB).dump()); 37919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 38019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman // basic blocks have just one branch so it is safe to add the hint a its 38119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (haveHBR) { 38219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB = BuildMI( MBB, findHBRPosition(MBB), DL, get(SPU::HBRA)); 38319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB.addSym(branchLabel); 38419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB.addMBB(TBB); 38519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 386894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 387894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Conditional branch 38819bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB = BuildMI(&MBB, DL, get(Cond[0].getImm())); 389894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MIB.addReg(Cond[1].getReg()).addMBB(TBB); 390894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 39119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (haveHBR) { 39219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB = BuildMI(MBB, findHBRPosition(MBB), DL, get(SPU::HBRA)); 39319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB.addSym(branchLabel); 39419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB.addMBB(TBB); 39519bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 39619bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 397894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Inserted one-way cond branch: "); 398894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG((*MIB).dump()); 399894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 400894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 1; 401894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } else { 40219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB = BuildMI(&MBB, DL, get(Cond[0].getImm())); 403894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MachineInstrBuilder MIB2 = BuildMI(&MBB, DL, get(SPU::BR)); 404894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 405894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Two-way Conditional Branch. 406894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MIB.addReg(Cond[1].getReg()).addMBB(TBB); 407894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman MIB2.addMBB(FBB); 408894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 40919bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman if (haveHBR) { 41019bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB = BuildMI( MBB, findHBRPosition(MBB), DL, get(SPU::HBRA)); 41119bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB.addSym(branchLabel); 41219bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman MIB.addMBB(FBB); 41319bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman } 41419bac1e08be200c31efd26f0f5fd144c9b3eefd3John Bauman 415894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "Inserted conditional branch: "); 416894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG((*MIB).dump()); 417894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG(errs() << "part 2: "); 418894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman DEBUG((*MIB2).dump()); 419894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return 2; 420894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 421894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 422894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 423894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman//! Reverses a branch's condition, returning false on success. 424894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Baumanbool 425894018228b0e0bdbd7aa7e8f47d4a9458789ca82John BaumanSPUInstrInfo::ReverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) 426894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman const { 427894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Pretty brainless way of inverting the condition, but it works, considering 428894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // there are only two conditions... 429894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman static struct { 430894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc; //! The incoming opcode 431894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned RevCondOpc; //! The reversed condition opcode 432894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } revconds[] = { 433894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { SPU::BRNZr32, SPU::BRZr32 }, 434894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { SPU::BRNZv4i32, SPU::BRZv4i32 }, 435894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { SPU::BRZr32, SPU::BRNZr32 }, 436894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { SPU::BRZv4i32, SPU::BRNZv4i32 }, 437894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { SPU::BRHNZr16, SPU::BRHZr16 }, 438894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { SPU::BRHNZv8i16, SPU::BRHZv8i16 }, 439894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { SPU::BRHZr16, SPU::BRHNZr16 }, 440894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman { SPU::BRHZv8i16, SPU::BRHNZv8i16 } 441894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman }; 442894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 443894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman unsigned Opc = unsigned(Cond[0].getImm()); 444894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman // Pretty dull mapping between the two conditions that SPU can generate: 445894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman for (int i = sizeof(revconds)/sizeof(revconds[0]) - 1; i >= 0; --i) { 446894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman if (revconds[i].Opc == Opc) { 447894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman Cond[0].setImm(revconds[i].RevCondOpc); 448894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return false; 449894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 450894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman } 451894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman 452894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman return true; 453894018228b0e0bdbd7aa7e8f47d4a9458789ca82John Bauman} 454