brintos

brintos / llvm-project-archived public Read only

0
0
Text · 7.7 KiB · 0a14746 Raw
229 lines · cpp
1//===-- SparcRegisterInfo.cpp - SPARC 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 SPARC implementation of the TargetRegisterInfo class.10//11//===----------------------------------------------------------------------===//12 13#include "SparcRegisterInfo.h"14#include "Sparc.h"15#include "SparcSubtarget.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/TargetInstrInfo.h"21#include "llvm/IR/Type.h"22#include "llvm/Support/CommandLine.h"23#include "llvm/Support/ErrorHandling.h"24 25using namespace llvm;26 27#define GET_REGINFO_TARGET_DESC28#include "SparcGenRegisterInfo.inc"29 30static cl::opt<bool>31ReserveAppRegisters("sparc-reserve-app-registers", cl::Hidden, cl::init(false),32                    cl::desc("Reserve application registers (%g2-%g4)"));33 34SparcRegisterInfo::SparcRegisterInfo(const SparcSubtarget &STI)35    : SparcGenRegisterInfo(SP::O7), Is64Bit(STI.is64Bit()) {}36 37const MCPhysReg*38SparcRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {39  return CSR_SaveList;40}41 42const uint32_t *43SparcRegisterInfo::getCallPreservedMask(const MachineFunction &MF,44                                        CallingConv::ID CC) const {45  return CSR_RegMask;46}47 48const uint32_t*49SparcRegisterInfo::getRTCallPreservedMask(CallingConv::ID CC) const {50  return RTCSR_RegMask;51}52 53BitVector SparcRegisterInfo::getReservedRegs(const MachineFunction &MF) const {54  BitVector Reserved(getNumRegs());55  const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>();56  // FIXME: G1 reserved for now for large imm generation by frame code.57  Reserved.set(SP::G1);58 59  // G1-G4 can be used in applications.60  if (ReserveAppRegisters) {61    Reserved.set(SP::G2);62    Reserved.set(SP::G3);63    Reserved.set(SP::G4);64  }65  // G5 is not reserved in 64 bit mode.66  if (!Subtarget.is64Bit())67    Reserved.set(SP::G5);68 69  Reserved.set(SP::O6);70  Reserved.set(SP::I6);71  Reserved.set(SP::I7);72  Reserved.set(SP::G0);73  Reserved.set(SP::G6);74  Reserved.set(SP::G7);75 76  // Also reserve the register pair aliases covering the above77  // registers, with the same conditions.78  Reserved.set(SP::G0_G1);79  if (ReserveAppRegisters)80    Reserved.set(SP::G2_G3);81  if (ReserveAppRegisters || !Subtarget.is64Bit())82    Reserved.set(SP::G4_G5);83 84  Reserved.set(SP::O6_O7);85  Reserved.set(SP::I6_I7);86  Reserved.set(SP::G6_G7);87 88  // Unaliased double registers are not available in non-V9 targets.89  if (!Subtarget.isV9()) {90    for (unsigned n = 0; n != 16; ++n) {91      for (MCRegAliasIterator AI(SP::D16 + n, this, true); AI.isValid(); ++AI)92        Reserved.set(*AI);93    }94  }95 96  // Reserve ASR1-ASR3197  for (unsigned n = 0; n < 31; n++)98    Reserved.set(SP::ASR1 + n);99 100  for (TargetRegisterClass::iterator i = SP::IntRegsRegClass.begin();101       i != SP::IntRegsRegClass.end(); ++i) {102    if (MF.getSubtarget<SparcSubtarget>().isRegisterReserved(*i))103      markSuperRegs(Reserved, *i);104  }105 106  assert(checkAllSuperRegsMarked(Reserved));107  return Reserved;108}109 110bool SparcRegisterInfo::isReservedReg(const MachineFunction &MF,111                                      MCRegister Reg) const {112  return getReservedRegs(MF)[Reg];113}114 115const TargetRegisterClass *116SparcRegisterInfo::getPointerRegClass(unsigned Kind) const {117  assert(Kind == 0 && "this should only be used for default cases");118  return Is64Bit ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;119}120 121static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,122                      MachineInstr &MI, const DebugLoc &dl,123                      unsigned FIOperandNum, int Offset, unsigned FramePtr) {124  // Replace frame index with a frame pointer reference.125  if (Offset >= -4096 && Offset <= 4095) {126    // If the offset is small enough to fit in the immediate field, directly127    // encode it.128    MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false);129    MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);130    return;131  }132 133  const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo();134 135  // FIXME: it would be better to scavenge a register here instead of136  // reserving G1 all of the time.137  if (Offset >= 0) {138    // Emit nonnegaive immediates with sethi + or.139    // sethi %hi(Offset), %g1140    // add %g1, %fp, %g1141    // Insert G1+%lo(offset) into the user.142    BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1)143      .addImm(HI22(Offset));144 145 146    // Emit G1 = G1 + I6147    BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1)148      .addReg(FramePtr);149    // Insert: G1+%lo(offset) into the user.150    MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false);151    MI.getOperand(FIOperandNum + 1).ChangeToImmediate(LO10(Offset));152    return;153  }154 155  // Emit Negative numbers with sethi + xor156  // sethi %hix(Offset), %g1157  // xor  %g1, %lox(offset), %g1158  // add %g1, %fp, %g1159  // Insert: G1 + 0 into the user.160  BuildMI(*MI.getParent(), II, dl, TII.get(SP::SETHIi), SP::G1)161    .addImm(HIX22(Offset));162  BuildMI(*MI.getParent(), II, dl, TII.get(SP::XORri), SP::G1)163    .addReg(SP::G1).addImm(LOX10(Offset));164 165  BuildMI(*MI.getParent(), II, dl, TII.get(SP::ADDrr), SP::G1).addReg(SP::G1)166    .addReg(FramePtr);167  // Insert: G1+%lo(offset) into the user.168  MI.getOperand(FIOperandNum).ChangeToRegister(SP::G1, false);169  MI.getOperand(FIOperandNum + 1).ChangeToImmediate(0);170}171 172 173bool174SparcRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,175                                       int SPAdj, unsigned FIOperandNum,176                                       RegScavenger *RS) const {177  assert(SPAdj == 0 && "Unexpected");178 179  MachineInstr &MI = *II;180  DebugLoc dl = MI.getDebugLoc();181  int FrameIndex = MI.getOperand(FIOperandNum).getIndex();182  MachineFunction &MF = *MI.getParent()->getParent();183  const SparcSubtarget &Subtarget = MF.getSubtarget<SparcSubtarget>();184  const SparcFrameLowering *TFI = getFrameLowering(MF);185 186  Register FrameReg;187  int Offset;188  Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg).getFixed();189 190  Offset += MI.getOperand(FIOperandNum + 1).getImm();191 192  if (!Subtarget.isV9() || !Subtarget.hasHardQuad()) {193    if (MI.getOpcode() == SP::STQFri) {194      const TargetInstrInfo &TII = *Subtarget.getInstrInfo();195      Register SrcReg = MI.getOperand(2).getReg();196      Register SrcEvenReg = getSubReg(SrcReg, SP::sub_even64);197      Register SrcOddReg = getSubReg(SrcReg, SP::sub_odd64);198      MachineInstr *StMI =199        BuildMI(*MI.getParent(), II, dl, TII.get(SP::STDFri))200        .addReg(FrameReg).addImm(0).addReg(SrcEvenReg);201      replaceFI(MF, *StMI, *StMI, dl, 0, Offset, FrameReg);202      MI.setDesc(TII.get(SP::STDFri));203      MI.getOperand(2).setReg(SrcOddReg);204      Offset += 8;205    } else if (MI.getOpcode() == SP::LDQFri) {206      const TargetInstrInfo &TII = *Subtarget.getInstrInfo();207      Register DestReg = MI.getOperand(0).getReg();208      Register DestEvenReg = getSubReg(DestReg, SP::sub_even64);209      Register DestOddReg = getSubReg(DestReg, SP::sub_odd64);210      MachineInstr *LdMI =211        BuildMI(*MI.getParent(), II, dl, TII.get(SP::LDDFri), DestEvenReg)212        .addReg(FrameReg).addImm(0);213      replaceFI(MF, *LdMI, *LdMI, dl, 1, Offset, FrameReg);214 215      MI.setDesc(TII.get(SP::LDDFri));216      MI.getOperand(0).setReg(DestOddReg);217      Offset += 8;218    }219  }220 221  replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);222  // replaceFI never removes II223  return false;224}225 226Register SparcRegisterInfo::getFrameRegister(const MachineFunction &MF) const {227  return SP::I6;228}229