LLVM 24.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"
23
24using namespace llvm;
25
26#define GET_INSTRINFO_CTOR_DTOR
27#include "SparcGenInstrInfo.inc"
28
29// Pin the vtable to this file.
30void SparcInstrInfo::anchor() {}
31
33 : SparcGenInstrInfo(ST, RI, SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP),
34 RI(ST), Subtarget(ST) {}
35
38 return Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
39}
40
41/// isLoadFromStackSlot - If the specified machine instruction is a direct
42/// load from a stack slot, return the virtual or physical register number of
43/// the destination along with the FrameIndex of the loaded stack slot. If
44/// not, return 0. This predicate must return 0 if the instruction has
45/// any side effects other than loading from the stack slot.
47 int &FrameIndex,
48 TypeSize &MemBytes) const {
49 switch (MI.getOpcode()) {
50 default:
51 return 0;
52 case SP::LDri:
53 MemBytes = TypeSize::getFixed(4);
54 break;
55 case SP::LDXri:
56 MemBytes = TypeSize::getFixed(8);
57 break;
58 case SP::LDFri:
59 MemBytes = TypeSize::getFixed(4);
60 break;
61 case SP::LDDFri:
62 MemBytes = TypeSize::getFixed(8);
63 break;
64 case SP::LDQFri:
65 MemBytes = TypeSize::getFixed(16);
66 break;
67 }
68 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
69 MI.getOperand(2).getImm() == 0) {
70 FrameIndex = MI.getOperand(1).getIndex();
71 return MI.getOperand(0).getReg();
72 }
73 return 0;
74}
75
76/// isStoreToStackSlot - If the specified machine instruction is a direct
77/// store to a stack slot, return the virtual or physical register number of
78/// the source reg along with the FrameIndex of the loaded stack slot. If
79/// not, return 0. This predicate must return 0 if the instruction has
80/// any side effects other than storing to the stack slot.
82 int &FrameIndex,
83 TypeSize &MemBytes) const {
84 switch (MI.getOpcode()) {
85 default:
86 return 0;
87 case SP::STri:
88 MemBytes = TypeSize::getFixed(4);
89 break;
90 case SP::STXri:
91 MemBytes = TypeSize::getFixed(8);
92 break;
93 case SP::STFri:
94 MemBytes = TypeSize::getFixed(4);
95 break;
96 case SP::STDFri:
97 MemBytes = TypeSize::getFixed(8);
98 break;
99 case SP::STQFri:
100 MemBytes = TypeSize::getFixed(16);
101 break;
102 }
103 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
104 MI.getOperand(1).getImm() == 0) {
105 FrameIndex = MI.getOperand(0).getIndex();
106 return MI.getOperand(2).getReg();
107 }
108 return 0;
109}
110
112{
113 switch(CC) {
114 case SPCC::ICC_A: return SPCC::ICC_N;
115 case SPCC::ICC_N: return SPCC::ICC_A;
116 case SPCC::ICC_NE: return SPCC::ICC_E;
117 case SPCC::ICC_E: return SPCC::ICC_NE;
118 case SPCC::ICC_G: return SPCC::ICC_LE;
119 case SPCC::ICC_LE: return SPCC::ICC_G;
120 case SPCC::ICC_GE: return SPCC::ICC_L;
121 case SPCC::ICC_L: return SPCC::ICC_GE;
122 case SPCC::ICC_GU: return SPCC::ICC_LEU;
123 case SPCC::ICC_LEU: return SPCC::ICC_GU;
124 case SPCC::ICC_CC: return SPCC::ICC_CS;
125 case SPCC::ICC_CS: return SPCC::ICC_CC;
126 case SPCC::ICC_POS: return SPCC::ICC_NEG;
127 case SPCC::ICC_NEG: return SPCC::ICC_POS;
128 case SPCC::ICC_VC: return SPCC::ICC_VS;
129 case SPCC::ICC_VS: return SPCC::ICC_VC;
130
131 case SPCC::FCC_A: return SPCC::FCC_N;
132 case SPCC::FCC_N: return SPCC::FCC_A;
133 case SPCC::FCC_U: return SPCC::FCC_O;
134 case SPCC::FCC_O: return SPCC::FCC_U;
135 case SPCC::FCC_G: return SPCC::FCC_ULE;
136 case SPCC::FCC_LE: return SPCC::FCC_UG;
137 case SPCC::FCC_UG: return SPCC::FCC_LE;
138 case SPCC::FCC_ULE: return SPCC::FCC_G;
139 case SPCC::FCC_L: return SPCC::FCC_UGE;
140 case SPCC::FCC_GE: return SPCC::FCC_UL;
141 case SPCC::FCC_UL: return SPCC::FCC_GE;
142 case SPCC::FCC_UGE: return SPCC::FCC_L;
143 case SPCC::FCC_LG: return SPCC::FCC_UE;
144 case SPCC::FCC_UE: return SPCC::FCC_LG;
145 case SPCC::FCC_NE: return SPCC::FCC_E;
146 case SPCC::FCC_E: return SPCC::FCC_NE;
147
148 case SPCC::CPCC_A: return SPCC::CPCC_N;
149 case SPCC::CPCC_N: return SPCC::CPCC_A;
150 case SPCC::CPCC_3: [[fallthrough]];
151 case SPCC::CPCC_2: [[fallthrough]];
152 case SPCC::CPCC_23: [[fallthrough]];
153 case SPCC::CPCC_1: [[fallthrough]];
154 case SPCC::CPCC_13: [[fallthrough]];
155 case SPCC::CPCC_12: [[fallthrough]];
156 case SPCC::CPCC_123: [[fallthrough]];
157 case SPCC::CPCC_0: [[fallthrough]];
158 case SPCC::CPCC_03: [[fallthrough]];
159 case SPCC::CPCC_02: [[fallthrough]];
160 case SPCC::CPCC_023: [[fallthrough]];
161 case SPCC::CPCC_01: [[fallthrough]];
162 case SPCC::CPCC_013: [[fallthrough]];
163 case SPCC::CPCC_012:
164 // "Opposite" code is not meaningful, as we don't know
165 // what the CoProc condition means here. The cond-code will
166 // only be used in inline assembler, so this code should
167 // not be reached in a normal compilation pass.
168 llvm_unreachable("Meaningless inversion of co-processor cond code");
169
170 case SPCC::REG_BEGIN:
171 llvm_unreachable("Use of reserved cond code");
172 case SPCC::REG_Z:
173 return SPCC::REG_NZ;
174 case SPCC::REG_LEZ:
175 return SPCC::REG_GZ;
176 case SPCC::REG_LZ:
177 return SPCC::REG_GEZ;
178 case SPCC::REG_NZ:
179 return SPCC::REG_Z;
180 case SPCC::REG_GZ:
181 return SPCC::REG_LEZ;
182 case SPCC::REG_GEZ:
183 return SPCC::REG_LZ;
184 }
185 llvm_unreachable("Invalid cond code");
186}
187
188static bool isUncondBranchOpcode(int Opc) { return Opc == SP::BA; }
189
190static bool isI32CondBranchOpcode(int Opc) {
191 return Opc == SP::BCOND || Opc == SP::BPICC || Opc == SP::BPICCA ||
192 Opc == SP::BPICCNT || Opc == SP::BPICCANT;
193}
194
195static bool isI64CondBranchOpcode(int Opc) {
196 return Opc == SP::BPXCC || Opc == SP::BPXCCA || Opc == SP::BPXCCNT ||
197 Opc == SP::BPXCCANT;
198}
199
200static bool isRegCondBranchOpcode(int Opc) {
201 return Opc == SP::BPR || Opc == SP::BPRA || Opc == SP::BPRNT ||
202 Opc == SP::BPRANT;
203}
204
205static bool isFCondBranchOpcode(int Opc) {
206 return Opc == SP::FBCOND || Opc == SP::FBCONDA || Opc == SP::FBCOND_V9 ||
207 Opc == SP::FBCONDA_V9;
208}
209
214
215static bool isIndirectBranchOpcode(int Opc) {
216 return Opc == SP::BINDrr || Opc == SP::BINDri;
217}
218
221 unsigned Opc = LastInst->getOpcode();
222 int64_t CC = LastInst->getOperand(1).getImm();
223
224 // Push the branch opcode into Cond too so later in insertBranch
225 // it can use the information to emit the correct SPARC branch opcode.
227 Cond.push_back(MachineOperand::CreateImm(CC));
228
229 // Branch on register contents need another argument to indicate
230 // the register it branches on.
232 Register Reg = LastInst->getOperand(2).getReg();
233 Cond.push_back(MachineOperand::CreateReg(Reg, false));
234 }
235
236 Target = LastInst->getOperand(0).getMBB();
237}
238
241 switch (MI.getOpcode()) {
242 default:
243 llvm_unreachable("unexpected opcode!");
244 case SP::BA:
245 case SP::BCOND:
246 case SP::BCONDA:
247 case SP::FBCOND:
248 case SP::FBCONDA:
249 case SP::BPICC:
250 case SP::BPICCA:
251 case SP::BPICCNT:
252 case SP::BPICCANT:
253 case SP::BPXCC:
254 case SP::BPXCCA:
255 case SP::BPXCCNT:
256 case SP::BPXCCANT:
257 case SP::BPFCC:
258 case SP::BPFCCA:
259 case SP::BPFCCNT:
260 case SP::BPFCCANT:
261 case SP::FBCOND_V9:
262 case SP::FBCONDA_V9:
263 case SP::BPR:
264 case SP::BPRA:
265 case SP::BPRNT:
266 case SP::BPRANT:
267 return MI.getOperand(0).getMBB();
268 }
269}
270
273 MachineBasicBlock *&FBB,
275 bool AllowModify) const {
276 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
277 if (I == MBB.end())
278 return false;
279
280 if (!isUnpredicatedTerminator(*I))
281 return false;
282
283 // Get the last instruction in the block.
284 MachineInstr *LastInst = &*I;
285 unsigned LastOpc = LastInst->getOpcode();
286
287 // If there is only one terminator instruction, process it.
288 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
289 if (isUncondBranchOpcode(LastOpc)) {
290 TBB = LastInst->getOperand(0).getMBB();
291 return false;
292 }
293 if (isCondBranchOpcode(LastOpc)) {
294 // Block ends with fall-through condbranch.
295 parseCondBranch(LastInst, TBB, Cond);
296 return false;
297 }
298 return true; // Can't handle indirect branch.
299 }
300
301 // Get the instruction before it if it is a terminator.
302 MachineInstr *SecondLastInst = &*I;
303 unsigned SecondLastOpc = SecondLastInst->getOpcode();
304
305 // If AllowModify is true and the block ends with two or more unconditional
306 // branches, delete all but the first unconditional branch.
307 if (AllowModify && isUncondBranchOpcode(LastOpc)) {
308 while (isUncondBranchOpcode(SecondLastOpc)) {
309 LastInst->eraseFromParent();
310 LastInst = SecondLastInst;
311 LastOpc = LastInst->getOpcode();
312 if (I == MBB.begin() || !isUnpredicatedTerminator(*--I)) {
313 // Return now the only terminator is an unconditional branch.
314 TBB = LastInst->getOperand(0).getMBB();
315 return false;
316 } else {
317 SecondLastInst = &*I;
318 SecondLastOpc = SecondLastInst->getOpcode();
319 }
320 }
321 }
322
323 // If there are three terminators, we don't know what sort of block this is.
324 if (SecondLastInst && I != MBB.begin() && isUnpredicatedTerminator(*--I))
325 return true;
326
327 // If the block ends with a B and a Bcc, handle it.
328 if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
329 parseCondBranch(SecondLastInst, TBB, Cond);
330 FBB = LastInst->getOperand(0).getMBB();
331 return false;
332 }
333
334 // If the block ends with two unconditional branches, handle it. The second
335 // one is not executed.
336 if (isUncondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
337 TBB = SecondLastInst->getOperand(0).getMBB();
338 return false;
339 }
340
341 // ...likewise if it ends with an indirect branch followed by an unconditional
342 // branch.
343 if (isIndirectBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
344 I = LastInst;
345 if (AllowModify)
346 I->eraseFromParent();
347 return true;
348 }
349
350 // Otherwise, can't handle this.
351 return true;
352}
353
358 const DebugLoc &DL,
359 int *BytesAdded) const {
360 assert(TBB && "insertBranch must not be told to insert a fallthrough");
361 assert((Cond.size() <= 3) &&
362 "Sparc branch conditions should have at most three components!");
363
364 if (Cond.empty()) {
365 assert(!FBB && "Unconditional branch with multiple successors!");
366 BuildMI(&MBB, DL, get(SP::BA)).addMBB(TBB);
367 if (BytesAdded)
368 *BytesAdded = 8;
369 return 1;
370 }
371
372 // Conditional branch
373 unsigned Opc = Cond[0].getImm();
374 unsigned CC = Cond[1].getImm();
376 Register Reg = Cond[2].getReg();
377 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC).addReg(Reg);
378 } else {
379 BuildMI(&MBB, DL, get(Opc)).addMBB(TBB).addImm(CC);
380 }
381
382 if (!FBB) {
383 if (BytesAdded)
384 *BytesAdded = 8;
385 return 1;
386 }
387
388 BuildMI(&MBB, DL, get(SP::BA)).addMBB(FBB);
389 if (BytesAdded)
390 *BytesAdded = 16;
391 return 2;
392}
393
395 int *BytesRemoved) const {
397 unsigned Count = 0;
398 int Removed = 0;
399 while (I != MBB.begin()) {
400 --I;
401
402 if (I->isDebugInstr())
403 continue;
404
405 if (!isCondBranchOpcode(I->getOpcode()) &&
406 !isUncondBranchOpcode(I->getOpcode()))
407 break; // Not a branch
408
409 Removed += getInstSizeInBytes(*I);
410 I->eraseFromParent();
411 I = MBB.end();
412 ++Count;
413 }
414
415 if (BytesRemoved)
416 *BytesRemoved = Removed;
417 return Count;
418}
419
422 assert(Cond.size() <= 3);
423 SPCC::CondCodes CC = static_cast<SPCC::CondCodes>(Cond[1].getImm());
424 Cond[1].setImm(GetOppositeBranchCondition(CC));
425 return false;
426}
427
429 int64_t Offset) const {
430 assert((Offset & 0b11) == 0 && "Malformed branch offset");
431 switch (BranchOpc) {
432 case SP::BA:
433 case SP::BCOND:
434 case SP::BCONDA:
435 case SP::FBCOND:
436 case SP::FBCONDA:
437 return isIntN(22, Offset >> 2);
438
439 case SP::BPICC:
440 case SP::BPICCA:
441 case SP::BPICCNT:
442 case SP::BPICCANT:
443 case SP::BPXCC:
444 case SP::BPXCCA:
445 case SP::BPXCCNT:
446 case SP::BPXCCANT:
447 case SP::BPFCC:
448 case SP::BPFCCA:
449 case SP::BPFCCNT:
450 case SP::BPFCCANT:
451 case SP::FBCOND_V9:
452 case SP::FBCONDA_V9:
453 return isIntN(Subtarget.getCLOpts().bpcc_offset_bits, Offset >> 2);
454
455 case SP::BPR:
456 case SP::BPRA:
457 case SP::BPRNT:
458 case SP::BPRANT:
459 return isIntN(Subtarget.getCLOpts().bpr_offset_bits, Offset >> 2);
460 }
461
462 llvm_unreachable("Unknown branch instruction!");
463}
464
467 const DebugLoc &DL, Register DestReg,
468 Register SrcReg, bool KillSrc,
469 bool RenamableDest, bool RenamableSrc) const {
470 unsigned numSubRegs = 0;
471 unsigned movOpc = 0;
472 const unsigned *subRegIdx = nullptr;
473 bool ExtraG0 = false;
474
475 const unsigned DW_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
476 const unsigned DFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd };
477 const unsigned QFP_DFP_SubRegsIdx[] = { SP::sub_even64, SP::sub_odd64 };
478 const unsigned QFP_FP_SubRegsIdx[] = { SP::sub_even, SP::sub_odd,
479 SP::sub_odd64_then_sub_even,
480 SP::sub_odd64_then_sub_odd };
481
482 if (SP::IntRegsRegClass.contains(DestReg, SrcReg))
483 BuildMI(MBB, I, DL, get(SP::ORrr), DestReg).addReg(SP::G0)
484 .addReg(SrcReg, getKillRegState(KillSrc));
485 else if (SP::IntPairRegClass.contains(DestReg, SrcReg)) {
486 subRegIdx = DW_SubRegsIdx;
487 numSubRegs = 2;
488 movOpc = SP::ORrr;
489 ExtraG0 = true;
490 } else if (SP::FPRegsRegClass.contains(DestReg, SrcReg))
491 BuildMI(MBB, I, DL, get(SP::FMOVS), DestReg)
492 .addReg(SrcReg, getKillRegState(KillSrc));
493 else if (SP::DFPRegsRegClass.contains(DestReg, SrcReg)) {
494 if (Subtarget.isV9()) {
495 BuildMI(MBB, I, DL, get(SP::FMOVD), DestReg)
496 .addReg(SrcReg, getKillRegState(KillSrc));
497 } else {
498 // Use two FMOVS instructions.
499 subRegIdx = DFP_FP_SubRegsIdx;
500 numSubRegs = 2;
501 movOpc = SP::FMOVS;
502 }
503 } else if (SP::QFPRegsRegClass.contains(DestReg, SrcReg)) {
504 if (Subtarget.isV9()) {
505 if (Subtarget.hasHardQuad()) {
506 BuildMI(MBB, I, DL, get(SP::FMOVQ), DestReg)
507 .addReg(SrcReg, getKillRegState(KillSrc));
508 } else {
509 // Use two FMOVD instructions.
510 subRegIdx = QFP_DFP_SubRegsIdx;
511 numSubRegs = 2;
512 movOpc = SP::FMOVD;
513 }
514 } else {
515 // Use four FMOVS instructions.
516 subRegIdx = QFP_FP_SubRegsIdx;
517 numSubRegs = 4;
518 movOpc = SP::FMOVS;
519 }
520 } else if (SP::ASRRegsRegClass.contains(DestReg) &&
521 SP::IntRegsRegClass.contains(SrcReg)) {
522 BuildMI(MBB, I, DL, get(SP::WRASRrr), DestReg)
523 .addReg(SP::G0)
524 .addReg(SrcReg, getKillRegState(KillSrc));
525 } else if (SP::IntRegsRegClass.contains(DestReg) &&
526 SP::ASRRegsRegClass.contains(SrcReg)) {
527 BuildMI(MBB, I, DL, get(SP::RDASR), DestReg)
528 .addReg(SrcReg, getKillRegState(KillSrc));
529 } else
530 llvm_unreachable("Impossible reg-to-reg copy");
531
532 if (numSubRegs == 0 || subRegIdx == nullptr || movOpc == 0)
533 return;
534
536 MachineInstr *MovMI = nullptr;
537
538 for (unsigned i = 0; i != numSubRegs; ++i) {
539 Register Dst = TRI->getSubReg(DestReg, subRegIdx[i]);
540 Register Src = TRI->getSubReg(SrcReg, subRegIdx[i]);
541 assert(Dst && Src && "Bad sub-register");
542
543 MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(movOpc), Dst);
544 if (ExtraG0)
545 MIB.addReg(SP::G0);
546 MIB.addReg(Src);
547 MovMI = MIB.getInstr();
548 }
549 // Add implicit super-register defs and kills to the last MovMI.
550 MovMI->addRegisterDefined(DestReg, TRI);
551 if (KillSrc)
552 MovMI->addRegisterKilled(SrcReg, TRI);
553}
554
557 Register SrcReg, bool isKill, int FI,
558 const TargetRegisterClass *RC,
559 Register VReg,
560 MachineInstr::MIFlag Flags) const {
561 DebugLoc DL;
562 if (I != MBB.end()) DL = I->getDebugLoc();
563
564 MachineFunction *MF = MBB.getParent();
565 const MachineFrameInfo &MFI = MF->getFrameInfo();
568 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
569
570 // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
571 if (RC == &SP::I64RegsRegClass)
572 BuildMI(MBB, I, DL, get(SP::STXri)).addFrameIndex(FI).addImm(0)
573 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
574 else if (RC == &SP::IntRegsRegClass)
575 BuildMI(MBB, I, DL, get(SP::STri)).addFrameIndex(FI).addImm(0)
576 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
577 else if (RC == &SP::IntPairRegClass)
578 BuildMI(MBB, I, DL, get(SP::STDri)).addFrameIndex(FI).addImm(0)
579 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
580 else if (RC == &SP::FPRegsRegClass)
581 BuildMI(MBB, I, DL, get(SP::STFri)).addFrameIndex(FI).addImm(0)
582 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
583 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
584 BuildMI(MBB, I, DL, get(SP::STDFri)).addFrameIndex(FI).addImm(0)
585 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
586 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
587 // Use STQFri irrespective of its legality. If STQ is not legal, it will be
588 // lowered into two STDs in eliminateFrameIndex.
589 BuildMI(MBB, I, DL, get(SP::STQFri)).addFrameIndex(FI).addImm(0)
590 .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
591 else
592 llvm_unreachable("Can't store this register to stack slot");
593}
594
597 Register DestReg, int FI,
598 const TargetRegisterClass *RC,
599 Register VReg, unsigned SubReg,
600 MachineInstr::MIFlag Flags) const {
601 DebugLoc DL;
602 if (I != MBB.end()) DL = I->getDebugLoc();
603
604 MachineFunction *MF = MBB.getParent();
605 const MachineFrameInfo &MFI = MF->getFrameInfo();
608 MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
609
610 if (RC == &SP::I64RegsRegClass)
611 BuildMI(MBB, I, DL, get(SP::LDXri), DestReg).addFrameIndex(FI).addImm(0)
612 .addMemOperand(MMO);
613 else if (RC == &SP::IntRegsRegClass)
614 BuildMI(MBB, I, DL, get(SP::LDri), DestReg).addFrameIndex(FI).addImm(0)
615 .addMemOperand(MMO);
616 else if (RC == &SP::IntPairRegClass)
617 BuildMI(MBB, I, DL, get(SP::LDDri), DestReg).addFrameIndex(FI).addImm(0)
618 .addMemOperand(MMO);
619 else if (RC == &SP::FPRegsRegClass)
620 BuildMI(MBB, I, DL, get(SP::LDFri), DestReg).addFrameIndex(FI).addImm(0)
621 .addMemOperand(MMO);
622 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
623 BuildMI(MBB, I, DL, get(SP::LDDFri), DestReg).addFrameIndex(FI).addImm(0)
624 .addMemOperand(MMO);
625 else if (SP::QFPRegsRegClass.hasSubClassEq(RC))
626 // Use LDQFri irrespective of its legality. If LDQ is not legal, it will be
627 // lowered into two LDDs in eliminateFrameIndex.
628 BuildMI(MBB, I, DL, get(SP::LDQFri), DestReg).addFrameIndex(FI).addImm(0)
629 .addMemOperand(MMO);
630 else
631 llvm_unreachable("Can't load this register from stack slot");
632}
633
636 Register GlobalBaseReg = SparcFI->getGlobalBaseReg();
637 if (GlobalBaseReg)
638 return GlobalBaseReg;
639
640 // Insert the set of GlobalBaseReg into the first MBB of the function
641 MachineBasicBlock &FirstMBB = MF->front();
643 MachineRegisterInfo &RegInfo = MF->getRegInfo();
644
645 const TargetRegisterClass *PtrRC =
646 Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
647 GlobalBaseReg = RegInfo.createVirtualRegister(PtrRC);
648
649 DebugLoc dl;
650
651 BuildMI(FirstMBB, MBBI, dl, get(SP::GETPCX), GlobalBaseReg)
652 .setOperandDead(1); // implicit-def $o7
653 SparcFI->setGlobalBaseReg(GlobalBaseReg);
654 return GlobalBaseReg;
655}
656
658 unsigned &StructSize) const {
659 if (!MI.isCall())
660 return false;
661
662 unsigned StructSizeOpNum = 0;
663 switch (MI.getOpcode()) {
664 default:
665 llvm_unreachable("Unknown call opcode.");
666 case SP::CALL:
667 StructSizeOpNum = 1;
668 break;
669 case SP::CALLrr:
670 case SP::CALLri:
671 StructSizeOpNum = 2;
672 break;
673 case SP::TLS_CALL:
674 return false;
675 case SP::TAIL_CALLri:
676 case SP::TAIL_CALL:
677 return false;
678 }
679
680 const MachineOperand &MO = MI.getOperand(StructSizeOpNum);
681 if (!MO.isImm())
682 return false;
683
684 // A zero-sized return value has nothing for the callee to copy, so GCC emits
685 // no unimp for it and returns to the instruction right after the delay slot.
686 // We replicate this behavior here.
687 StructSize = MO.getImm();
688 return StructSize != 0;
689}
690
692 unsigned Opcode = MI.getOpcode();
693
694 if (MI.isInlineAsm()) {
695 const MachineFunction *MF = MI.getParent()->getParent();
696 const char *AsmStr = MI.getOperand(0).getSymbolName();
697 return getInlineAsmLength(AsmStr, MF->getTarget().getMCAsmInfo());
698 }
699
700 if (Opcode == TargetOpcode::BUNDLE)
701 return getInstBundleSize(MI);
702
703 if (MI.getOpcode() == SP::GETPCX) {
704 const TargetMachine &TM = MI.getParent()->getParent()->getTarget();
705 if (TM.isPositionIndependent())
706 return 16;
707 switch (TM.getCodeModel()) {
708 default:
709 llvm_unreachable("Unsupported absolute code model");
710 case CodeModel::Small:
711 return 8;
713 return 16;
714 case CodeModel::Large:
715 return 24;
716 }
717 }
718
719 // If the instruction has a delay slot, be conservative and also include
720 // it for sizing purposes. This is done so that the BranchRelaxation pass
721 // will not mistakenly mark out-of-range branches as in-range.
722 if (MI.hasDelaySlot()) {
723 unsigned StructSize = 0;
724 return get(Opcode).getSize() * (2 + needsUnimp(MI, StructSize));
725 }
726 return get(Opcode).getSize();
727}
728
730 Register &SrcReg2, int64_t &CmpMask,
731 int64_t &CmpValue) const {
732 Register DstReg;
733 switch (MI.getOpcode()) {
734 default:
735 break;
736 case SP::SUBCCri:
737 DstReg = MI.getOperand(0).getReg();
738 SrcReg = MI.getOperand(1).getReg();
739 SrcReg2 = 0;
740 CmpMask = ~0;
741 CmpValue = MI.getOperand(2).getImm();
742 return DstReg == SP::G0 && CmpValue == 0;
743 case SP::SUBCCrr:
744 DstReg = MI.getOperand(0).getReg();
745 SrcReg = MI.getOperand(1).getReg();
746 SrcReg2 = MI.getOperand(2).getReg();
747 CmpMask = ~0;
748 CmpValue = 0;
749 return DstReg == SP::G0 && SrcReg2 == SP::G0;
750 }
751
752 return false;
753}
754
756 MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask,
757 int64_t CmpValue, const MachineRegisterInfo *MRI) const {
758
759 // Get the unique definition of SrcReg.
760 MachineInstr *MI = MRI->getUniqueVRegDef(SrcReg);
761 if (!MI)
762 return false;
763
764 // Only optimize if defining and comparing instruction in same block.
765 if (MI->getParent() != CmpInstr.getParent())
766 return false;
767
768 unsigned NewOpcode;
769 switch (MI->getOpcode()) {
770 case SP::ANDNrr:
771 NewOpcode = SP::ANDNCCrr;
772 break;
773 case SP::ANDNri:
774 NewOpcode = SP::ANDNCCri;
775 break;
776 case SP::ANDrr:
777 NewOpcode = SP::ANDCCrr;
778 break;
779 case SP::ANDri:
780 NewOpcode = SP::ANDCCri;
781 break;
782 case SP::ORrr:
783 NewOpcode = SP::ORCCrr;
784 break;
785 case SP::ORri:
786 NewOpcode = SP::ORCCri;
787 break;
788 case SP::ORNCCrr:
789 NewOpcode = SP::ORNCCrr;
790 break;
791 case SP::ORNri:
792 NewOpcode = SP::ORNCCri;
793 break;
794 case SP::XORrr:
795 NewOpcode = SP::XORCCrr;
796 break;
797 case SP::XNORri:
798 NewOpcode = SP::XNORCCri;
799 break;
800 case SP::XNORrr:
801 NewOpcode = SP::XNORCCrr;
802 break;
803 case SP::ADDrr:
804 NewOpcode = SP::ADDCCrr;
805 break;
806 case SP::ADDri:
807 NewOpcode = SP::ADDCCri;
808 break;
809 case SP::SUBrr:
810 NewOpcode = SP::SUBCCrr;
811 break;
812 case SP::SUBri:
813 NewOpcode = SP::SUBCCri;
814 break;
815 default:
816 return false;
817 }
818
819 bool IsICCModified = false;
822 MachineBasicBlock::iterator E = CmpInstr.getParent()->end();
824
825 // If ICC is used or modified between MI and CmpInstr we cannot optimize.
826 while (++I != C) {
827 if (I->modifiesRegister(SP::ICC, TRI) || I->readsRegister(SP::ICC, TRI))
828 return false;
829 }
830
831 while (++I != E) {
832 // Only allow conditionals on equality.
833 if (I->readsRegister(SP::ICC, TRI)) {
834 bool IsICCBranch = I->getOpcode() == SP::BCOND ||
835 I->getOpcode() == SP::BPICC ||
836 I->getOpcode() == SP::BPXCC;
837 bool IsICCMove =
838 I->getOpcode() == SP::MOVICCrr || I->getOpcode() == SP::MOVICCri ||
839 I->getOpcode() == SP::MOVXCCrr || I->getOpcode() == SP::MOVXCCri;
840 bool IsICCConditional = IsICCBranch || IsICCMove;
841 if (!IsICCConditional ||
842 (I->getOperand(IsICCBranch ? 1 : 3).getImm() != SPCC::ICC_E &&
843 I->getOperand(IsICCBranch ? 1 : 3).getImm() != SPCC::ICC_NE))
844 return false;
845 } else if (I->modifiesRegister(SP::ICC, TRI)) {
846 IsICCModified = true;
847 break;
848 }
849 }
850
851 if (!IsICCModified) {
852 MachineBasicBlock *MBB = CmpInstr.getParent();
853 if (any_of(MBB->successors(),
854 [](MachineBasicBlock *Succ) { return Succ->isLiveIn(SP::ICC); }))
855 return false;
856 }
857
858 if (MRI->hasOneNonDBGUse(SrcReg))
859 MI->getOperand(0).setReg(SP::G0);
860
861 MI->setDesc(get(NewOpcode));
862 MI->addRegisterDefined(SP::ICC);
863 CmpInstr.eraseFromParent();
864
865 return true;
866}
867
869 switch (MI.getOpcode()) {
870 case TargetOpcode::LOAD_STACK_GUARD: {
871 assert(Subtarget.getTargetTriple().isOSLinux() &&
872 "Only Linux target is expected to contain LOAD_STACK_GUARD");
873 // offsetof(tcbhead_t, stack_guard) from sysdeps/sparc/nptl/tls.h in glibc.
874 const int64_t Offset = Subtarget.is64Bit() ? 0x28 : 0x14;
875 MI.setDesc(get(Subtarget.is64Bit() ? SP::LDXri : SP::LDri));
876 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
877 .addReg(SP::G7)
878 .addImm(Offset);
879 return true;
880 }
881 case SP::V8BAR: {
882 assert(!Subtarget.isV9() &&
883 "V8BAR should not be emitted on V9 processors!");
884
885 // Emit stbar; ldstub [%sp-1], %g0
886 // The sequence acts as a full barrier on V8 systems.
887 MachineBasicBlock &MBB = *MI.getParent();
888 MachineInstr &InstSTBAR =
889 *BuildMI(MBB, MI, MI.getDebugLoc(), get(SP::STBAR));
890 MachineInstr &InstLDSTUB =
891 *BuildMI(MBB, MI, MI.getDebugLoc(), get(SP::LDSTUBri), SP::G0)
892 .addReg(SP::O6)
893 .addImm(-1);
894 MIBundleBuilder(MBB, InstSTBAR, InstLDSTUB);
895 MBB.erase(MI);
896 return true;
897 }
898 }
899 return false;
900}
static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target, SmallVectorImpl< MachineOperand > &Cond)
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock & MBB
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
IRTranslator LLVM IR MI
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
Definition Value.cpp:484
This file defines the SmallVector class.
static bool isFCondBranchOpcode(int Opc)
static bool isRegCondBranchOpcode(int Opc)
static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
static bool isI32CondBranchOpcode(int Opc)
static bool isI64CondBranchOpcode(int Opc)
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
A debug info location.
Definition DebugLoc.h:126
Helper class for constructing bundles of MachineInstrs.
MachineInstrBundleIterator< MachineInstr > iterator
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.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
const MachineBasicBlock & front() const
MachineMemOperand * getMachineMemOperand(MachinePointerInfo PtrInfo, MachineMemOperand::Flags F, LLT MemTy, Align BaseAlignment, const MMOMetadata &Metadata=MMOMetadata(), SyncScope::ID SSID=SyncScope::System, AtomicOrdering Ordering=AtomicOrdering::NotAtomic, AtomicOrdering FailureOrdering=AtomicOrdering::NotAtomic)
getMachineMemOperand - Allocate a new MachineMemOperand.
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & setOperandDead(unsigned OpIdx) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & addFrameIndex(int Idx) const
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.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
const MachineBasicBlock * getParent() const
LLVM_ABI bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
LLVM_ABI void addRegisterDefined(Register Reg, const TargetRegisterInfo *RegInfo=nullptr)
We have determined MI defines a register.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI MachineInstrBundleIterator< MachineInstr > eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
A description of a memory reference used in the backend.
@ MOLoad
The memory access reads data.
@ MOStore
The memory access writes data.
MachineOperand class - Representation of each machine instruction operand.
int64_t getImm() const
MachineBasicBlock * getMBB() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
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,...
LLVM_ABI bool hasOneNonDBGUse(Register RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug use of the specified register.
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
Wrapper class representing virtual and physical registers.
Definition Register.h:20
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool needsUnimp(const MachineInstr &MI, unsigned &StructSize) const
Register isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex, TypeSize &MemBytes) const override
isLoadFromStackSlot - If the specified machine instruction is a direct load from a stack slot,...
void copyPhysReg(MachineBasicBlock &MBB, MachineBasicBlock::iterator I, const DebugLoc &DL, Register DestReg, Register SrcReg, bool KillSrc, bool RenamableDest=false, bool RenamableSrc=false) const override
bool isBranchOffsetInRange(unsigned BranchOpc, int64_t Offset) const override
Determine if the branch target is in range.
void storeRegToStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register SrcReg, bool isKill, int FrameIndex, const TargetRegisterClass *RC, Register VReg, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) const override
bool analyzeCompare(const MachineInstr &MI, Register &SrcReg, Register &SrcReg2, int64_t &CmpMask, int64_t &CmpValue) const override
bool optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, Register SrcReg2, int64_t CmpMask, int64_t CmpValue, const MachineRegisterInfo *MRI) const override
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Register getGlobalBaseReg(MachineFunction *MF) const
void loadRegFromStackSlot(MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register DestReg, int FrameIndex, const TargetRegisterClass *RC, Register VReg, unsigned SubReg=0, MachineInstr::MIFlag Flags=MachineInstr::NoFlags) 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 isStoreToStackSlot(const MachineInstr &MI, int &FrameIndex, TypeSize &MemBytes) const override
isStoreToStackSlot - If the specified machine instruction is a direct store to a stack slot,...
SparcInstrInfo(const SparcSubtarget &ST)
const SparcRegisterInfo & getRegisterInfo() const
getRegisterInfo - TargetInstrInfo is a superset of MRegister info.
const TargetRegisterClass * getInlineAsmMemoryOperandRegClass(InlineAsm::ConstraintCode C) const override
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
Primary interface to the complete machine description for the target machine.
bool isPositionIndependent() const
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
CodeModel::Model getCodeModel() const
Returns the code model.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Target - Wrapper for Target specific information.
static constexpr TypeSize getFixed(ScalarTy ExactSize)
Definition TypeSize.h:339
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ CPCC_03
Definition Sparc.h:88
@ CPCC_013
Definition Sparc.h:92
@ FCC_ULE
Definition Sparc.h:74
@ ICC_POS
Definition Sparc.h:54
@ FCC_UG
Definition Sparc.h:64
@ ICC_N
Definition Sparc.h:43
@ CPCC_123
Definition Sparc.h:86
@ ICC_G
Definition Sparc.h:46
@ REG_LEZ
Definition Sparc.h:97
@ CPCC_23
Definition Sparc.h:82
@ ICC_L
Definition Sparc.h:49
@ REG_BEGIN
Definition Sparc.h:95
@ FCC_NE
Definition Sparc.h:68
@ CPCC_01
Definition Sparc.h:91
@ CPCC_12
Definition Sparc.h:85
@ ICC_CS
Definition Sparc.h:53
@ FCC_LG
Definition Sparc.h:67
@ ICC_VS
Definition Sparc.h:57
@ CPCC_1
Definition Sparc.h:83
@ ICC_LEU
Definition Sparc.h:51
@ CPCC_A
Definition Sparc.h:78
@ CPCC_0
Definition Sparc.h:87
@ FCC_LE
Definition Sparc.h:73
@ CPCC_012
Definition Sparc.h:93
@ ICC_LE
Definition Sparc.h:47
@ FCC_U
Definition Sparc.h:62
@ CPCC_2
Definition Sparc.h:81
@ FCC_A
Definition Sparc.h:60
@ CPCC_023
Definition Sparc.h:90
@ CPCC_13
Definition Sparc.h:84
@ ICC_GE
Definition Sparc.h:48
@ FCC_E
Definition Sparc.h:69
@ CPCC_02
Definition Sparc.h:89
@ REG_LZ
Definition Sparc.h:98
@ FCC_L
Definition Sparc.h:65
@ ICC_GU
Definition Sparc.h:50
@ FCC_O
Definition Sparc.h:75
@ ICC_NE
Definition Sparc.h:44
@ FCC_UE
Definition Sparc.h:70
@ REG_NZ
Definition Sparc.h:99
@ ICC_E
Definition Sparc.h:45
@ FCC_GE
Definition Sparc.h:71
@ ICC_A
Definition Sparc.h:42
@ CPCC_3
Definition Sparc.h:80
@ FCC_UGE
Definition Sparc.h:72
@ REG_Z
Definition Sparc.h:96
@ ICC_VC
Definition Sparc.h:56
@ ICC_CC
Definition Sparc.h:52
@ REG_GEZ
Definition Sparc.h:101
@ CPCC_N
Definition Sparc.h:79
@ FCC_G
Definition Sparc.h:63
@ FCC_UL
Definition Sparc.h:66
@ FCC_N
Definition Sparc.h:61
@ ICC_NEG
Definition Sparc.h:55
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:577
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.
constexpr RegState getKillRegState(bool B)
static bool isIndirectBranchOpcode(int Opc)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1762
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
static bool isUncondBranchOpcode(int Opc)
constexpr bool isIntN(unsigned N, int64_t x)
Checks if an signed integer fits into the given (dynamic) bit width.
Definition MathExtras.h:249
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58
static LLVM_ABI MachinePointerInfo getFixedStack(MachineFunction &MF, int FI, int64_t Offset=0)
Return a MachinePointerInfo record that refers to the specified FrameIndex.