1 //===- SystemZInstrInfo.cpp - SystemZ 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 SystemZ implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 #include "SystemZInstrBuilder.h"
16 #include "SystemZInstrInfo.h"
17 #include "SystemZMachineFunctionInfo.h"
18 #include "SystemZTargetMachine.h"
19 #include "SystemZGenInstrInfo.inc"
20 #include "llvm/Function.h"
21 #include "llvm/CodeGen/MachineFrameInfo.h"
22 #include "llvm/CodeGen/MachineInstrBuilder.h"
23 #include "llvm/CodeGen/MachineRegisterInfo.h"
24 #include "llvm/CodeGen/PseudoSourceValue.h"
25 #include "llvm/Support/ErrorHandling.h"
28 SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine
&tm
)
29 : TargetInstrInfoImpl(SystemZInsts
, array_lengthof(SystemZInsts
)),
30 RI(tm
, *this), TM(tm
) {
33 /// isGVStub - Return true if the GV requires an extra load to get the
35 static inline bool isGVStub(GlobalValue
*GV
, SystemZTargetMachine
&TM
) {
36 return TM
.getSubtarget
<SystemZSubtarget
>().GVRequiresExtraLoad(GV
, TM
, false);
39 void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock
&MBB
,
40 MachineBasicBlock::iterator MI
,
41 unsigned SrcReg
, bool isKill
, int FrameIdx
,
42 const TargetRegisterClass
*RC
,
43 const TargetRegisterInfo
*TRI
) const {
45 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
48 if (RC
== &SystemZ::GR32RegClass
||
49 RC
== &SystemZ::ADDR32RegClass
)
50 Opc
= SystemZ::MOV32mr
;
51 else if (RC
== &SystemZ::GR64RegClass
||
52 RC
== &SystemZ::ADDR64RegClass
) {
53 Opc
= SystemZ::MOV64mr
;
54 } else if (RC
== &SystemZ::FP32RegClass
) {
55 Opc
= SystemZ::FMOV32mr
;
56 } else if (RC
== &SystemZ::FP64RegClass
) {
57 Opc
= SystemZ::FMOV64mr
;
58 } else if (RC
== &SystemZ::GR64PRegClass
) {
59 Opc
= SystemZ::MOV64Pmr
;
60 } else if (RC
== &SystemZ::GR128RegClass
) {
61 Opc
= SystemZ::MOV128mr
;
63 llvm_unreachable("Unsupported regclass to store");
65 addFrameReference(BuildMI(MBB
, MI
, DL
, get(Opc
)), FrameIdx
)
66 .addReg(SrcReg
, getKillRegState(isKill
));
69 void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock
&MBB
,
70 MachineBasicBlock::iterator MI
,
71 unsigned DestReg
, int FrameIdx
,
72 const TargetRegisterClass
*RC
,
73 const TargetRegisterInfo
*TRI
) const{
75 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
78 if (RC
== &SystemZ::GR32RegClass
||
79 RC
== &SystemZ::ADDR32RegClass
)
80 Opc
= SystemZ::MOV32rm
;
81 else if (RC
== &SystemZ::GR64RegClass
||
82 RC
== &SystemZ::ADDR64RegClass
) {
83 Opc
= SystemZ::MOV64rm
;
84 } else if (RC
== &SystemZ::FP32RegClass
) {
85 Opc
= SystemZ::FMOV32rm
;
86 } else if (RC
== &SystemZ::FP64RegClass
) {
87 Opc
= SystemZ::FMOV64rm
;
88 } else if (RC
== &SystemZ::GR64PRegClass
) {
89 Opc
= SystemZ::MOV64Prm
;
90 } else if (RC
== &SystemZ::GR128RegClass
) {
91 Opc
= SystemZ::MOV128rm
;
93 llvm_unreachable("Unsupported regclass to load");
95 addFrameReference(BuildMI(MBB
, MI
, DL
, get(Opc
), DestReg
), FrameIdx
);
98 void SystemZInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
99 MachineBasicBlock::iterator I
, DebugLoc DL
,
100 unsigned DestReg
, unsigned SrcReg
,
101 bool KillSrc
) const {
103 if (SystemZ::GR64RegClass
.contains(DestReg
, SrcReg
))
104 Opc
= SystemZ::MOV64rr
;
105 else if (SystemZ::GR32RegClass
.contains(DestReg
, SrcReg
))
106 Opc
= SystemZ::MOV32rr
;
107 else if (SystemZ::GR64PRegClass
.contains(DestReg
, SrcReg
))
108 Opc
= SystemZ::MOV64rrP
;
109 else if (SystemZ::GR128RegClass
.contains(DestReg
, SrcReg
))
110 Opc
= SystemZ::MOV128rr
;
111 else if (SystemZ::FP32RegClass
.contains(DestReg
, SrcReg
))
112 Opc
= SystemZ::FMOV32rr
;
113 else if (SystemZ::FP64RegClass
.contains(DestReg
, SrcReg
))
114 Opc
= SystemZ::FMOV64rr
;
116 llvm_unreachable("Impossible reg-to-reg copy");
118 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
)
119 .addReg(SrcReg
, getKillRegState(KillSrc
));
122 unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
123 int &FrameIndex
) const {
124 switch (MI
->getOpcode()) {
126 case SystemZ::MOV32rm
:
127 case SystemZ::MOV32rmy
:
128 case SystemZ::MOV64rm
:
129 case SystemZ::MOVSX32rm8
:
130 case SystemZ::MOVSX32rm16y
:
131 case SystemZ::MOVSX64rm8
:
132 case SystemZ::MOVSX64rm16
:
133 case SystemZ::MOVSX64rm32
:
134 case SystemZ::MOVZX32rm8
:
135 case SystemZ::MOVZX32rm16
:
136 case SystemZ::MOVZX64rm8
:
137 case SystemZ::MOVZX64rm16
:
138 case SystemZ::MOVZX64rm32
:
139 case SystemZ::FMOV32rm
:
140 case SystemZ::FMOV32rmy
:
141 case SystemZ::FMOV64rm
:
142 case SystemZ::FMOV64rmy
:
143 case SystemZ::MOV64Prm
:
144 case SystemZ::MOV64Prmy
:
145 case SystemZ::MOV128rm
:
146 if (MI
->getOperand(1).isFI() &&
147 MI
->getOperand(2).isImm() && MI
->getOperand(3).isReg() &&
148 MI
->getOperand(2).getImm() == 0 && MI
->getOperand(3).getReg() == 0) {
149 FrameIndex
= MI
->getOperand(1).getIndex();
150 return MI
->getOperand(0).getReg();
157 unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
158 int &FrameIndex
) const {
159 switch (MI
->getOpcode()) {
161 case SystemZ::MOV32mr
:
162 case SystemZ::MOV32mry
:
163 case SystemZ::MOV64mr
:
164 case SystemZ::MOV32m8r
:
165 case SystemZ::MOV32m8ry
:
166 case SystemZ::MOV32m16r
:
167 case SystemZ::MOV32m16ry
:
168 case SystemZ::MOV64m8r
:
169 case SystemZ::MOV64m8ry
:
170 case SystemZ::MOV64m16r
:
171 case SystemZ::MOV64m16ry
:
172 case SystemZ::MOV64m32r
:
173 case SystemZ::MOV64m32ry
:
174 case SystemZ::FMOV32mr
:
175 case SystemZ::FMOV32mry
:
176 case SystemZ::FMOV64mr
:
177 case SystemZ::FMOV64mry
:
178 case SystemZ::MOV64Pmr
:
179 case SystemZ::MOV64Pmry
:
180 case SystemZ::MOV128mr
:
181 if (MI
->getOperand(0).isFI() &&
182 MI
->getOperand(1).isImm() && MI
->getOperand(2).isReg() &&
183 MI
->getOperand(1).getImm() == 0 && MI
->getOperand(2).getReg() == 0) {
184 FrameIndex
= MI
->getOperand(0).getIndex();
185 return MI
->getOperand(3).getReg();
192 bool SystemZInstrInfo::
193 ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const {
194 assert(Cond
.size() == 1 && "Invalid Xbranch condition!");
196 SystemZCC::CondCodes CC
= static_cast<SystemZCC::CondCodes
>(Cond
[0].getImm());
197 Cond
[0].setImm(getOppositeCondition(CC
));
201 bool SystemZInstrInfo::isUnpredicatedTerminator(const MachineInstr
*MI
) const {
202 const TargetInstrDesc
&TID
= MI
->getDesc();
203 if (!TID
.isTerminator()) return false;
205 // Conditional branch is a special case.
206 if (TID
.isBranch() && !TID
.isBarrier())
208 if (!TID
.isPredicable())
210 return !isPredicated(MI
);
213 bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock
&MBB
,
214 MachineBasicBlock
*&TBB
,
215 MachineBasicBlock
*&FBB
,
216 SmallVectorImpl
<MachineOperand
> &Cond
,
217 bool AllowModify
) const {
218 // Start from the bottom of the block and work up, examining the
219 // terminator instructions.
220 MachineBasicBlock::iterator I
= MBB
.end();
221 while (I
!= MBB
.begin()) {
223 if (I
->isDebugValue())
225 // Working from the bottom, when we see a non-terminator
226 // instruction, we're done.
227 if (!isUnpredicatedTerminator(I
))
230 // A terminator that isn't a branch can't easily be handled
232 if (!I
->getDesc().isBranch())
235 // Handle unconditional branches.
236 if (I
->getOpcode() == SystemZ::JMP
) {
238 TBB
= I
->getOperand(0).getMBB();
242 // If the block has any instructions after a JMP, delete them.
243 while (llvm::next(I
) != MBB
.end())
244 llvm::next(I
)->eraseFromParent();
248 // Delete the JMP if it's equivalent to a fall-through.
249 if (MBB
.isLayoutSuccessor(I
->getOperand(0).getMBB())) {
251 I
->eraseFromParent();
256 // TBB is used to indicate the unconditinal destination.
257 TBB
= I
->getOperand(0).getMBB();
261 // Handle conditional branches.
262 SystemZCC::CondCodes BranchCode
= getCondFromBranchOpc(I
->getOpcode());
263 if (BranchCode
== SystemZCC::INVALID
)
264 return true; // Can't handle indirect branch.
266 // Working from the bottom, handle the first conditional branch.
269 TBB
= I
->getOperand(0).getMBB();
270 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
274 // Handle subsequent conditional branches. Only handle the case where all
275 // conditional branches branch to the same destination.
276 assert(Cond
.size() == 1);
279 // Only handle the case where all conditional branches branch to
280 // the same destination.
281 if (TBB
!= I
->getOperand(0).getMBB())
284 SystemZCC::CondCodes OldBranchCode
= (SystemZCC::CondCodes
)Cond
[0].getImm();
285 // If the conditions are the same, we can leave them alone.
286 if (OldBranchCode
== BranchCode
)
295 unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock
&MBB
) const {
296 MachineBasicBlock::iterator I
= MBB
.end();
299 while (I
!= MBB
.begin()) {
301 if (I
->isDebugValue())
303 if (I
->getOpcode() != SystemZ::JMP
&&
304 getCondFromBranchOpc(I
->getOpcode()) == SystemZCC::INVALID
)
306 // Remove the branch.
307 I
->eraseFromParent();
316 SystemZInstrInfo::InsertBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*TBB
,
317 MachineBasicBlock
*FBB
,
318 const SmallVectorImpl
<MachineOperand
> &Cond
,
320 // Shouldn't be a fall through.
321 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
322 assert((Cond
.size() == 1 || Cond
.size() == 0) &&
323 "SystemZ branch conditions have one component!");
326 // Unconditional branch?
327 assert(!FBB
&& "Unconditional branch with multiple successors!");
328 BuildMI(&MBB
, DL
, get(SystemZ::JMP
)).addMBB(TBB
);
332 // Conditional branch.
334 SystemZCC::CondCodes CC
= (SystemZCC::CondCodes
)Cond
[0].getImm();
335 BuildMI(&MBB
, DL
, getBrCond(CC
)).addMBB(TBB
);
339 // Two-way Conditional branch. Insert the second branch.
340 BuildMI(&MBB
, DL
, get(SystemZ::JMP
)).addMBB(FBB
);
346 const TargetInstrDesc
&
347 SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC
) const {
350 llvm_unreachable("Unknown condition code!");
351 case SystemZCC::O
: return get(SystemZ::JO
);
352 case SystemZCC::H
: return get(SystemZ::JH
);
353 case SystemZCC::NLE
: return get(SystemZ::JNLE
);
354 case SystemZCC::L
: return get(SystemZ::JL
);
355 case SystemZCC::NHE
: return get(SystemZ::JNHE
);
356 case SystemZCC::LH
: return get(SystemZ::JLH
);
357 case SystemZCC::NE
: return get(SystemZ::JNE
);
358 case SystemZCC::E
: return get(SystemZ::JE
);
359 case SystemZCC::NLH
: return get(SystemZ::JNLH
);
360 case SystemZCC::HE
: return get(SystemZ::JHE
);
361 case SystemZCC::NL
: return get(SystemZ::JNL
);
362 case SystemZCC::LE
: return get(SystemZ::JLE
);
363 case SystemZCC::NH
: return get(SystemZ::JNH
);
364 case SystemZCC::NO
: return get(SystemZ::JNO
);
369 SystemZInstrInfo::getCondFromBranchOpc(unsigned Opc
) const {
371 default: return SystemZCC::INVALID
;
372 case SystemZ::JO
: return SystemZCC::O
;
373 case SystemZ::JH
: return SystemZCC::H
;
374 case SystemZ::JNLE
: return SystemZCC::NLE
;
375 case SystemZ::JL
: return SystemZCC::L
;
376 case SystemZ::JNHE
: return SystemZCC::NHE
;
377 case SystemZ::JLH
: return SystemZCC::LH
;
378 case SystemZ::JNE
: return SystemZCC::NE
;
379 case SystemZ::JE
: return SystemZCC::E
;
380 case SystemZ::JNLH
: return SystemZCC::NLH
;
381 case SystemZ::JHE
: return SystemZCC::HE
;
382 case SystemZ::JNL
: return SystemZCC::NL
;
383 case SystemZ::JLE
: return SystemZCC::LE
;
384 case SystemZ::JNH
: return SystemZCC::NH
;
385 case SystemZ::JNO
: return SystemZCC::NO
;
390 SystemZInstrInfo::getOppositeCondition(SystemZCC::CondCodes CC
) const {
393 llvm_unreachable("Invalid condition!");
394 case SystemZCC::O
: return SystemZCC::NO
;
395 case SystemZCC::H
: return SystemZCC::NH
;
396 case SystemZCC::NLE
: return SystemZCC::LE
;
397 case SystemZCC::L
: return SystemZCC::NL
;
398 case SystemZCC::NHE
: return SystemZCC::HE
;
399 case SystemZCC::LH
: return SystemZCC::NLH
;
400 case SystemZCC::NE
: return SystemZCC::E
;
401 case SystemZCC::E
: return SystemZCC::NE
;
402 case SystemZCC::NLH
: return SystemZCC::LH
;
403 case SystemZCC::HE
: return SystemZCC::NHE
;
404 case SystemZCC::NL
: return SystemZCC::L
;
405 case SystemZCC::LE
: return SystemZCC::NLE
;
406 case SystemZCC::NH
: return SystemZCC::H
;
407 case SystemZCC::NO
: return SystemZCC::O
;
411 const TargetInstrDesc
&
412 SystemZInstrInfo::getLongDispOpc(unsigned Opc
) const {
415 llvm_unreachable("Don't have long disp version of this instruction");
416 case SystemZ::MOV32mr
: return get(SystemZ::MOV32mry
);
417 case SystemZ::MOV32rm
: return get(SystemZ::MOV32rmy
);
418 case SystemZ::MOVSX32rm16
: return get(SystemZ::MOVSX32rm16y
);
419 case SystemZ::MOV32m8r
: return get(SystemZ::MOV32m8ry
);
420 case SystemZ::MOV32m16r
: return get(SystemZ::MOV32m16ry
);
421 case SystemZ::MOV64m8r
: return get(SystemZ::MOV64m8ry
);
422 case SystemZ::MOV64m16r
: return get(SystemZ::MOV64m16ry
);
423 case SystemZ::MOV64m32r
: return get(SystemZ::MOV64m32ry
);
424 case SystemZ::MOV8mi
: return get(SystemZ::MOV8miy
);
425 case SystemZ::MUL32rm
: return get(SystemZ::MUL32rmy
);
426 case SystemZ::CMP32rm
: return get(SystemZ::CMP32rmy
);
427 case SystemZ::UCMP32rm
: return get(SystemZ::UCMP32rmy
);
428 case SystemZ::FMOV32mr
: return get(SystemZ::FMOV32mry
);
429 case SystemZ::FMOV64mr
: return get(SystemZ::FMOV64mry
);
430 case SystemZ::FMOV32rm
: return get(SystemZ::FMOV32rmy
);
431 case SystemZ::FMOV64rm
: return get(SystemZ::FMOV64rmy
);
432 case SystemZ::MOV64Pmr
: return get(SystemZ::MOV64Pmry
);
433 case SystemZ::MOV64Prm
: return get(SystemZ::MOV64Prmy
);