brintos

brintos / llvm-project-archived public Read only

0
0
Text · 10.2 KiB · d78babd Raw
323 lines · cpp
1//===-- XCoreRegisterInfo.cpp - XCore Register Information ----------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file contains the XCore implementation of the MRegisterInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "XCoreRegisterInfo.h"14#include "XCoreInstrInfo.h"15#include "XCoreSubtarget.h"16#include "llvm/ADT/BitVector.h"17#include "llvm/CodeGen/MachineFrameInfo.h"18#include "llvm/CodeGen/MachineFunction.h"19#include "llvm/CodeGen/MachineInstrBuilder.h"20#include "llvm/CodeGen/MachineModuleInfo.h"21#include "llvm/CodeGen/RegisterScavenging.h"22#include "llvm/CodeGen/TargetFrameLowering.h"23#include "llvm/IR/Function.h"24#include "llvm/IR/Type.h"25#include "llvm/Support/Debug.h"26#include "llvm/Support/ErrorHandling.h"27#include "llvm/Support/raw_ostream.h"28#include "llvm/Target/TargetMachine.h"29#include "llvm/Target/TargetOptions.h"30 31using namespace llvm;32 33#define DEBUG_TYPE "xcore-reg-info"34 35#define GET_REGINFO_TARGET_DESC36#include "XCoreGenRegisterInfo.inc"37 38XCoreRegisterInfo::XCoreRegisterInfo()39  : XCoreGenRegisterInfo(XCore::LR) {40}41 42// helper functions43static inline bool isImmUs(unsigned val) {44  return val <= 11;45}46 47static inline bool isImmU6(unsigned val) {48  return val < (1 << 6);49}50 51static inline bool isImmU16(unsigned val) {52  return val < (1 << 16);53}54 55 56static void InsertFPImmInst(MachineBasicBlock::iterator II,57                            const XCoreInstrInfo &TII,58                            unsigned Reg, unsigned FrameReg, int Offset ) {59  MachineInstr &MI = *II;60  MachineBasicBlock &MBB = *MI.getParent();61  DebugLoc dl = MI.getDebugLoc();62 63  switch (MI.getOpcode()) {64  case XCore::LDWFI:65    BuildMI(MBB, II, dl, TII.get(XCore::LDW_2rus), Reg)66          .addReg(FrameReg)67          .addImm(Offset)68          .addMemOperand(*MI.memoperands_begin());69    break;70  case XCore::STWFI:71    BuildMI(MBB, II, dl, TII.get(XCore::STW_2rus))72          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))73          .addReg(FrameReg)74          .addImm(Offset)75          .addMemOperand(*MI.memoperands_begin());76    break;77  case XCore::LDAWFI:78    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l2rus), Reg)79          .addReg(FrameReg)80          .addImm(Offset);81    break;82  default:83    llvm_unreachable("Unexpected Opcode");84  }85}86 87static void InsertFPConstInst(MachineBasicBlock::iterator II,88                              const XCoreInstrInfo &TII,89                              unsigned Reg, unsigned FrameReg,90                              int Offset, RegScavenger *RS ) {91  assert(RS && "requiresRegisterScavenging failed");92  MachineInstr &MI = *II;93  MachineBasicBlock &MBB = *MI.getParent();94  DebugLoc dl = MI.getDebugLoc();95  Register ScratchOffset =96      RS->scavengeRegisterBackwards(XCore::GRRegsRegClass, II, false, 0);97  RS->setRegUsed(ScratchOffset);98  TII.loadImmediate(MBB, II, ScratchOffset, Offset);99 100  switch (MI.getOpcode()) {101  case XCore::LDWFI:102    BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)103          .addReg(FrameReg)104          .addReg(ScratchOffset, RegState::Kill)105          .addMemOperand(*MI.memoperands_begin());106    break;107  case XCore::STWFI:108    BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))109          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))110          .addReg(FrameReg)111          .addReg(ScratchOffset, RegState::Kill)112          .addMemOperand(*MI.memoperands_begin());113    break;114  case XCore::LDAWFI:115    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)116          .addReg(FrameReg)117          .addReg(ScratchOffset, RegState::Kill);118    break;119  default:120    llvm_unreachable("Unexpected Opcode");121  }122}123 124static void InsertSPImmInst(MachineBasicBlock::iterator II,125                            const XCoreInstrInfo &TII,126                            unsigned Reg, int Offset) {127  MachineInstr &MI = *II;128  MachineBasicBlock &MBB = *MI.getParent();129  DebugLoc dl = MI.getDebugLoc();130  bool isU6 = isImmU6(Offset);131 132  switch (MI.getOpcode()) {133  int NewOpcode;134  case XCore::LDWFI:135    NewOpcode = (isU6) ? XCore::LDWSP_ru6 : XCore::LDWSP_lru6;136    BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)137          .addImm(Offset)138          .addMemOperand(*MI.memoperands_begin());139    break;140  case XCore::STWFI:141    NewOpcode = (isU6) ? XCore::STWSP_ru6 : XCore::STWSP_lru6;142    BuildMI(MBB, II, dl, TII.get(NewOpcode))143          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))144          .addImm(Offset)145          .addMemOperand(*MI.memoperands_begin());146    break;147  case XCore::LDAWFI:148    NewOpcode = (isU6) ? XCore::LDAWSP_ru6 : XCore::LDAWSP_lru6;149    BuildMI(MBB, II, dl, TII.get(NewOpcode), Reg)150          .addImm(Offset);151    break;152  default:153    llvm_unreachable("Unexpected Opcode");154  }155}156 157static void InsertSPConstInst(MachineBasicBlock::iterator II,158                                const XCoreInstrInfo &TII,159                                unsigned Reg, int Offset, RegScavenger *RS ) {160  assert(RS && "requiresRegisterScavenging failed");161  MachineInstr &MI = *II;162  MachineBasicBlock &MBB = *MI.getParent();163  DebugLoc dl = MI.getDebugLoc();164  unsigned OpCode = MI.getOpcode();165 166  unsigned ScratchBase;167  if (OpCode==XCore::STWFI) {168    ScratchBase =169        RS->scavengeRegisterBackwards(XCore::GRRegsRegClass, II, false, 0);170    RS->setRegUsed(ScratchBase);171  } else172    ScratchBase = Reg;173  BuildMI(MBB, II, dl, TII.get(XCore::LDAWSP_ru6), ScratchBase).addImm(0);174  Register ScratchOffset =175      RS->scavengeRegisterBackwards(XCore::GRRegsRegClass, II, false, 0);176  RS->setRegUsed(ScratchOffset);177  TII.loadImmediate(MBB, II, ScratchOffset, Offset);178 179  switch (OpCode) {180  case XCore::LDWFI:181    BuildMI(MBB, II, dl, TII.get(XCore::LDW_3r), Reg)182          .addReg(ScratchBase, RegState::Kill)183          .addReg(ScratchOffset, RegState::Kill)184          .addMemOperand(*MI.memoperands_begin());185    break;186  case XCore::STWFI:187    BuildMI(MBB, II, dl, TII.get(XCore::STW_l3r))188          .addReg(Reg, getKillRegState(MI.getOperand(0).isKill()))189          .addReg(ScratchBase, RegState::Kill)190          .addReg(ScratchOffset, RegState::Kill)191          .addMemOperand(*MI.memoperands_begin());192    break;193  case XCore::LDAWFI:194    BuildMI(MBB, II, dl, TII.get(XCore::LDAWF_l3r), Reg)195          .addReg(ScratchBase, RegState::Kill)196          .addReg(ScratchOffset, RegState::Kill);197    break;198  default:199    llvm_unreachable("Unexpected Opcode");200  }201}202 203bool XCoreRegisterInfo::needsFrameMoves(const MachineFunction &MF) {204  return MF.needsFrameMoves();205}206 207const MCPhysReg *208XCoreRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {209  // The callee saved registers LR & FP are explicitly handled during210  // emitPrologue & emitEpilogue and related functions.211  static const MCPhysReg CalleeSavedRegs[] = {212    XCore::R4, XCore::R5, XCore::R6, XCore::R7,213    XCore::R8, XCore::R9, XCore::R10,214    0215  };216  static const MCPhysReg CalleeSavedRegsFP[] = {217    XCore::R4, XCore::R5, XCore::R6, XCore::R7,218    XCore::R8, XCore::R9,219    0220  };221  const XCoreFrameLowering *TFI = getFrameLowering(*MF);222  if (TFI->hasFP(*MF))223    return CalleeSavedRegsFP;224  return CalleeSavedRegs;225}226 227BitVector XCoreRegisterInfo::getReservedRegs(const MachineFunction &MF) const {228  BitVector Reserved(getNumRegs());229  const XCoreFrameLowering *TFI = getFrameLowering(MF);230 231  Reserved.set(XCore::CP);232  Reserved.set(XCore::DP);233  Reserved.set(XCore::SP);234  Reserved.set(XCore::LR);235  if (TFI->hasFP(MF)) {236    Reserved.set(XCore::R10);237  }238  return Reserved;239}240 241bool242XCoreRegisterInfo::requiresRegisterScavenging(const MachineFunction &MF) const {243  return true;244}245 246bool247XCoreRegisterInfo::useFPForScavengingIndex(const MachineFunction &MF) const {248  return false;249}250 251bool252XCoreRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,253                                       int SPAdj, unsigned FIOperandNum,254                                       RegScavenger *RS) const {255  assert(SPAdj == 0 && "Unexpected");256  MachineInstr &MI = *II;257  MachineOperand &FrameOp = MI.getOperand(FIOperandNum);258  int FrameIndex = FrameOp.getIndex();259 260  MachineFunction &MF = *MI.getParent()->getParent();261  const XCoreInstrInfo &TII =262      *static_cast<const XCoreInstrInfo *>(MF.getSubtarget().getInstrInfo());263 264  const XCoreFrameLowering *TFI = getFrameLowering(MF);265  int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex);266  int StackSize = MF.getFrameInfo().getStackSize();267 268  #ifndef NDEBUG269  LLVM_DEBUG(errs() << "\nFunction         : " << MF.getName() << "\n");270  LLVM_DEBUG(errs() << "<--------->\n");271  LLVM_DEBUG(MI.print(errs()));272  LLVM_DEBUG(errs() << "FrameIndex         : " << FrameIndex << "\n");273  LLVM_DEBUG(errs() << "FrameOffset        : " << Offset << "\n");274  LLVM_DEBUG(errs() << "StackSize          : " << StackSize << "\n");275#endif276 277  Offset += StackSize;278 279  Register FrameReg = getFrameRegister(MF);280 281  // Special handling of DBG_VALUE instructions.282  if (MI.isDebugValue()) {283    MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false /*isDef*/);284    MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);285    return false;286  }287 288  // fold constant into offset.289  Offset += MI.getOperand(FIOperandNum + 1).getImm();290  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);291 292  assert(Offset%4 == 0 && "Misaligned stack offset");293  LLVM_DEBUG(errs() << "Offset             : " << Offset << "\n"294                    << "<--------->\n");295  Offset/=4;296 297  Register Reg = MI.getOperand(0).getReg();298  assert(XCore::GRRegsRegClass.contains(Reg) && "Unexpected register operand");299 300  if (TFI->hasFP(MF)) {301    if (isImmUs(Offset))302      InsertFPImmInst(II, TII, Reg, FrameReg, Offset);303    else304      InsertFPConstInst(II, TII, Reg, FrameReg, Offset, RS);305  } else {306    if (isImmU16(Offset))307      InsertSPImmInst(II, TII, Reg, Offset);308    else309      InsertSPConstInst(II, TII, Reg, Offset, RS);310  }311  // Erase old instruction.312  MachineBasicBlock &MBB = *MI.getParent();313  MBB.erase(II);314  return true;315}316 317 318Register XCoreRegisterInfo::getFrameRegister(const MachineFunction &MF) const {319  const XCoreFrameLowering *TFI = getFrameLowering(MF);320 321  return TFI->hasFP(MF) ? XCore::R10 : XCore::SP;322}323