Path: blob/main/contrib/llvm-project/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
35294 views
//===-- SparcInstrInfo.cpp - Sparc Instruction Information ----------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file contains the Sparc implementation of the TargetInstrInfo class.9//10//===----------------------------------------------------------------------===//1112#include "SparcInstrInfo.h"13#include "Sparc.h"14#include "SparcMachineFunctionInfo.h"15#include "SparcSubtarget.h"16#include "llvm/ADT/STLExtras.h"17#include "llvm/ADT/SmallVector.h"18#include "llvm/CodeGen/MachineFrameInfo.h"19#include "llvm/CodeGen/MachineInstrBuilder.h"20#include "llvm/CodeGen/MachineMemOperand.h"21#include "llvm/CodeGen/MachineRegisterInfo.h"22#include "llvm/MC/TargetRegistry.h"23#include "llvm/Support/ErrorHandling.h"2425using namespace llvm;2627#define GET_INSTRINFO_CTOR_DTOR28#include "SparcGenInstrInfo.inc"2930static cl::opt<unsigned> BPccDisplacementBits(31"sparc-bpcc-offset-bits", cl::Hidden, cl::init(19),32cl::desc("Restrict range of BPcc/FBPfcc instructions (DEBUG)"));3334static cl::opt<unsigned>35BPrDisplacementBits("sparc-bpr-offset-bits", cl::Hidden, cl::init(16),36cl::desc("Restrict range of BPr instructions (DEBUG)"));3738// Pin the vtable to this file.39void SparcInstrInfo::anchor() {}4041SparcInstrInfo::SparcInstrInfo(SparcSubtarget &ST)42: SparcGenInstrInfo(SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP), RI(),43Subtarget(ST) {}4445/// isLoadFromStackSlot - If the specified machine instruction is a direct46/// load from a stack slot, return the virtual or physical register number of47/// the destination along with the FrameIndex of the loaded stack slot. If48/// not, return 0. This predicate must return 0 if the instruction has49/// any side effects other than loading from the stack slot.50Register SparcInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,51int &FrameIndex) const {52if (MI.getOpcode() == SP::LDri || MI.getOpcode() == SP::LDXri ||53MI.getOpcode() == SP::LDFri || MI.getOpcode() == SP::LDDFri ||54MI.getOpcode() == SP::LDQFri) {55if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&56MI.getOperand(2).getImm() == 0) {57FrameIndex = MI.getOperand(1).getIndex();58return MI.getOperand(0).getReg();59}60}61return 0;62}6364/// isStoreToStackSlot - If the specified machine instruction is a direct65/// store to a stack slot, return the virtual or physical register number of66/// the source reg along with the FrameIndex of the loaded stack slot. If67/// not, return 0. This predicate must return 0 if the instruction has68/// any side effects other than storing to the stack slot.69Register SparcInstrInfo::isStoreToStackSlot(const MachineInstr &MI,70int &FrameIndex) const {71if (MI.getOpcode() == SP::STri || MI.getOpcode() == SP::STXri ||72MI.getOpcode() == SP::STFri || MI.getOpcode() == SP::STDFri ||73MI.getOpcode() == SP::STQFri) {74if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&75MI.getOperand(1).getImm() == 0) {76FrameIndex = MI.getOperand(0).getIndex();77return MI.getOperand(2).getReg();78}79}80return 0;81}8283static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)84{85switch(CC) {86case SPCC::ICC_A: return SPCC::ICC_N;87case SPCC::ICC_N: return SPCC::ICC_A;88case SPCC::ICC_NE: return SPCC::ICC_E;89case SPCC::ICC_E: return SPCC::ICC_NE;90case SPCC::ICC_G: return SPCC::ICC_LE;91case SPCC::ICC_LE: return SPCC::ICC_G;92case SPCC::ICC_GE: return SPCC::ICC_L;93case SPCC::ICC_L: return SPCC::ICC_GE;94case SPCC::ICC_GU: return SPCC::ICC_LEU;95case SPCC::ICC_LEU: return SPCC::ICC_GU;96case SPCC::ICC_CC: return SPCC::ICC_CS;97case SPCC::ICC_CS: return SPCC::ICC_CC;98case SPCC::ICC_POS: return SPCC::ICC_NEG;99case SPCC::ICC_NEG: return SPCC::ICC_POS;100case SPCC::ICC_VC: return SPCC::ICC_VS;101case SPCC::ICC_VS: return SPCC::ICC_VC;102103case SPCC::FCC_A: return SPCC::FCC_N;104case SPCC::FCC_N: return SPCC::FCC_A;105case SPCC::FCC_U: return SPCC::FCC_O;106case SPCC::FCC_O: return SPCC::FCC_U;107case SPCC::FCC_G: return SPCC::FCC_ULE;108case SPCC::FCC_LE: return SPCC::FCC_UG;109case SPCC::FCC_UG: return SPCC::FCC_LE;110case SPCC::FCC_ULE: return SPCC::FCC_G;111case SPCC::FCC_L: return SPCC::FCC_UGE;112case SPCC::FCC_GE: return SPCC::FCC_UL;113case SPCC::FCC_UL: return SPCC::FCC_GE;114case SPCC::FCC_UGE: return SPCC::FCC_L;115case SPCC::FCC_LG: return SPCC::FCC_UE;116case SPCC::FCC_UE: return SPCC::FCC_LG;117case SPCC::FCC_NE: return SPCC::FCC_E;118case SPCC::FCC_E: return SPCC::FCC_NE;119120case SPCC::CPCC_A: return SPCC::CPCC_N;121case SPCC::CPCC_N: return SPCC::CPCC_A;122case SPCC::CPCC_3: [[fallthrough]];123case SPCC::CPCC_2: [[fallthrough]];124case SPCC::CPCC_23: [[fallthrough]];125case SPCC::CPCC_1: [[fallthrough]];126case SPCC::CPCC_13: [[fallthrough]];127case SPCC::CPCC_12: [[fallthrough]];128case SPCC::CPCC_123: [[fallthrough]];129case SPCC::CPCC_0: [[fallthrough]];130case SPCC::CPCC_03: [[fallthrough]];131case SPCC::CPCC_02: [[fallthrough]];132case SPCC::CPCC_023: [[fallthrough]];133case SPCC::CPCC_01: [[fallthrough]];134case SPCC::CPCC_013: [[fallthrough]];135case SPCC::CPCC_012:136// "Opposite" code is not meaningful, as we don't know137// what the CoProc condition means here. The cond-code will138// only be used in inline assembler, so this code should139// not be reached in a normal compilation pass.140llvm_unreachable("Meaningless inversion of co-processor cond code");141142case SPCC::REG_BEGIN:143llvm_unreachable("Use of reserved cond code");144case SPCC::REG_Z:145return SPCC::REG_NZ;146case SPCC::REG_LEZ:147return SPCC::REG_GZ;148case SPCC::REG_LZ:149return SPCC::REG_GEZ;150case SPCC::REG_NZ:151return SPCC::REG_Z;152case SPCC::REG_GZ:153return SPCC::REG_LEZ;154case SPCC::REG_GEZ:155return SPCC::REG_LZ;156}157llvm_unreachable("Invalid cond code");158}159160static bool isUncondBranchOpcode(int Opc) { return Opc == SP::BA; }161162static bool isI32CondBranchOpcode(int Opc) {163return Opc == SP::BCOND || Opc == SP::BPICC || Opc == SP::BPICCA ||164Opc == SP::BPICCNT || Opc == SP::BPICCANT;165}166167static bool isI64CondBranchOpcode(int Opc) {168return Opc == SP::BPXCC || Opc == SP::BPXCCA || Opc == SP::BPXCCNT ||169Opc == SP::BPXCCANT;170}171172static bool isRegCondBranchOpcode(int Opc) {173return Opc == SP::BPR || Opc == SP::BPRA || Opc == SP::BPRNT ||174Opc == SP::BPRANT;175}176177static bool isFCondBranchOpcode(int Opc) {178return Opc == SP::FBCOND || Opc == SP::FBCONDA || Opc == SP::FBCOND_V9 ||179Opc == SP::FBCONDA_V9;180}181182static bool isCondBranchOpcode(int Opc) {183return isI32CondBranchOpcode(Opc) || isI64CondBranchOpcode(Opc) ||184isRegCondBranchOpcode(Opc) || isFCondBranchOpcode(Opc);185}186187static bool isIndirectBranchOpcode(int Opc) {188return Opc == SP::BINDrr || Opc == SP::BINDri;189}190191static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,192SmallVectorImpl<MachineOperand> &Cond) {193unsigned Opc = LastInst->getOpcode();194int64_t CC = LastInst->getOperand(1).getImm();195196// Push the branch opcode into Cond too so later in insertBranch197// it can use the information to emit the correct SPARC branch opcode.198Cond.push_back(MachineOperand::CreateImm(Opc));199Cond.push_back(MachineOperand::CreateImm(CC));200201// Branch on register contents need another argument to indicate202// the register it branches on.203if (isRegCondBranchOpcode(Opc)) {204Register Reg = LastInst->getOperand(2).getReg();205Cond.push_back(MachineOperand::CreateReg(Reg, false));206}207208Target = LastInst->getOperand(0).getMBB();209}210211MachineBasicBlock *212SparcInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {213switch (MI.getOpcode()) {214default:215llvm_unreachable("unexpected opcode!");216case SP::BA:217case SP::BCOND:218case SP::BCONDA:219case SP::FBCOND:220case SP::FBCONDA:221case SP::BPICC:222case SP::BPICCA:223case SP::BPICCNT:224case SP::BPICCANT:225case SP::BPXCC:226case SP::BPXCCA:227case SP::BPXCCNT:228case SP::BPXCCANT:229case SP::BPFCC:230case SP::BPFCCA:231case SP::BPFCCNT:232case SP::BPFCCANT:233case SP::FBCOND_V9:234case SP::FBCONDA_V9:235case SP::BPR:236case SP::BPRA:237case SP::BPRNT:238case SP::BPRANT:239return MI.getOperand(0).getMBB();240}241}242243bool SparcInstrInfo::analyzeBranch(MachineBasicBlock &MBB,244MachineBasicBlock *&TBB,245MachineBasicBlock *&FBB,246SmallVectorImpl<MachineOperand> &Cond,247bool AllowModify) const {248MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();249if (I == MBB.end())250return false;251252if (!isUnpredicatedTerminator(*I))253return false;254255// Get the last instruction in the block.256MachineInstr *LastInst = &*I;257unsigned LastOpc = LastInst->getOpcode();258259// If there is only one terminator instruction, process it.260if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {261if (isUncondBranchOpcode(LastOpc)) {262TBB = LastInst->getOperand(0).getMBB();263return false;264}265if (isCondBranchOpcode(LastOpc)) {266// Block ends with fall-through condbranch.267parseCondBranch(LastInst, TBB, Cond);268return false;269}270return true; // Can't handle indirect branch.271}272273// Get the instruction before it if it is a terminator.274MachineInstr *SecondLastInst = &*I;275unsigned SecondLastOpc = SecondLastInst->getOpcode();276277// If AllowModify is true and the block ends with two or more unconditional278// branches, delete all but the first unconditional branch.279if (AllowModify && isUncondBranchOpcode(LastOpc)) {280while (isUncondBranchOpcode(SecondLastOpc)) {281LastInst->eraseFromParent();282LastInst = SecondLastInst;283LastOpc = LastInst->getOpcode();284if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {285// Return now the only terminator is an unconditional branch.286TBB = LastInst->getOperand(0).getMBB();287return false;288} else {289SecondLastInst = &*I;290SecondLastOpc = SecondLastInst->getOpcode();291}292}293}294295// If there are three terminators, we don't know what sort of block this is.296if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))297return true;298299// If the block ends with a B and a Bcc, handle it.300if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {301parseCondBranch(SecondLastInst, TBB, Cond);302FBB = LastInst->getOperand(0).getMBB();303return false;304}305306// If the block ends with two unconditional branches, handle it. The second307// one is not executed.308if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {309TBB = SecondLastInst->getOperand(0).getMBB();310return false;311}312313// ...likewise if it ends with an indirect branch followed by an unconditional314// branch.315if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {316I = LastInst;317if (AllowModify)318I->eraseFromParent();319return true;320}321322// Otherwise, can't handle this.323return true;324}325326unsigned SparcInstrInfo::insertBranch(MachineBasicBlock &MBB,327MachineBasicBlock *TBB,328MachineBasicBlock *FBB,329ArrayRef<MachineOperand> Cond,330const DebugLoc &DL,331int *BytesAdded) const {332assert(TBB && "insertBranch must not be told to insert a fallthrough");333assert((Cond.size() <= 3) &&334"Sparc branch conditions should have at most three components!");335336if (Cond.empty()) {337assert(!FBB && "Unconditional branch with multiple successors!");338BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);339if (BytesAdded)340*BytesAdded = 8;341return 1;342}343344// Conditional branch345unsigned Opc = Cond[0].getImm();346unsigned CC = Cond[1].getImm();347if (isRegCondBranchOpcode(Opc)) {348Register Reg = Cond[2].getReg();349BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC).addReg(Reg);350} else {351BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC);352}353354if (!FBB) {355if (BytesAdded)356*BytesAdded = 8;357return 1;358}359360BuildMI(&MBB, DL, get(SP::BA)).addMBB(FBB);361if (BytesAdded)362*BytesAdded = 16;363return 2;364}365366unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB,367int *BytesRemoved) const {368MachineBasicBlock::iterator I = MBB.end();369unsigned Count = 0;370int Removed = 0;371while (I != MBB.begin()) {372--I;373374if (I->isDebugInstr())375continue;376377if (!isCondBranchOpcode(I->getOpcode()) &&378!isUncondBranchOpcode(I->getOpcode()))379break; // Not a branch380381Removed += getInstSizeInBytes(*I);382I->eraseFromParent();383I = MBB.end();384++Count;385}386387if (BytesRemoved)388*BytesRemoved = Removed;389return Count;390}391392bool SparcInstrInfo::reverseBranchCondition(393SmallVectorImpl<MachineOperand> &Cond) const {394assert(Cond.size() <= 3);395SPCC::CondCodes CC = static_cast<SPCC::CondCodes>(Cond[1].getImm());396Cond[1].setImm(GetOppositeBranchCondition(CC));397return false;398}399400bool SparcInstrInfo::isBranchOffsetInRange(unsigned BranchOpc,401int64_t Offset) const {402assert((Offset & 0b11) == 0 && "Malformed branch offset");403switch (BranchOpc) {404case SP::BA:405case SP::BCOND:406case SP::BCONDA:407case SP::FBCOND:408case SP::FBCONDA:409return isIntN(22, Offset >> 2);410411case SP::BPICC:412case SP::BPICCA:413case SP::BPICCNT:414case SP::BPICCANT:415case SP::BPXCC:416case SP::BPXCCA:417case SP::BPXCCNT:418case SP::BPXCCANT:419case SP::BPFCC:420case SP::BPFCCA:421case SP::BPFCCNT:422case SP::BPFCCANT:423case SP::FBCOND_V9:424case SP::FBCONDA_V9:425return isIntN(BPccDisplacementBits, Offset >> 2);426427case SP::BPR:428case SP::BPRA:429case SP::BPRNT:430case SP::BPRANT:431return isIntN(BPrDisplacementBits, Offset >> 2);432}433434llvm_unreachable("Unknown branch instruction!");435}436437void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB,438MachineBasicBlock::iterator I,439const DebugLoc &DL, MCRegister DestReg,440MCRegister SrcReg, bool KillSrc) const {441unsigned numSubRegs = 0;442unsigned movOpc = 0;443const unsigned *subRegIdx = nullptr;444bool ExtraG0 = false;445446const unsigned DW_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };447const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };448const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 };449const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd,450SP::sub_odd64_then_sub_even,451SP::sub_odd64_then_sub_odd };452453if (SP::IntRegsRegClass.contains(DestReg, SrcReg))454BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0)455.addReg(SrcReg, getKillRegState(KillSrc));456else if (SP::IntPairRegClass.contains(DestReg, SrcReg)) {457subRegIdx = DW_SubRegsIdx;458numSubRegs = 2;459movOpc = SP::ORrr;460ExtraG0 = true;461} else if (SP::FPRegsRegClass.contains(DestReg, SrcReg))462BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg)463.addReg(SrcReg, getKillRegState(KillSrc));464else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg)) {465if (Subtarget.isV9()) {466BuildMI(MBB, I, DL, get(SP::FMOVD), DestReg)467.addReg(SrcReg, getKillRegState(KillSrc));468} else {469// Use two FMOVS instructions.470subRegIdx = DFP_FP_SubRegsIdx;471numSubRegs = 2;472movOpc = SP::FMOVS;473}474} else if (SP::QFPRegsRegClass.contains(DestReg, SrcReg)) {475if (Subtarget.isV9()) {476if (Subtarget.hasHardQuad()) {477BuildMI(MBB, I, DL, get(SP::FMOVQ), DestReg)478.addReg(SrcReg, getKillRegState(KillSrc));479} else {480// Use two FMOVD instructions.481subRegIdx = QFP_DFP_SubRegsIdx;482numSubRegs = 2;483movOpc = SP::FMOVD;484}485} else {486// Use four FMOVS instructions.487subRegIdx = QFP_FP_SubRegsIdx;488numSubRegs = 4;489movOpc = SP::FMOVS;490}491} else if (SP::ASRRegsRegClass.contains(DestReg) &&492SP::IntRegsRegClass.contains(SrcReg)) {493BuildMI(MBB, I, DL, get(SP::WRASRrr), DestReg)494.addReg(SP::G0)495.addReg(SrcReg, getKillRegState(KillSrc));496} else if (SP::IntRegsRegClass.contains(DestReg) &&497SP::ASRRegsRegClass.contains(SrcReg)) {498BuildMI(MBB, I, DL, get(SP::RDASR), DestReg)499.addReg(SrcReg, getKillRegState(KillSrc));500} else501llvm_unreachable("Impossible reg-to-reg copy");502503if (numSubRegs == 0 || subRegIdx == nullptr || movOpc == 0)504return;505506const TargetRegisterInfo *TRI = &getRegisterInfo();507MachineInstr *MovMI = nullptr;508509for (unsigned i = 0; i != numSubRegs; ++i) {510Register Dst = TRI->getSubReg(DestReg, subRegIdx[i]);511Register Src = TRI->getSubReg(SrcReg, subRegIdx[i]);512assert(Dst && Src && "Bad sub-register");513514MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(movOpc), Dst);515if (ExtraG0)516MIB.addReg(SP::G0);517MIB.addReg(Src);518MovMI = MIB.getInstr();519}520// Add implicit super-register defs and kills to the last MovMI.521MovMI->addRegisterDefined(DestReg, TRI);522if (KillSrc)523MovMI->addRegisterKilled(SrcReg, TRI);524}525526void SparcInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,527MachineBasicBlock::iterator I,528Register SrcReg, bool isKill, int FI,529const TargetRegisterClass *RC,530const TargetRegisterInfo *TRI,531Register VReg) const {532DebugLoc DL;533if (I != MBB.end()) DL = I->getDebugLoc();534535MachineFunction *MF = MBB.getParent();536const MachineFrameInfo &MFI = MF->getFrameInfo();537MachineMemOperand *MMO = MF->getMachineMemOperand(538MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOStore,539MFI.getObjectSize(FI), MFI.getObjectAlign(FI));540541// On the order of operands here: think "[FrameIdx + 0] = SrcReg".542if (RC == &SP::I64RegsRegClass)543BuildMI(MBB, I, DL, get(SP::STXri)).addFrameIndex(FI).addImm(0)544.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);545else if (RC == &SP::IntRegsRegClass)546BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)547.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);548else if (RC == &SP::IntPairRegClass)549BuildMI(MBB, I, DL, get(SP::STDri)).addFrameIndex(FI).addImm(0)550.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);551else if (RC == &SP::FPRegsRegClass)552BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)553.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);554else if (SP::DFPRegsRegClass.hasSubClassEq(RC))555BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)556.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);557else if (SP::QFPRegsRegClass.hasSubClassEq(RC))558// Use STQFri irrespective of its legality. If STQ is not legal, it will be559// lowered into two STDs in eliminateFrameIndex.560BuildMI(MBB, I, DL, get(SP::STQFri)).addFrameIndex(FI).addImm(0)561.addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);562else563llvm_unreachable("Can't store this register to stack slot");564}565566void SparcInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,567MachineBasicBlock::iterator I,568Register DestReg, int FI,569const TargetRegisterClass *RC,570const TargetRegisterInfo *TRI,571Register VReg) const {572DebugLoc DL;573if (I != MBB.end()) DL = I->getDebugLoc();574575MachineFunction *MF = MBB.getParent();576const MachineFrameInfo &MFI = MF->getFrameInfo();577MachineMemOperand *MMO = MF->getMachineMemOperand(578MachinePointerInfo::getFixedStack(*MF, FI), MachineMemOperand::MOLoad,579MFI.getObjectSize(FI), MFI.getObjectAlign(FI));580581if (RC == &SP::I64RegsRegClass)582BuildMI(MBB, I, DL, get(SP::LDXri), DestReg).addFrameIndex(FI).addImm(0)583.addMemOperand(MMO);584else if (RC == &SP::IntRegsRegClass)585BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0)586.addMemOperand(MMO);587else if (RC == &SP::IntPairRegClass)588BuildMI(MBB, I, DL, get(SP::LDDri), DestReg).addFrameIndex(FI).addImm(0)589.addMemOperand(MMO);590else if (RC == &SP::FPRegsRegClass)591BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0)592.addMemOperand(MMO);593else if (SP::DFPRegsRegClass.hasSubClassEq(RC))594BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0)595.addMemOperand(MMO);596else if (SP::QFPRegsRegClass.hasSubClassEq(RC))597// Use LDQFri irrespective of its legality. If LDQ is not legal, it will be598// lowered into two LDDs in eliminateFrameIndex.599BuildMI(MBB, I, DL, get(SP::LDQFri), DestReg).addFrameIndex(FI).addImm(0)600.addMemOperand(MMO);601else602llvm_unreachable("Can't load this register from stack slot");603}604605Register SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {606SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>();607Register GlobalBaseReg = SparcFI->getGlobalBaseReg();608if (GlobalBaseReg)609return GlobalBaseReg;610611// Insert the set of GlobalBaseReg into the first MBB of the function612MachineBasicBlock &FirstMBB = MF->front();613MachineBasicBlock::iterator MBBI = FirstMBB.begin();614MachineRegisterInfo &RegInfo = MF->getRegInfo();615616const TargetRegisterClass *PtrRC =617Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;618GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);619620DebugLoc dl;621622BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);623SparcFI->setGlobalBaseReg(GlobalBaseReg);624return GlobalBaseReg;625}626627unsigned SparcInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {628unsigned Opcode = MI.getOpcode();629630if (MI.isInlineAsm()) {631const MachineFunction *MF = MI.getParent()->getParent();632const char *AsmStr = MI.getOperand(0).getSymbolName();633return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());634}635636// If the instruction has a delay slot, be conservative and also include637// it for sizing purposes. This is done so that the BranchRelaxation pass638// will not mistakenly mark out-of-range branches as in-range.639if (MI.hasDelaySlot())640return get(Opcode).getSize() * 2;641return get(Opcode).getSize();642}643644bool SparcInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {645switch (MI.getOpcode()) {646case TargetOpcode::LOAD_STACK_GUARD: {647assert(Subtarget.isTargetLinux() &&648"Only Linux target is expected to contain LOAD_STACK_GUARD");649// offsetof(tcbhead_t, stack_guard) from sysdeps/sparc/nptl/tls.h in glibc.650const int64_t Offset = Subtarget.is64Bit() ? 0x28 : 0x14;651MI.setDesc(get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri));652MachineInstrBuilder(*MI.getParent()->getParent(), MI)653.addReg(SP::G7)654.addImm(Offset);655return true;656}657}658return false;659}660661662