1480093f4SDimitry Andric //===-- VERegisterInfo.cpp - VE Register Information ----------------------===// 2480093f4SDimitry Andric // 3480093f4SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4480093f4SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5480093f4SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6480093f4SDimitry Andric // 7480093f4SDimitry Andric //===----------------------------------------------------------------------===// 8480093f4SDimitry Andric // 9480093f4SDimitry Andric // This file contains the VE implementation of the TargetRegisterInfo class. 10480093f4SDimitry Andric // 11480093f4SDimitry Andric //===----------------------------------------------------------------------===// 12480093f4SDimitry Andric 13480093f4SDimitry Andric #include "VERegisterInfo.h" 14480093f4SDimitry Andric #include "VE.h" 15480093f4SDimitry Andric #include "VESubtarget.h" 16480093f4SDimitry Andric #include "llvm/ADT/BitVector.h" 17480093f4SDimitry Andric #include "llvm/ADT/STLExtras.h" 18480093f4SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h" 19480093f4SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 20480093f4SDimitry Andric #include "llvm/CodeGen/MachineInstrBuilder.h" 21480093f4SDimitry Andric #include "llvm/CodeGen/MachineRegisterInfo.h" 22480093f4SDimitry Andric #include "llvm/CodeGen/TargetInstrInfo.h" 23480093f4SDimitry Andric #include "llvm/IR/Type.h" 24480093f4SDimitry Andric #include "llvm/Support/CommandLine.h" 25480093f4SDimitry Andric #include "llvm/Support/ErrorHandling.h" 26480093f4SDimitry Andric 27480093f4SDimitry Andric using namespace llvm; 28480093f4SDimitry Andric 29480093f4SDimitry Andric #define GET_REGINFO_TARGET_DESC 30480093f4SDimitry Andric #include "VEGenRegisterInfo.inc" 31480093f4SDimitry Andric 32480093f4SDimitry Andric // VE uses %s10 == %lp to keep return address 33480093f4SDimitry Andric VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {} 34480093f4SDimitry Andric 35480093f4SDimitry Andric const MCPhysReg * 36480093f4SDimitry Andric VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 37*5ffd83dbSDimitry Andric switch (MF->getFunction().getCallingConv()) { 38*5ffd83dbSDimitry Andric default: 39480093f4SDimitry Andric return CSR_SaveList; 40*5ffd83dbSDimitry Andric case CallingConv::PreserveAll: 41*5ffd83dbSDimitry Andric return CSR_preserve_all_SaveList; 42*5ffd83dbSDimitry Andric } 43480093f4SDimitry Andric } 44480093f4SDimitry Andric 45480093f4SDimitry Andric const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF, 46480093f4SDimitry Andric CallingConv::ID CC) const { 47*5ffd83dbSDimitry Andric switch (CC) { 48*5ffd83dbSDimitry Andric default: 49480093f4SDimitry Andric return CSR_RegMask; 50*5ffd83dbSDimitry Andric case CallingConv::PreserveAll: 51*5ffd83dbSDimitry Andric return CSR_preserve_all_RegMask; 52*5ffd83dbSDimitry Andric } 53480093f4SDimitry Andric } 54480093f4SDimitry Andric 55480093f4SDimitry Andric const uint32_t *VERegisterInfo::getNoPreservedMask() const { 56480093f4SDimitry Andric return CSR_NoRegs_RegMask; 57480093f4SDimitry Andric } 58480093f4SDimitry Andric 59480093f4SDimitry Andric BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const { 60480093f4SDimitry Andric BitVector Reserved(getNumRegs()); 61480093f4SDimitry Andric 62*5ffd83dbSDimitry Andric const Register ReservedRegs[] = { 63*5ffd83dbSDimitry Andric VE::SX8, // Stack limit 64*5ffd83dbSDimitry Andric VE::SX9, // Frame pointer 65*5ffd83dbSDimitry Andric VE::SX10, // Link register (return address) 66*5ffd83dbSDimitry Andric VE::SX11, // Stack pointer 67480093f4SDimitry Andric 68*5ffd83dbSDimitry Andric // FIXME: maybe not need to be reserved 69*5ffd83dbSDimitry Andric VE::SX12, // Outer register 70*5ffd83dbSDimitry Andric VE::SX13, // Id register for dynamic linker 71480093f4SDimitry Andric 72*5ffd83dbSDimitry Andric VE::SX14, // Thread pointer 73*5ffd83dbSDimitry Andric VE::SX15, // Global offset table register 74*5ffd83dbSDimitry Andric VE::SX16, // Procedure linkage table register 75*5ffd83dbSDimitry Andric VE::SX17, // Linkage-area register 76480093f4SDimitry Andric // sx18-sx33 are callee-saved registers 77480093f4SDimitry Andric // sx34-sx63 are temporary registers 78*5ffd83dbSDimitry Andric }; 79*5ffd83dbSDimitry Andric 80*5ffd83dbSDimitry Andric for (auto R : ReservedRegs) 81*5ffd83dbSDimitry Andric for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid(); 82*5ffd83dbSDimitry Andric ++ItAlias) 83*5ffd83dbSDimitry Andric Reserved.set(*ItAlias); 84480093f4SDimitry Andric 85480093f4SDimitry Andric return Reserved; 86480093f4SDimitry Andric } 87480093f4SDimitry Andric 88*5ffd83dbSDimitry Andric bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { return false; } 89480093f4SDimitry Andric 90480093f4SDimitry Andric const TargetRegisterClass * 91480093f4SDimitry Andric VERegisterInfo::getPointerRegClass(const MachineFunction &MF, 92480093f4SDimitry Andric unsigned Kind) const { 93480093f4SDimitry Andric return &VE::I64RegClass; 94480093f4SDimitry Andric } 95480093f4SDimitry Andric 96480093f4SDimitry Andric static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II, 97480093f4SDimitry Andric MachineInstr &MI, const DebugLoc &dl, 98*5ffd83dbSDimitry Andric unsigned FIOperandNum, int Offset, Register FrameReg) { 99480093f4SDimitry Andric // Replace frame index with a frame pointer reference directly. 100480093f4SDimitry Andric // VE has 32 bit offset field, so no need to expand a target instruction. 101480093f4SDimitry Andric // Directly encode it. 102*5ffd83dbSDimitry Andric MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); 103*5ffd83dbSDimitry Andric MI.getOperand(FIOperandNum + 2).ChangeToImmediate(Offset); 104480093f4SDimitry Andric } 105480093f4SDimitry Andric 106480093f4SDimitry Andric void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 107480093f4SDimitry Andric int SPAdj, unsigned FIOperandNum, 108480093f4SDimitry Andric RegScavenger *RS) const { 109480093f4SDimitry Andric assert(SPAdj == 0 && "Unexpected"); 110480093f4SDimitry Andric 111480093f4SDimitry Andric MachineInstr &MI = *II; 112480093f4SDimitry Andric DebugLoc dl = MI.getDebugLoc(); 113480093f4SDimitry Andric int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 114480093f4SDimitry Andric MachineFunction &MF = *MI.getParent()->getParent(); 115480093f4SDimitry Andric const VEFrameLowering *TFI = getFrameLowering(MF); 116480093f4SDimitry Andric 117*5ffd83dbSDimitry Andric Register FrameReg; 118480093f4SDimitry Andric int Offset; 119480093f4SDimitry Andric Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg); 120480093f4SDimitry Andric 121*5ffd83dbSDimitry Andric Offset += MI.getOperand(FIOperandNum + 2).getImm(); 122480093f4SDimitry Andric 123480093f4SDimitry Andric replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg); 124480093f4SDimitry Andric } 125480093f4SDimitry Andric 126480093f4SDimitry Andric Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const { 127480093f4SDimitry Andric return VE::SX9; 128480093f4SDimitry Andric } 129480093f4SDimitry Andric 130480093f4SDimitry Andric // VE has no architectural need for stack realignment support, 131480093f4SDimitry Andric // except that LLVM unfortunately currently implements overaligned 132480093f4SDimitry Andric // stack objects by depending upon stack realignment support. 133480093f4SDimitry Andric // If that ever changes, this can probably be deleted. 134480093f4SDimitry Andric bool VERegisterInfo::canRealignStack(const MachineFunction &MF) const { 135480093f4SDimitry Andric if (!TargetRegisterInfo::canRealignStack(MF)) 136480093f4SDimitry Andric return false; 137480093f4SDimitry Andric 138480093f4SDimitry Andric // VE always has a fixed frame pointer register, so don't need to 139480093f4SDimitry Andric // worry about needing to reserve it. [even if we don't have a frame 140480093f4SDimitry Andric // pointer for our frame, it still cannot be used for other things, 141480093f4SDimitry Andric // or register window traps will be SADNESS.] 142480093f4SDimitry Andric 143480093f4SDimitry Andric // If there's a reserved call frame, we can use VE to access locals. 144480093f4SDimitry Andric if (getFrameLowering(MF)->hasReservedCallFrame(MF)) 145480093f4SDimitry Andric return true; 146480093f4SDimitry Andric 147480093f4SDimitry Andric // Otherwise, we'd need a base pointer, but those aren't implemented 148480093f4SDimitry Andric // for VE at the moment. 149480093f4SDimitry Andric 150480093f4SDimitry Andric return false; 151480093f4SDimitry Andric } 152