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