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 DEBUG_TYPE "ve-register-info"
31
32 #define GET_REGINFO_TARGET_DESC
33 #include "VEGenRegisterInfo.inc"
34
35 // VE uses %s10 == %lp to keep return address
VERegisterInfo()36 VERegisterInfo::VERegisterInfo() : VEGenRegisterInfo(VE::SX10) {}
37
38 const MCPhysReg *
getCalleeSavedRegs(const MachineFunction * MF) const39 VERegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
40 switch (MF->getFunction().getCallingConv()) {
41 case CallingConv::Fast:
42 // Being explicit (same as standard CC).
43 default:
44 return CSR_SaveList;
45 case CallingConv::PreserveAll:
46 return CSR_preserve_all_SaveList;
47 }
48 }
49
getCallPreservedMask(const MachineFunction & MF,CallingConv::ID CC) const50 const uint32_t *VERegisterInfo::getCallPreservedMask(const MachineFunction &MF,
51 CallingConv::ID CC) const {
52 switch (CC) {
53 case CallingConv::Fast:
54 // Being explicit (same as standard CC).
55 default:
56 return CSR_RegMask;
57 case CallingConv::PreserveAll:
58 return CSR_preserve_all_RegMask;
59 }
60 }
61
getNoPreservedMask() const62 const uint32_t *VERegisterInfo::getNoPreservedMask() const {
63 return CSR_NoRegs_RegMask;
64 }
65
getReservedRegs(const MachineFunction & MF) const66 BitVector VERegisterInfo::getReservedRegs(const MachineFunction &MF) const {
67 BitVector Reserved(getNumRegs());
68
69 const Register ReservedRegs[] = {
70 VE::SX8, // Stack limit
71 VE::SX9, // Frame pointer
72 VE::SX10, // Link register (return address)
73 VE::SX11, // Stack pointer
74
75 // FIXME: maybe not need to be reserved
76 VE::SX12, // Outer register
77 VE::SX13, // Id register for dynamic linker
78
79 VE::SX14, // Thread pointer
80 VE::SX15, // Global offset table register
81 VE::SX16, // Procedure linkage table register
82 VE::SX17, // Linkage-area register
83 // sx18-sx33 are callee-saved registers
84 // sx34-sx63 are temporary registers
85 };
86
87 for (auto R : ReservedRegs)
88 for (MCRegAliasIterator ItAlias(R, this, true); ItAlias.isValid();
89 ++ItAlias)
90 Reserved.set(*ItAlias);
91
92 // Reserve constant registers.
93 Reserved.set(VE::VM0);
94 Reserved.set(VE::VMP0);
95
96 return Reserved;
97 }
98
isConstantPhysReg(MCRegister PhysReg) const99 bool VERegisterInfo::isConstantPhysReg(MCRegister PhysReg) const {
100 switch (PhysReg) {
101 case VE::VM0:
102 case VE::VMP0:
103 return true;
104 default:
105 return false;
106 }
107 }
108
109 const TargetRegisterClass *
getPointerRegClass(const MachineFunction & MF,unsigned Kind) const110 VERegisterInfo::getPointerRegClass(const MachineFunction &MF,
111 unsigned Kind) const {
112 return &VE::I64RegClass;
113 }
114
offsetToDisp(MachineInstr & MI)115 static unsigned offsetToDisp(MachineInstr &MI) {
116 // Default offset in instruction's operands (reg+reg+imm).
117 unsigned OffDisp = 2;
118
119 #define RRCAS_multi_cases(NAME) NAME##rir : case NAME##rii
120
121 {
122 using namespace llvm::VE;
123 switch (MI.getOpcode()) {
124 case RRCAS_multi_cases(TS1AML):
125 case RRCAS_multi_cases(TS1AMW):
126 case RRCAS_multi_cases(CASL):
127 case RRCAS_multi_cases(CASW):
128 // These instructions use AS format (reg+imm).
129 OffDisp = 1;
130 break;
131 }
132 }
133 #undef RRCAS_multi_cases
134
135 return OffDisp;
136 }
137
138 class EliminateFrameIndex {
139 const TargetInstrInfo &TII;
140 const TargetRegisterInfo &TRI;
141 const DebugLoc &DL;
142 MachineBasicBlock &MBB;
143 MachineBasicBlock::iterator II;
144 Register clobber;
145
146 // Some helper functions for the ease of instruction building.
getFunc() const147 MachineFunction &getFunc() const { return *MBB.getParent(); }
getSubReg(MCRegister Reg,unsigned Idx) const148 inline MCRegister getSubReg(MCRegister Reg, unsigned Idx) const {
149 return TRI.getSubReg(Reg, Idx);
150 }
get(unsigned Opcode) const151 inline const MCInstrDesc &get(unsigned Opcode) const {
152 return TII.get(Opcode);
153 }
build(const MCInstrDesc & MCID,Register DestReg)154 inline MachineInstrBuilder build(const MCInstrDesc &MCID, Register DestReg) {
155 return BuildMI(MBB, II, DL, MCID, DestReg);
156 }
build(unsigned InstOpc,Register DestReg)157 inline MachineInstrBuilder build(unsigned InstOpc, Register DestReg) {
158 return build(get(InstOpc), DestReg);
159 }
build(const MCInstrDesc & MCID)160 inline MachineInstrBuilder build(const MCInstrDesc &MCID) {
161 return BuildMI(MBB, II, DL, MCID);
162 }
build(unsigned InstOpc)163 inline MachineInstrBuilder build(unsigned InstOpc) {
164 return build(get(InstOpc));
165 }
166
167 // Calculate an address of frame index from a frame register and a given
168 // offset if the offset doesn't fit in the immediate field. Use a clobber
169 // register to hold calculated address.
170 void prepareReplaceFI(MachineInstr &MI, Register &FrameReg, int64_t &Offset,
171 int64_t Bytes = 0);
172 // Replace the frame index in \p MI with a frame register and a given offset
173 // if it fits in the immediate field. Otherwise, use pre-calculated address
174 // in a clobber regsiter.
175 void replaceFI(MachineInstr &MI, Register FrameReg, int64_t Offset,
176 int FIOperandNum);
177
178 // Expand and eliminate Frame Index of pseudo STQrii and LDQrii.
179 void processSTQ(MachineInstr &MI, Register FrameReg, int64_t Offset,
180 int FIOperandNum);
181 void processLDQ(MachineInstr &MI, Register FrameReg, int64_t Offset,
182 int FIOperandNum);
183 // Expand and eliminate Frame Index of pseudo STVMrii and LDVMrii.
184 void processSTVM(MachineInstr &MI, Register FrameReg, int64_t Offset,
185 int FIOperandNum);
186 void processLDVM(MachineInstr &MI, Register FrameReg, int64_t Offset,
187 int FIOperandNum);
188 // Expand and eliminate Frame Index of pseudo STVM512rii and LDVM512rii.
189 void processSTVM512(MachineInstr &MI, Register FrameReg, int64_t Offset,
190 int FIOperandNum);
191 void processLDVM512(MachineInstr &MI, Register FrameReg, int64_t Offset,
192 int FIOperandNum);
193
194 public:
EliminateFrameIndex(const TargetInstrInfo & TII,const TargetRegisterInfo & TRI,const DebugLoc & DL,MachineBasicBlock & MBB,MachineBasicBlock::iterator II)195 EliminateFrameIndex(const TargetInstrInfo &TII, const TargetRegisterInfo &TRI,
196 const DebugLoc &DL, MachineBasicBlock &MBB,
197 MachineBasicBlock::iterator II)
198 : TII(TII), TRI(TRI), DL(DL), MBB(MBB), II(II), clobber(VE::SX13) {}
199
200 // Expand and eliminate Frame Index from MI
201 void processMI(MachineInstr &MI, Register FrameReg, int64_t Offset,
202 int FIOperandNum);
203 };
204
205 // Prepare the frame index if it doesn't fit in the immediate field. Use
206 // clobber register to hold calculated address.
prepareReplaceFI(MachineInstr & MI,Register & FrameReg,int64_t & Offset,int64_t Bytes)207 void EliminateFrameIndex::prepareReplaceFI(MachineInstr &MI, Register &FrameReg,
208 int64_t &Offset, int64_t Bytes) {
209 if (isInt<32>(Offset) && isInt<32>(Offset + Bytes)) {
210 // If the offset is small enough to fit in the immediate field, directly
211 // encode it. So, nothing to prepare here.
212 return;
213 }
214
215 // If the offset doesn't fit, emit following codes. This clobbers SX13
216 // which we always know is available here.
217 // lea %clobber, Offset@lo
218 // and %clobber, %clobber, (32)0
219 // lea.sl %clobber, Offset@hi(FrameReg, %clobber)
220 build(VE::LEAzii, clobber).addImm(0).addImm(0).addImm(Lo_32(Offset));
221 build(VE::ANDrm, clobber).addReg(clobber).addImm(M0(32));
222 build(VE::LEASLrri, clobber)
223 .addReg(clobber)
224 .addReg(FrameReg)
225 .addImm(Hi_32(Offset));
226
227 // Use clobber register as a frame register and 0 offset
228 FrameReg = clobber;
229 Offset = 0;
230 }
231
232 // Replace the frame index in \p MI with a proper byte and framereg offset.
replaceFI(MachineInstr & MI,Register FrameReg,int64_t Offset,int FIOperandNum)233 void EliminateFrameIndex::replaceFI(MachineInstr &MI, Register FrameReg,
234 int64_t Offset, int FIOperandNum) {
235 assert(isInt<32>(Offset));
236
237 // The offset must be small enough to fit in the immediate field after
238 // call of prepareReplaceFI. Therefore, we directly encode it.
239 MI.getOperand(FIOperandNum).ChangeToRegister(FrameReg, false);
240 MI.getOperand(FIOperandNum + offsetToDisp(MI)).ChangeToImmediate(Offset);
241 }
242
processSTQ(MachineInstr & MI,Register FrameReg,int64_t Offset,int FIOperandNum)243 void EliminateFrameIndex::processSTQ(MachineInstr &MI, Register FrameReg,
244 int64_t Offset, int FIOperandNum) {
245 assert(MI.getOpcode() == VE::STQrii);
246 LLVM_DEBUG(dbgs() << "processSTQ: "; MI.dump());
247
248 prepareReplaceFI(MI, FrameReg, Offset, 8);
249
250 Register SrcReg = MI.getOperand(3).getReg();
251 Register SrcHiReg = getSubReg(SrcReg, VE::sub_even);
252 Register SrcLoReg = getSubReg(SrcReg, VE::sub_odd);
253 // VE stores HiReg to 8(addr) and LoReg to 0(addr)
254 MachineInstr *StMI =
255 build(VE::STrii).addReg(FrameReg).addImm(0).addImm(0).addReg(SrcLoReg);
256 replaceFI(*StMI, FrameReg, Offset, 0);
257 // Mutate to 'hi' store.
258 MI.setDesc(get(VE::STrii));
259 MI.getOperand(3).setReg(SrcHiReg);
260 Offset += 8;
261 replaceFI(MI, FrameReg, Offset, FIOperandNum);
262 }
263
processLDQ(MachineInstr & MI,Register FrameReg,int64_t Offset,int FIOperandNum)264 void EliminateFrameIndex::processLDQ(MachineInstr &MI, Register FrameReg,
265 int64_t Offset, int FIOperandNum) {
266 assert(MI.getOpcode() == VE::LDQrii);
267 LLVM_DEBUG(dbgs() << "processLDQ: "; MI.dump());
268
269 prepareReplaceFI(MI, FrameReg, Offset, 8);
270
271 Register DestReg = MI.getOperand(0).getReg();
272 Register DestHiReg = getSubReg(DestReg, VE::sub_even);
273 Register DestLoReg = getSubReg(DestReg, VE::sub_odd);
274 // VE loads HiReg from 8(addr) and LoReg from 0(addr)
275 MachineInstr *StMI =
276 build(VE::LDrii, DestLoReg).addReg(FrameReg).addImm(0).addImm(0);
277 replaceFI(*StMI, FrameReg, Offset, 1);
278 MI.setDesc(get(VE::LDrii));
279 MI.getOperand(0).setReg(DestHiReg);
280 Offset += 8;
281 replaceFI(MI, FrameReg, Offset, FIOperandNum);
282 }
283
processSTVM(MachineInstr & MI,Register FrameReg,int64_t Offset,int FIOperandNum)284 void EliminateFrameIndex::processSTVM(MachineInstr &MI, Register FrameReg,
285 int64_t Offset, int FIOperandNum) {
286 assert(MI.getOpcode() == VE::STVMrii);
287 LLVM_DEBUG(dbgs() << "processSTVM: "; MI.dump());
288
289 // Original MI is:
290 // STVMrii frame-index, 0, offset, reg (, memory operand)
291 // Convert it to:
292 // SVMi tmp-reg, reg, 0
293 // STrii frame-reg, 0, offset, tmp-reg
294 // SVMi tmp-reg, reg, 1
295 // STrii frame-reg, 0, offset+8, tmp-reg
296 // SVMi tmp-reg, reg, 2
297 // STrii frame-reg, 0, offset+16, tmp-reg
298 // SVMi tmp-reg, reg, 3
299 // STrii frame-reg, 0, offset+24, tmp-reg
300
301 prepareReplaceFI(MI, FrameReg, Offset, 24);
302
303 Register SrcReg = MI.getOperand(3).getReg();
304 bool isKill = MI.getOperand(3).isKill();
305 // FIXME: it would be better to scavenge a register here instead of
306 // reserving SX16 all of the time.
307 Register TmpReg = VE::SX16;
308 for (int i = 0; i < 3; ++i) {
309 build(VE::SVMmr, TmpReg).addReg(SrcReg).addImm(i);
310 MachineInstr *StMI =
311 build(VE::STrii).addReg(FrameReg).addImm(0).addImm(0).addReg(
312 TmpReg, getKillRegState(true));
313 replaceFI(*StMI, FrameReg, Offset, 0);
314 Offset += 8;
315 }
316 build(VE::SVMmr, TmpReg).addReg(SrcReg, getKillRegState(isKill)).addImm(3);
317 MI.setDesc(get(VE::STrii));
318 MI.getOperand(3).ChangeToRegister(TmpReg, false, false, true);
319 replaceFI(MI, FrameReg, Offset, FIOperandNum);
320 }
321
processLDVM(MachineInstr & MI,Register FrameReg,int64_t Offset,int FIOperandNum)322 void EliminateFrameIndex::processLDVM(MachineInstr &MI, Register FrameReg,
323 int64_t Offset, int FIOperandNum) {
324 assert(MI.getOpcode() == VE::LDVMrii);
325 LLVM_DEBUG(dbgs() << "processLDVM: "; MI.dump());
326
327 // Original MI is:
328 // LDVMri reg, frame-index, 0, offset (, memory operand)
329 // Convert it to:
330 // LDrii tmp-reg, frame-reg, 0, offset
331 // LVMir vm, 0, tmp-reg
332 // LDrii tmp-reg, frame-reg, 0, offset+8
333 // LVMir_m vm, 1, tmp-reg, vm
334 // LDrii tmp-reg, frame-reg, 0, offset+16
335 // LVMir_m vm, 2, tmp-reg, vm
336 // LDrii tmp-reg, frame-reg, 0, offset+24
337 // LVMir_m vm, 3, tmp-reg, vm
338
339 prepareReplaceFI(MI, FrameReg, Offset, 24);
340
341 Register DestReg = MI.getOperand(0).getReg();
342 // FIXME: it would be better to scavenge a register here instead of
343 // reserving SX16 all of the time.
344 unsigned TmpReg = VE::SX16;
345 for (int i = 0; i < 4; ++i) {
346 if (i != 3) {
347 MachineInstr *StMI =
348 build(VE::LDrii, TmpReg).addReg(FrameReg).addImm(0).addImm(0);
349 replaceFI(*StMI, FrameReg, Offset, 1);
350 Offset += 8;
351 } else {
352 // Last LDrii replace the target instruction.
353 MI.setDesc(get(VE::LDrii));
354 MI.getOperand(0).ChangeToRegister(TmpReg, true);
355 }
356 // First LVM is LVMir. Others are LVMir_m. Last LVM places at the
357 // next of the target instruction.
358 if (i == 0)
359 build(VE::LVMir, DestReg).addImm(i).addReg(TmpReg, getKillRegState(true));
360 else if (i != 3)
361 build(VE::LVMir_m, DestReg)
362 .addImm(i)
363 .addReg(TmpReg, getKillRegState(true))
364 .addReg(DestReg);
365 else
366 BuildMI(*MI.getParent(), std::next(II), DL, get(VE::LVMir_m), DestReg)
367 .addImm(3)
368 .addReg(TmpReg, getKillRegState(true))
369 .addReg(DestReg);
370 }
371 replaceFI(MI, FrameReg, Offset, FIOperandNum);
372 }
373
processSTVM512(MachineInstr & MI,Register FrameReg,int64_t Offset,int FIOperandNum)374 void EliminateFrameIndex::processSTVM512(MachineInstr &MI, Register FrameReg,
375 int64_t Offset, int FIOperandNum) {
376 assert(MI.getOpcode() == VE::STVM512rii);
377 LLVM_DEBUG(dbgs() << "processSTVM512: "; MI.dump());
378
379 prepareReplaceFI(MI, FrameReg, Offset, 56);
380
381 Register SrcReg = MI.getOperand(3).getReg();
382 Register SrcLoReg = getSubReg(SrcReg, VE::sub_vm_odd);
383 Register SrcHiReg = getSubReg(SrcReg, VE::sub_vm_even);
384 bool isKill = MI.getOperand(3).isKill();
385 // FIXME: it would be better to scavenge a register here instead of
386 // reserving SX16 all of the time.
387 Register TmpReg = VE::SX16;
388 // store low part of VMP
389 MachineInstr *LastMI = nullptr;
390 for (int i = 0; i < 4; ++i) {
391 LastMI = build(VE::SVMmr, TmpReg).addReg(SrcLoReg).addImm(i);
392 MachineInstr *StMI =
393 build(VE::STrii).addReg(FrameReg).addImm(0).addImm(0).addReg(
394 TmpReg, getKillRegState(true));
395 replaceFI(*StMI, FrameReg, Offset, 0);
396 Offset += 8;
397 }
398 if (isKill)
399 LastMI->addRegisterKilled(SrcLoReg, &TRI, true);
400 // store high part of VMP
401 for (int i = 0; i < 3; ++i) {
402 build(VE::SVMmr, TmpReg).addReg(SrcHiReg).addImm(i);
403 MachineInstr *StMI =
404 build(VE::STrii).addReg(FrameReg).addImm(0).addImm(0).addReg(
405 TmpReg, getKillRegState(true));
406 replaceFI(*StMI, FrameReg, Offset, 0);
407 Offset += 8;
408 }
409 LastMI = build(VE::SVMmr, TmpReg).addReg(SrcHiReg).addImm(3);
410 if (isKill) {
411 LastMI->addRegisterKilled(SrcHiReg, &TRI, true);
412 // Add implicit super-register kills to the particular MI.
413 LastMI->addRegisterKilled(SrcReg, &TRI, true);
414 }
415 MI.setDesc(get(VE::STrii));
416 MI.getOperand(3).ChangeToRegister(TmpReg, false, false, true);
417 replaceFI(MI, FrameReg, Offset, FIOperandNum);
418 }
419
processLDVM512(MachineInstr & MI,Register FrameReg,int64_t Offset,int FIOperandNum)420 void EliminateFrameIndex::processLDVM512(MachineInstr &MI, Register FrameReg,
421 int64_t Offset, int FIOperandNum) {
422 assert(MI.getOpcode() == VE::LDVM512rii);
423 LLVM_DEBUG(dbgs() << "processLDVM512: "; MI.dump());
424
425 prepareReplaceFI(MI, FrameReg, Offset, 56);
426
427 Register DestReg = MI.getOperand(0).getReg();
428 Register DestLoReg = getSubReg(DestReg, VE::sub_vm_odd);
429 Register DestHiReg = getSubReg(DestReg, VE::sub_vm_even);
430 // FIXME: it would be better to scavenge a register here instead of
431 // reserving SX16 all of the time.
432 Register TmpReg = VE::SX16;
433 build(VE::IMPLICIT_DEF, DestReg);
434 for (int i = 0; i < 4; ++i) {
435 MachineInstr *LdMI =
436 build(VE::LDrii, TmpReg).addReg(FrameReg).addImm(0).addImm(0);
437 replaceFI(*LdMI, FrameReg, Offset, 1);
438 build(VE::LVMir_m, DestLoReg)
439 .addImm(i)
440 .addReg(TmpReg, getKillRegState(true))
441 .addReg(DestLoReg);
442 Offset += 8;
443 }
444 for (int i = 0; i < 3; ++i) {
445 MachineInstr *LdMI =
446 build(VE::LDrii, TmpReg).addReg(FrameReg).addImm(0).addImm(0);
447 replaceFI(*LdMI, FrameReg, Offset, 1);
448 build(VE::LVMir_m, DestHiReg)
449 .addImm(i)
450 .addReg(TmpReg, getKillRegState(true))
451 .addReg(DestHiReg);
452 Offset += 8;
453 }
454 MI.setDesc(get(VE::LDrii));
455 MI.getOperand(0).ChangeToRegister(TmpReg, true);
456 BuildMI(*MI.getParent(), std::next(II), DL, get(VE::LVMir_m), DestHiReg)
457 .addImm(3)
458 .addReg(TmpReg, getKillRegState(true))
459 .addReg(DestHiReg);
460 replaceFI(MI, FrameReg, Offset, FIOperandNum);
461 }
462
processMI(MachineInstr & MI,Register FrameReg,int64_t Offset,int FIOperandNum)463 void EliminateFrameIndex::processMI(MachineInstr &MI, Register FrameReg,
464 int64_t Offset, int FIOperandNum) {
465 switch (MI.getOpcode()) {
466 case VE::STQrii:
467 processSTQ(MI, FrameReg, Offset, FIOperandNum);
468 return;
469 case VE::LDQrii:
470 processLDQ(MI, FrameReg, Offset, FIOperandNum);
471 return;
472 case VE::STVMrii:
473 processSTVM(MI, FrameReg, Offset, FIOperandNum);
474 return;
475 case VE::LDVMrii:
476 processLDVM(MI, FrameReg, Offset, FIOperandNum);
477 return;
478 case VE::STVM512rii:
479 processSTVM512(MI, FrameReg, Offset, FIOperandNum);
480 return;
481 case VE::LDVM512rii:
482 processLDVM512(MI, FrameReg, Offset, FIOperandNum);
483 return;
484 }
485 prepareReplaceFI(MI, FrameReg, Offset);
486 replaceFI(MI, FrameReg, Offset, FIOperandNum);
487 }
488
eliminateFrameIndex(MachineBasicBlock::iterator II,int SPAdj,unsigned FIOperandNum,RegScavenger * RS) const489 void VERegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
490 int SPAdj, unsigned FIOperandNum,
491 RegScavenger *RS) const {
492 assert(SPAdj == 0 && "Unexpected");
493
494 MachineInstr &MI = *II;
495 int FrameIndex = MI.getOperand(FIOperandNum).getIndex();
496
497 MachineFunction &MF = *MI.getParent()->getParent();
498 const VESubtarget &Subtarget = MF.getSubtarget<VESubtarget>();
499 const VEFrameLowering &TFI = *getFrameLowering(MF);
500 const TargetInstrInfo &TII = *Subtarget.getInstrInfo();
501 const VERegisterInfo &TRI = *Subtarget.getRegisterInfo();
502 DebugLoc DL = MI.getDebugLoc();
503 EliminateFrameIndex EFI(TII, TRI, DL, *MI.getParent(), II);
504
505 // Retrieve FrameReg and byte offset for stack slot.
506 Register FrameReg;
507 int64_t Offset =
508 TFI.getFrameIndexReference(MF, FrameIndex, FrameReg).getFixed();
509 Offset += MI.getOperand(FIOperandNum + offsetToDisp(MI)).getImm();
510
511 EFI.processMI(MI, FrameReg, Offset, FIOperandNum);
512 }
513
getFrameRegister(const MachineFunction & MF) const514 Register VERegisterInfo::getFrameRegister(const MachineFunction &MF) const {
515 return VE::SX9;
516 }
517