XCoreRegisterInfo.cpp revision 360784
1139804Simp//===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===// 2139013Sdavidxu// 3112904Sjeff// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4112904Sjeff// See https://llvm.org/LICENSE.txt for license information. 5112904Sjeff// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6112904Sjeff// 7112904Sjeff//===----------------------------------------------------------------------===// 8112904Sjeff// 9112904Sjeff// This file contains the XCore implementation of the MRegisterInfo class. 10112904Sjeff// 11112904Sjeff//===----------------------------------------------------------------------===// 12112904Sjeff 13112904Sjeff#include "XCoreRegisterInfo.h" 14112904Sjeff#include "XCore.h" 15112904Sjeff#include "XCoreInstrInfo.h" 16112904Sjeff#include "XCoreMachineFunctionInfo.h" 17112904Sjeff#include "XCoreSubtarget.h" 18112904Sjeff#include "llvm/ADT/BitVector.h" 19112904Sjeff#include "llvm/ADT/STLExtras.h" 20112904Sjeff#include "llvm/CodeGen/MachineFrameInfo.h" 21112904Sjeff#include "llvm/CodeGen/MachineFunction.h" 22112904Sjeff#include "llvm/CodeGen/MachineInstrBuilder.h" 23112904Sjeff#include "llvm/CodeGen/MachineModuleInfo.h" 24112904Sjeff#include "llvm/CodeGen/MachineRegisterInfo.h" 25112904Sjeff#include "llvm/CodeGen/RegisterScavenging.h" 26112904Sjeff#include "llvm/IR/Function.h" 27112904Sjeff#include "llvm/IR/Type.h" 28116182Sobrien#include "llvm/Support/Debug.h" 29116182Sobrien#include "llvm/Support/ErrorHandling.h" 30116182Sobrien#include "llvm/Support/MathExtras.h" 31162536Sdavidxu#include "llvm/Support/raw_ostream.h" 32112904Sjeff#include "llvm/CodeGen/TargetFrameLowering.h" 33112904Sjeff#include "llvm/Target/TargetMachine.h" 34131431Smarcel#include "llvm/Target/TargetOptions.h" 35112904Sjeff 36115765Sjeffusing namespace llvm; 37112904Sjeff 38164033Srwatson#define DEBUG_TYPE "xcore-reg-info" 39112904Sjeff 40161678Sdavidxu#define GET_REGINFO_TARGET_DESC 41161678Sdavidxu#include "XCoreGenRegisterInfo.inc" 42112904Sjeff 43112904SjeffXCoreRegisterInfo::XCoreRegisterInfo() 44112904Sjeff : XCoreGenRegisterInfo(XCore::LR) { 45139013Sdavidxu} 46112904Sjeff 47112904Sjeff// helper functions 48139013Sdavidxustatic inline bool isImmUs(unsigned val) { 49139013Sdavidxu return val <= 11; 50139013Sdavidxu} 51139013Sdavidxu 52139013Sdavidxustatic inline bool isImmU6(unsigned val) { 53139013Sdavidxu return val < (1 << 6); 54162536Sdavidxu} 55162536Sdavidxu 56162536Sdavidxustatic inline bool isImmU16(unsigned val) { 57162536Sdavidxu return val < (1 << 16); 58161678Sdavidxu} 59161678Sdavidxu 60161678Sdavidxu 61161678Sdavidxustatic void InsertFPImmInst(MachineBasicBlock::iterator II, 62161678Sdavidxu const XCoreInstrInfo &TII, 63161678Sdavidxu unsigned Reg, unsigned FrameReg, int Offset ) { 64139013Sdavidxu MachineInstr &MI = *II; 65161678Sdavidxu MachineBasicBlock &MBB = *MI.getParent(); 66139013Sdavidxu DebugLoc dl = MI.getDebugLoc(); 67161678Sdavidxu 68139013Sdavidxu switch (MI.getOpcode()) { 69161678Sdavidxu case XCore::LDWFI: 70139013Sdavidxu BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg) 71139013Sdavidxu .addReg(FrameReg) 72139013Sdavidxu .addImm(Offset) 73161678Sdavidxu .addMemOperand(*MI.memoperands_begin()); 74139013Sdavidxu break; 75139013Sdavidxu case XCore::STWFI: 76161678Sdavidxu BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus)) 77161678Sdavidxu .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) 78139013Sdavidxu .addReg(FrameReg) 79139013Sdavidxu .addImm(Offset) 80161678Sdavidxu .addMemOperand(*MI.memoperands_begin()); 81161678Sdavidxu break; 82139013Sdavidxu case XCore::LDAWFI: 83139013Sdavidxu BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg) 84139013Sdavidxu .addReg(FrameReg) 85139013Sdavidxu .addImm(Offset); 86161678Sdavidxu break; 87161678Sdavidxu default: 88161678Sdavidxu llvm_unreachable("Unexpected Opcode"); 89161678Sdavidxu } 90161678Sdavidxu} 91161678Sdavidxu 92161678Sdavidxustatic void InsertFPConstInst(MachineBasicBlock::iterator II, 93161678Sdavidxu const XCoreInstrInfo &TII, 94161678Sdavidxu unsigned Reg, unsigned FrameReg, 95161678Sdavidxu int Offset, RegScavenger *RS ) { 96161678Sdavidxu assert(RS && "requiresRegisterScavenging failed"); 97161678Sdavidxu MachineInstr &MI = *II; 98161678Sdavidxu MachineBasicBlock &MBB = *MI.getParent(); 99161678Sdavidxu DebugLoc dl = MI.getDebugLoc(); 100161678Sdavidxu unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); 101161678Sdavidxu RS->setRegUsed(ScratchOffset); 102161678Sdavidxu TII.loadImmediate(MBB, II, ScratchOffset, Offset); 103161678Sdavidxu 104161678Sdavidxu switch (MI.getOpcode()) { 105161678Sdavidxu case XCore::LDWFI: 106161678Sdavidxu BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) 107161678Sdavidxu .addReg(FrameReg) 108115765Sjeff .addReg(ScratchOffset, RegState::Kill) 109161678Sdavidxu .addMemOperand(*MI.memoperands_begin()); 110161678Sdavidxu break; 111161678Sdavidxu case XCore::STWFI: 112161678Sdavidxu BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) 113161678Sdavidxu .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) 114161678Sdavidxu .addReg(FrameReg) 115161678Sdavidxu .addReg(ScratchOffset, RegState::Kill) 116161678Sdavidxu .addMemOperand(*MI.memoperands_begin()); 117161678Sdavidxu break; 118161678Sdavidxu case XCore::LDAWFI: 119161678Sdavidxu BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) 120161678Sdavidxu .addReg(FrameReg) 121161678Sdavidxu .addReg(ScratchOffset, RegState::Kill); 122161678Sdavidxu break; 123161678Sdavidxu default: 124161678Sdavidxu llvm_unreachable("Unexpected Opcode"); 125161678Sdavidxu } 126161678Sdavidxu} 127161678Sdavidxu 128161678Sdavidxustatic void InsertSPImmInst(MachineBasicBlock::iterator II, 129161678Sdavidxu const XCoreInstrInfo &TII, 130161678Sdavidxu unsigned Reg, int Offset) { 131161678Sdavidxu MachineInstr &MI = *II; 132161678Sdavidxu MachineBasicBlock &MBB = *MI.getParent(); 133161678Sdavidxu DebugLoc dl = MI.getDebugLoc(); 134161678Sdavidxu bool isU6 = isImmU6(Offset); 135161742Sdavidxu 136161678Sdavidxu switch (MI.getOpcode()) { 137115765Sjeff int NewOpcode; 138115765Sjeff case XCore::LDWFI: 139161678Sdavidxu NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6; 140161678Sdavidxu BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 141161678Sdavidxu .addImm(Offset) 142138224Sdavidxu .addMemOperand(*MI.memoperands_begin()); 143161678Sdavidxu break; 144161678Sdavidxu case XCore::STWFI: 145161678Sdavidxu NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6; 146161678Sdavidxu BuildMI(MBB, II, dl, TII.get(NewOpcode)) 147161678Sdavidxu .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) 148161678Sdavidxu .addImm(Offset) 149161678Sdavidxu .addMemOperand(*MI.memoperands_begin()); 150161678Sdavidxu break; 151161678Sdavidxu case XCore::LDAWFI: 152161678Sdavidxu NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6; 153158377Sdavidxu BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg) 154161678Sdavidxu .addImm(Offset); 155161678Sdavidxu break; 156161678Sdavidxu default: 157138224Sdavidxu llvm_unreachable("Unexpected Opcode"); 158115765Sjeff } 159161678Sdavidxu} 160161678Sdavidxu 161161678Sdavidxustatic void InsertSPConstInst(MachineBasicBlock::iterator II, 162161678Sdavidxu const XCoreInstrInfo &TII, 163161678Sdavidxu unsigned Reg, int Offset, RegScavenger *RS ) { 164161678Sdavidxu assert(RS && "requiresRegisterScavenging failed"); 165161678Sdavidxu MachineInstr &MI = *II; 166161678Sdavidxu MachineBasicBlock &MBB = *MI.getParent(); 167161678Sdavidxu DebugLoc dl = MI.getDebugLoc(); 168161678Sdavidxu unsigned OpCode = MI.getOpcode(); 169161678Sdavidxu 170163709Sjb unsigned ScratchBase; 171161678Sdavidxu if (OpCode==XCore::STWFI) { 172161678Sdavidxu ScratchBase = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); 173161678Sdavidxu RS->setRegUsed(ScratchBase); 174163709Sjb } else 175163709Sjb ScratchBase = Reg; 176163709Sjb BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0); 177163709Sjb unsigned ScratchOffset = RS->scavengeRegister(&XCore::GRRegsRegClass, II, 0); 178163709Sjb RS->setRegUsed(ScratchOffset); 179161678Sdavidxu TII.loadImmediate(MBB, II, ScratchOffset, Offset); 180138224Sdavidxu 181138224Sdavidxu switch (OpCode) { 182138224Sdavidxu case XCore::LDWFI: 183115765Sjeff BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg) 184161678Sdavidxu .addReg(ScratchBase, RegState::Kill) 185161678Sdavidxu .addReg(ScratchOffset, RegState::Kill) 186161678Sdavidxu .addMemOperand(*MI.memoperands_begin()); 187161678Sdavidxu break; 188161678Sdavidxu case XCore::STWFI: 189161678Sdavidxu BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r)) 190161678Sdavidxu .addReg(Reg, getKillRegState(MI.getOperand(0).isKill())) 191161678Sdavidxu .addReg(ScratchBase, RegState::Kill) 192161678Sdavidxu .addReg(ScratchOffset, RegState::Kill) 193138224Sdavidxu .addMemOperand(*MI.memoperands_begin()); 194161678Sdavidxu break; 195115310Sjeff case XCore::LDAWFI: 196161678Sdavidxu BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg) 197161678Sdavidxu .addReg(ScratchBase, RegState::Kill) 198161678Sdavidxu .addReg(ScratchOffset, RegState::Kill); 199161678Sdavidxu break; 200161678Sdavidxu default: 201161678Sdavidxu llvm_unreachable("Unexpected Opcode"); 202161678Sdavidxu } 203139013Sdavidxu} 204139013Sdavidxu 205139257Sdavidxubool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) { 206139257Sdavidxu return MF.needsFrameMoves(); 207139013Sdavidxu} 208139013Sdavidxu 209161678Sdavidxuconst MCPhysReg * 210139257SdavidxuXCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 211139257Sdavidxu // The callee saved registers LR & FP are explicitly handled during 212139013Sdavidxu // emitPrologue & emitEpilogue and related functions. 213161678Sdavidxu static const MCPhysReg CalleeSavedRegs[] = { 214139013Sdavidxu XCore::R4, XCore::R5, XCore::R6, XCore::R7, 215139013Sdavidxu XCore::R8, XCore::R9, XCore::R10, 216163697Sdavidxu 0 217161678Sdavidxu }; 218161678Sdavidxu static const MCPhysReg CalleeSavedRegsFP[] = { 219161678Sdavidxu XCore::R4, XCore::R5, XCore::R6, XCore::R7, 220161678Sdavidxu XCore::R8, XCore::R9, 221161678Sdavidxu 0 222161678Sdavidxu }; 223115310Sjeff const XCoreFrameLowering *TFI = getFrameLowering(*MF); 224161678Sdavidxu if (TFI->hasFP(*MF)) 225161678Sdavidxu return CalleeSavedRegsFP; 226161678Sdavidxu return CalleeSavedRegs; 227161678Sdavidxu} 228138224Sdavidxu 229161678SdavidxuBitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 230161678Sdavidxu BitVector Reserved(getNumRegs()); 231161678Sdavidxu const XCoreFrameLowering *TFI = getFrameLowering(MF); 232161678Sdavidxu 233161678Sdavidxu Reserved.set(XCore::CP); 234161678Sdavidxu Reserved.set(XCore::DP); 235161678Sdavidxu Reserved.set(XCore::SP); 236161678Sdavidxu Reserved.set(XCore::LR); 237161678Sdavidxu if (TFI->hasFP(MF)) { 238161678Sdavidxu Reserved.set(XCore::R10); 239161678Sdavidxu } 240161678Sdavidxu return Reserved; 241161678Sdavidxu} 242161678Sdavidxu 243143149Sdavidxubool 244143149SdavidxuXCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const { 245143149Sdavidxu return true; 246161678Sdavidxu} 247161678Sdavidxu 248161678Sdavidxubool 249161678SdavidxuXCoreRegisterInfo::trackLivenessAfterRegAlloc(const MachineFunction &MF) const { 250161678Sdavidxu return true; 251161678Sdavidxu} 252143149Sdavidxu 253143149Sdavidxubool 254143149SdavidxuXCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const { 255143149Sdavidxu return false; 256143149Sdavidxu} 257143149Sdavidxu 258143149Sdavidxuvoid 259143149SdavidxuXCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 260161678Sdavidxu int SPAdj, unsigned FIOperandNum, 261139013Sdavidxu RegScavenger *RS) const { 262138224Sdavidxu assert(SPAdj == 0 && "Unexpected"); 263161678Sdavidxu MachineInstr &MI = *II; 264161678Sdavidxu MachineOperand &FrameOp = MI.getOperand(FIOperandNum); 265138224Sdavidxu int FrameIndex = FrameOp.getIndex(); 266138224Sdavidxu 267139013Sdavidxu MachineFunction &MF = *MI.getParent()->getParent(); 268139013Sdavidxu const XCoreInstrInfo &TII = 269139013Sdavidxu *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo()); 270139013Sdavidxu 271161678Sdavidxu const XCoreFrameLowering *TFI = getFrameLowering(MF); 272161678Sdavidxu int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex); 273139013Sdavidxu int StackSize = MF.getFrameInfo().getStackSize(); 274139013Sdavidxu 275161678Sdavidxu #ifndef NDEBUG 276161678Sdavidxu LLVM_DEBUG(errs() << "\nFunction : " << MF.getName() << "\n"); 277139013Sdavidxu LLVM_DEBUG(errs() << "<--------->\n"); 278161678Sdavidxu LLVM_DEBUG(MI.print(errs())); 279139013Sdavidxu LLVM_DEBUG(errs() << "FrameIndex : " << FrameIndex << "\n"); 280139013Sdavidxu LLVM_DEBUG(errs() << "FrameOffset : " << Offset << "\n"); 281161678Sdavidxu LLVM_DEBUG(errs() << "StackSize : " << StackSize << "\n"); 282161678Sdavidxu#endif 283161678Sdavidxu 284161678Sdavidxu Offset += StackSize; 285138224Sdavidxu 286139257Sdavidxu Register FrameReg = getFrameRegister(MF); 287139257Sdavidxu 288161678Sdavidxu // Special handling of DBG_VALUE instructions. 289139257Sdavidxu if (MI.isDebugValue()) { 290161678Sdavidxu MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/); 291161678Sdavidxu MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 292161678Sdavidxu return; 293161678Sdavidxu } 294161678Sdavidxu 295161678Sdavidxu // fold constant into offset. 296139257Sdavidxu Offset += MI.getOperand(FIOperandNum + 1).getImm(); 297161678Sdavidxu MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0); 298139257Sdavidxu 299139257Sdavidxu assert(Offset%4 == 0 && "Misaligned stack offset"); 300161678Sdavidxu LLVM_DEBUG(errs() << "Offset : " << Offset << "\n" 301161678Sdavidxu << "<--------->\n"); 302161678Sdavidxu Offset/=4; 303139257Sdavidxu 304139257Sdavidxu Register Reg = MI.getOperand(0).getReg(); 305139257Sdavidxu assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand"); 306161678Sdavidxu 307139257Sdavidxu if (TFI->hasFP(MF)) { 308161678Sdavidxu if (isImmUs(Offset)) 309161678Sdavidxu InsertFPImmInst(II, TII, Reg, FrameReg, Offset); 310161678Sdavidxu else 311161678Sdavidxu InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS); 312161678Sdavidxu } else { 313161678Sdavidxu if (isImmU16(Offset)) 314139257Sdavidxu InsertSPImmInst(II, TII, Reg, Offset); 315139257Sdavidxu else 316161678Sdavidxu InsertSPConstInst(II, TII, Reg, Offset, RS); 317161678Sdavidxu } 318161678Sdavidxu // Erase old instruction. 319139257Sdavidxu MachineBasicBlock &MBB = *MI.getParent(); 320139013Sdavidxu MBB.erase(II); 321138224Sdavidxu} 322161678Sdavidxu 323161678Sdavidxu 324161678SdavidxuRegister XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 325161678Sdavidxu const XCoreFrameLowering *TFI = getFrameLowering(MF); 326138224Sdavidxu 327138224Sdavidxu return TFI->hasFP(MF) ? XCore::R10 : XCore::SP; 328161678Sdavidxu} 329161678Sdavidxu