blob: e1ff614abc20218b1a684f3fc9f491e76064e322 [file] [log] [blame]
//===-- VERegisterInfo.cpp - VE Register Information ----------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the VE implementation of the TargetRegisterInfo class.
//
//===----------------------------------------------------------------------===//
#include "VERegisterInfo.h"
#include "VE.h"
#include "VESubtarget.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/TargetInstrInfo.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ErrorHandling.h"
using namespace llvm;
#define GET_REGINFO_TARGET_DESC
#include "VEGenRegisterInfo.inc"
// VE uses %s10 == %lp to keep return address
VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
const MCPhysReg *
VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
return CSR_SaveList;
}
const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
CallingConv::ID CC) const {
return CSR_RegMask;
}
const uint32_t *VERegisterInfo::getNoPreservedMask() const {
return CSR_NoRegs_RegMask;
}
BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
BitVector Reserved(getNumRegs());
Reserved.set(VE::SX8); // stack limit
Reserved.set(VE::SX9); // frame pointer
Reserved.set(VE::SX10); // link register (return address)
Reserved.set(VE::SX11); // stack pointer
Reserved.set(VE::SX12); // outer register
Reserved.set(VE::SX13); // id register for dynamic linker
Reserved.set(VE::SX14); // thread pointer
Reserved.set(VE::SX15); // global offset table register
Reserved.set(VE::SX16); // procedure linkage table register
Reserved.set(VE::SX17); // linkage-area register
// sx18-sx33 are callee-saved registers
// sx34-sx63 are temporary registers
return Reserved;
}
bool VERegisterInfo::isConstantPhysReg(unsigned PhysReg) const { return false; }
const TargetRegisterClass *
VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
unsigned Kind) const {
return &VE::I64RegClass;
}
static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II,
MachineInstr &MI, const DebugLoc &dl,
unsigned FIOperandNum, int Offset, unsigned FramePtr) {
// Replace frame index with a frame pointer reference directly.
// VE has 32 bit offset field, so no need to expand a target instruction.
// Directly encode it.
MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false);
MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
}
void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
int SPAdj, unsigned FIOperandNum,
RegScavenger *RS) const {
assert(SPAdj == 0 && "Unexpected");
MachineInstr &MI = *II;
DebugLoc dl = MI.getDebugLoc();
int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
MachineFunction &MF = *MI.getParent()->getParent();
const VEFrameLowering *TFI = getFrameLowering(MF);
unsigned FrameReg;
int Offset;
Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg);
Offset += MI.getOperand(FIOperandNum + 1).getImm();
replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg);
}
Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
return VE::SX9;
}
// VE has no architectural need for stack realignment support,
// except that LLVM unfortunately currently implements overaligned
// stack objects by depending upon stack realignment support.
// If that ever changes, this can probably be deleted.
bool VERegisterInfo::canRealignStack(const MachineFunction &MF) const {
if (!TargetRegisterInfo::canRealignStack(MF))
return false;
// VE always has a fixed frame pointer register, so don't need to
// worry about needing to reserve it. [even if we don't have a frame
// pointer for our frame, it still cannot be used for other things,
// or register window traps will be SADNESS.]
// If there's a reserved call frame, we can use VE to access locals.
if (getFrameLowering(MF)->hasReservedCallFrame(MF))
return true;
// Otherwise, we'd need a base pointer, but those aren't implemented
// for VE at the moment.
return false;
}