]>
git.proxmox.com Git - rustc.git/blob - src/llvm/lib/Target/Sparc/SparcInstrInfo.cpp
1 //===-- SparcInstrInfo.cpp - Sparc Instruction Information ----------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the Sparc implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
14 #include "SparcInstrInfo.h"
16 #include "SparcMachineFunctionInfo.h"
17 #include "SparcSubtarget.h"
18 #include "llvm/ADT/STLExtras.h"
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineMemOperand.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/Support/ErrorHandling.h"
25 #include "llvm/Support/TargetRegistry.h"
29 #define GET_INSTRINFO_CTOR_DTOR
30 #include "SparcGenInstrInfo.inc"
32 // Pin the vtable to this file.
33 void SparcInstrInfo::anchor() {}
35 SparcInstrInfo::SparcInstrInfo(SparcSubtarget
&ST
)
36 : SparcGenInstrInfo(SP::ADJCALLSTACKDOWN
, SP::ADJCALLSTACKUP
),
37 RI(ST
), Subtarget(ST
) {
40 /// isLoadFromStackSlot - If the specified machine instruction is a direct
41 /// load from a stack slot, return the virtual or physical register number of
42 /// the destination along with the FrameIndex of the loaded stack slot. If
43 /// not, return 0. This predicate must return 0 if the instruction has
44 /// any side effects other than loading from the stack slot.
45 unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
46 int &FrameIndex
) const {
47 if (MI
->getOpcode() == SP::LDri
||
48 MI
->getOpcode() == SP::LDXri
||
49 MI
->getOpcode() == SP::LDFri
||
50 MI
->getOpcode() == SP::LDDFri
||
51 MI
->getOpcode() == SP::LDQFri
) {
52 if (MI
->getOperand(1).isFI() && MI
->getOperand(2).isImm() &&
53 MI
->getOperand(2).getImm() == 0) {
54 FrameIndex
= MI
->getOperand(1).getIndex();
55 return MI
->getOperand(0).getReg();
61 /// isStoreToStackSlot - If the specified machine instruction is a direct
62 /// store to a stack slot, return the virtual or physical register number of
63 /// the source reg along with the FrameIndex of the loaded stack slot. If
64 /// not, return 0. This predicate must return 0 if the instruction has
65 /// any side effects other than storing to the stack slot.
66 unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
67 int &FrameIndex
) const {
68 if (MI
->getOpcode() == SP::STri
||
69 MI
->getOpcode() == SP::STXri
||
70 MI
->getOpcode() == SP::STFri
||
71 MI
->getOpcode() == SP::STDFri
||
72 MI
->getOpcode() == SP::STQFri
) {
73 if (MI
->getOperand(0).isFI() && MI
->getOperand(1).isImm() &&
74 MI
->getOperand(1).getImm() == 0) {
75 FrameIndex
= MI
->getOperand(0).getIndex();
76 return MI
->getOperand(2).getReg();
82 static bool IsIntegerCC(unsigned CC
)
84 return (CC
<= SPCC::ICC_VC
);
88 static SPCC::CondCodes
GetOppositeBranchCondition(SPCC::CondCodes CC
)
91 case SPCC::ICC_A
: return SPCC::ICC_N
;
92 case SPCC::ICC_N
: return SPCC::ICC_A
;
93 case SPCC::ICC_NE
: return SPCC::ICC_E
;
94 case SPCC::ICC_E
: return SPCC::ICC_NE
;
95 case SPCC::ICC_G
: return SPCC::ICC_LE
;
96 case SPCC::ICC_LE
: return SPCC::ICC_G
;
97 case SPCC::ICC_GE
: return SPCC::ICC_L
;
98 case SPCC::ICC_L
: return SPCC::ICC_GE
;
99 case SPCC::ICC_GU
: return SPCC::ICC_LEU
;
100 case SPCC::ICC_LEU
: return SPCC::ICC_GU
;
101 case SPCC::ICC_CC
: return SPCC::ICC_CS
;
102 case SPCC::ICC_CS
: return SPCC::ICC_CC
;
103 case SPCC::ICC_POS
: return SPCC::ICC_NEG
;
104 case SPCC::ICC_NEG
: return SPCC::ICC_POS
;
105 case SPCC::ICC_VC
: return SPCC::ICC_VS
;
106 case SPCC::ICC_VS
: return SPCC::ICC_VC
;
108 case SPCC::FCC_A
: return SPCC::FCC_N
;
109 case SPCC::FCC_N
: return SPCC::FCC_A
;
110 case SPCC::FCC_U
: return SPCC::FCC_O
;
111 case SPCC::FCC_O
: return SPCC::FCC_U
;
112 case SPCC::FCC_G
: return SPCC::FCC_ULE
;
113 case SPCC::FCC_LE
: return SPCC::FCC_UG
;
114 case SPCC::FCC_UG
: return SPCC::FCC_LE
;
115 case SPCC::FCC_ULE
: return SPCC::FCC_G
;
116 case SPCC::FCC_L
: return SPCC::FCC_UGE
;
117 case SPCC::FCC_GE
: return SPCC::FCC_UL
;
118 case SPCC::FCC_UL
: return SPCC::FCC_GE
;
119 case SPCC::FCC_UGE
: return SPCC::FCC_L
;
120 case SPCC::FCC_LG
: return SPCC::FCC_UE
;
121 case SPCC::FCC_UE
: return SPCC::FCC_LG
;
122 case SPCC::FCC_NE
: return SPCC::FCC_E
;
123 case SPCC::FCC_E
: return SPCC::FCC_NE
;
125 llvm_unreachable("Invalid cond code");
128 bool SparcInstrInfo::AnalyzeBranch(MachineBasicBlock
&MBB
,
129 MachineBasicBlock
*&TBB
,
130 MachineBasicBlock
*&FBB
,
131 SmallVectorImpl
<MachineOperand
> &Cond
,
132 bool AllowModify
) const
135 MachineBasicBlock::iterator I
= MBB
.end();
136 MachineBasicBlock::iterator UnCondBrIter
= MBB
.end();
137 while (I
!= MBB
.begin()) {
140 if (I
->isDebugValue())
143 // When we see a non-terminator, we are done.
144 if (!isUnpredicatedTerminator(I
))
147 // Terminator is not a branch.
151 // Handle Unconditional branches.
152 if (I
->getOpcode() == SP::BA
) {
156 TBB
= I
->getOperand(0).getMBB();
160 while (std::next(I
) != MBB
.end())
161 std::next(I
)->eraseFromParent();
166 if (MBB
.isLayoutSuccessor(I
->getOperand(0).getMBB())) {
168 I
->eraseFromParent();
170 UnCondBrIter
= MBB
.end();
174 TBB
= I
->getOperand(0).getMBB();
178 unsigned Opcode
= I
->getOpcode();
179 if (Opcode
!= SP::BCOND
&& Opcode
!= SP::FBCOND
)
180 return true; // Unknown Opcode.
182 SPCC::CondCodes BranchCode
= (SPCC::CondCodes
)I
->getOperand(1).getImm();
185 MachineBasicBlock
*TargetBB
= I
->getOperand(0).getMBB();
186 if (AllowModify
&& UnCondBrIter
!= MBB
.end() &&
187 MBB
.isLayoutSuccessor(TargetBB
)) {
189 // Transform the code
204 BranchCode
= GetOppositeBranchCondition(BranchCode
);
205 MachineBasicBlock::iterator OldInst
= I
;
206 BuildMI(MBB
, UnCondBrIter
, MBB
.findDebugLoc(I
), get(Opcode
))
207 .addMBB(UnCondBrIter
->getOperand(0).getMBB()).addImm(BranchCode
);
208 BuildMI(MBB
, UnCondBrIter
, MBB
.findDebugLoc(I
), get(SP::BA
))
211 OldInst
->eraseFromParent();
212 UnCondBrIter
->eraseFromParent();
214 UnCondBrIter
= MBB
.end();
219 TBB
= I
->getOperand(0).getMBB();
220 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
223 // FIXME: Handle subsequent conditional branches.
224 // For now, we can't handle multiple conditional branches.
231 SparcInstrInfo::InsertBranch(MachineBasicBlock
&MBB
,MachineBasicBlock
*TBB
,
232 MachineBasicBlock
*FBB
,
233 const SmallVectorImpl
<MachineOperand
> &Cond
,
235 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
236 assert((Cond
.size() == 1 || Cond
.size() == 0) &&
237 "Sparc branch conditions should have one component!");
240 assert(!FBB
&& "Unconditional branch with multiple successors!");
241 BuildMI(&MBB
, DL
, get(SP::BA
)).addMBB(TBB
);
245 // Conditional branch
246 unsigned CC
= Cond
[0].getImm();
249 BuildMI(&MBB
, DL
, get(SP::BCOND
)).addMBB(TBB
).addImm(CC
);
251 BuildMI(&MBB
, DL
, get(SP::FBCOND
)).addMBB(TBB
).addImm(CC
);
255 BuildMI(&MBB
, DL
, get(SP::BA
)).addMBB(FBB
);
259 unsigned SparcInstrInfo::RemoveBranch(MachineBasicBlock
&MBB
) const
261 MachineBasicBlock::iterator I
= MBB
.end();
263 while (I
!= MBB
.begin()) {
266 if (I
->isDebugValue())
269 if (I
->getOpcode() != SP::BA
270 && I
->getOpcode() != SP::BCOND
271 && I
->getOpcode() != SP::FBCOND
)
272 break; // Not a branch
274 I
->eraseFromParent();
281 void SparcInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
282 MachineBasicBlock::iterator I
, DebugLoc DL
,
283 unsigned DestReg
, unsigned SrcReg
,
284 bool KillSrc
) const {
285 unsigned numSubRegs
= 0;
287 const unsigned *subRegIdx
= nullptr;
289 const unsigned DFP_FP_SubRegsIdx
[] = { SP::sub_even
, SP::sub_odd
};
290 const unsigned QFP_DFP_SubRegsIdx
[] = { SP::sub_even64
, SP::sub_odd64
};
291 const unsigned QFP_FP_SubRegsIdx
[] = { SP::sub_even
, SP::sub_odd
,
292 SP::sub_odd64_then_sub_even
,
293 SP::sub_odd64_then_sub_odd
};
295 if (SP::IntRegsRegClass
.contains(DestReg
, SrcReg
))
296 BuildMI(MBB
, I
, DL
, get(SP::ORrr
), DestReg
).addReg(SP::G0
)
297 .addReg(SrcReg
, getKillRegState(KillSrc
));
298 else if (SP::FPRegsRegClass
.contains(DestReg
, SrcReg
))
299 BuildMI(MBB
, I
, DL
, get(SP::FMOVS
), DestReg
)
300 .addReg(SrcReg
, getKillRegState(KillSrc
));
301 else if (SP::DFPRegsRegClass
.contains(DestReg
, SrcReg
)) {
302 if (Subtarget
.isV9()) {
303 BuildMI(MBB
, I
, DL
, get(SP::FMOVD
), DestReg
)
304 .addReg(SrcReg
, getKillRegState(KillSrc
));
306 // Use two FMOVS instructions.
307 subRegIdx
= DFP_FP_SubRegsIdx
;
311 } else if (SP::QFPRegsRegClass
.contains(DestReg
, SrcReg
)) {
312 if (Subtarget
.isV9()) {
313 if (Subtarget
.hasHardQuad()) {
314 BuildMI(MBB
, I
, DL
, get(SP::FMOVQ
), DestReg
)
315 .addReg(SrcReg
, getKillRegState(KillSrc
));
317 // Use two FMOVD instructions.
318 subRegIdx
= QFP_DFP_SubRegsIdx
;
323 // Use four FMOVS instructions.
324 subRegIdx
= QFP_FP_SubRegsIdx
;
329 llvm_unreachable("Impossible reg-to-reg copy");
331 if (numSubRegs
== 0 || subRegIdx
== nullptr || movOpc
== 0)
334 const TargetRegisterInfo
*TRI
= &getRegisterInfo();
335 MachineInstr
*MovMI
= nullptr;
337 for (unsigned i
= 0; i
!= numSubRegs
; ++i
) {
338 unsigned Dst
= TRI
->getSubReg(DestReg
, subRegIdx
[i
]);
339 unsigned Src
= TRI
->getSubReg(SrcReg
, subRegIdx
[i
]);
340 assert(Dst
&& Src
&& "Bad sub-register");
342 MovMI
= BuildMI(MBB
, I
, DL
, get(movOpc
), Dst
).addReg(Src
);
344 // Add implicit super-register defs and kills to the last MovMI.
345 MovMI
->addRegisterDefined(DestReg
, TRI
);
347 MovMI
->addRegisterKilled(SrcReg
, TRI
);
350 void SparcInstrInfo::
351 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
352 unsigned SrcReg
, bool isKill
, int FI
,
353 const TargetRegisterClass
*RC
,
354 const TargetRegisterInfo
*TRI
) const {
356 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
358 MachineFunction
*MF
= MBB
.getParent();
359 const MachineFrameInfo
&MFI
= *MF
->getFrameInfo();
360 MachineMemOperand
*MMO
=
361 MF
->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI
),
362 MachineMemOperand::MOStore
,
363 MFI
.getObjectSize(FI
),
364 MFI
.getObjectAlignment(FI
));
366 // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
367 if (RC
== &SP::I64RegsRegClass
)
368 BuildMI(MBB
, I
, DL
, get(SP::STXri
)).addFrameIndex(FI
).addImm(0)
369 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
370 else if (RC
== &SP::IntRegsRegClass
)
371 BuildMI(MBB
, I
, DL
, get(SP::STri
)).addFrameIndex(FI
).addImm(0)
372 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
373 else if (RC
== &SP::FPRegsRegClass
)
374 BuildMI(MBB
, I
, DL
, get(SP::STFri
)).addFrameIndex(FI
).addImm(0)
375 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
376 else if (SP::DFPRegsRegClass
.hasSubClassEq(RC
))
377 BuildMI(MBB
, I
, DL
, get(SP::STDFri
)).addFrameIndex(FI
).addImm(0)
378 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
379 else if (SP::QFPRegsRegClass
.hasSubClassEq(RC
))
380 // Use STQFri irrespective of its legality. If STQ is not legal, it will be
381 // lowered into two STDs in eliminateFrameIndex.
382 BuildMI(MBB
, I
, DL
, get(SP::STQFri
)).addFrameIndex(FI
).addImm(0)
383 .addReg(SrcReg
, getKillRegState(isKill
)).addMemOperand(MMO
);
385 llvm_unreachable("Can't store this register to stack slot");
388 void SparcInstrInfo::
389 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
390 unsigned DestReg
, int FI
,
391 const TargetRegisterClass
*RC
,
392 const TargetRegisterInfo
*TRI
) const {
394 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
396 MachineFunction
*MF
= MBB
.getParent();
397 const MachineFrameInfo
&MFI
= *MF
->getFrameInfo();
398 MachineMemOperand
*MMO
=
399 MF
->getMachineMemOperand(MachinePointerInfo::getFixedStack(FI
),
400 MachineMemOperand::MOLoad
,
401 MFI
.getObjectSize(FI
),
402 MFI
.getObjectAlignment(FI
));
404 if (RC
== &SP::I64RegsRegClass
)
405 BuildMI(MBB
, I
, DL
, get(SP::LDXri
), DestReg
).addFrameIndex(FI
).addImm(0)
407 else if (RC
== &SP::IntRegsRegClass
)
408 BuildMI(MBB
, I
, DL
, get(SP::LDri
), DestReg
).addFrameIndex(FI
).addImm(0)
410 else if (RC
== &SP::FPRegsRegClass
)
411 BuildMI(MBB
, I
, DL
, get(SP::LDFri
), DestReg
).addFrameIndex(FI
).addImm(0)
413 else if (SP::DFPRegsRegClass
.hasSubClassEq(RC
))
414 BuildMI(MBB
, I
, DL
, get(SP::LDDFri
), DestReg
).addFrameIndex(FI
).addImm(0)
416 else if (SP::QFPRegsRegClass
.hasSubClassEq(RC
))
417 // Use LDQFri irrespective of its legality. If LDQ is not legal, it will be
418 // lowered into two LDDs in eliminateFrameIndex.
419 BuildMI(MBB
, I
, DL
, get(SP::LDQFri
), DestReg
).addFrameIndex(FI
).addImm(0)
422 llvm_unreachable("Can't load this register from stack slot");
425 unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction
*MF
) const
427 SparcMachineFunctionInfo
*SparcFI
= MF
->getInfo
<SparcMachineFunctionInfo
>();
428 unsigned GlobalBaseReg
= SparcFI
->getGlobalBaseReg();
429 if (GlobalBaseReg
!= 0)
430 return GlobalBaseReg
;
432 // Insert the set of GlobalBaseReg into the first MBB of the function
433 MachineBasicBlock
&FirstMBB
= MF
->front();
434 MachineBasicBlock::iterator MBBI
= FirstMBB
.begin();
435 MachineRegisterInfo
&RegInfo
= MF
->getRegInfo();
437 const TargetRegisterClass
*PtrRC
=
438 Subtarget
.is64Bit() ? &SP::I64RegsRegClass
: &SP::IntRegsRegClass
;
439 GlobalBaseReg
= RegInfo
.createVirtualRegister(PtrRC
);
443 BuildMI(FirstMBB
, MBBI
, dl
, get(SP::GETPCX
), GlobalBaseReg
);
444 SparcFI
->setGlobalBaseReg(GlobalBaseReg
);
445 return GlobalBaseReg
;