1 //===-- SparcInstrInfo.cpp - Sparc Instruction Information ----------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file contains the Sparc implementation of the TargetInstrInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "SparcInstrInfo.h"
15 #include "SparcMachineFunctionInfo.h"
16 #include "SparcSubtarget.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineMemOperand.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/TargetRegistry.h"
28 #define GET_INSTRINFO_CTOR_DTOR
29 #include "SparcGenInstrInfo.inc"
31 // Pin the vtable to this file.
32 void SparcInstrInfo::anchor() {}
34 SparcInstrInfo::SparcInstrInfo(SparcSubtarget
&ST
)
35 : SparcGenInstrInfo(SP::ADJCALLSTACKDOWN
, SP::ADJCALLSTACKUP
), RI(),
38 /// isLoadFromStackSlot - If the specified machine instruction is a direct
39 /// load from a stack slot, return the virtual or physical register number of
40 /// the destination along with the FrameIndex of the loaded stack slot. If
41 /// not, return 0. This predicate must return 0 if the instruction has
42 /// any side effects other than loading from the stack slot.
43 unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr
&MI
,
44 int &FrameIndex
) const {
45 if (MI
.getOpcode() == SP::LDri
|| MI
.getOpcode() == SP::LDXri
||
46 MI
.getOpcode() == SP::LDFri
|| MI
.getOpcode() == SP::LDDFri
||
47 MI
.getOpcode() == SP::LDQFri
) {
48 if (MI
.getOperand(1).isFI() && MI
.getOperand(2).isImm() &&
49 MI
.getOperand(2).getImm() == 0) {
50 FrameIndex
= MI
.getOperand(1).getIndex();
51 return MI
.getOperand(0).getReg();
57 /// isStoreToStackSlot - If the specified machine instruction is a direct
58 /// store to a stack slot, return the virtual or physical register number of
59 /// the source reg along with the FrameIndex of the loaded stack slot. If
60 /// not, return 0. This predicate must return 0 if the instruction has
61 /// any side effects other than storing to the stack slot.
62 unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr
&MI
,
63 int &FrameIndex
) const {
64 if (MI
.getOpcode() == SP::STri
|| MI
.getOpcode() == SP::STXri
||
65 MI
.getOpcode() == SP::STFri
|| MI
.getOpcode() == SP::STDFri
||
66 MI
.getOpcode() == SP::STQFri
) {
67 if (MI
.getOperand(0).isFI() && MI
.getOperand(1).isImm() &&
68 MI
.getOperand(1).getImm() == 0) {
69 FrameIndex
= MI
.getOperand(0).getIndex();
70 return MI
.getOperand(2).getReg();
76 static bool IsIntegerCC(unsigned CC
)
78 return (CC
<= SPCC::ICC_VC
);
81 static SPCC::CondCodes
GetOppositeBranchCondition(SPCC::CondCodes CC
)
84 case SPCC::ICC_A
: return SPCC::ICC_N
;
85 case SPCC::ICC_N
: return SPCC::ICC_A
;
86 case SPCC::ICC_NE
: return SPCC::ICC_E
;
87 case SPCC::ICC_E
: return SPCC::ICC_NE
;
88 case SPCC::ICC_G
: return SPCC::ICC_LE
;
89 case SPCC::ICC_LE
: return SPCC::ICC_G
;
90 case SPCC::ICC_GE
: return SPCC::ICC_L
;
91 case SPCC::ICC_L
: return SPCC::ICC_GE
;
92 case SPCC::ICC_GU
: return SPCC::ICC_LEU
;
93 case SPCC::ICC_LEU
: return SPCC::ICC_GU
;
94 case SPCC::ICC_CC
: return SPCC::ICC_CS
;
95 case SPCC::ICC_CS
: return SPCC::ICC_CC
;
96 case SPCC::ICC_POS
: return SPCC::ICC_NEG
;
97 case SPCC::ICC_NEG
: return SPCC::ICC_POS
;
98 case SPCC::ICC_VC
: return SPCC::ICC_VS
;
99 case SPCC::ICC_VS
: return SPCC::ICC_VC
;
101 case SPCC::FCC_A
: return SPCC::FCC_N
;
102 case SPCC::FCC_N
: return SPCC::FCC_A
;
103 case SPCC::FCC_U
: return SPCC::FCC_O
;
104 case SPCC::FCC_O
: return SPCC::FCC_U
;
105 case SPCC::FCC_G
: return SPCC::FCC_ULE
;
106 case SPCC::FCC_LE
: return SPCC::FCC_UG
;
107 case SPCC::FCC_UG
: return SPCC::FCC_LE
;
108 case SPCC::FCC_ULE
: return SPCC::FCC_G
;
109 case SPCC::FCC_L
: return SPCC::FCC_UGE
;
110 case SPCC::FCC_GE
: return SPCC::FCC_UL
;
111 case SPCC::FCC_UL
: return SPCC::FCC_GE
;
112 case SPCC::FCC_UGE
: return SPCC::FCC_L
;
113 case SPCC::FCC_LG
: return SPCC::FCC_UE
;
114 case SPCC::FCC_UE
: return SPCC::FCC_LG
;
115 case SPCC::FCC_NE
: return SPCC::FCC_E
;
116 case SPCC::FCC_E
: return SPCC::FCC_NE
;
118 case SPCC::CPCC_A
: return SPCC::CPCC_N
;
119 case SPCC::CPCC_N
: return SPCC::CPCC_A
;
120 case SPCC::CPCC_3
: LLVM_FALLTHROUGH
;
121 case SPCC::CPCC_2
: LLVM_FALLTHROUGH
;
122 case SPCC::CPCC_23
: LLVM_FALLTHROUGH
;
123 case SPCC::CPCC_1
: LLVM_FALLTHROUGH
;
124 case SPCC::CPCC_13
: LLVM_FALLTHROUGH
;
125 case SPCC::CPCC_12
: LLVM_FALLTHROUGH
;
126 case SPCC::CPCC_123
: LLVM_FALLTHROUGH
;
127 case SPCC::CPCC_0
: LLVM_FALLTHROUGH
;
128 case SPCC::CPCC_03
: LLVM_FALLTHROUGH
;
129 case SPCC::CPCC_02
: LLVM_FALLTHROUGH
;
130 case SPCC::CPCC_023
: LLVM_FALLTHROUGH
;
131 case SPCC::CPCC_01
: LLVM_FALLTHROUGH
;
132 case SPCC::CPCC_013
: LLVM_FALLTHROUGH
;
134 // "Opposite" code is not meaningful, as we don't know
135 // what the CoProc condition means here. The cond-code will
136 // only be used in inline assembler, so this code should
137 // not be reached in a normal compilation pass.
138 llvm_unreachable("Meaningless inversion of co-processor cond code");
140 llvm_unreachable("Invalid cond code");
143 static bool isUncondBranchOpcode(int Opc
) { return Opc
== SP::BA
; }
145 static bool isCondBranchOpcode(int Opc
) {
146 return Opc
== SP::FBCOND
|| Opc
== SP::BCOND
;
149 static bool isIndirectBranchOpcode(int Opc
) {
150 return Opc
== SP::BINDrr
|| Opc
== SP::BINDri
;
153 static void parseCondBranch(MachineInstr
*LastInst
, MachineBasicBlock
*&Target
,
154 SmallVectorImpl
<MachineOperand
> &Cond
) {
155 Cond
.push_back(MachineOperand::CreateImm(LastInst
->getOperand(1).getImm()));
156 Target
= LastInst
->getOperand(0).getMBB();
159 bool SparcInstrInfo::analyzeBranch(MachineBasicBlock
&MBB
,
160 MachineBasicBlock
*&TBB
,
161 MachineBasicBlock
*&FBB
,
162 SmallVectorImpl
<MachineOperand
> &Cond
,
163 bool AllowModify
) const {
164 MachineBasicBlock::iterator I
= MBB
.getLastNonDebugInstr();
168 if (!isUnpredicatedTerminator(*I
))
171 // Get the last instruction in the block.
172 MachineInstr
*LastInst
= &*I
;
173 unsigned LastOpc
= LastInst
->getOpcode();
175 // If there is only one terminator instruction, process it.
176 if (I
== MBB
.begin() || !isUnpredicatedTerminator(*--I
)) {
177 if (isUncondBranchOpcode(LastOpc
)) {
178 TBB
= LastInst
->getOperand(0).getMBB();
181 if (isCondBranchOpcode(LastOpc
)) {
182 // Block ends with fall-through condbranch.
183 parseCondBranch(LastInst
, TBB
, Cond
);
186 return true; // Can't handle indirect branch.
189 // Get the instruction before it if it is a terminator.
190 MachineInstr
*SecondLastInst
= &*I
;
191 unsigned SecondLastOpc
= SecondLastInst
->getOpcode();
193 // If AllowModify is true and the block ends with two or more unconditional
194 // branches, delete all but the first unconditional branch.
195 if (AllowModify
&& isUncondBranchOpcode(LastOpc
)) {
196 while (isUncondBranchOpcode(SecondLastOpc
)) {
197 LastInst
->eraseFromParent();
198 LastInst
= SecondLastInst
;
199 LastOpc
= LastInst
->getOpcode();
200 if (I
== MBB
.begin() || !isUnpredicatedTerminator(*--I
)) {
201 // Return now the only terminator is an unconditional branch.
202 TBB
= LastInst
->getOperand(0).getMBB();
205 SecondLastInst
= &*I
;
206 SecondLastOpc
= SecondLastInst
->getOpcode();
211 // If there are three terminators, we don't know what sort of block this is.
212 if (SecondLastInst
&& I
!= MBB
.begin() && isUnpredicatedTerminator(*--I
))
215 // If the block ends with a B and a Bcc, handle it.
216 if (isCondBranchOpcode(SecondLastOpc
) && isUncondBranchOpcode(LastOpc
)) {
217 parseCondBranch(SecondLastInst
, TBB
, Cond
);
218 FBB
= LastInst
->getOperand(0).getMBB();
222 // If the block ends with two unconditional branches, handle it. The second
223 // one is not executed.
224 if (isUncondBranchOpcode(SecondLastOpc
) && isUncondBranchOpcode(LastOpc
)) {
225 TBB
= SecondLastInst
->getOperand(0).getMBB();
229 // ...likewise if it ends with an indirect branch followed by an unconditional
231 if (isIndirectBranchOpcode(SecondLastOpc
) && isUncondBranchOpcode(LastOpc
)) {
234 I
->eraseFromParent();
238 // Otherwise, can't handle this.
242 unsigned SparcInstrInfo::insertBranch(MachineBasicBlock
&MBB
,
243 MachineBasicBlock
*TBB
,
244 MachineBasicBlock
*FBB
,
245 ArrayRef
<MachineOperand
> Cond
,
247 int *BytesAdded
) const {
248 assert(TBB
&& "insertBranch must not be told to insert a fallthrough");
249 assert((Cond
.size() == 1 || Cond
.size() == 0) &&
250 "Sparc branch conditions should have one component!");
251 assert(!BytesAdded
&& "code size not handled");
254 assert(!FBB
&& "Unconditional branch with multiple successors!");
255 BuildMI(&MBB
, DL
, get(SP::BA
)).addMBB(TBB
);
259 // Conditional branch
260 unsigned CC
= Cond
[0].getImm();
263 BuildMI(&MBB
, DL
, get(SP::BCOND
)).addMBB(TBB
).addImm(CC
);
265 BuildMI(&MBB
, DL
, get(SP::FBCOND
)).addMBB(TBB
).addImm(CC
);
269 BuildMI(&MBB
, DL
, get(SP::BA
)).addMBB(FBB
);
273 unsigned SparcInstrInfo::removeBranch(MachineBasicBlock
&MBB
,
274 int *BytesRemoved
) const {
275 assert(!BytesRemoved
&& "code size not handled");
277 MachineBasicBlock::iterator I
= MBB
.end();
279 while (I
!= MBB
.begin()) {
282 if (I
->isDebugInstr())
285 if (I
->getOpcode() != SP::BA
286 && I
->getOpcode() != SP::BCOND
287 && I
->getOpcode() != SP::FBCOND
)
288 break; // Not a branch
290 I
->eraseFromParent();
297 bool SparcInstrInfo::reverseBranchCondition(
298 SmallVectorImpl
<MachineOperand
> &Cond
) const {
299 assert(Cond
.size() == 1);
300 SPCC::CondCodes CC
= static_cast<SPCC::CondCodes
>(Cond
[0].getImm());
301 Cond
[0].setImm(GetOppositeBranchCondition(CC
));
305 void SparcInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
306 MachineBasicBlock::iterator I
,
307 const DebugLoc
&DL
, unsigned DestReg
,
308 unsigned SrcReg
, bool KillSrc
) const {
309 unsigned numSubRegs
= 0;
311 const unsigned *subRegIdx
= nullptr;
312 bool ExtraG0
= false;
314 const unsigned DW_SubRegsIdx
[] = { SP::sub_even
, SP::sub_odd
};
315 const unsigned DFP_FP_SubRegsIdx
[] = { SP::sub_even
, SP::sub_odd
};
316 const unsigned QFP_DFP_SubRegsIdx
[] = { SP::sub_even64
, SP::sub_odd64
};
317 const unsigned QFP_FP_SubRegsIdx
[] = { SP::sub_even
, SP::sub_odd
,
318 SP::sub_odd64_then_sub_even
,
319 SP::sub_odd64_then_sub_odd
};
321 if (SP::IntRegsRegClass
.contains(DestReg
, SrcReg
))
322 BuildMI(MBB
, I
, DL
, get(SP::ORrr
), DestReg
).addReg(SP::G0
)
323 .addReg(SrcReg
, getKillRegState(KillSrc
));
324 else if (SP::IntPairRegClass
.contains(DestReg
, SrcReg
)) {
325 subRegIdx
= DW_SubRegsIdx
;
329 } else if (SP::FPRegsRegClass
.contains(DestReg
, SrcReg
))
330 BuildMI(MBB
, I
, DL
, get(SP::FMOVS
), DestReg
)
331 .addReg(SrcReg
, getKillRegState(KillSrc
));
332 else if (SP::DFPRegsRegClass
.contains(DestReg
, SrcReg
)) {
333 if (Subtarget
.isV9()) {
334 BuildMI(MBB
, I
, DL
, get(SP::FMOVD
), DestReg
)
335 .addReg(SrcReg
, getKillRegState(KillSrc
));
337 // Use two FMOVS instructions.
338 subRegIdx
= DFP_FP_SubRegsIdx
;
342 } else if (SP::QFPRegsRegClass
.contains(DestReg
, SrcReg
)) {
343 if (Subtarget
.isV9()) {
344 if (Subtarget
.hasHardQuad()) {
345 BuildMI(MBB
, I
, DL
, get(SP::FMOVQ
), DestReg
)
346 .addReg(SrcReg
, getKillRegState(KillSrc
));
348 // Use two FMOVD instructions.
349 subRegIdx
= QFP_DFP_SubRegsIdx
;
354 // Use four FMOVS instructions.
355 subRegIdx
= QFP_FP_SubRegsIdx
;
359 } else if (SP::ASRRegsRegClass
.contains(DestReg
) &&
360 SP::IntRegsRegClass
.contains(SrcReg
)) {
361 BuildMI(MBB
, I
, DL
, get(SP::WRASRrr
), DestReg
)
363 .addReg(SrcReg
, getKillRegState(KillSrc
));
364 } else if (SP::IntRegsRegClass
.contains(DestReg
) &&
365 SP::ASRRegsRegClass
.contains(SrcReg
)) {
366 BuildMI(MBB
, I
, DL
, get(SP::RDASR
), DestReg
)
367 .addReg(SrcReg
, getKillRegState(KillSrc
));
369 llvm_unreachable("Impossible reg-to-reg copy");
371 if (numSubRegs
== 0 || subRegIdx
== nullptr || movOpc
== 0)
374 const TargetRegisterInfo
*TRI
= &getRegisterInfo();
375 MachineInstr
*MovMI
= nullptr;
377 for (unsigned i
= 0; i
!= numSubRegs
; ++i
) {
378 Register Dst
= TRI
->getSubReg(DestReg
, subRegIdx
[i
]);
379 Register Src
= TRI
->getSubReg(SrcReg
, subRegIdx
[i
]);
380 assert(Dst
&& Src
&& "Bad sub-register");
382 MachineInstrBuilder MIB
= BuildMI(MBB
, I
, DL
, get(movOpc
), Dst
);
386 MovMI
= MIB
.getInstr();
388 // Add implicit super-register defs and kills to the last MovMI.
389 MovMI
->addRegisterDefined(DestReg
, TRI
);
391 MovMI
->addRegisterKilled(SrcReg
, TRI
);
394 void SparcInstrInfo::
395 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
396 unsigned SrcReg
, bool isKill
, int FI
,
397 const TargetRegisterClass
*RC
,
398 const TargetRegisterInfo
*TRI
) const {
400 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
402 MachineFunction
*MF
= MBB
.getParent();
403 const MachineFrameInfo
&MFI
= MF
->getFrameInfo();
404 MachineMemOperand
*MMO
= MF
->getMachineMemOperand(
405 MachinePointerInfo::getFixedStack(*MF
, FI
), MachineMemOperand::MOStore
,
406 MFI
.getObjectSize(FI
), MFI
.getObjectAlignment(FI
));
408 // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
409 if (RC
== &SP::I64RegsRegClass
)
410 BuildMI(MBB
, I
, DL
, get(SP::STXri
)).addFrameIndex(FI
).addImm(0)
411 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
412 else if (RC
== &SP::IntRegsRegClass
)
413 BuildMI(MBB
, I
, DL
, get(SP::STri
)).addFrameIndex(FI
).addImm(0)
414 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
415 else if (RC
== &SP::IntPairRegClass
)
416 BuildMI(MBB
, I
, DL
, get(SP::STDri
)).addFrameIndex(FI
).addImm(0)
417 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
418 else if (RC
== &SP::FPRegsRegClass
)
419 BuildMI(MBB
, I
, DL
, get(SP::STFri
)).addFrameIndex(FI
).addImm(0)
420 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
421 else if (SP::DFPRegsRegClass
.hasSubClassEq(RC
))
422 BuildMI(MBB
, I
, DL
, get(SP::STDFri
)).addFrameIndex(FI
).addImm(0)
423 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
424 else if (SP::QFPRegsRegClass
.hasSubClassEq(RC
))
425 // Use STQFri irrespective of its legality. If STQ is not legal, it will be
426 // lowered into two STDs in eliminateFrameIndex.
427 BuildMI(MBB
, I
, DL
, get(SP::STQFri
)).addFrameIndex(FI
).addImm(0)
428 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
430 llvm_unreachable("Can't store this register to stack slot");
433 void SparcInstrInfo::
434 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
435 unsigned DestReg
, int FI
,
436 const TargetRegisterClass
*RC
,
437 const TargetRegisterInfo
*TRI
) const {
439 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
441 MachineFunction
*MF
= MBB
.getParent();
442 const MachineFrameInfo
&MFI
= MF
->getFrameInfo();
443 MachineMemOperand
*MMO
= MF
->getMachineMemOperand(
444 MachinePointerInfo::getFixedStack(*MF
, FI
), MachineMemOperand::MOLoad
,
445 MFI
.getObjectSize(FI
), MFI
.getObjectAlignment(FI
));
447 if (RC
== &SP::I64RegsRegClass
)
448 BuildMI(MBB
, I
, DL
, get(SP::LDXri
), DestReg
).addFrameIndex(FI
).addImm(0)
450 else if (RC
== &SP::IntRegsRegClass
)
451 BuildMI(MBB
, I
, DL
, get(SP::LDri
), DestReg
).addFrameIndex(FI
).addImm(0)
453 else if (RC
== &SP::IntPairRegClass
)
454 BuildMI(MBB
, I
, DL
, get(SP::LDDri
), DestReg
).addFrameIndex(FI
).addImm(0)
456 else if (RC
== &SP::FPRegsRegClass
)
457 BuildMI(MBB
, I
, DL
, get(SP::LDFri
), DestReg
).addFrameIndex(FI
).addImm(0)
459 else if (SP::DFPRegsRegClass
.hasSubClassEq(RC
))
460 BuildMI(MBB
, I
, DL
, get(SP::LDDFri
), DestReg
).addFrameIndex(FI
).addImm(0)
462 else if (SP::QFPRegsRegClass
.hasSubClassEq(RC
))
463 // Use LDQFri irrespective of its legality. If LDQ is not legal, it will be
464 // lowered into two LDDs in eliminateFrameIndex.
465 BuildMI(MBB
, I
, DL
, get(SP::LDQFri
), DestReg
).addFrameIndex(FI
).addImm(0)
468 llvm_unreachable("Can't load this register from stack slot");
471 unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction
*MF
) const
473 SparcMachineFunctionInfo
*SparcFI
= MF
->getInfo
<SparcMachineFunctionInfo
>();
474 unsigned GlobalBaseReg
= SparcFI
->getGlobalBaseReg();
475 if (GlobalBaseReg
!= 0)
476 return GlobalBaseReg
;
478 // Insert the set of GlobalBaseReg into the first MBB of the function
479 MachineBasicBlock
&FirstMBB
= MF
->front();
480 MachineBasicBlock::iterator MBBI
= FirstMBB
.begin();
481 MachineRegisterInfo
&RegInfo
= MF
->getRegInfo();
483 const TargetRegisterClass
*PtrRC
=
484 Subtarget
.is64Bit() ? &SP::I64RegsRegClass
: &SP::IntRegsRegClass
;
485 GlobalBaseReg
= RegInfo
.createVirtualRegister(PtrRC
);
489 BuildMI(FirstMBB
, MBBI
, dl
, get(SP::GETPCX
), GlobalBaseReg
);
490 SparcFI
->setGlobalBaseReg(GlobalBaseReg
);
491 return GlobalBaseReg
;
494 bool SparcInstrInfo::expandPostRAPseudo(MachineInstr
&MI
) const {
495 switch (MI
.getOpcode()) {
496 case TargetOpcode::LOAD_STACK_GUARD
: {
497 assert(Subtarget
.isTargetLinux() &&
498 "Only Linux target is expected to contain LOAD_STACK_GUARD");
499 // offsetof(tcbhead_t, stack_guard) from sysdeps/sparc/nptl/tls.h in glibc.
500 const int64_t Offset
= Subtarget
.is64Bit() ? 0x28 : 0x14;
501 MI
.setDesc(get(Subtarget
.is64Bit() ? SP::LDXri
: SP::LDri
));
502 MachineInstrBuilder(*MI
.getParent()->getParent(), MI
)