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 "llvm/Function.h"
20 #include "llvm/CodeGen/MachineFrameInfo.h"
21 #include "llvm/CodeGen/MachineInstrBuilder.h"
22 #include "llvm/CodeGen/MachineRegisterInfo.h"
23 #include "llvm/CodeGen/PseudoSourceValue.h"
24 #include "llvm/Support/ErrorHandling.h"
26 #define GET_INSTRINFO_CTOR
27 #define GET_INSTRINFO_MC_DESC
28 #include "SystemZGenInstrInfo.inc"
32 SystemZInstrInfo::SystemZInstrInfo(SystemZTargetMachine
&tm
)
33 : SystemZGenInstrInfo(SystemZ::ADJCALLSTACKUP
, SystemZ::ADJCALLSTACKDOWN
),
34 RI(tm
, *this), TM(tm
) {
37 /// isGVStub - Return true if the GV requires an extra load to get the
39 static inline bool isGVStub(GlobalValue
*GV
, SystemZTargetMachine
&TM
) {
40 return TM
.getSubtarget
<SystemZSubtarget
>().GVRequiresExtraLoad(GV
, TM
, false);
43 void SystemZInstrInfo::storeRegToStackSlot(MachineBasicBlock
&MBB
,
44 MachineBasicBlock::iterator MI
,
45 unsigned SrcReg
, bool isKill
, int FrameIdx
,
46 const TargetRegisterClass
*RC
,
47 const TargetRegisterInfo
*TRI
) const {
49 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
52 if (RC
== &SystemZ::GR32RegClass
||
53 RC
== &SystemZ::ADDR32RegClass
)
54 Opc
= SystemZ::MOV32mr
;
55 else if (RC
== &SystemZ::GR64RegClass
||
56 RC
== &SystemZ::ADDR64RegClass
) {
57 Opc
= SystemZ::MOV64mr
;
58 } else if (RC
== &SystemZ::FP32RegClass
) {
59 Opc
= SystemZ::FMOV32mr
;
60 } else if (RC
== &SystemZ::FP64RegClass
) {
61 Opc
= SystemZ::FMOV64mr
;
62 } else if (RC
== &SystemZ::GR64PRegClass
) {
63 Opc
= SystemZ::MOV64Pmr
;
64 } else if (RC
== &SystemZ::GR128RegClass
) {
65 Opc
= SystemZ::MOV128mr
;
67 llvm_unreachable("Unsupported regclass to store");
69 addFrameReference(BuildMI(MBB
, MI
, DL
, get(Opc
)), FrameIdx
)
70 .addReg(SrcReg
, getKillRegState(isKill
));
73 void SystemZInstrInfo::loadRegFromStackSlot(MachineBasicBlock
&MBB
,
74 MachineBasicBlock::iterator MI
,
75 unsigned DestReg
, int FrameIdx
,
76 const TargetRegisterClass
*RC
,
77 const TargetRegisterInfo
*TRI
) const{
79 if (MI
!= MBB
.end()) DL
= MI
->getDebugLoc();
82 if (RC
== &SystemZ::GR32RegClass
||
83 RC
== &SystemZ::ADDR32RegClass
)
84 Opc
= SystemZ::MOV32rm
;
85 else if (RC
== &SystemZ::GR64RegClass
||
86 RC
== &SystemZ::ADDR64RegClass
) {
87 Opc
= SystemZ::MOV64rm
;
88 } else if (RC
== &SystemZ::FP32RegClass
) {
89 Opc
= SystemZ::FMOV32rm
;
90 } else if (RC
== &SystemZ::FP64RegClass
) {
91 Opc
= SystemZ::FMOV64rm
;
92 } else if (RC
== &SystemZ::GR64PRegClass
) {
93 Opc
= SystemZ::MOV64Prm
;
94 } else if (RC
== &SystemZ::GR128RegClass
) {
95 Opc
= SystemZ::MOV128rm
;
97 llvm_unreachable("Unsupported regclass to load");
99 addFrameReference(BuildMI(MBB
, MI
, DL
, get(Opc
), DestReg
), FrameIdx
);
102 void SystemZInstrInfo::copyPhysReg(MachineBasicBlock
&MBB
,
103 MachineBasicBlock::iterator I
, DebugLoc DL
,
104 unsigned DestReg
, unsigned SrcReg
,
105 bool KillSrc
) const {
107 if (SystemZ::GR64RegClass
.contains(DestReg
, SrcReg
))
108 Opc
= SystemZ::MOV64rr
;
109 else if (SystemZ::GR32RegClass
.contains(DestReg
, SrcReg
))
110 Opc
= SystemZ::MOV32rr
;
111 else if (SystemZ::GR64PRegClass
.contains(DestReg
, SrcReg
))
112 Opc
= SystemZ::MOV64rrP
;
113 else if (SystemZ::GR128RegClass
.contains(DestReg
, SrcReg
))
114 Opc
= SystemZ::MOV128rr
;
115 else if (SystemZ::FP32RegClass
.contains(DestReg
, SrcReg
))
116 Opc
= SystemZ::FMOV32rr
;
117 else if (SystemZ::FP64RegClass
.contains(DestReg
, SrcReg
))
118 Opc
= SystemZ::FMOV64rr
;
120 llvm_unreachable("Impossible reg-to-reg copy");
122 BuildMI(MBB
, I
, DL
, get(Opc
), DestReg
)
123 .addReg(SrcReg
, getKillRegState(KillSrc
));
126 unsigned SystemZInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
127 int &FrameIndex
) const {
128 switch (MI
->getOpcode()) {
130 case SystemZ::MOV32rm
:
131 case SystemZ::MOV32rmy
:
132 case SystemZ::MOV64rm
:
133 case SystemZ::MOVSX32rm8
:
134 case SystemZ::MOVSX32rm16y
:
135 case SystemZ::MOVSX64rm8
:
136 case SystemZ::MOVSX64rm16
:
137 case SystemZ::MOVSX64rm32
:
138 case SystemZ::MOVZX32rm8
:
139 case SystemZ::MOVZX32rm16
:
140 case SystemZ::MOVZX64rm8
:
141 case SystemZ::MOVZX64rm16
:
142 case SystemZ::MOVZX64rm32
:
143 case SystemZ::FMOV32rm
:
144 case SystemZ::FMOV32rmy
:
145 case SystemZ::FMOV64rm
:
146 case SystemZ::FMOV64rmy
:
147 case SystemZ::MOV64Prm
:
148 case SystemZ::MOV64Prmy
:
149 case SystemZ::MOV128rm
:
150 if (MI
->getOperand(1).isFI() &&
151 MI
->getOperand(2).isImm() && MI
->getOperand(3).isReg() &&
152 MI
->getOperand(2).getImm() == 0 && MI
->getOperand(3).getReg() == 0) {
153 FrameIndex
= MI
->getOperand(1).getIndex();
154 return MI
->getOperand(0).getReg();
161 unsigned SystemZInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
162 int &FrameIndex
) const {
163 switch (MI
->getOpcode()) {
165 case SystemZ::MOV32mr
:
166 case SystemZ::MOV32mry
:
167 case SystemZ::MOV64mr
:
168 case SystemZ::MOV32m8r
:
169 case SystemZ::MOV32m8ry
:
170 case SystemZ::MOV32m16r
:
171 case SystemZ::MOV32m16ry
:
172 case SystemZ::MOV64m8r
:
173 case SystemZ::MOV64m8ry
:
174 case SystemZ::MOV64m16r
:
175 case SystemZ::MOV64m16ry
:
176 case SystemZ::MOV64m32r
:
177 case SystemZ::MOV64m32ry
:
178 case SystemZ::FMOV32mr
:
179 case SystemZ::FMOV32mry
:
180 case SystemZ::FMOV64mr
:
181 case SystemZ::FMOV64mry
:
182 case SystemZ::MOV64Pmr
:
183 case SystemZ::MOV64Pmry
:
184 case SystemZ::MOV128mr
:
185 if (MI
->getOperand(0).isFI() &&
186 MI
->getOperand(1).isImm() && MI
->getOperand(2).isReg() &&
187 MI
->getOperand(1).getImm() == 0 && MI
->getOperand(2).getReg() == 0) {
188 FrameIndex
= MI
->getOperand(0).getIndex();
189 return MI
->getOperand(3).getReg();
196 bool SystemZInstrInfo::
197 ReverseBranchCondition(SmallVectorImpl
<MachineOperand
> &Cond
) const {
198 assert(Cond
.size() == 1 && "Invalid Xbranch condition!");
200 SystemZCC::CondCodes CC
= static_cast<SystemZCC::CondCodes
>(Cond
[0].getImm());
201 Cond
[0].setImm(getOppositeCondition(CC
));
205 bool SystemZInstrInfo::isUnpredicatedTerminator(const MachineInstr
*MI
) const {
206 const MCInstrDesc
&MCID
= MI
->getDesc();
207 if (!MCID
.isTerminator()) return false;
209 // Conditional branch is a special case.
210 if (MCID
.isBranch() && !MCID
.isBarrier())
212 if (!MCID
.isPredicable())
214 return !isPredicated(MI
);
217 bool SystemZInstrInfo::AnalyzeBranch(MachineBasicBlock
&MBB
,
218 MachineBasicBlock
*&TBB
,
219 MachineBasicBlock
*&FBB
,
220 SmallVectorImpl
<MachineOperand
> &Cond
,
221 bool AllowModify
) const {
222 // Start from the bottom of the block and work up, examining the
223 // terminator instructions.
224 MachineBasicBlock::iterator I
= MBB
.end();
225 while (I
!= MBB
.begin()) {
227 if (I
->isDebugValue())
229 // Working from the bottom, when we see a non-terminator
230 // instruction, we're done.
231 if (!isUnpredicatedTerminator(I
))
234 // A terminator that isn't a branch can't easily be handled
236 if (!I
->getDesc().isBranch())
239 // Handle unconditional branches.
240 if (I
->getOpcode() == SystemZ::JMP
) {
242 TBB
= I
->getOperand(0).getMBB();
246 // If the block has any instructions after a JMP, delete them.
247 while (llvm::next(I
) != MBB
.end())
248 llvm::next(I
)->eraseFromParent();
252 // Delete the JMP if it's equivalent to a fall-through.
253 if (MBB
.isLayoutSuccessor(I
->getOperand(0).getMBB())) {
255 I
->eraseFromParent();
260 // TBB is used to indicate the unconditinal destination.
261 TBB
= I
->getOperand(0).getMBB();
265 // Handle conditional branches.
266 SystemZCC::CondCodes BranchCode
= getCondFromBranchOpc(I
->getOpcode());
267 if (BranchCode
== SystemZCC::INVALID
)
268 return true; // Can't handle indirect branch.
270 // Working from the bottom, handle the first conditional branch.
273 TBB
= I
->getOperand(0).getMBB();
274 Cond
.push_back(MachineOperand::CreateImm(BranchCode
));
278 // Handle subsequent conditional branches. Only handle the case where all
279 // conditional branches branch to the same destination.
280 assert(Cond
.size() == 1);
283 // Only handle the case where all conditional branches branch to
284 // the same destination.
285 if (TBB
!= I
->getOperand(0).getMBB())
288 SystemZCC::CondCodes OldBranchCode
= (SystemZCC::CondCodes
)Cond
[0].getImm();
289 // If the conditions are the same, we can leave them alone.
290 if (OldBranchCode
== BranchCode
)
299 unsigned SystemZInstrInfo::RemoveBranch(MachineBasicBlock
&MBB
) const {
300 MachineBasicBlock::iterator I
= MBB
.end();
303 while (I
!= MBB
.begin()) {
305 if (I
->isDebugValue())
307 if (I
->getOpcode() != SystemZ::JMP
&&
308 getCondFromBranchOpc(I
->getOpcode()) == SystemZCC::INVALID
)
310 // Remove the branch.
311 I
->eraseFromParent();
320 SystemZInstrInfo::InsertBranch(MachineBasicBlock
&MBB
, MachineBasicBlock
*TBB
,
321 MachineBasicBlock
*FBB
,
322 const SmallVectorImpl
<MachineOperand
> &Cond
,
324 // Shouldn't be a fall through.
325 assert(TBB
&& "InsertBranch must not be told to insert a fallthrough");
326 assert((Cond
.size() == 1 || Cond
.size() == 0) &&
327 "SystemZ branch conditions have one component!");
330 // Unconditional branch?
331 assert(!FBB
&& "Unconditional branch with multiple successors!");
332 BuildMI(&MBB
, DL
, get(SystemZ::JMP
)).addMBB(TBB
);
336 // Conditional branch.
338 SystemZCC::CondCodes CC
= (SystemZCC::CondCodes
)Cond
[0].getImm();
339 BuildMI(&MBB
, DL
, getBrCond(CC
)).addMBB(TBB
);
343 // Two-way Conditional branch. Insert the second branch.
344 BuildMI(&MBB
, DL
, get(SystemZ::JMP
)).addMBB(FBB
);
351 SystemZInstrInfo::getBrCond(SystemZCC::CondCodes CC
) const {
354 llvm_unreachable("Unknown condition code!");
355 case SystemZCC::O
: return get(SystemZ::JO
);
356 case SystemZCC::H
: return get(SystemZ::JH
);
357 case SystemZCC::NLE
: return get(SystemZ::JNLE
);
358 case SystemZCC::L
: return get(SystemZ::JL
);
359 case SystemZCC::NHE
: return get(SystemZ::JNHE
);
360 case SystemZCC::LH
: return get(SystemZ::JLH
);
361 case SystemZCC::NE
: return get(SystemZ::JNE
);
362 case SystemZCC::E
: return get(SystemZ::JE
);
363 case SystemZCC::NLH
: return get(SystemZ::JNLH
);
364 case SystemZCC::HE
: return get(SystemZ::JHE
);
365 case SystemZCC::NL
: return get(SystemZ::JNL
);
366 case SystemZCC::LE
: return get(SystemZ::JLE
);
367 case SystemZCC::NH
: return get(SystemZ::JNH
);
368 case SystemZCC::NO
: return get(SystemZ::JNO
);
373 SystemZInstrInfo::getCondFromBranchOpc(unsigned Opc
) const {
375 default: return SystemZCC::INVALID
;
376 case SystemZ::JO
: return SystemZCC::O
;
377 case SystemZ::JH
: return SystemZCC::H
;
378 case SystemZ::JNLE
: return SystemZCC::NLE
;
379 case SystemZ::JL
: return SystemZCC::L
;
380 case SystemZ::JNHE
: return SystemZCC::NHE
;
381 case SystemZ::JLH
: return SystemZCC::LH
;
382 case SystemZ::JNE
: return SystemZCC::NE
;
383 case SystemZ::JE
: return SystemZCC::E
;
384 case SystemZ::JNLH
: return SystemZCC::NLH
;
385 case SystemZ::JHE
: return SystemZCC::HE
;
386 case SystemZ::JNL
: return SystemZCC::NL
;
387 case SystemZ::JLE
: return SystemZCC::LE
;
388 case SystemZ::JNH
: return SystemZCC::NH
;
389 case SystemZ::JNO
: return SystemZCC::NO
;
394 SystemZInstrInfo::getOppositeCondition(SystemZCC::CondCodes CC
) const {
397 llvm_unreachable("Invalid condition!");
398 case SystemZCC::O
: return SystemZCC::NO
;
399 case SystemZCC::H
: return SystemZCC::NH
;
400 case SystemZCC::NLE
: return SystemZCC::LE
;
401 case SystemZCC::L
: return SystemZCC::NL
;
402 case SystemZCC::NHE
: return SystemZCC::HE
;
403 case SystemZCC::LH
: return SystemZCC::NLH
;
404 case SystemZCC::NE
: return SystemZCC::E
;
405 case SystemZCC::E
: return SystemZCC::NE
;
406 case SystemZCC::NLH
: return SystemZCC::LH
;
407 case SystemZCC::HE
: return SystemZCC::NHE
;
408 case SystemZCC::NL
: return SystemZCC::L
;
409 case SystemZCC::LE
: return SystemZCC::NLE
;
410 case SystemZCC::NH
: return SystemZCC::H
;
411 case SystemZCC::NO
: return SystemZCC::O
;
416 SystemZInstrInfo::getLongDispOpc(unsigned Opc
) const {
419 llvm_unreachable("Don't have long disp version of this instruction");
420 case SystemZ::MOV32mr
: return get(SystemZ::MOV32mry
);
421 case SystemZ::MOV32rm
: return get(SystemZ::MOV32rmy
);
422 case SystemZ::MOVSX32rm16
: return get(SystemZ::MOVSX32rm16y
);
423 case SystemZ::MOV32m8r
: return get(SystemZ::MOV32m8ry
);
424 case SystemZ::MOV32m16r
: return get(SystemZ::MOV32m16ry
);
425 case SystemZ::MOV64m8r
: return get(SystemZ::MOV64m8ry
);
426 case SystemZ::MOV64m16r
: return get(SystemZ::MOV64m16ry
);
427 case SystemZ::MOV64m32r
: return get(SystemZ::MOV64m32ry
);
428 case SystemZ::MOV8mi
: return get(SystemZ::MOV8miy
);
429 case SystemZ::MUL32rm
: return get(SystemZ::MUL32rmy
);
430 case SystemZ::CMP32rm
: return get(SystemZ::CMP32rmy
);
431 case SystemZ::UCMP32rm
: return get(SystemZ::UCMP32rmy
);
432 case SystemZ::FMOV32mr
: return get(SystemZ::FMOV32mry
);
433 case SystemZ::FMOV64mr
: return get(SystemZ::FMOV64mry
);
434 case SystemZ::FMOV32rm
: return get(SystemZ::FMOV32rmy
);
435 case SystemZ::FMOV64rm
: return get(SystemZ::FMOV64rmy
);
436 case SystemZ::MOV64Pmr
: return get(SystemZ::MOV64Pmry
);
437 case SystemZ::MOV64Prm
: return get(SystemZ::MOV64Prmy
);