1*480093f4SDimitry Andric //===-- VERegisterInfo.cpp - VE Register Information ----------------------===// 2*480093f4SDimitry Andric // 3*480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*480093f4SDimitry Andric // 7*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8*480093f4SDimitry Andric // 9*480093f4SDimitry Andric // This file contains the VE implementation of the TargetRegisterInfo class. 10*480093f4SDimitry Andric // 11*480093f4SDimitry Andric //===----------------------------------------------------------------------===// 12*480093f4SDimitry Andric 13*480093f4SDimitry Andric #include "VERegisterInfo.h" 14*480093f4SDimitry Andric #include "VE.h" 15*480093f4SDimitry Andric #include "VESubtarget.h" 16*480093f4SDimitry Andric #include "llvm/ADT/BitVector.h" 17*480093f4SDimitry Andric #include "llvm/ADT/STLExtras.h" 18*480093f4SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 19*480093f4SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 20*480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 21*480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 22*480093f4SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 23*480093f4SDimitry Andric #include "llvm/IR/Type.h" 24*480093f4SDimitry Andric #include "llvm/Support/CommandLine.h" 25*480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h" 26*480093f4SDimitry Andric 27*480093f4SDimitry Andric using namespace llvm; 28*480093f4SDimitry Andric 29*480093f4SDimitry Andric #define GET_REGINFO_TARGET_DESC 30*480093f4SDimitry Andric #include "VEGenRegisterInfo.inc" 31*480093f4SDimitry Andric 32*480093f4SDimitry Andric // VE uses %s10 == %lp to keep return address 33*480093f4SDimitry Andric VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {} 34*480093f4SDimitry Andric 35*480093f4SDimitry Andric const MCPhysReg * 36*480093f4SDimitry Andric VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 37*480093f4SDimitry Andric return CSR_SaveList; 38*480093f4SDimitry Andric } 39*480093f4SDimitry Andric 40*480093f4SDimitry Andric const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF, 41*480093f4SDimitry Andric CallingConv::ID CC) const { 42*480093f4SDimitry Andric return CSR_RegMask; 43*480093f4SDimitry Andric } 44*480093f4SDimitry Andric 45*480093f4SDimitry Andric const uint32_t *VERegisterInfo::getNoPreservedMask() const { 46*480093f4SDimitry Andric return CSR_NoRegs_RegMask; 47*480093f4SDimitry Andric } 48*480093f4SDimitry Andric 49*480093f4SDimitry Andric BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const { 50*480093f4SDimitry Andric BitVector Reserved(getNumRegs()); 51*480093f4SDimitry Andric Reserved.set(VE::SX8); // stack limit 52*480093f4SDimitry Andric Reserved.set(VE::SX9); // frame pointer 53*480093f4SDimitry Andric Reserved.set(VE::SX10); // link register (return address) 54*480093f4SDimitry Andric Reserved.set(VE::SX11); // stack pointer 55*480093f4SDimitry Andric 56*480093f4SDimitry Andric Reserved.set(VE::SX12); // outer register 57*480093f4SDimitry Andric Reserved.set(VE::SX13); // id register for dynamic linker 58*480093f4SDimitry Andric 59*480093f4SDimitry Andric Reserved.set(VE::SX14); // thread pointer 60*480093f4SDimitry Andric Reserved.set(VE::SX15); // global offset table register 61*480093f4SDimitry Andric Reserved.set(VE::SX16); // procedure linkage table register 62*480093f4SDimitry Andric Reserved.set(VE::SX17); // linkage-area register 63*480093f4SDimitry Andric 64*480093f4SDimitry Andric // sx18-sx33 are callee-saved registers 65*480093f4SDimitry Andric // sx34-sx63 are temporary registers 66*480093f4SDimitry Andric 67*480093f4SDimitry Andric return Reserved; 68*480093f4SDimitry Andric } 69*480093f4SDimitry Andric 70*480093f4SDimitry Andric bool VERegisterInfo::isConstantPhysReg(unsigned PhysReg) const { return false; } 71*480093f4SDimitry Andric 72*480093f4SDimitry Andric const TargetRegisterClass * 73*480093f4SDimitry Andric VERegisterInfo::getPointerRegClass(const MachineFunction &MF, 74*480093f4SDimitry Andric unsigned Kind) const { 75*480093f4SDimitry Andric return &VE::I64RegClass; 76*480093f4SDimitry Andric } 77*480093f4SDimitry Andric 78*480093f4SDimitry Andric static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II, 79*480093f4SDimitry Andric MachineInstr &MI, const DebugLoc &dl, 80*480093f4SDimitry Andric unsigned FIOperandNum, int Offset, unsigned FramePtr) { 81*480093f4SDimitry Andric // Replace frame index with a frame pointer reference directly. 82*480093f4SDimitry Andric // VE has 32 bit offset field, so no need to expand a target instruction. 83*480093f4SDimitry Andric // Directly encode it. 84*480093f4SDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(FramePtr, false); 85*480093f4SDimitry Andric MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 86*480093f4SDimitry Andric } 87*480093f4SDimitry Andric 88*480093f4SDimitry Andric void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 89*480093f4SDimitry Andric int SPAdj, unsigned FIOperandNum, 90*480093f4SDimitry Andric RegScavenger *RS) const { 91*480093f4SDimitry Andric assert(SPAdj == 0 && "Unexpected"); 92*480093f4SDimitry Andric 93*480093f4SDimitry Andric MachineInstr &MI = *II; 94*480093f4SDimitry Andric DebugLoc dl = MI.getDebugLoc(); 95*480093f4SDimitry Andric int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 96*480093f4SDimitry Andric MachineFunction &MF = *MI.getParent()->getParent(); 97*480093f4SDimitry Andric const VEFrameLowering *TFI = getFrameLowering(MF); 98*480093f4SDimitry Andric 99*480093f4SDimitry Andric unsigned FrameReg; 100*480093f4SDimitry Andric int Offset; 101*480093f4SDimitry Andric Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg); 102*480093f4SDimitry Andric 103*480093f4SDimitry Andric Offset += MI.getOperand(FIOperandNum + 1).getImm(); 104*480093f4SDimitry Andric 105*480093f4SDimitry Andric replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg); 106*480093f4SDimitry Andric } 107*480093f4SDimitry Andric 108*480093f4SDimitry Andric Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const { 109*480093f4SDimitry Andric return VE::SX9; 110*480093f4SDimitry Andric } 111*480093f4SDimitry Andric 112*480093f4SDimitry Andric // VE has no architectural need for stack realignment support, 113*480093f4SDimitry Andric // except that LLVM unfortunately currently implements overaligned 114*480093f4SDimitry Andric // stack objects by depending upon stack realignment support. 115*480093f4SDimitry Andric // If that ever changes, this can probably be deleted. 116*480093f4SDimitry Andric bool VERegisterInfo::canRealignStack(const MachineFunction &MF) const { 117*480093f4SDimitry Andric if (!TargetRegisterInfo::canRealignStack(MF)) 118*480093f4SDimitry Andric return false; 119*480093f4SDimitry Andric 120*480093f4SDimitry Andric // VE always has a fixed frame pointer register, so don't need to 121*480093f4SDimitry Andric // worry about needing to reserve it. [even if we don't have a frame 122*480093f4SDimitry Andric // pointer for our frame, it still cannot be used for other things, 123*480093f4SDimitry Andric // or register window traps will be SADNESS.] 124*480093f4SDimitry Andric 125*480093f4SDimitry Andric // If there's a reserved call frame, we can use VE to access locals. 126*480093f4SDimitry Andric if (getFrameLowering(MF)->hasReservedCallFrame(MF)) 127*480093f4SDimitry Andric return true; 128*480093f4SDimitry Andric 129*480093f4SDimitry Andric // Otherwise, we'd need a base pointer, but those aren't implemented 130*480093f4SDimitry Andric // for VE at the moment. 131*480093f4SDimitry Andric 132*480093f4SDimitry Andric return false; 133*480093f4SDimitry Andric } 134