LLVM 20.0.0git
SparcInstrInfo.cpp
Go to the documentation of this file.
1//===-- SparcInstrInfo.cpp - Sparc Instruction 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 Sparc implementation of the TargetInstrInfo class.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SparcInstrInfo.h"
14#include "Sparc.h"
16#include "SparcSubtarget.h"
17#include "llvm/ADT/STLExtras.h"
25
26using namespace llvm;
27
28#define GET_INSTRINFO_CTOR_DTOR
29#include "SparcGenInstrInfo.inc"
30
32 "sparc-bpcc-offset-bits", cl::Hidden, cl::init(19),
33 cl::desc("Restrict range of BPcc/FBPfcc instructions (DEBUG)"));
34
36 BPrDisplacementBits("sparc-bpr-offset-bits", cl::Hidden, cl::init(16),
37 cl::desc("Restrict range of BPr instructions (DEBUG)"));
38
39// Pin the vtable to this file.
40void SparcInstrInfo::anchor() {}
41
43 : SparcGenInstrInfo(SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP), RI(),
44 Subtarget(ST) {}
45
46/// isLoadFromStackSlot - If the specified machine instruction is a direct
47/// load from a stack slot, return the virtual or physical register number of
48/// the destination along with the FrameIndex of the loaded stack slot. If
49/// not, return 0. This predicate must return 0 if the instruction has
50/// any side effects other than loading from the stack slot.
52 int &FrameIndex) const {
53 if (MI.getOpcode() == SP::LDri || MI.getOpcode() == SP::LDXri ||
54 MI.getOpcode() == SP::LDFri || MI.getOpcode() == SP::LDDFri ||
55 MI.getOpcode() == SP::LDQFri) {
56 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
57 MI.getOperand(2).getImm() == 0) {
58 FrameIndex = MI.getOperand(1).getIndex();
59 return MI.getOperand(0).getReg();
60 }
61 }
62 return 0;
63}
64
65/// isStoreToStackSlot - If the specified machine instruction is a direct
66/// store to a stack slot, return the virtual or physical register number of
67/// the source reg along with the FrameIndex of the loaded stack slot. If
68/// not, return 0. This predicate must return 0 if the instruction has
69/// any side effects other than storing to the stack slot.
71 int &FrameIndex) const {
72 if (MI.getOpcode() == SP::STri || MI.getOpcode() == SP::STXri ||
73 MI.getOpcode() == SP::STFri || MI.getOpcode() == SP::STDFri ||
74 MI.getOpcode() == SP::STQFri) {
75 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
76 MI.getOperand(1).getImm() == 0) {
77 FrameIndex = MI.getOperand(0).getIndex();
78 return MI.getOperand(2).getReg();
79 }
80 }
81 return 0;
82}
83
85{
86 switch(CC) {
87 case SPCC::ICC_A: return SPCC::ICC_N;
88 case SPCC::ICC_N: return SPCC::ICC_A;
89 case SPCC::ICC_NE: return SPCC::ICC_E;
90 case SPCC::ICC_E: return SPCC::ICC_NE;
91 case SPCC::ICC_G: return SPCC::ICC_LE;
92 case SPCC::ICC_LE: return SPCC::ICC_G;
93 case SPCC::ICC_GE: return SPCC::ICC_L;
94 case SPCC::ICC_L: return SPCC::ICC_GE;
95 case SPCC::ICC_GU: return SPCC::ICC_LEU;
96 case SPCC::ICC_LEU: return SPCC::ICC_GU;
97 case SPCC::ICC_CC: return SPCC::ICC_CS;
98 case SPCC::ICC_CS: return SPCC::ICC_CC;
99 case SPCC::ICC_POS: return SPCC::ICC_NEG;
100 case SPCC::ICC_NEG: return SPCC::ICC_POS;
101 case SPCC::ICC_VC: return SPCC::ICC_VS;
102 case SPCC::ICC_VS: return SPCC::ICC_VC;
103
104 case SPCC::FCC_A: return SPCC::FCC_N;
105 case SPCC::FCC_N: return SPCC::FCC_A;
106 case SPCC::FCC_U: return SPCC::FCC_O;
107 case SPCC::FCC_O: return SPCC::FCC_U;
108 case SPCC::FCC_G: return SPCC::FCC_ULE;
109 case SPCC::FCC_LE: return SPCC::FCC_UG;
110 case SPCC::FCC_UG: return SPCC::FCC_LE;
111 case SPCC::FCC_ULE: return SPCC::FCC_G;
112 case SPCC::FCC_L: return SPCC::FCC_UGE;
113 case SPCC::FCC_GE: return SPCC::FCC_UL;
114 case SPCC::FCC_UL: return SPCC::FCC_GE;
115 case SPCC::FCC_UGE: return SPCC::FCC_L;
116 case SPCC::FCC_LG: return SPCC::FCC_UE;
117 case SPCC::FCC_UE: return SPCC::FCC_LG;
118 case SPCC::FCC_NE: return SPCC::FCC_E;
119 case SPCC::FCC_E: return SPCC::FCC_NE;
120
121 case SPCC::CPCC_A: return SPCC::CPCC_N;
122 case SPCC::CPCC_N: return SPCC::CPCC_A;
123 case SPCC::CPCC_3: [[fallthrough]];
124 case SPCC::CPCC_2: [[fallthrough]];
125 case SPCC::CPCC_23: [[fallthrough]];
126 case SPCC::CPCC_1: [[fallthrough]];
127 case SPCC::CPCC_13: [[fallthrough]];
128 case SPCC::CPCC_12: [[fallthrough]];
129 case SPCC::CPCC_123: [[fallthrough]];
130 case SPCC::CPCC_0: [[fallthrough]];
131 case SPCC::CPCC_03: [[fallthrough]];
132 case SPCC::CPCC_02: [[fallthrough]];
133 case SPCC::CPCC_023: [[fallthrough]];
134 case SPCC::CPCC_01: [[fallthrough]];
135 case SPCC::CPCC_013: [[fallthrough]];
136 case SPCC::CPCC_012:
137 // "Opposite" code is not meaningful, as we don't know
138 // what the CoProc condition means here. The cond-code will
139 // only be used in inline assembler, so this code should
140 // not be reached in a normal compilation pass.
141 llvm_unreachable("Meaningless inversion of co-processor cond code");
142
143 case SPCC::REG_BEGIN:
144 llvm_unreachable("Use of reserved cond code");
145 case SPCC::REG_Z:
146 return SPCC::REG_NZ;
147 case SPCC::REG_LEZ:
148 return SPCC::REG_GZ;
149 case SPCC::REG_LZ:
150 return SPCC::REG_GEZ;
151 case SPCC::REG_NZ:
152 return SPCC::REG_Z;
153 case SPCC::REG_GZ:
154 return SPCC::REG_LEZ;
155 case SPCC::REG_GEZ:
156 return SPCC::REG_LZ;
157 }
158 llvm_unreachable("Invalid cond code");
159}
160
161static bool isUncondBranchOpcode(int Opc) { return Opc == SP::BA; }
162
163static bool isI32CondBranchOpcode(int Opc) {
164 return Opc == SP::BCOND || Opc == SP::BPICC || Opc == SP::BPICCA ||
165 Opc == SP::BPICCNT || Opc == SP::BPICCANT;
166}
167
168static bool isI64CondBranchOpcode(int Opc) {
169 return Opc == SP::BPXCC || Opc == SP::BPXCCA || Opc == SP::BPXCCNT ||
170 Opc == SP::BPXCCANT;
171}
172
173static bool isRegCondBranchOpcode(int Opc) {
174 return Opc == SP::BPR || Opc == SP::BPRA || Opc == SP::BPRNT ||
175 Opc == SP::BPRANT;
176}
177
178static bool isFCondBranchOpcode(int Opc) {
179 return Opc == SP::FBCOND || Opc == SP::FBCONDA || Opc == SP::FBCOND_V9 ||
180 Opc == SP::FBCONDA_V9;
181}
182
183static bool isCondBranchOpcode(int Opc) {
184 return isI32CondBranchOpcode(Opc) || isI64CondBranchOpcode(Opc) ||
186}
187
188static bool isIndirectBranchOpcode(int Opc) {
189 return Opc == SP::BINDrr || Opc == SP::BINDri;
190}
191
194 unsigned Opc = LastInst->getOpcode();
195 int64_t CC = LastInst->getOperand(1).getImm();
196
197 // Push the branch opcode into Cond too so later in insertBranch
198 // it can use the information to emit the correct SPARC branch opcode.
199 Cond.push_back(MachineOperand::CreateImm(Opc));
201
202 // Branch on register contents need another argument to indicate
203 // the register it branches on.
204 if (isRegCondBranchOpcode(Opc)) {
205 Register Reg = LastInst->getOperand(2).getReg();
206 Cond.push_back(MachineOperand::CreateReg(Reg, false));
207 }
208
209 Target = LastInst->getOperand(0).getMBB();
210}
211
214 switch (MI.getOpcode()) {
215 default:
216 llvm_unreachable("unexpected opcode!");
217 case SP::BA:
218 case SP::BCOND:
219 case SP::BCONDA:
220 case SP::FBCOND:
221 case SP::FBCONDA:
222 case SP::BPICC:
223 case SP::BPICCA:
224 case SP::BPICCNT:
225 case SP::BPICCANT:
226 case SP::BPXCC:
227 case SP::BPXCCA:
228 case SP::BPXCCNT:
229 case SP::BPXCCANT:
230 case SP::BPFCC:
231 case SP::BPFCCA:
232 case SP::BPFCCNT:
233 case SP::BPFCCANT:
234 case SP::FBCOND_V9:
235 case SP::FBCONDA_V9:
236 case SP::BPR:
237 case SP::BPRA:
238 case SP::BPRNT:
239 case SP::BPRANT:
240 return MI.getOperand(0).getMBB();
241 }
242}
243
246 MachineBasicBlock *&FBB,
248 bool AllowModify) const {
250 if (I == MBB.end())
251 return false;
252
253 if (!isUnpredicatedTerminator(*I))
254 return false;
255
256 // Get the last instruction in the block.
257 MachineInstr *LastInst = &*I;
258 unsigned LastOpc = LastInst->getOpcode();
259
260 // If there is only one terminator instruction, process it.
261 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
262 if (isUncondBranchOpcode(LastOpc)) {
263 TBB = LastInst->getOperand(0).getMBB();
264 return false;
265 }
266 if (isCondBranchOpcode(LastOpc)) {
267 // Block ends with fall-through condbranch.
268 parseCondBranch(LastInst, TBB, Cond);
269 return false;
270 }
271 return true; // Can't handle indirect branch.
272 }
273
274 // Get the instruction before it if it is a terminator.
275 MachineInstr *SecondLastInst = &*I;
276 unsigned SecondLastOpc = SecondLastInst->getOpcode();
277
278 // If AllowModify is true and the block ends with two or more unconditional
279 // branches, delete all but the first unconditional branch.
280 if (AllowModify && isUncondBranchOpcode(LastOpc)) {
281 while (isUncondBranchOpcode(SecondLastOpc)) {
282 LastInst->eraseFromParent();
283 LastInst = SecondLastInst;
284 LastOpc = LastInst->getOpcode();
285 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
286 // Return now the only terminator is an unconditional branch.
287 TBB = LastInst->getOperand(0).getMBB();
288 return false;
289 } else {
290 SecondLastInst = &*I;
291 SecondLastOpc = SecondLastInst->getOpcode();
292 }
293 }
294 }
295
296 // If there are three terminators, we don't know what sort of block this is.
297 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
298 return true;
299
300 // If the block ends with a B and a Bcc, handle it.
301 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
302 parseCondBranch(SecondLastInst, TBB, Cond);
303 FBB = LastInst->getOperand(0).getMBB();
304 return false;
305 }
306
307 // If the block ends with two unconditional branches, handle it. The second
308 // one is not executed.
309 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
310 TBB = SecondLastInst->getOperand(0).getMBB();
311 return false;
312 }
313
314 // ...likewise if it ends with an indirect branch followed by an unconditional
315 // branch.
316 if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
317 I = LastInst;
318 if (AllowModify)
319 I->eraseFromParent();
320 return true;
321 }
322
323 // Otherwise, can't handle this.
324 return true;
325}
326
331 const DebugLoc &DL,
332 int *BytesAdded) const {
333 assert(TBB && "insertBranch must not be told to insert a fallthrough");
334 assert((Cond.size() <= 3) &&
335 "Sparc branch conditions should have at most three components!");
336
337 if (Cond.empty()) {
338 assert(!FBB && "Unconditional branch with multiple successors!");
339 BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
340 if (BytesAdded)
341 *BytesAdded = 8;
342 return 1;
343 }
344
345 // Conditional branch
346 unsigned Opc = Cond[0].getImm();
347 unsigned CC = Cond[1].getImm();
348 if (isRegCondBranchOpcode(Opc)) {
349 Register Reg = Cond[2].getReg();
350 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC).addReg(Reg);
351 } else {
352 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC);
353 }
354
355 if (!FBB) {
356 if (BytesAdded)
357 *BytesAdded = 8;
358 return 1;
359 }
360
361 BuildMI(&MBB, DL, get(SP::BA)).addMBB(FBB);
362 if (BytesAdded)
363 *BytesAdded = 16;
364 return 2;
365}
366
368 int *BytesRemoved) const {
370 unsigned Count = 0;
371 int Removed = 0;
372 while (I != MBB.begin()) {
373 --I;
374
375 if (I->isDebugInstr())
376 continue;
377
378 if (!isCondBranchOpcode(I->getOpcode()) &&
379 !isUncondBranchOpcode(I->getOpcode()))
380 break; // Not a branch
381
382 Removed += getInstSizeInBytes(*I);
383 I->eraseFromParent();
384 I = MBB.end();
385 ++Count;
386 }
387
388 if (BytesRemoved)
389 *BytesRemoved = Removed;
390 return Count;
391}
392
395 assert(Cond.size() <= 3);
396 SPCC::CondCodes CC = static_cast<SPCC::CondCodes>(Cond[1].getImm());
398 return false;
399}
400
402 int64_t Offset) const {
403 assert((Offset & 0b11) == 0 && "Malformed branch offset");
404 switch (BranchOpc) {
405 case SP::BA:
406 case SP::BCOND:
407 case SP::BCONDA:
408 case SP::FBCOND:
409 case SP::FBCONDA:
410 return isIntN(22, Offset >> 2);
411
412 case SP::BPICC:
413 case SP::BPICCA:
414 case SP::BPICCNT:
415 case SP::BPICCANT:
416 case SP::BPXCC:
417 case SP::BPXCCA:
418 case SP::BPXCCNT:
419 case SP::BPXCCANT:
420 case SP::BPFCC:
421 case SP::BPFCCA:
422 case SP::BPFCCNT:
423 case SP::BPFCCANT:
424 case SP::FBCOND_V9:
425 case SP::FBCONDA_V9:
426 return isIntN(BPccDisplacementBits, Offset >> 2);
427
428 case SP::BPR:
429 case SP::BPRA:
430 case SP::BPRNT:
431 case SP::BPRANT:
432 return isIntN(BPrDisplacementBits, Offset >> 2);
433 }
434
435 llvm_unreachable("Unknown branch instruction!");
436}
437
440 const DebugLoc &DL, MCRegister DestReg,
441 MCRegister SrcReg, bool KillSrc) const {
442 unsigned numSubRegs = 0;
443 unsigned movOpc = 0;
444 const unsigned *subRegIdx = nullptr;
445 bool ExtraG0 = false;
446
447 const unsigned DW_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
448 const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
449 const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 };
450 const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd,
451 SP::sub_odd64_then_sub_even,
452 SP::sub_odd64_then_sub_odd };
453
454 if (SP::IntRegsRegClass.contains(DestReg, SrcReg))
455 BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0)
456 .addReg(SrcReg, getKillRegState(KillSrc));
457 else if (SP::IntPairRegClass.contains(DestReg, SrcReg)) {
458 subRegIdx = DW_SubRegsIdx;
459 numSubRegs = 2;
460 movOpc = SP::ORrr;
461 ExtraG0 = true;
462 } else if (SP::FPRegsRegClass.contains(DestReg, SrcReg))
463 BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg)
464 .addReg(SrcReg, getKillRegState(KillSrc));
465 else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg)) {
466 if (Subtarget.isV9()) {
467 BuildMI(MBB, I, DL, get(SP::FMOVD), DestReg)
468 .addReg(SrcReg, getKillRegState(KillSrc));
469 } else {
470 // Use two FMOVS instructions.
471 subRegIdx = DFP_FP_SubRegsIdx;
472 numSubRegs = 2;
473 movOpc = SP::FMOVS;
474 }
475 } else if (SP::QFPRegsRegClass.contains(DestReg, SrcReg)) {
476 if (Subtarget.isV9()) {
477 if (Subtarget.hasHardQuad()) {
478 BuildMI(MBB, I, DL, get(SP::FMOVQ), DestReg)
479 .addReg(SrcReg, getKillRegState(KillSrc));
480 } else {
481 // Use two FMOVD instructions.
482 subRegIdx = QFP_DFP_SubRegsIdx;
483 numSubRegs = 2;
484 movOpc = SP::FMOVD;
485 }
486 } else {
487 // Use four FMOVS instructions.
488 subRegIdx = QFP_FP_SubRegsIdx;
489 numSubRegs = 4;
490 movOpc = SP::FMOVS;
491 }
492 } else if (SP::ASRRegsRegClass.contains(DestReg) &&
493 SP::IntRegsRegClass.contains(SrcReg)) {
494 BuildMI(MBB, I, DL, get(SP::WRASRrr), DestReg)
495 .addReg(SP::G0)
496 .addReg(SrcReg, getKillRegState(KillSrc));
497 } else if (SP::IntRegsRegClass.contains(DestReg) &&
498 SP::ASRRegsRegClass.contains(SrcReg)) {
499 BuildMI(MBB, I, DL, get(SP::RDASR), DestReg)
500 .addReg(SrcReg, getKillRegState(KillSrc));
501 } else
502 llvm_unreachable("Impossible reg-to-reg copy");
503
504 if (numSubRegs == 0 || subRegIdx == nullptr || movOpc == 0)
505 return;
506
508 MachineInstr *MovMI = nullptr;
509
510 for (unsigned i = 0; i != numSubRegs; ++i) {
511 Register Dst = TRI->getSubReg(DestReg, subRegIdx[i]);
512 Register Src = TRI->getSubReg(SrcReg, subRegIdx[i]);
513 assert(Dst && Src && "Bad sub-register");
514
515 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(movOpc), Dst);
516 if (ExtraG0)
517 MIB.addReg(SP::G0);
518 MIB.addReg(Src);
519 MovMI = MIB.getInstr();
520 }
521 // Add implicit super-register defs and kills to the last MovMI.
522 MovMI->addRegisterDefined(DestReg, TRI);
523 if (KillSrc)
524 MovMI->addRegisterKilled(SrcReg, TRI);
525}
526
529 Register SrcReg, bool isKill, int FI,
530 const TargetRegisterClass *RC,
531 const TargetRegisterInfo *TRI,
532 Register VReg) const {
533 DebugLoc DL;
534 if (I != MBB.end()) DL = I->getDebugLoc();
535
537 const MachineFrameInfo &MFI = MF->getFrameInfo();
540 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
541
542 // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
543 if (RC == &SP::I64RegsRegClass)
544 BuildMI(MBB, I, DL, get(SP::STXri)).addFrameIndex(FI).addImm(0)
545 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
546 else if (RC == &SP::IntRegsRegClass)
547 BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)
548 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
549 else if (RC == &SP::IntPairRegClass)
550 BuildMI(MBB, I, DL, get(SP::STDri)).addFrameIndex(FI).addImm(0)
551 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
552 else if (RC == &SP::FPRegsRegClass)
553 BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)
554 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
555 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
556 BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)
557 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
558 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
559 // Use STQFri irrespective of its legality. If STQ is not legal, it will be
560 // lowered into two STDs in eliminateFrameIndex.
561 BuildMI(MBB, I, DL, get(SP::STQFri)).addFrameIndex(FI).addImm(0)
562 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
563 else
564 llvm_unreachable("Can't store this register to stack slot");
565}
566
569 Register DestReg, int FI,
570 const TargetRegisterClass *RC,
571 const TargetRegisterInfo *TRI,
572 Register VReg) const {
573 DebugLoc DL;
574 if (I != MBB.end()) DL = I->getDebugLoc();
575
577 const MachineFrameInfo &MFI = MF->getFrameInfo();
580 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
581
582 if (RC == &SP::I64RegsRegClass)
583 BuildMI(MBB, I, DL, get(SP::LDXri), DestReg).addFrameIndex(FI).addImm(0)
584 .addMemOperand(MMO);
585 else if (RC == &SP::IntRegsRegClass)
586 BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0)
587 .addMemOperand(MMO);
588 else if (RC == &SP::IntPairRegClass)
589 BuildMI(MBB, I, DL, get(SP::LDDri), DestReg).addFrameIndex(FI).addImm(0)
590 .addMemOperand(MMO);
591 else if (RC == &SP::FPRegsRegClass)
592 BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0)
593 .addMemOperand(MMO);
594 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
595 BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0)
596 .addMemOperand(MMO);
597 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
598 // Use LDQFri irrespective of its legality. If LDQ is not legal, it will be
599 // lowered into two LDDs in eliminateFrameIndex.
600 BuildMI(MBB, I, DL, get(SP::LDQFri), DestReg).addFrameIndex(FI).addImm(0)
601 .addMemOperand(MMO);
602 else
603 llvm_unreachable("Can't load this register from stack slot");
604}
605
608 Register GlobalBaseReg = SparcFI->getGlobalBaseReg();
609 if (GlobalBaseReg)
610 return GlobalBaseReg;
611
612 // Insert the set of GlobalBaseReg into the first MBB of the function
613 MachineBasicBlock &FirstMBB = MF->front();
615 MachineRegisterInfo &RegInfo = MF->getRegInfo();
616
617 const TargetRegisterClass *PtrRC =
618 Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
619 GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);
620
621 DebugLoc dl;
622
623 BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg);
624 SparcFI->setGlobalBaseReg(GlobalBaseReg);
625 return GlobalBaseReg;
626}
627
629 unsigned Opcode = MI.getOpcode();
630
631 if (MI.isInlineAsm()) {
632 const MachineFunction *MF = MI.getParent()->getParent();
633 const char *AsmStr = MI.getOperand(0).getSymbolName();
634 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
635 }
636
637 // If the instruction has a delay slot, be conservative and also include
638 // it for sizing purposes. This is done so that the BranchRelaxation pass
639 // will not mistakenly mark out-of-range branches as in-range.
640 if (MI.hasDelaySlot())
641 return get(Opcode).getSize() * 2;
642 return get(Opcode).getSize();
643}
644
646 switch (MI.getOpcode()) {
647 case TargetOpcode::LOAD_STACK_GUARD: {
648 assert(Subtarget.isTargetLinux() &&
649 "Only Linux target is expected to contain LOAD_STACK_GUARD");
650 // offsetof(tcbhead_t, stack_guard) from sysdeps/sparc/nptl/tls.h in glibc.
651 const int64_t Offset = Subtarget.is64Bit() ? 0x28 : 0x14;
652 MI.setDesc(get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri));
653 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
654 .addReg(SP::G7)
655 .addImm(Offset);
656 return true;
657 }
658 }
659 return false;
660}
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file contains some templates that are useful if you are working with the STL at all.
This file defines the SmallVector class.
static bool isFCondBranchOpcode(int Opc)
static bool isRegCondBranchOpcode(int Opc)
static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
static cl::opt< unsigned > BPrDisplacementBits("sparc-bpr-offset-bits", cl::Hidden, cl::init(16), cl::desc("Restrict range of BPr instructions (DEBUG)"))
static bool isI32CondBranchOpcode(int Opc)
static cl::opt< unsigned > BPccDisplacementBits("sparc-bpcc-offset-bits", cl::Hidden, cl::init(19), cl::desc("Restrict range of BPcc/FBPfcc instructions (DEBUG)"))
static bool isI64CondBranchOpcode(int Opc)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition: Value.cpp:469
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
A debug info location.
Definition: DebugLoc.h:33
Wrapper class representing physical registers. Should be passed by value.
Definition: MCRegister.h:33
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Align getObjectAlign(int ObjectIdx) const
Return the alignment of the specified stack object.
int64_t getObjectSize(int ObjectIdx) const
Return the size of the specified object.
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags f, LLT MemTy, Align base_alignment, const AAMDNodes &AAInfo=AAMDNodes(), const MDNode *Ranges=nullptr, SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const LLVMTargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMemOperand(MachineMemOperand *MMO) const
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
Definition: MachineInstr.h:69
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
Definition: MachineInstr.h:569
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
void addRegisterDefined(Register Reg, const TargetRegisterInfo *RegInfo=nullptr)
We have determined MI defines a register.
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:579
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
int64_t getImm() const
MachineBasicBlock * getMBB() const
static MachineOperand CreateImm(int64_t Val)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateReg(Register Reg, bool isDef, bool isImp=false, bool isKill=false, bool isDead=false, bool isUndef=false, bool isEarlyClobber=false, unsigned SubReg=0, bool isDebug=false, bool isInternalRead=false, bool isRenamable=false)
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: SmallVector.h:586
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
Register isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot,...
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t Offset) const override
Determine if the branch target is in range.
SparcInstrInfo(SparcSubtarget &ST)
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Register getGlobalBaseReg(MachineFunction *MF) const
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI, Register VReg) const override
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, MCRegister DestReg, MCRegister SrcReg, bool KillSrc) const override
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
MachineBasicBlock * getBranchDestBlock(const MachineInstr &MI) const override
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify=false) const override
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot,...
const SparcRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
unsigned getInstSizeInBytes(const MachineInstr &MI) const override
GetInstSize - Return the number of bytes of code the specified instruction may be.
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
bool expandPostRAPseudo(MachineInstr &MI) const override
bool isTargetLinux() const
bool is64Bit() const
const MCAsmInfo * getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
CondCodes
Definition: Sparc.h:42
@ CPCC_03
Definition: Sparc.h:89
@ CPCC_013
Definition: Sparc.h:93
@ FCC_ULE
Definition: Sparc.h:75
@ ICC_POS
Definition: Sparc.h:55
@ FCC_UG
Definition: Sparc.h:65
@ ICC_N
Definition: Sparc.h:44
@ CPCC_123
Definition: Sparc.h:87
@ ICC_G
Definition: Sparc.h:47
@ REG_LEZ
Definition: Sparc.h:98
@ CPCC_23
Definition: Sparc.h:83
@ REG_GZ
Definition: Sparc.h:101
@ ICC_L
Definition: Sparc.h:50
@ REG_BEGIN
Definition: Sparc.h:96
@ FCC_NE
Definition: Sparc.h:69
@ CPCC_01
Definition: Sparc.h:92
@ CPCC_12
Definition: Sparc.h:86
@ ICC_CS
Definition: Sparc.h:54
@ FCC_LG
Definition: Sparc.h:68
@ ICC_VS
Definition: Sparc.h:58
@ CPCC_1
Definition: Sparc.h:84
@ ICC_LEU
Definition: Sparc.h:52
@ CPCC_A
Definition: Sparc.h:79
@ CPCC_0
Definition: Sparc.h:88
@ FCC_LE
Definition: Sparc.h:74
@ CPCC_012
Definition: Sparc.h:94
@ ICC_LE
Definition: Sparc.h:48
@ FCC_U
Definition: Sparc.h:63
@ CPCC_2
Definition: Sparc.h:82
@ FCC_A
Definition: Sparc.h:61
@ CPCC_023
Definition: Sparc.h:91
@ CPCC_13
Definition: Sparc.h:85
@ ICC_GE
Definition: Sparc.h:49
@ FCC_E
Definition: Sparc.h:70
@ CPCC_02
Definition: Sparc.h:90
@ REG_LZ
Definition: Sparc.h:99
@ FCC_L
Definition: Sparc.h:66
@ ICC_GU
Definition: Sparc.h:51
@ FCC_O
Definition: Sparc.h:76
@ ICC_NE
Definition: Sparc.h:45
@ FCC_UE
Definition: Sparc.h:71
@ REG_NZ
Definition: Sparc.h:100
@ ICC_E
Definition: Sparc.h:46
@ FCC_GE
Definition: Sparc.h:72
@ ICC_A
Definition: Sparc.h:43
@ CPCC_3
Definition: Sparc.h:81
@ FCC_UGE
Definition: Sparc.h:73
@ REG_Z
Definition: Sparc.h:97
@ ICC_VC
Definition: Sparc.h:57
@ ICC_CC
Definition: Sparc.h:53
@ REG_GEZ
Definition: Sparc.h:102
@ CPCC_N
Definition: Sparc.h:80
@ FCC_G
Definition: Sparc.h:64
@ FCC_UL
Definition: Sparc.h:67
@ FCC_N
Definition: Sparc.h:62
@ ICC_NEG
Definition: Sparc.h:56
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:443
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:480
static bool isCondBranchOpcode(int Opc)
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
static bool isIndirectBranchOpcode(int Opc)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
unsigned getKillRegState(bool B)
bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition: MathExtras.h:260
static bool isUncondBranchOpcode(int Opc)
static MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.