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