XCoreRegisterInfo.cpp revision 360784
1234353Sdim//===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===// 2193323Sed// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6193323Sed// 7193323Sed//===----------------------------------------------------------------------===// 8193323Sed// 9193323Sed// This file contains the XCore implementation of the MRegisterInfo class. 10193323Sed// 11193323Sed//===----------------------------------------------------------------------===// 12193323Sed 13193323Sed#include "XCoreRegisterInfo.h" 14249423Sdim#include "XCore.h" 15276479Sdim#include "XCoreInstrInfo.h" 16193323Sed#include "XCoreMachineFunctionInfo.h" 17280031Sdim#include "XCoreSubtarget.h" 18249423Sdim#include "llvm/ADT/BitVector.h" 19249423Sdim#include "llvm/ADT/STLExtras.h" 20249423Sdim#include "llvm/CodeGen/MachineFrameInfo.h" 21249423Sdim#include "llvm/CodeGen/MachineFunction.h" 22193323Sed#include "llvm/CodeGen/MachineInstrBuilder.h" 23193323Sed#include "llvm/CodeGen/MachineModuleInfo.h" 24193323Sed#include "llvm/CodeGen/MachineRegisterInfo.h" 25193323Sed#include "llvm/CodeGen/RegisterScavenging.h" 26249423Sdim#include "llvm/IR/Function.h" 27249423Sdim#include "llvm/IR/Type.h" 28249423Sdim#include "llvm/Support/Debug.h" 29249423Sdim#include "llvm/Support/ErrorHandling.h" 30276479Sdim#include "llvm/Support/MathExtras.h" 31249423Sdim#include "llvm/Support/raw_ostream.h" 32327952Sdim#include "llvm/CodeGen/TargetFrameLowering.h" 33193323Sed#include "llvm/Target/TargetMachine.h" 34193323Sed#include "llvm/Target/TargetOptions.h" 35193323Sed 36276479Sdimusing namespace llvm; 37276479Sdim 38276479Sdim#define DEBUG_TYPE "xcore-reg-info" 39276479Sdim 40224145Sdim#define GET_REGINFO_TARGET_DESC 41224145Sdim#include "XCoreGenRegisterInfo.inc" 42224145Sdim 43261991SdimXCoreRegisterInfo::XCoreRegisterInfo() 44261991Sdim : XCoreGenRegisterInfo(XCore::LR) { 45193323Sed} 46193323Sed 47193323Sed// helper functions 48193323Sedstatic inline bool isImmUs(unsigned val) { 49193323Sed return val <= 11; 50193323Sed} 51193323Sed 52193323Sedstatic inline bool isImmU6(unsigned val) { 53193323Sed return val < (1 << 6); 54193323Sed} 55193323Sed 56193323Sedstatic inline bool isImmU16(unsigned val) { 57193323Sed return val < (1 << 16); 58193323Sed} 59193323Sed 60276479Sdim 61276479Sdimstatic void InsertFPImmInst(MachineBasicBlock::iterator II, 62276479Sdim const XCoreInstrInfo &TII, 63276479Sdim unsigned Reg, unsigned FrameReg, int Offset ) { 64276479Sdim MachineInstr &MI = *II; 65276479Sdim MachineBasicBlock &MBB = *MI.getParent(); 66276479Sdim DebugLoc dl = MI.getDebugLoc(); 67276479Sdim 68276479Sdim switch (MI.getOpcode()) { 69276479Sdim case XCore::LDWFI: 70276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) 71276479Sdim .addReg(FrameReg) 72276479Sdim .addImm(Offset) 73276479Sdim .addMemOperand(*MI.memoperands_begin()); 74276479Sdim break; 75276479Sdim case XCore::STWFI: 76276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) 77276479Sdim .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) 78276479Sdim .addReg(FrameReg) 79276479Sdim .addImm(Offset) 80276479Sdim .addMemOperand(*MI.memoperands_begin()); 81276479Sdim break; 82276479Sdim case XCore::LDAWFI: 83276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) 84276479Sdim .addReg(FrameReg) 85276479Sdim .addImm(Offset); 86276479Sdim break; 87276479Sdim default: 88276479Sdim llvm_unreachable("Unexpected Opcode"); 89276479Sdim } 90276479Sdim} 91276479Sdim 92276479Sdimstatic void InsertFPConstInst(MachineBasicBlock::iterator II, 93276479Sdim const XCoreInstrInfo &TII, 94276479Sdim unsigned Reg, unsigned FrameReg, 95276479Sdim int Offset, RegScavenger *RS ) { 96276479Sdim assert(RS && "requiresRegisterScavenging failed"); 97276479Sdim MachineInstr &MI = *II; 98276479Sdim MachineBasicBlock &MBB = *MI.getParent(); 99276479Sdim DebugLoc dl = MI.getDebugLoc(); 100276479Sdim unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); 101280031Sdim RS->setRegUsed(ScratchOffset); 102276479Sdim TII.loadImmediate(MBB, II, ScratchOffset, Offset); 103276479Sdim 104276479Sdim switch (MI.getOpcode()) { 105276479Sdim case XCore::LDWFI: 106276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) 107276479Sdim .addReg(FrameReg) 108276479Sdim .addReg(ScratchOffset, RegState::Kill) 109276479Sdim .addMemOperand(*MI.memoperands_begin()); 110276479Sdim break; 111276479Sdim case XCore::STWFI: 112276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) 113276479Sdim .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) 114276479Sdim .addReg(FrameReg) 115276479Sdim .addReg(ScratchOffset, RegState::Kill) 116276479Sdim .addMemOperand(*MI.memoperands_begin()); 117276479Sdim break; 118276479Sdim case XCore::LDAWFI: 119276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) 120276479Sdim .addReg(FrameReg) 121276479Sdim .addReg(ScratchOffset, RegState::Kill); 122276479Sdim break; 123276479Sdim default: 124276479Sdim llvm_unreachable("Unexpected Opcode"); 125276479Sdim } 126276479Sdim} 127276479Sdim 128276479Sdimstatic void InsertSPImmInst(MachineBasicBlock::iterator II, 129276479Sdim const XCoreInstrInfo &TII, 130276479Sdim unsigned Reg, int Offset) { 131276479Sdim MachineInstr &MI = *II; 132276479Sdim MachineBasicBlock &MBB = *MI.getParent(); 133276479Sdim DebugLoc dl = MI.getDebugLoc(); 134276479Sdim bool isU6 = isImmU6(Offset); 135276479Sdim 136276479Sdim switch (MI.getOpcode()) { 137276479Sdim int NewOpcode; 138276479Sdim case XCore::LDWFI: 139276479Sdim NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 140276479Sdim BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 141276479Sdim .addImm(Offset) 142276479Sdim .addMemOperand(*MI.memoperands_begin()); 143276479Sdim break; 144276479Sdim case XCore::STWFI: 145276479Sdim NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 146276479Sdim BuildMI(MBB, II, dl, TII.get(NewOpcode)) 147276479Sdim .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) 148276479Sdim .addImm(Offset) 149276479Sdim .addMemOperand(*MI.memoperands_begin()); 150276479Sdim break; 151276479Sdim case XCore::LDAWFI: 152276479Sdim NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 153276479Sdim BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 154276479Sdim .addImm(Offset); 155276479Sdim break; 156276479Sdim default: 157276479Sdim llvm_unreachable("Unexpected Opcode"); 158276479Sdim } 159276479Sdim} 160276479Sdim 161276479Sdimstatic void InsertSPConstInst(MachineBasicBlock::iterator II, 162276479Sdim const XCoreInstrInfo &TII, 163276479Sdim unsigned Reg, int Offset, RegScavenger *RS ) { 164276479Sdim assert(RS && "requiresRegisterScavenging failed"); 165276479Sdim MachineInstr &MI = *II; 166276479Sdim MachineBasicBlock &MBB = *MI.getParent(); 167276479Sdim DebugLoc dl = MI.getDebugLoc(); 168276479Sdim unsigned OpCode = MI.getOpcode(); 169276479Sdim 170276479Sdim unsigned ScratchBase; 171276479Sdim if (OpCode==XCore::STWFI) { 172276479Sdim ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); 173280031Sdim RS->setRegUsed(ScratchBase); 174276479Sdim } else 175276479Sdim ScratchBase = Reg; 176276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0); 177276479Sdim unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); 178280031Sdim RS->setRegUsed(ScratchOffset); 179276479Sdim TII.loadImmediate(MBB, II, ScratchOffset, Offset); 180276479Sdim 181276479Sdim switch (OpCode) { 182276479Sdim case XCore::LDWFI: 183276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) 184276479Sdim .addReg(ScratchBase, RegState::Kill) 185276479Sdim .addReg(ScratchOffset, RegState::Kill) 186276479Sdim .addMemOperand(*MI.memoperands_begin()); 187276479Sdim break; 188276479Sdim case XCore::STWFI: 189276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) 190276479Sdim .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) 191276479Sdim .addReg(ScratchBase, RegState::Kill) 192276479Sdim .addReg(ScratchOffset, RegState::Kill) 193276479Sdim .addMemOperand(*MI.memoperands_begin()); 194276479Sdim break; 195276479Sdim case XCore::LDAWFI: 196276479Sdim BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) 197276479Sdim .addReg(ScratchBase, RegState::Kill) 198276479Sdim .addReg(ScratchOffset, RegState::Kill); 199276479Sdim break; 200276479Sdim default: 201276479Sdim llvm_unreachable("Unexpected Opcode"); 202276479Sdim } 203276479Sdim} 204276479Sdim 205206274Srdivackybool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) { 206360784Sdim return MF.needsFrameMoves(); 207193323Sed} 208193323Sed 209288943Sdimconst MCPhysReg * 210288943SdimXCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 211276479Sdim // The callee saved registers LR & FP are explicitly handled during 212276479Sdim // emitPrologue & emitEpilogue and related functions. 213276479Sdim static const MCPhysReg CalleeSavedRegs[] = { 214193323Sed XCore::R4, XCore::R5, XCore::R6, XCore::R7, 215276479Sdim XCore::R8, XCore::R9, XCore::R10, 216193323Sed 0 217193323Sed }; 218276479Sdim static const MCPhysReg CalleeSavedRegsFP[] = { 219276479Sdim XCore::R4, XCore::R5, XCore::R6, XCore::R7, 220276479Sdim XCore::R8, XCore::R9, 221276479Sdim 0 222276479Sdim }; 223288943Sdim const XCoreFrameLowering *TFI = getFrameLowering(*MF); 224276479Sdim if (TFI->hasFP(*MF)) 225276479Sdim return CalleeSavedRegsFP; 226193323Sed return CalleeSavedRegs; 227193323Sed} 228193323Sed 229193323SedBitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 230193323Sed BitVector Reserved(getNumRegs()); 231288943Sdim const XCoreFrameLowering *TFI = getFrameLowering(MF); 232218893Sdim 233193323Sed Reserved.set(XCore::CP); 234193323Sed Reserved.set(XCore::DP); 235193323Sed Reserved.set(XCore::SP); 236193323Sed Reserved.set(XCore::LR); 237218893Sdim if (TFI->hasFP(MF)) { 238193323Sed Reserved.set(XCore::R10); 239193323Sed } 240193323Sed return Reserved; 241193323Sed} 242193323Sed 243193323Sedbool 244193323SedXCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 245276479Sdim return true; 246193323Sed} 247193323Sed 248221345Sdimbool 249239462SdimXCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const { 250276479Sdim return true; 251239462Sdim} 252239462Sdim 253239462Sdimbool 254221345SdimXCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 255221345Sdim return false; 256221345Sdim} 257221345Sdim 258212904Sdimvoid 259198090SrdivackyXCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 260249423Sdim int SPAdj, unsigned FIOperandNum, 261249423Sdim RegScavenger *RS) const { 262193323Sed assert(SPAdj == 0 && "Unexpected"); 263193323Sed MachineInstr &MI = *II; 264249423Sdim MachineOperand &FrameOp = MI.getOperand(FIOperandNum); 265193323Sed int FrameIndex = FrameOp.getIndex(); 266193323Sed 267193323Sed MachineFunction &MF = *MI.getParent()->getParent(); 268276479Sdim const XCoreInstrInfo &TII = 269280031Sdim *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo()); 270276479Sdim 271288943Sdim const XCoreFrameLowering *TFI = getFrameLowering(MF); 272314564Sdim int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex); 273314564Sdim int StackSize = MF.getFrameInfo().getStackSize(); 274193323Sed 275193323Sed #ifndef NDEBUG 276341825Sdim LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n"); 277341825Sdim LLVM_DEBUG(errs() << "<--------->\n"); 278341825Sdim LLVM_DEBUG(MI.print(errs())); 279341825Sdim LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"); 280341825Sdim LLVM_DEBUG(errs() << "FrameOffset : " << Offset << "\n"); 281341825Sdim LLVM_DEBUG(errs() << "StackSize : " << StackSize << "\n"); 282341825Sdim#endif 283193323Sed 284193323Sed Offset += StackSize; 285224145Sdim 286353358Sdim Register FrameReg = getFrameRegister(MF); 287224145Sdim 288224145Sdim // Special handling of DBG_VALUE instructions. 289224145Sdim if (MI.isDebugValue()) { 290249423Sdim MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/); 291249423Sdim MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 292224145Sdim return; 293224145Sdim } 294224145Sdim 295193323Sed // fold constant into offset. 296249423Sdim Offset += MI.getOperand(FIOperandNum + 1).getImm(); 297249423Sdim MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); 298341825Sdim 299193323Sed assert(Offset%4 == 0 && "Misaligned stack offset"); 300341825Sdim LLVM_DEBUG(errs() << "Offset : " << Offset << "\n" 301341825Sdim << "<--------->\n"); 302193323Sed Offset/=4; 303341825Sdim 304360784Sdim Register Reg = MI.getOperand(0).getReg(); 305276479Sdim assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand"); 306193323Sed 307276479Sdim if (TFI->hasFP(MF)) { 308276479Sdim if (isImmUs(Offset)) 309276479Sdim InsertFPImmInst(II, TII, Reg, FrameReg, Offset); 310276479Sdim else 311276479Sdim InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS); 312193323Sed } else { 313276479Sdim if (isImmU16(Offset)) 314276479Sdim InsertSPImmInst(II, TII, Reg, Offset); 315276479Sdim else 316276479Sdim InsertSPConstInst(II, TII, Reg, Offset, RS); 317193323Sed } 318193323Sed // Erase old instruction. 319276479Sdim MachineBasicBlock &MBB = *MI.getParent(); 320193323Sed MBB.erase(II); 321193323Sed} 322193323Sed 323193323Sed 324353358SdimRegister XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 325288943Sdim const XCoreFrameLowering *TFI = getFrameLowering(MF); 326218893Sdim 327218893Sdim return TFI->hasFP(MF) ? XCore::R10 : XCore::SP; 328193323Sed} 329