1 //===-- LanaiRegisterInfo.cpp - Lanai Register Information ------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Lanai implementation of the TargetRegisterInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "LanaiRegisterInfo.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"
29 #define GET_REGINFO_TARGET_DESC
30 #include "LanaiGenRegisterInfo.inc"
34 LanaiRegisterInfo::LanaiRegisterInfo() : LanaiGenRegisterInfo(Lanai::RCA) {}
37 LanaiRegisterInfo::getCalleeSavedRegs(const MachineFunction * /*MF*/) const {
41 BitVector LanaiRegisterInfo::getReservedRegs(const MachineFunction &MF) const {
42 BitVector Reserved(getNumRegs());
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());
63 bool LanaiRegisterInfo::requiresRegisterScavenging(
64 const MachineFunction & /*MF*/) const {
68 bool LanaiRegisterInfo::trackLivenessAfterRegAlloc(
69 const MachineFunction & /*MF*/) const {
73 static bool isALUArithLoOpcode(unsigned Opcode) {
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:
89 static unsigned getOppositeALULoOpcode(unsigned Opcode) {
92 return 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;
108 llvm_unreachable("Invalid ALU lo opcode");
112 static unsigned getRRMOpcodeVariant(unsigned Opcode) {
115 return Lanai::LDBs_RR;
117 return Lanai::LDBz_RR;
119 return Lanai::LDHs_RR;
121 return Lanai::LDHz_RR;
123 return Lanai::LDW_RR;
125 return Lanai::STB_RR;
127 return Lanai::STH_RR;
131 llvm_unreachable("Opcode has no RRM variant");
135 void LanaiRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
136 int SPAdj, unsigned FIOperandNum,
137 RegScavenger *RS) const {
138 assert(SPAdj == 0 && "Unexpected");
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();
147 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
149 int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) +
150 MI.getOperand(FIOperandNum + 1).getImm();
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();
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;
165 // Replace frame index with a frame pointer reference.
166 // If the offset is small enough to fit in the immediate field, directly
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);
174 Reg = RS->scavengeRegister(&Lanai::GPRRegClass, II, SPAdj);
175 assert(Reg && "Register scavenger failed");
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.
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)
191 .addImm(Offset & 0xffffU);
194 BuildMI(*MI.getParent(), II, DL, TII->get(Lanai::ADD_I_LO), Reg)
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())
205 .addImm(LPCC::ICC_T);
206 MI.eraseFromParent();
209 if (isSPLSOpcode(MI.getOpcode()) || isRMOpcode(MI.getOpcode())) {
210 MI.setDesc(TII->get(getRRMOpcodeVariant(MI.getOpcode())));
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);
219 llvm_unreachable("Unexpected opcode in frame index operation");
221 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
222 MI.getOperand(FIOperandNum + 1)
223 .ChangeToRegister(Reg, /*isDef=*/false, /*isImp=*/false,
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
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)
237 BuildMI(*MI.getParent(), II, DL, TII->get(NewOpcode),
238 MI.getOperand(0).getReg())
241 MI.eraseFromParent();
243 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, /*isDef=*/false);
244 MI.getOperand(FIOperandNum + 1).ChangeToImmediate(Offset);
248 bool 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())
258 unsigned LanaiRegisterInfo::getRARegister() const { return Lanai::RCA; }
261 LanaiRegisterInfo::getFrameRegister(const MachineFunction & /*MF*/) const {
265 unsigned LanaiRegisterInfo::getBaseRegister() const { return Lanai::R14; }
268 LanaiRegisterInfo::getCallPreservedMask(const MachineFunction & /*MF*/,
269 CallingConv::ID /*CC*/) const {