XCoreRegisterInfo.cpp revision 252723
165832Snyan//===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===// 265832Snyan// 365832Snyan// The LLVM Compiler Infrastructure 465832Snyan// 565832Snyan// This file is distributed under the University of Illinois Open Source 665832Snyan// License. See LICENSE.TXT for details. 765832Snyan// 865832Snyan//===----------------------------------------------------------------------===// 965832Snyan// 1065832Snyan// This file contains the XCore implementation of the MRegisterInfo class. 1165832Snyan// 1265832Snyan//===----------------------------------------------------------------------===// 1365832Snyan 1465832Snyan#include "XCoreRegisterInfo.h" 1565832Snyan#include "XCore.h" 1665832Snyan#include "XCoreMachineFunctionInfo.h" 1765832Snyan#include "llvm/ADT/BitVector.h" 1865832Snyan#include "llvm/ADT/STLExtras.h" 1965832Snyan#include "llvm/CodeGen/MachineFrameInfo.h" 2065832Snyan#include "llvm/CodeGen/MachineFunction.h" 2165832Snyan#include "llvm/CodeGen/MachineInstrBuilder.h" 2265832Snyan#include "llvm/CodeGen/MachineModuleInfo.h" 2365832Snyan#include "llvm/CodeGen/MachineRegisterInfo.h" 2465832Snyan#include "llvm/CodeGen/RegisterScavenging.h" 2565832Snyan#include "llvm/IR/Function.h" 2665832Snyan#include "llvm/IR/Type.h" 2765832Snyan#include "llvm/Support/Debug.h" 2865832Snyan#include "llvm/Support/ErrorHandling.h" 2965832Snyan#include "llvm/Support/raw_ostream.h" 3065832Snyan#include "llvm/Target/TargetFrameLowering.h" 3165832Snyan#include "llvm/Target/TargetInstrInfo.h" 3265832Snyan#include "llvm/Target/TargetMachine.h" 3365832Snyan#include "llvm/Target/TargetOptions.h" 3465832Snyan 3565832Snyan#define GET_REGINFO_TARGET_DESC 3665832Snyan#include "XCoreGenRegisterInfo.inc" 3765832Snyan 3865832Snyanusing namespace llvm; 3965832Snyan 4065832SnyanXCoreRegisterInfo::XCoreRegisterInfo(const TargetInstrInfo &tii) 4165832Snyan : XCoreGenRegisterInfo(XCore::LR), TII(tii) { 4265832Snyan} 4365832Snyan 4465832Snyan// helper functions 4565832Snyanstatic inline bool isImmUs(unsigned val) { 4665832Snyan return val <= 11; 4765832Snyan} 4865832Snyan 4965832Snyanstatic inline bool isImmU6(unsigned val) { 5065832Snyan return val < (1 << 6); 5165832Snyan} 5267442Snyan 5367442Snyanstatic inline bool isImmU16(unsigned val) { 5465832Snyan return val < (1 << 16); 5565832Snyan} 5665832Snyan 5765832Snyanbool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) { 5865832Snyan return MF.getMMI().hasDebugInfo() || 5965832Snyan MF.getFunction()->needsUnwindTableEntry(); 6065832Snyan} 6165832Snyan 6265832Snyanconst uint16_t* XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) 6365832Snyan const { 6465832Snyan static const uint16_t CalleeSavedRegs[] = { 6565832Snyan XCore::R4, XCore::R5, XCore::R6, XCore::R7, 6665832Snyan XCore::R8, XCore::R9, XCore::R10, XCore::LR, 6765832Snyan 0 6865832Snyan }; 6965832Snyan return CalleeSavedRegs; 7065832Snyan} 7165832Snyan 7265832SnyanBitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 7365832Snyan BitVector Reserved(getNumRegs()); 7465832Snyan const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 7565832Snyan 7665832Snyan Reserved.set(XCore::CP); 7765832Snyan Reserved.set(XCore::DP); 7865832Snyan Reserved.set(XCore::SP); 7965832Snyan Reserved.set(XCore::LR); 8065832Snyan if (TFI->hasFP(MF)) { 8165832Snyan Reserved.set(XCore::R10); 8265832Snyan } 8365832Snyan return Reserved; 8465832Snyan} 8565832Snyan 8665832Snyanbool 8765832SnyanXCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 8865832Snyan const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 8965832Snyan 9065832Snyan // TODO can we estimate stack size? 9165832Snyan return TFI->hasFP(MF); 9265832Snyan} 9365832Snyan 9465832Snyanbool 9565832SnyanXCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const { 9665832Snyan return requiresRegisterScavenging(MF); 9765832Snyan} 9865832Snyan 9965832Snyanbool 10065832SnyanXCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 10165832Snyan return false; 10265832Snyan} 10365832Snyan 10465832Snyanvoid 10565832SnyanXCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 10665832Snyan int SPAdj, unsigned FIOperandNum, 10765832Snyan RegScavenger *RS) const { 10865832Snyan assert(SPAdj == 0 && "Unexpected"); 10965832Snyan MachineInstr &MI = *II; 11065832Snyan DebugLoc dl = MI.getDebugLoc(); 11165832Snyan MachineOperand &FrameOp = MI.getOperand(FIOperandNum); 11265832Snyan int FrameIndex = FrameOp.getIndex(); 11365832Snyan 11465832Snyan MachineFunction &MF = *MI.getParent()->getParent(); 11565832Snyan const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 11665832Snyan int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 11765832Snyan int StackSize = MF.getFrameInfo()->getStackSize(); 11865832Snyan 11965832Snyan #ifndef NDEBUG 12065832Snyan DEBUG(errs() << "\nFunction : " 12165832Snyan << MF.getName() << "\n"); 12265832Snyan DEBUG(errs() << "<--------->\n"); 12365832Snyan DEBUG(MI.print(errs())); 12465832Snyan DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"); 12565832Snyan DEBUG(errs() << "FrameOffset : " << Offset << "\n"); 12665832Snyan DEBUG(errs() << "StackSize : " << StackSize << "\n"); 12765832Snyan #endif 12865832Snyan 12965832Snyan Offset += StackSize; 13065832Snyan 13165832Snyan unsigned FrameReg = getFrameRegister(MF); 13265832Snyan 13365832Snyan // Special handling of DBG_VALUE instructions. 13465832Snyan if (MI.isDebugValue()) { 13565832Snyan MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/); 13665832Snyan MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 13765832Snyan return; 13865832Snyan } 13965832Snyan 14065832Snyan // fold constant into offset. 14165832Snyan Offset += MI.getOperand(FIOperandNum + 1).getImm(); 14265832Snyan MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); 14365832Snyan 14465832Snyan assert(Offset%4 == 0 && "Misaligned stack offset"); 14565832Snyan 14665832Snyan DEBUG(errs() << "Offset : " << Offset << "\n" << "<--------->\n"); 14765832Snyan 14865832Snyan Offset/=4; 14965832Snyan 15065832Snyan bool FP = TFI->hasFP(MF); 15165832Snyan 15265832Snyan unsigned Reg = MI.getOperand(0).getReg(); 15365832Snyan bool isKill = MI.getOpcode() == XCore::STWFI && MI.getOperand(0).isKill(); 15465832Snyan 15565832Snyan assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand"); 15665832Snyan 15765832Snyan MachineBasicBlock &MBB = *MI.getParent(); 15865832Snyan 15965832Snyan if (FP) { 16065832Snyan bool isUs = isImmUs(Offset); 16165832Snyan 16265832Snyan if (!isUs) { 16365832Snyan if (!RS) 16465832Snyan report_fatal_error("eliminateFrameIndex Frame size too big: " + 16565832Snyan Twine(Offset)); 16665832Snyan unsigned ScratchReg = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 16765832Snyan SPAdj); 16865832Snyan loadConstant(MBB, II, ScratchReg, Offset, dl); 16965832Snyan switch (MI.getOpcode()) { 17065832Snyan case XCore::LDWFI: 17165832Snyan BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) 17265832Snyan .addReg(FrameReg) 17365832Snyan .addReg(ScratchReg, RegState::Kill); 17465832Snyan break; 17565832Snyan case XCore::STWFI: 17665832Snyan BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) 17765832Snyan .addReg(Reg, getKillRegState(isKill)) 17865832Snyan .addReg(FrameReg) 17965832Snyan .addReg(ScratchReg, RegState::Kill); 18065832Snyan break; 18165832Snyan case XCore::LDAWFI: 18265832Snyan BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) 18365832Snyan .addReg(FrameReg) 18465832Snyan .addReg(ScratchReg, RegState::Kill); 18565832Snyan break; 18665832Snyan default: 18765832Snyan llvm_unreachable("Unexpected Opcode"); 18865832Snyan } 18965832Snyan } else { 19065832Snyan switch (MI.getOpcode()) { 19165832Snyan case XCore::LDWFI: 19265832Snyan BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) 19365832Snyan .addReg(FrameReg) 19465832Snyan .addImm(Offset); 19565832Snyan break; 19665832Snyan case XCore::STWFI: 19765832Snyan BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) 19865832Snyan .addReg(Reg, getKillRegState(isKill)) 19965832Snyan .addReg(FrameReg) 20065832Snyan .addImm(Offset); 20165832Snyan break; 20265832Snyan case XCore::LDAWFI: 20365832Snyan BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) 20465832Snyan .addReg(FrameReg) 20565832Snyan .addImm(Offset); 20665832Snyan break; 20765832Snyan default: 20865832Snyan llvm_unreachable("Unexpected Opcode"); 20965832Snyan } 21065832Snyan } 21165832Snyan } else { 21265832Snyan bool isU6 = isImmU6(Offset); 21365832Snyan if (!isU6 && !isImmU16(Offset)) 21465832Snyan report_fatal_error("eliminateFrameIndex Frame size too big: " + 21565832Snyan Twine(Offset)); 21665832Snyan 21765832Snyan switch (MI.getOpcode()) { 21865832Snyan int NewOpcode; 21965832Snyan case XCore::LDWFI: 22065832Snyan NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 22165832Snyan BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 22265832Snyan .addImm(Offset); 22365832Snyan break; 22465832Snyan case XCore::STWFI: 22565832Snyan NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 22665832Snyan BuildMI(MBB, II, dl, TII.get(NewOpcode)) 22765832Snyan .addReg(Reg, getKillRegState(isKill)) 22865832Snyan .addImm(Offset); 22965832Snyan break; 23065832Snyan case XCore::LDAWFI: 23165832Snyan NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 23265832Snyan BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 23365832Snyan .addImm(Offset); 23465832Snyan break; 23565832Snyan default: 23665832Snyan llvm_unreachable("Unexpected Opcode"); 23765832Snyan } 23865832Snyan } 23965832Snyan // Erase old instruction. 24065832Snyan MBB.erase(II); 24165832Snyan} 24265832Snyan 24365832Snyanvoid XCoreRegisterInfo:: 24465832SnyanloadConstant(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, 24565832Snyan unsigned DstReg, int64_t Value, DebugLoc dl) const { 24665832Snyan // TODO use mkmsk if possible. 24765832Snyan if (!isImmU16(Value)) { 24865832Snyan // TODO use constant pool. 24965832Snyan report_fatal_error("loadConstant value too big " + Twine(Value)); 25065832Snyan } 25165832Snyan int Opcode = isImmU6(Value) ? XCore::LDC_ru6 : XCore::LDC_lru6; 25265832Snyan BuildMI(MBB, I, dl, TII.get(Opcode), DstReg).addImm(Value); 25365832Snyan} 25465832Snyan 25565832Snyanunsigned XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 25665832Snyan const TargetFrameLowering *TFI = MF.getTarget().getFrameLowering(); 25765832Snyan 25865832Snyan return TFI->hasFP(MF) ? XCore::R10 : XCore::SP; 25965832Snyan} 26065832Snyan