XCoreRegisterInfo.cpp revision 252723
1235633Sdim//===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===// 2193323Sed// 3193323Sed// The LLVM Compiler Infrastructure 4193323Sed// 5193323Sed// This file is distributed under the University of Illinois Open Source 6193323Sed// License. See LICENSE.TXT for details. 7193323Sed// 8193323Sed//===----------------------------------------------------------------------===// 9193323Sed// 10193323Sed// This file contains the XCore implementation of the MRegisterInfo class. 11193323Sed// 12193323Sed//===----------------------------------------------------------------------===// 13193323Sed 14193323Sed#include "XCoreRegisterInfo.h" 15252723Sdim#include "XCore.h" 16193323Sed#include "XCoreMachineFunctionInfo.h" 17252723Sdim#include "llvm/ADT/BitVector.h" 18252723Sdim#include "llvm/ADT/STLExtras.h" 19252723Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 20252723Sdim#include "llvm/CodeGen/MachineFunction.h" 21193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 22193323Sed#include "llvm/CodeGen/MachineModuleInfo.h" 23193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h" 24193323Sed#include "llvm/CodeGen/RegisterScavenging.h" 25252723Sdim#include "llvm/IR/Function.h" 26252723Sdim#include "llvm/IR/Type.h" 27252723Sdim#include "llvm/Support/Debug.h" 28252723Sdim#include "llvm/Support/ErrorHandling.h" 29252723Sdim#include "llvm/Support/raw_ostream.h" 30218893Sdim#include "llvm/Target/TargetFrameLowering.h" 31252723Sdim#include "llvm/Target/TargetInstrInfo.h" 32193323Sed#include "llvm/Target/TargetMachine.h" 33193323Sed#include "llvm/Target/TargetOptions.h" 34193323Sed 35224145Sdim#define GET_REGINFO_TARGET_DESC 36224145Sdim#include "XCoreGenRegisterInfo.inc" 37224145Sdim 38193323Sedusing namespace llvm; 39193323Sed 40193323SedXCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii) 41226890Sdim : XCoreGenRegisterInfo(XCore::LR), TII(tii) { 42193323Sed} 43193323Sed 44193323Sed// helper functions 45193323Sedstatic inline bool isImmUs(unsigned val) { 46193323Sed return val <= 11; 47193323Sed} 48193323Sed 49193323Sedstatic inline bool isImmU6(unsigned val) { 50193323Sed return val < (1 << 6); 51193323Sed} 52193323Sed 53193323Sedstatic inline bool isImmU16(unsigned val) { 54193323Sed return val < (1 << 16); 55193323Sed} 56193323Sed 57206274Srdivackybool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) { 58223017Sdim return MF.getMMI().hasDebugInfo() || 59223017Sdim MF.getFunction()->needsUnwindTableEntry(); 60193323Sed} 61193323Sed 62235633Sdimconst uint16_t* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) 63193323Sed const { 64235633Sdim static const uint16_t CalleeSavedRegs[] = { 65193323Sed XCore::R4, XCore::R5, XCore::R6, XCore::R7, 66193323Sed XCore::R8, XCore::R9, XCore::R10, XCore::LR, 67193323Sed 0 68193323Sed }; 69193323Sed return CalleeSavedRegs; 70193323Sed} 71193323Sed 72193323SedBitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 73193323Sed BitVector Reserved(getNumRegs()); 74218893Sdim const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 75218893Sdim 76193323Sed Reserved.set(XCore::CP); 77193323Sed Reserved.set(XCore::DP); 78193323Sed Reserved.set(XCore::SP); 79193323Sed Reserved.set(XCore::LR); 80218893Sdim if (TFI->hasFP(MF)) { 81193323Sed Reserved.set(XCore::R10); 82193323Sed } 83193323Sed return Reserved; 84193323Sed} 85193323Sed 86193323Sedbool 87193323SedXCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 88218893Sdim const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 89218893Sdim 90193323Sed // TODO can we estimate stack size? 91218893Sdim return TFI->hasFP(MF); 92193323Sed} 93193323Sed 94221345Sdimbool 95245431SdimXCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const { 96245431Sdim return requiresRegisterScavenging(MF); 97245431Sdim} 98245431Sdim 99245431Sdimbool 100221345SdimXCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 101221345Sdim return false; 102221345Sdim} 103221345Sdim 104212904Sdimvoid 105198090SrdivackyXCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 106252723Sdim int SPAdj, unsigned FIOperandNum, 107252723Sdim RegScavenger *RS) const { 108193323Sed assert(SPAdj == 0 && "Unexpected"); 109193323Sed MachineInstr &MI = *II; 110193323Sed DebugLoc dl = MI.getDebugLoc(); 111252723Sdim MachineOperand &FrameOp = MI.getOperand(FIOperandNum); 112193323Sed int FrameIndex = FrameOp.getIndex(); 113193323Sed 114193323Sed MachineFunction &MF = *MI.getParent()->getParent(); 115218893Sdim const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 116193323Sed int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 117193323Sed int StackSize = MF.getFrameInfo()->getStackSize(); 118193323Sed 119193323Sed #ifndef NDEBUG 120198090Srdivacky DEBUG(errs() << "\nFunction : " 121245431Sdim << MF.getName() << "\n"); 122198090Srdivacky DEBUG(errs() << "<--------->\n"); 123198090Srdivacky DEBUG(MI.print(errs())); 124198090Srdivacky DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"); 125198090Srdivacky DEBUG(errs() << "FrameOffset : " << Offset << "\n"); 126198090Srdivacky DEBUG(errs() << "StackSize : " << StackSize << "\n"); 127193323Sed #endif 128193323Sed 129193323Sed Offset += StackSize; 130224145Sdim 131224145Sdim unsigned FrameReg = getFrameRegister(MF); 132224145Sdim 133224145Sdim // Special handling of DBG_VALUE instructions. 134224145Sdim if (MI.isDebugValue()) { 135252723Sdim MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/); 136252723Sdim MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 137224145Sdim return; 138224145Sdim } 139224145Sdim 140193323Sed // fold constant into offset. 141252723Sdim Offset += MI.getOperand(FIOperandNum + 1).getImm(); 142252723Sdim MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); 143193323Sed 144193323Sed assert(Offset%4 == 0 && "Misaligned stack offset"); 145193323Sed 146198090Srdivacky DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); 147193323Sed 148193323Sed Offset/=4; 149193323Sed 150218893Sdim bool FP = TFI->hasFP(MF); 151224145Sdim 152193323Sed unsigned Reg = MI.getOperand(0).getReg(); 153193323Sed bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill(); 154193323Sed 155245431Sdim assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand"); 156193323Sed 157193323Sed MachineBasicBlock &MBB = *MI.getParent(); 158193323Sed 159193323Sed if (FP) { 160193323Sed bool isUs = isImmUs(Offset); 161193323Sed 162193323Sed if (!isUs) { 163207618Srdivacky if (!RS) 164207618Srdivacky report_fatal_error("eliminateFrameIndex Frame size too big: " + 165207618Srdivacky Twine(Offset)); 166245431Sdim unsigned ScratchReg = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 167193323Sed SPAdj); 168193323Sed loadConstant(MBB, II, ScratchReg, Offset, dl); 169193323Sed switch (MI.getOpcode()) { 170193323Sed case XCore::LDWFI: 171198090Srdivacky BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) 172224145Sdim .addReg(FrameReg) 173193323Sed .addReg(ScratchReg, RegState::Kill); 174193323Sed break; 175193323Sed case XCore::STWFI: 176252723Sdim BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) 177193323Sed .addReg(Reg, getKillRegState(isKill)) 178224145Sdim .addReg(FrameReg) 179193323Sed .addReg(ScratchReg, RegState::Kill); 180193323Sed break; 181193323Sed case XCore::LDAWFI: 182198090Srdivacky BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) 183224145Sdim .addReg(FrameReg) 184193323Sed .addReg(ScratchReg, RegState::Kill); 185193323Sed break; 186193323Sed default: 187198090Srdivacky llvm_unreachable("Unexpected Opcode"); 188193323Sed } 189193323Sed } else { 190193323Sed switch (MI.getOpcode()) { 191193323Sed case XCore::LDWFI: 192198090Srdivacky BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) 193224145Sdim .addReg(FrameReg) 194193323Sed .addImm(Offset); 195193323Sed break; 196193323Sed case XCore::STWFI: 197198090Srdivacky BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) 198193323Sed .addReg(Reg, getKillRegState(isKill)) 199224145Sdim .addReg(FrameReg) 200193323Sed .addImm(Offset); 201193323Sed break; 202193323Sed case XCore::LDAWFI: 203198090Srdivacky BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) 204224145Sdim .addReg(FrameReg) 205193323Sed .addImm(Offset); 206193323Sed break; 207193323Sed default: 208198090Srdivacky llvm_unreachable("Unexpected Opcode"); 209193323Sed } 210193323Sed } 211193323Sed } else { 212193323Sed bool isU6 = isImmU6(Offset); 213207618Srdivacky if (!isU6 && !isImmU16(Offset)) 214207618Srdivacky report_fatal_error("eliminateFrameIndex Frame size too big: " + 215207618Srdivacky Twine(Offset)); 216193323Sed 217193323Sed switch (MI.getOpcode()) { 218193323Sed int NewOpcode; 219193323Sed case XCore::LDWFI: 220193323Sed NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 221193323Sed BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 222193323Sed .addImm(Offset); 223193323Sed break; 224193323Sed case XCore::STWFI: 225193323Sed NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 226193323Sed BuildMI(MBB, II, dl, TII.get(NewOpcode)) 227193323Sed .addReg(Reg, getKillRegState(isKill)) 228193323Sed .addImm(Offset); 229193323Sed break; 230193323Sed case XCore::LDAWFI: 231193323Sed NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 232193323Sed BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 233193323Sed .addImm(Offset); 234193323Sed break; 235193323Sed default: 236198090Srdivacky llvm_unreachable("Unexpected Opcode"); 237193323Sed } 238193323Sed } 239193323Sed // Erase old instruction. 240193323Sed MBB.erase(II); 241193323Sed} 242193323Sed 243193323Sedvoid XCoreRegisterInfo:: 244193323SedloadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 245193323Sed unsigned DstReg, int64_t Value, DebugLoc dl) const { 246193323Sed // TODO use mkmsk if possible. 247193323Sed if (!isImmU16(Value)) { 248193323Sed // TODO use constant pool. 249207618Srdivacky report_fatal_error("loadConstant value too big " + Twine(Value)); 250193323Sed } 251193323Sed int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; 252193323Sed BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value); 253193323Sed} 254193323Sed 255199481Srdivackyunsigned XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 256218893Sdim const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 257218893Sdim 258218893Sdim return TFI->hasFP(MF) ? XCore::R10 : XCore::SP; 259193323Sed} 260