1 //===-- VERegisterInfo.cpp - VE Register Information ----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file contains the VE implementation of the TargetRegisterInfo class. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "VERegisterInfo.h" 14 #include "VE.h" 15 #include "VESubtarget.h" 16 #include "llvm/ADT/BitVector.h" 17 #include "llvm/ADT/STLExtras.h" 18 #include "llvm/CodeGen/MachineFrameInfo.h" 19 #include "llvm/CodeGen/MachineFunction.h" 20 #include "llvm/CodeGen/MachineInstrBuilder.h" 21 #include "llvm/CodeGen/MachineRegisterInfo.h" 22 #include "llvm/CodeGen/TargetInstrInfo.h" 23 #include "llvm/IR/Type.h" 24 #include "llvm/Support/CommandLine.h" 25 #include "llvm/Support/Debug.h" 26 #include "llvm/Support/ErrorHandling.h" 27 28 using namespace llvm; 29 30 #define GET_REGINFO_TARGET_DESC 31 #include "VEGenRegisterInfo.inc" 32 33 // VE uses %s10 == %lp to keep return address 34 VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {} 35 36 const MCPhysReg * 37 VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 38 switch (MF->getFunction().getCallingConv()) { 39 case CallingConv::Fast: 40 // Being explicit (same as standard CC). 41 default: 42 return CSR_SaveList; 43 case CallingConv::PreserveAll: 44 return CSR_preserve_all_SaveList; 45 } 46 } 47 48 const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF, 49 CallingConv::ID CC) const { 50 switch (CC) { 51 case CallingConv::Fast: 52 // Being explicit (same as standard CC). 53 default: 54 return CSR_RegMask; 55 case CallingConv::PreserveAll: 56 return CSR_preserve_all_RegMask; 57 } 58 } 59 60 const uint32_t *VERegisterInfo::getNoPreservedMask() const { 61 return CSR_NoRegs_RegMask; 62 } 63 64 BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const { 65 BitVector Reserved(getNumRegs()); 66 67 const Register ReservedRegs[] = { 68 VE::SX8, // Stack limit 69 VE::SX9, // Frame pointer 70 VE::SX10, // Link register (return address) 71 VE::SX11, // Stack pointer 72 73 // FIXME: maybe not need to be reserved 74 VE::SX12, // Outer register 75 VE::SX13, // Id register for dynamic linker 76 77 VE::SX14, // Thread pointer 78 VE::SX15, // Global offset table register 79 VE::SX16, // Procedure linkage table register 80 VE::SX17, // Linkage-area register 81 // sx18-sx33 are callee-saved registers 82 // sx34-sx63 are temporary registers 83 }; 84 85 for (auto R : ReservedRegs) 86 for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid(); 87 ++ItAlias) 88 Reserved.set(*ItAlias); 89 90 // Reserve constant registers. 91 Reserved.set(VE::VM0); 92 Reserved.set(VE::VMP0); 93 94 return Reserved; 95 } 96 97 bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const { 98 switch (PhysReg) { 99 case VE::VM0: 100 case VE::VMP0: 101 return true; 102 default: 103 return false; 104 } 105 } 106 107 const TargetRegisterClass * 108 VERegisterInfo::getPointerRegClass(const MachineFunction &MF, 109 unsigned Kind) const { 110 return &VE::I64RegClass; 111 } 112 113 static unsigned offsetToDisp(MachineInstr &MI) { 114 // Default offset in instruction's operands (reg+reg+imm). 115 unsigned OffDisp = 2; 116 117 #define RRCAS_multi_cases(NAME) NAME##rir : case NAME##rii 118 119 { 120 using namespace llvm::VE; 121 switch (MI.getOpcode()) { 122 case RRCAS_multi_cases(TS1AML): 123 case RRCAS_multi_cases(TS1AMW): 124 case RRCAS_multi_cases(CASL): 125 case RRCAS_multi_cases(CASW): 126 // These instructions use AS format (reg+imm). 127 OffDisp = 1; 128 break; 129 } 130 } 131 #undef RRCAS_multi_cases 132 133 return OffDisp; 134 } 135 136 static void replaceFI(MachineFunction &MF, MachineBasicBlock::iterator II, 137 MachineInstr &MI, const DebugLoc &dl, 138 unsigned FIOperandNum, int Offset, Register FrameReg) { 139 // Replace frame index with a frame pointer reference directly. 140 // VE has 32 bit offset field, so no need to expand a target instruction. 141 // Directly encode it. 142 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false); 143 MI.getOperand(FIOperandNum + offsetToDisp(MI)).ChangeToImmediate(Offset); 144 } 145 146 void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 147 int SPAdj, unsigned FIOperandNum, 148 RegScavenger *RS) const { 149 assert(SPAdj == 0 && "Unexpected"); 150 151 MachineInstr &MI = *II; 152 DebugLoc dl = MI.getDebugLoc(); 153 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 154 MachineFunction &MF = *MI.getParent()->getParent(); 155 const VEFrameLowering *TFI = getFrameLowering(MF); 156 157 Register FrameReg; 158 int Offset; 159 Offset = TFI->getFrameIndexReference(MF, FrameIndex, FrameReg).getFixed(); 160 161 Offset += MI.getOperand(FIOperandNum + offsetToDisp(MI)).getImm(); 162 163 if (MI.getOpcode() == VE::STQrii) { 164 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 165 Register SrcReg = MI.getOperand(3).getReg(); 166 Register SrcHiReg = getSubReg(SrcReg, VE::sub_even); 167 Register SrcLoReg = getSubReg(SrcReg, VE::sub_odd); 168 // VE stores HiReg to 8(addr) and LoReg to 0(addr) 169 MachineInstr *StMI = BuildMI(*MI.getParent(), II, dl, TII.get(VE::STrii)) 170 .addReg(FrameReg) 171 .addImm(0) 172 .addImm(0) 173 .addReg(SrcLoReg); 174 replaceFI(MF, II, *StMI, dl, 0, Offset, FrameReg); 175 MI.setDesc(TII.get(VE::STrii)); 176 MI.getOperand(3).setReg(SrcHiReg); 177 Offset += 8; 178 } else if (MI.getOpcode() == VE::LDQrii) { 179 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 180 Register DestReg = MI.getOperand(0).getReg(); 181 Register DestHiReg = getSubReg(DestReg, VE::sub_even); 182 Register DestLoReg = getSubReg(DestReg, VE::sub_odd); 183 // VE loads HiReg from 8(addr) and LoReg from 0(addr) 184 MachineInstr *StMI = 185 BuildMI(*MI.getParent(), II, dl, TII.get(VE::LDrii), DestLoReg) 186 .addReg(FrameReg) 187 .addImm(0) 188 .addImm(0); 189 replaceFI(MF, II, *StMI, dl, 1, Offset, FrameReg); 190 MI.setDesc(TII.get(VE::LDrii)); 191 MI.getOperand(0).setReg(DestHiReg); 192 Offset += 8; 193 } 194 195 replaceFI(MF, II, MI, dl, FIOperandNum, Offset, FrameReg); 196 } 197 198 Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const { 199 return VE::SX9; 200 } 201