| //===-- 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; | |
| } |