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"
15#include "SparcMachineFunctionInfo.h"
16#include "SparcSubtarget.h"
17#include "llvm/ADT/SmallVector.h"
18#include "llvm/CodeGen/MachineFrameInfo.h"
19#include "llvm/CodeGen/MachineInstrBuilder.h"
20#include "llvm/CodeGen/MachineMemOperand.h"
21#include "llvm/CodeGen/MachineRegisterInfo.h"
22#include "llvm/Support/ErrorHandling.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
32SparcInstrInfo::SparcInstrInfo(const SparcSubtarget &ST)
33 : SparcGenInstrInfo(ST, RI, SP::ADJCALLSTACKDOWN, SP::ADJCALLSTACKUP),
34 RI(ST), Subtarget(ST) {}
35
36const TargetRegisterClass *SparcInstrInfo::getInlineAsmMemoryOperandRegClass(
37 InlineAsm::ConstraintCode C) const {
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.
46Register SparcInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
47 int &FrameIndex,
48 TypeSize &MemBytes) const {
49 switch (MI.getOpcode()) {
50 default:
51 return 0;
52 case SP::LDri:
53 MemBytes = TypeSize::getFixed(ExactSize: 4);
54 break;
55 case SP::LDXri:
56 MemBytes = TypeSize::getFixed(ExactSize: 8);
57 break;
58 case SP::LDFri:
59 MemBytes = TypeSize::getFixed(ExactSize: 4);
60 break;
61 case SP::LDDFri:
62 MemBytes = TypeSize::getFixed(ExactSize: 8);
63 break;
64 case SP::LDQFri:
65 MemBytes = TypeSize::getFixed(ExactSize: 16);
66 break;
67 }
68 if (MI.getOperand(i: 1).isFI() && MI.getOperand(i: 2).isImm() &&
69 MI.getOperand(i: 2).getImm() == 0) {
70 FrameIndex = MI.getOperand(i: 1).getIndex();
71 return MI.getOperand(i: 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.
81Register SparcInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
82 int &FrameIndex,
83 TypeSize &MemBytes) const {
84 switch (MI.getOpcode()) {
85 default:
86 return 0;
87 case SP::STri:
88 MemBytes = TypeSize::getFixed(ExactSize: 4);
89 break;
90 case SP::STXri:
91 MemBytes = TypeSize::getFixed(ExactSize: 8);
92 break;
93 case SP::STFri:
94 MemBytes = TypeSize::getFixed(ExactSize: 4);
95 break;
96 case SP::STDFri:
97 MemBytes = TypeSize::getFixed(ExactSize: 8);
98 break;
99 case SP::STQFri:
100 MemBytes = TypeSize::getFixed(ExactSize: 16);
101 break;
102 }
103 if (MI.getOperand(i: 0).isFI() && MI.getOperand(i: 1).isImm() &&
104 MI.getOperand(i: 1).getImm() == 0) {
105 FrameIndex = MI.getOperand(i: 0).getIndex();
106 return MI.getOperand(i: 2).getReg();
107 }
108 return 0;
109}
110
111static SPCC::CondCodes GetOppositeBranchCondition(SPCC::CondCodes CC)
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
210static bool isCondBranchOpcode(int Opc) {
211 return isI32CondBranchOpcode(Opc) || isI64CondBranchOpcode(Opc) ||
212 isRegCondBranchOpcode(Opc) || isFCondBranchOpcode(Opc);
213}
214
215static bool isIndirectBranchOpcode(int Opc) {
216 return Opc == SP::BINDrr || Opc == SP::BINDri;
217}
218
219static void parseCondBranch(MachineInstr *LastInst, MachineBasicBlock *&Target,
220 SmallVectorImpl<MachineOperand> &Cond) {
221 unsigned Opc = LastInst->getOpcode();
222 int64_t CC = LastInst->getOperand(i: 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.
226 Cond.push_back(Elt: MachineOperand::CreateImm(Val: Opc));
227 Cond.push_back(Elt: MachineOperand::CreateImm(Val: CC));
228
229 // Branch on register contents need another argument to indicate
230 // the register it branches on.
231 if (isRegCondBranchOpcode(Opc)) {
232 Register Reg = LastInst->getOperand(i: 2).getReg();
233 Cond.push_back(Elt: MachineOperand::CreateReg(Reg, isDef: false));
234 }
235
236 Target = LastInst->getOperand(i: 0).getMBB();
237}
238
239MachineBasicBlock *
240SparcInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
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(i: 0).getMBB();
268 }
269}
270
271bool SparcInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
272 MachineBasicBlock *&TBB,
273 MachineBasicBlock *&FBB,
274 SmallVectorImpl<MachineOperand> &Cond,
275 bool AllowModify) const {
276 MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
277 if (I == MBB.end())
278 return false;
279
280 if (!isUnpredicatedTerminator(MI: *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(MI: *--I)) {
289 if (isUncondBranchOpcode(Opc: LastOpc)) {
290 TBB = LastInst->getOperand(i: 0).getMBB();
291 return false;
292 }
293 if (isCondBranchOpcode(Opc: LastOpc)) {
294 // Block ends with fall-through condbranch.
295 parseCondBranch(LastInst, Target&: 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(Opc: LastOpc)) {
308 while (isUncondBranchOpcode(Opc: SecondLastOpc)) {
309 LastInst->eraseFromParent();
310 LastInst = SecondLastInst;
311 LastOpc = LastInst->getOpcode();
312 if (I == MBB.begin() || !isUnpredicatedTerminator(MI: *--I)) {
313 // Return now the only terminator is an unconditional branch.
314 TBB = LastInst->getOperand(i: 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(MI: *--I))
325 return true;
326
327 // If the block ends with a B and a Bcc, handle it.
328 if (isCondBranchOpcode(Opc: SecondLastOpc) && isUncondBranchOpcode(Opc: LastOpc)) {
329 parseCondBranch(LastInst: SecondLastInst, Target&: TBB, Cond);
330 FBB = LastInst->getOperand(i: 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(Opc: SecondLastOpc) && isUncondBranchOpcode(Opc: LastOpc)) {
337 TBB = SecondLastInst->getOperand(i: 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(Opc: SecondLastOpc) && isUncondBranchOpcode(Opc: 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
354unsigned SparcInstrInfo::insertBranch(MachineBasicBlock &MBB,
355 MachineBasicBlock *TBB,
356 MachineBasicBlock *FBB,
357 ArrayRef<MachineOperand> Cond,
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(BB: &MBB, MIMD: DL, MCID: get(Opcode: SP::BA)).addMBB(MBB: 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();
375 if (isRegCondBranchOpcode(Opc)) {
376 Register Reg = Cond[2].getReg();
377 BuildMI(BB: &MBB, MIMD: DL, MCID: get(Opcode: Opc)).addMBB(MBB: TBB).addImm(Val: CC).addReg(RegNo: Reg);
378 } else {
379 BuildMI(BB: &MBB, MIMD: DL, MCID: get(Opcode: Opc)).addMBB(MBB: TBB).addImm(Val: CC);
380 }
381
382 if (!FBB) {
383 if (BytesAdded)
384 *BytesAdded = 8;
385 return 1;
386 }
387
388 BuildMI(BB: &MBB, MIMD: DL, MCID: get(Opcode: SP::BA)).addMBB(MBB: FBB);
389 if (BytesAdded)
390 *BytesAdded = 16;
391 return 2;
392}
393
394unsigned SparcInstrInfo::removeBranch(MachineBasicBlock &MBB,
395 int *BytesRemoved) const {
396 MachineBasicBlock::iterator I = MBB.end();
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(Opc: I->getOpcode()) &&
406 !isUncondBranchOpcode(Opc: I->getOpcode()))
407 break; // Not a branch
408
409 Removed += getInstSizeInBytes(MI: *I);
410 I->eraseFromParent();
411 I = MBB.end();
412 ++Count;
413 }
414
415 if (BytesRemoved)
416 *BytesRemoved = Removed;
417 return Count;
418}
419
420bool SparcInstrInfo::reverseBranchCondition(
421 SmallVectorImpl<MachineOperand> &Cond) const {
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
428bool SparcInstrInfo::isBranchOffsetInRange(unsigned BranchOpc,
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(N: 22, x: 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(N: Subtarget.getCLOpts().bpcc_offset_bits, x: Offset >> 2);
454
455 case SP::BPR:
456 case SP::BPRA:
457 case SP::BPRNT:
458 case SP::BPRANT:
459 return isIntN(N: Subtarget.getCLOpts().bpr_offset_bits, x: Offset >> 2);
460 }
461
462 llvm_unreachable("Unknown branch instruction!");
463}
464
465void SparcInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
466 MachineBasicBlock::iterator I,
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(Reg1: DestReg, Reg2: SrcReg))
483 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::ORrr), DestReg).addReg(RegNo: SP::G0)
484 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc));
485 else if (SP::IntPairRegClass.contains(Reg1: DestReg, Reg2: SrcReg)) {
486 subRegIdx = DW_SubRegsIdx;
487 numSubRegs = 2;
488 movOpc = SP::ORrr;
489 ExtraG0 = true;
490 } else if (SP::FPRegsRegClass.contains(Reg1: DestReg, Reg2: SrcReg))
491 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::FMOVS), DestReg)
492 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc));
493 else if (SP::DFPRegsRegClass.contains(Reg1: DestReg, Reg2: SrcReg)) {
494 if (Subtarget.isV9()) {
495 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::FMOVD), DestReg)
496 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: 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(Reg1: DestReg, Reg2: SrcReg)) {
504 if (Subtarget.isV9()) {
505 if (Subtarget.hasHardQuad()) {
506 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::FMOVQ), DestReg)
507 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: 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(Reg: DestReg) &&
521 SP::IntRegsRegClass.contains(Reg: SrcReg)) {
522 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::WRASRrr), DestReg)
523 .addReg(RegNo: SP::G0)
524 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc));
525 } else if (SP::IntRegsRegClass.contains(Reg: DestReg) &&
526 SP::ASRRegsRegClass.contains(Reg: SrcReg)) {
527 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::RDASR), DestReg)
528 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: KillSrc));
529 } else
530 llvm_unreachable("Impossible reg-to-reg copy");
531
532 if (numSubRegs == 0 || subRegIdx == nullptr || movOpc == 0)
533 return;
534
535 const TargetRegisterInfo *TRI = &getRegisterInfo();
536 MachineInstr *MovMI = nullptr;
537
538 for (unsigned i = 0; i != numSubRegs; ++i) {
539 Register Dst = TRI->getSubReg(Reg: DestReg, Idx: subRegIdx[i]);
540 Register Src = TRI->getSubReg(Reg: SrcReg, Idx: subRegIdx[i]);
541 assert(Dst && Src && "Bad sub-register");
542
543 MachineInstrBuilder MIB = BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: movOpc), DestReg: Dst);
544 if (ExtraG0)
545 MIB.addReg(RegNo: SP::G0);
546 MIB.addReg(RegNo: Src);
547 MovMI = MIB.getInstr();
548 }
549 // Add implicit super-register defs and kills to the last MovMI.
550 MovMI->addRegisterDefined(Reg: DestReg, RegInfo: TRI);
551 if (KillSrc)
552 MovMI->addRegisterKilled(IncomingReg: SrcReg, RegInfo: TRI);
553}
554
555void SparcInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
556 MachineBasicBlock::iterator I,
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();
566 MachineMemOperand *MMO = MF->getMachineMemOperand(
567 PtrInfo: MachinePointerInfo::getFixedStack(MF&: *MF, FI), F: MachineMemOperand::MOStore,
568 Size: MFI.getObjectSize(ObjectIdx: FI), BaseAlignment: MFI.getObjectAlign(ObjectIdx: FI));
569
570 // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
571 if (RC == &SP::I64RegsRegClass)
572 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::STXri)).addFrameIndex(Idx: FI).addImm(Val: 0)
573 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: isKill)).addMemOperand(MMO);
574 else if (RC == &SP::IntRegsRegClass)
575 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::STri)).addFrameIndex(Idx: FI).addImm(Val: 0)
576 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: isKill)).addMemOperand(MMO);
577 else if (RC == &SP::IntPairRegClass)
578 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::STDri)).addFrameIndex(Idx: FI).addImm(Val: 0)
579 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: isKill)).addMemOperand(MMO);
580 else if (RC == &SP::FPRegsRegClass)
581 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::STFri)).addFrameIndex(Idx: FI).addImm(Val: 0)
582 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: isKill)).addMemOperand(MMO);
583 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
584 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::STDFri)).addFrameIndex(Idx: FI).addImm(Val: 0)
585 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: 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(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::STQFri)).addFrameIndex(Idx: FI).addImm(Val: 0)
590 .addReg(RegNo: SrcReg, Flags: getKillRegState(B: isKill)).addMemOperand(MMO);
591 else
592 llvm_unreachable("Can't store this register to stack slot");
593}
594
595void SparcInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
596 MachineBasicBlock::iterator I,
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();
606 MachineMemOperand *MMO = MF->getMachineMemOperand(
607 PtrInfo: MachinePointerInfo::getFixedStack(MF&: *MF, FI), F: MachineMemOperand::MOLoad,
608 Size: MFI.getObjectSize(ObjectIdx: FI), BaseAlignment: MFI.getObjectAlign(ObjectIdx: FI));
609
610 if (RC == &SP::I64RegsRegClass)
611 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::LDXri), DestReg).addFrameIndex(Idx: FI).addImm(Val: 0)
612 .addMemOperand(MMO);
613 else if (RC == &SP::IntRegsRegClass)
614 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::LDri), DestReg).addFrameIndex(Idx: FI).addImm(Val: 0)
615 .addMemOperand(MMO);
616 else if (RC == &SP::IntPairRegClass)
617 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::LDDri), DestReg).addFrameIndex(Idx: FI).addImm(Val: 0)
618 .addMemOperand(MMO);
619 else if (RC == &SP::FPRegsRegClass)
620 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::LDFri), DestReg).addFrameIndex(Idx: FI).addImm(Val: 0)
621 .addMemOperand(MMO);
622 else if (SP::DFPRegsRegClass.hasSubClassEq(RC))
623 BuildMI(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::LDDFri), DestReg).addFrameIndex(Idx: FI).addImm(Val: 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(BB&: MBB, I, MIMD: DL, MCID: get(Opcode: SP::LDQFri), DestReg).addFrameIndex(Idx: FI).addImm(Val: 0)
629 .addMemOperand(MMO);
630 else
631 llvm_unreachable("Can't load this register from stack slot");
632}
633
634Register SparcInstrInfo::getGlobalBaseReg(MachineFunction *MF) const {
635 SparcMachineFunctionInfo *SparcFI = MF->getInfo<SparcMachineFunctionInfo>();
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();
642 MachineBasicBlock::iterator MBBI = FirstMBB.begin();
643 MachineRegisterInfo &RegInfo = MF->getRegInfo();
644
645 const TargetRegisterClass *PtrRC =
646 Subtarget.is64Bit() ? &SP::I64RegsRegClass : &SP::IntRegsRegClass;
647 GlobalBaseReg = RegInfo.createVirtualRegister(RegClass: PtrRC);
648
649 DebugLoc dl;
650
651 BuildMI(BB&: FirstMBB, I: MBBI, MIMD: dl, MCID: get(Opcode: SP::GETPCX), DestReg: GlobalBaseReg)
652 .setOperandDead(1); // implicit-def $o7
653 SparcFI->setGlobalBaseReg(GlobalBaseReg);
654 return GlobalBaseReg;
655}
656
657bool SparcInstrInfo::needsUnimp(const MachineInstr &MI,
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(i: 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
691unsigned SparcInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
692 unsigned Opcode = MI.getOpcode();
693
694 if (MI.isInlineAsm()) {
695 const MachineFunction *MF = MI.getParent()->getParent();
696 const char *AsmStr = MI.getOperand(i: 0).getSymbolName();
697 return getInlineAsmLength(Str: AsmStr, MAI: 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;
712 case CodeModel::Medium:
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
729bool SparcInstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg,
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(i: 0).getReg();
738 SrcReg = MI.getOperand(i: 1).getReg();
739 SrcReg2 = 0;
740 CmpMask = ~0;
741 CmpValue = MI.getOperand(i: 2).getImm();
742 return DstReg == SP::G0 && CmpValue == 0;
743 case SP::SUBCCrr:
744 DstReg = MI.getOperand(i: 0).getReg();
745 SrcReg = MI.getOperand(i: 1).getReg();
746 SrcReg2 = MI.getOperand(i: 2).getReg();
747 CmpMask = ~0;
748 CmpValue = 0;
749 return DstReg == SP::G0 && SrcReg2 == SP::G0;
750 }
751
752 return false;
753}
754
755bool SparcInstrInfo::optimizeCompareInstr(
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(Reg: 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;
820 MachineBasicBlock::iterator I = MI;
821 MachineBasicBlock::iterator C = CmpInstr;
822 MachineBasicBlock::iterator E = CmpInstr.getParent()->end();
823 const TargetRegisterInfo *TRI = &getRegisterInfo();
824
825 // If ICC is used or modified between MI and CmpInstr we cannot optimize.
826 while (++I != C) {
827 if (I->modifiesRegister(Reg: SP::ICC, TRI) || I->readsRegister(Reg: SP::ICC, TRI))
828 return false;
829 }
830
831 while (++I != E) {
832 // Only allow conditionals on equality.
833 if (I->readsRegister(Reg: 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(i: IsICCBranch ? 1 : 3).getImm() != SPCC::ICC_E &&
843 I->getOperand(i: IsICCBranch ? 1 : 3).getImm() != SPCC::ICC_NE))
844 return false;
845 } else if (I->modifiesRegister(Reg: SP::ICC, TRI)) {
846 IsICCModified = true;
847 break;
848 }
849 }
850
851 if (!IsICCModified) {
852 MachineBasicBlock *MBB = CmpInstr.getParent();
853 if (any_of(Range: MBB->successors(),
854 P: [](MachineBasicBlock *Succ) { return Succ->isLiveIn(Reg: SP::ICC); }))
855 return false;
856 }
857
858 if (MRI->hasOneNonDBGUse(RegNo: SrcReg))
859 MI->getOperand(i: 0).setReg(SP::G0);
860
861 MI->setDesc(get(Opcode: NewOpcode));
862 MI->addRegisterDefined(Reg: SP::ICC);
863 CmpInstr.eraseFromParent();
864
865 return true;
866}
867
868bool SparcInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
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(Opcode: Subtarget.is64Bit() ? SP::LDXri : SP::LDri));
876 MachineInstrBuilder(*MI.getParent()->getParent(), MI)
877 .addReg(RegNo: SP::G7)
878 .addImm(Val: 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(BB&: MBB, I&: MI, MIMD: MI.getDebugLoc(), MCID: get(Opcode: SP::STBAR));
890 MachineInstr &InstLDSTUB =
891 *BuildMI(BB&: MBB, I&: MI, MIMD: MI.getDebugLoc(), MCID: get(Opcode: SP::LDSTUBri), DestReg: SP::G0)
892 .addReg(RegNo: SP::O6)
893 .addImm(Val: -1);
894 MIBundleBuilder(MBB, InstSTBAR, InstLDSTUB);
895 MBB.erase(I: MI);
896 return true;
897 }
898 }
899 return false;
900}
901