LanaiRegisterInfo.cpp revision 327952
1//===-- LanaiRegisterInfo.cpp - Lanai Register Information ------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains the Lanai implementation of the TargetRegisterInfo class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "LanaiRegisterInfo.h" 15#include "Lanai.h" 16#include "LanaiSubtarget.h" 17#include "llvm/ADT/BitVector.h" 18#include "llvm/ADT/STLExtras.h" 19#include "llvm/CodeGen/MachineFrameInfo.h" 20#include "llvm/CodeGen/MachineFunction.h" 21#include "llvm/CodeGen/MachineInstrBuilder.h" 22#include "llvm/CodeGen/RegisterScavenging.h" 23#include "llvm/CodeGen/TargetFrameLowering.h" 24#include "llvm/CodeGen/TargetInstrInfo.h" 25#include "llvm/IR/Function.h" 26#include "llvm/IR/Type.h" 27#include "llvm/Support/ErrorHandling.h" 28 29#define GET_REGINFO_TARGET_DESC 30#include "LanaiGenRegisterInfo.inc" 31 32using namespace llvm; 33 34LanaiRegisterInfo::LanaiRegisterInfo() : LanaiGenRegisterInfo(Lanai::RCA) {} 35 36const uint16_t * 37LanaiRegisterInfo::getCalleeSavedRegs(const MachineFunction * /*MF*/) const { 38 return CSR_SaveList; 39} 40 41BitVector LanaiRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 42 BitVector Reserved(getNumRegs()); 43 44 Reserved.set(Lanai::R0); 45 Reserved.set(Lanai::R1); 46 Reserved.set(Lanai::PC); 47 Reserved.set(Lanai::R2); 48 Reserved.set(Lanai::SP); 49 Reserved.set(Lanai::R4); 50 Reserved.set(Lanai::FP); 51 Reserved.set(Lanai::R5); 52 Reserved.set(Lanai::RR1); 53 Reserved.set(Lanai::R10); 54 Reserved.set(Lanai::RR2); 55 Reserved.set(Lanai::R11); 56 Reserved.set(Lanai::RCA); 57 Reserved.set(Lanai::R15); 58 if (hasBasePointer(MF)) 59 Reserved.set(getBaseRegister()); 60 return Reserved; 61} 62 63bool LanaiRegisterInfo::requiresRegisterScavenging( 64 const MachineFunction & /*MF*/) const { 65 return true; 66} 67 68bool LanaiRegisterInfo::trackLivenessAfterRegAlloc( 69 const MachineFunction & /*MF*/) const { 70 return true; 71} 72 73static bool isALUArithLoOpcode(unsigned Opcode) { 74 switch (Opcode) { 75 case Lanai::ADD_I_LO: 76 case Lanai::SUB_I_LO: 77 case Lanai::ADD_F_I_LO: 78 case Lanai::SUB_F_I_LO: 79 case Lanai::ADDC_I_LO: 80 case Lanai::SUBB_I_LO: 81 case Lanai::ADDC_F_I_LO: 82 case Lanai::SUBB_F_I_LO: 83 return true; 84 default: 85 return false; 86 } 87} 88 89static unsigned getOppositeALULoOpcode(unsigned Opcode) { 90 switch (Opcode) { 91 case Lanai::ADD_I_LO: 92 return Lanai::SUB_I_LO; 93 case Lanai::SUB_I_LO: 94 return Lanai::ADD_I_LO; 95 case Lanai::ADD_F_I_LO: 96 return Lanai::SUB_F_I_LO; 97 case Lanai::SUB_F_I_LO: 98 return Lanai::ADD_F_I_LO; 99 case Lanai::ADDC_I_LO: 100 return Lanai::SUBB_I_LO; 101 case Lanai::SUBB_I_LO: 102 return Lanai::ADDC_I_LO; 103 case Lanai::ADDC_F_I_LO: 104 return Lanai::SUBB_F_I_LO; 105 case Lanai::SUBB_F_I_LO: 106 return Lanai::ADDC_F_I_LO; 107 default: 108 llvm_unreachable("Invalid ALU lo opcode"); 109 } 110} 111 112static unsigned getRRMOpcodeVariant(unsigned Opcode) { 113 switch (Opcode) { 114 case Lanai::LDBs_RI: 115 return Lanai::LDBs_RR; 116 case Lanai::LDBz_RI: 117 return Lanai::LDBz_RR; 118 case Lanai::LDHs_RI: 119 return Lanai::LDHs_RR; 120 case Lanai::LDHz_RI: 121 return Lanai::LDHz_RR; 122 case Lanai::LDW_RI: 123 return Lanai::LDW_RR; 124 case Lanai::STB_RI: 125 return Lanai::STB_RR; 126 case Lanai::STH_RI: 127 return Lanai::STH_RR; 128 case Lanai::SW_RI: 129 return Lanai::SW_RR; 130 default: 131 llvm_unreachable("Opcode has no RRM variant"); 132 } 133} 134 135void LanaiRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 136 int SPAdj, unsigned FIOperandNum, 137 RegScavenger *RS) const { 138 assert(SPAdj == 0 && "Unexpected"); 139 140 MachineInstr &MI = *II; 141 MachineFunction &MF = *MI.getParent()->getParent(); 142 const TargetInstrInfo *TII = MF.getSubtarget().getInstrInfo(); 143 const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); 144 bool HasFP = TFI->hasFP(MF); 145 DebugLoc DL = MI.getDebugLoc(); 146 147 int FrameIndex = MI.getOperand(FIOperandNum).getIndex(); 148 149 int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) + 150 MI.getOperand(FIOperandNum + 1).getImm(); 151 152 // Addressable stack objects are addressed using neg. offsets from fp 153 // or pos. offsets from sp/basepointer 154 if (!HasFP || (needsStackRealignment(MF) && FrameIndex >= 0)) 155 Offset += MF.getFrameInfo().getStackSize(); 156 157 unsigned FrameReg = getFrameRegister(MF); 158 if (FrameIndex >= 0) { 159 if (hasBasePointer(MF)) 160 FrameReg = getBaseRegister(); 161 else if (needsStackRealignment(MF)) 162 FrameReg = Lanai::SP; 163 } 164 165 // Replace frame index with a frame pointer reference. 166 // If the offset is small enough to fit in the immediate field, directly 167 // encode it. 168 // Otherwise scavenge a register and encode it into a MOVHI, OR_I_LO sequence. 169 if ((isSPLSOpcode(MI.getOpcode()) && !isInt<10>(Offset)) || 170 !isInt<16>(Offset)) { 171 assert(RS && "Register scavenging must be on"); 172 unsigned Reg = RS->FindUnusedReg(&Lanai::GPRRegClass); 173 if (!Reg) 174 Reg = RS->scavengeRegister(&Lanai::GPRRegClass, II, SPAdj); 175 assert(Reg && "Register scavenger failed"); 176 177 bool HasNegOffset = false; 178 // ALU ops have unsigned immediate values. If the Offset is negative, we 179 // negate it here and reverse the opcode later. 180 if (Offset < 0) { 181 HasNegOffset = true; 182 Offset = -Offset; 183 } 184 185 if (!isInt<16>(Offset)) { 186 // Reg = hi(offset) | lo(offset) 187 BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::MOVHI), Reg) 188 .addImm(static_cast<uint32_t>(Offset) >> 16); 189 BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::OR_I_LO), Reg) 190 .addReg(Reg) 191 .addImm(Offset & 0xffffU); 192 } else { 193 // Reg = mov(offset) 194 BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::ADD_I_LO), Reg) 195 .addImm(0) 196 .addImm(Offset); 197 } 198 // Reg = FrameReg OP Reg 199 if (MI.getOpcode() == Lanai::ADD_I_LO) { 200 BuildMI(*MI.getParent(), II, DL, 201 HasNegOffset ? TII->get(Lanai::SUB_R) : TII->get(Lanai::ADD_R), 202 MI.getOperand(0).getReg()) 203 .addReg(FrameReg) 204 .addReg(Reg) 205 .addImm(LPCC::ICC_T); 206 MI.eraseFromParent(); 207 return; 208 } 209 if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) { 210 MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode()))); 211 if (HasNegOffset) { 212 // Change the ALU op (operand 3) from LPAC::ADD (the default) to 213 // LPAC::SUB with the already negated offset. 214 assert((MI.getOperand(3).getImm() == LPAC::ADD) && 215 "Unexpected ALU op in RRM instruction"); 216 MI.getOperand(3).setImm(LPAC::SUB); 217 } 218 } else 219 llvm_unreachable("Unexpected opcode in frame index operation"); 220 221 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false); 222 MI.getOperand(FIOperandNum + 1) 223 .ChangeToRegister(Reg, /*isDef=*/false, /*isImp=*/false, 224 /*isKill=*/true); 225 return; 226 } 227 228 // ALU arithmetic ops take unsigned immediates. If the offset is negative, 229 // we replace the instruction with one that inverts the opcode and negates 230 // the immediate. 231 if ((Offset < 0) && isALUArithLoOpcode(MI.getOpcode())) { 232 unsigned NewOpcode = getOppositeALULoOpcode(MI.getOpcode()); 233 // We know this is an ALU op, so we know the operands are as follows: 234 // 0: destination register 235 // 1: source register (frame register) 236 // 2: immediate 237 BuildMI(*MI.getParent(), II, DL, TII->get(NewOpcode), 238 MI.getOperand(0).getReg()) 239 .addReg(FrameReg) 240 .addImm(-Offset); 241 MI.eraseFromParent(); 242 } else { 243 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false); 244 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset); 245 } 246} 247 248bool LanaiRegisterInfo::hasBasePointer(const MachineFunction &MF) const { 249 const MachineFrameInfo &MFI = MF.getFrameInfo(); 250 // When we need stack realignment and there are dynamic allocas, we can't 251 // reference off of the stack pointer, so we reserve a base pointer. 252 if (needsStackRealignment(MF) && MFI.hasVarSizedObjects()) 253 return true; 254 255 return false; 256} 257 258unsigned LanaiRegisterInfo::getRARegister() const { return Lanai::RCA; } 259 260unsigned 261LanaiRegisterInfo::getFrameRegister(const MachineFunction & /*MF*/) const { 262 return Lanai::FP; 263} 264 265unsigned LanaiRegisterInfo::getBaseRegister() const { return Lanai::R14; } 266 267const uint32_t * 268LanaiRegisterInfo::getCallPreservedMask(const MachineFunction & /*MF*/, 269 CallingConv::ID /*CC*/) const { 270 return CSR_RegMask; 271} 272