1 //===- SparcInstrInfo.cpp - Sparc Instruction Information -------*- C++ -*-===//
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"
15 #include "SparcSubtarget.h"
17 #include "llvm/ADT/STLExtras.h"
18 #include "llvm/ADT/SmallVector.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "SparcGenInstrInfo.inc"
23 SparcInstrInfo::SparcInstrInfo(SparcSubtarget
&ST
)
24 : TargetInstrInfoImpl(SparcInsts
, array_lengthof(SparcInsts
)),
25 RI(ST
, *this), Subtarget(ST
) {
28 static bool isZeroImm(const MachineOperand
&op
) {
29 return op
.isImm() && op
.getImm() == 0;
32 /// Return true if the instruction is a register to register move and
33 /// leave the source and dest operands in the passed parameters.
35 bool SparcInstrInfo::isMoveInstr(const MachineInstr
&MI
,
36 unsigned &SrcReg
, unsigned &DstReg
,
37 unsigned &SrcSR
, unsigned &DstSR
) const {
38 SrcSR
= DstSR
= 0; // No sub-registers.
40 // We look for 3 kinds of patterns here:
43 // fmovs or FpMOVD (pseudo double move).
44 if (MI
.getOpcode() == SP::ORrr
|| MI
.getOpcode() == SP::ADDrr
) {
45 if (MI
.getOperand(1).getReg() == SP::G0
) {
46 DstReg
= MI
.getOperand(0).getReg();
47 SrcReg
= MI
.getOperand(2).getReg();
49 } else if (MI
.getOperand(2).getReg() == SP::G0
) {
50 DstReg
= MI
.getOperand(0).getReg();
51 SrcReg
= MI
.getOperand(1).getReg();
54 } else if ((MI
.getOpcode() == SP::ORri
|| MI
.getOpcode() == SP::ADDri
) &&
55 isZeroImm(MI
.getOperand(2)) && MI
.getOperand(1).isReg()) {
56 DstReg
= MI
.getOperand(0).getReg();
57 SrcReg
= MI
.getOperand(1).getReg();
59 } else if (MI
.getOpcode() == SP::FMOVS
|| MI
.getOpcode() == SP::FpMOVD
||
60 MI
.getOpcode() == SP::FMOVD
) {
61 SrcReg
= MI
.getOperand(1).getReg();
62 DstReg
= MI
.getOperand(0).getReg();
68 /// isLoadFromStackSlot - If the specified machine instruction is a direct
69 /// load from a stack slot, return the virtual or physical register number of
70 /// the destination along with the FrameIndex of the loaded stack slot. If
71 /// not, return 0. This predicate must return 0 if the instruction has
72 /// any side effects other than loading from the stack slot.
73 unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
74 int &FrameIndex
) const {
75 if (MI
->getOpcode() == SP::LDri
||
76 MI
->getOpcode() == SP::LDFri
||
77 MI
->getOpcode() == SP::LDDFri
) {
78 if (MI
->getOperand(1).isFI() && MI
->getOperand(2).isImm() &&
79 MI
->getOperand(2).getImm() == 0) {
80 FrameIndex
= MI
->getOperand(1).getIndex();
81 return MI
->getOperand(0).getReg();
87 /// isStoreToStackSlot - If the specified machine instruction is a direct
88 /// store to a stack slot, return the virtual or physical register number of
89 /// the source reg along with the FrameIndex of the loaded stack slot. If
90 /// not, return 0. This predicate must return 0 if the instruction has
91 /// any side effects other than storing to the stack slot.
92 unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
93 int &FrameIndex
) const {
94 if (MI
->getOpcode() == SP::STri
||
95 MI
->getOpcode() == SP::STFri
||
96 MI
->getOpcode() == SP::STDFri
) {
97 if (MI
->getOperand(0).isFI() && MI
->getOperand(1).isImm() &&
98 MI
->getOperand(1).getImm() == 0) {
99 FrameIndex
= MI
->getOperand(0).getIndex();
100 return MI
->getOperand(2).getReg();
107 SparcInstrInfo::InsertBranch(MachineBasicBlock
&MBB
,MachineBasicBlock
*TBB
,
108 MachineBasicBlock
*FBB
,
109 const SmallVectorImpl
<MachineOperand
> &Cond
)const{
110 // FIXME this should probably take a DebugLoc argument
111 DebugLoc dl
= DebugLoc::getUnknownLoc();
112 // Can only insert uncond branches so far.
113 assert(Cond
.empty() && !FBB
&& TBB
&& "Can only handle uncond branches!");
114 BuildMI(&MBB
, dl
, get(SP::BA
)).addMBB(TBB
);
118 bool SparcInstrInfo::copyRegToReg(MachineBasicBlock
&MBB
,
119 MachineBasicBlock::iterator I
,
120 unsigned DestReg
, unsigned SrcReg
,
121 const TargetRegisterClass
*DestRC
,
122 const TargetRegisterClass
*SrcRC
) const {
123 if (DestRC
!= SrcRC
) {
124 // Not yet supported!
128 DebugLoc DL
= DebugLoc::getUnknownLoc();
129 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
131 if (DestRC
== SP::IntRegsRegisterClass
)
132 BuildMI(MBB
, I
, DL
, get(SP::ORrr
), DestReg
).addReg(SP::G0
).addReg(SrcReg
);
133 else if (DestRC
== SP::FPRegsRegisterClass
)
134 BuildMI(MBB
, I
, DL
, get(SP::FMOVS
), DestReg
).addReg(SrcReg
);
135 else if (DestRC
== SP::DFPRegsRegisterClass
)
136 BuildMI(MBB
, I
, DL
, get(Subtarget
.isV9() ? SP::FMOVD
: SP::FpMOVD
),DestReg
)
139 // Can't copy this register
145 void SparcInstrInfo::
146 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
147 unsigned SrcReg
, bool isKill
, int FI
,
148 const TargetRegisterClass
*RC
) const {
149 DebugLoc DL
= DebugLoc::getUnknownLoc();
150 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
152 // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
153 if (RC
== SP::IntRegsRegisterClass
)
154 BuildMI(MBB
, I
, DL
, get(SP::STri
)).addFrameIndex(FI
).addImm(0)
155 .addReg(SrcReg
, false, false, isKill
);
156 else if (RC
== SP::FPRegsRegisterClass
)
157 BuildMI(MBB
, I
, DL
, get(SP::STFri
)).addFrameIndex(FI
).addImm(0)
158 .addReg(SrcReg
, false, false, isKill
);
159 else if (RC
== SP::DFPRegsRegisterClass
)
160 BuildMI(MBB
, I
, DL
, get(SP::STDFri
)).addFrameIndex(FI
).addImm(0)
161 .addReg(SrcReg
, false, false, isKill
);
163 assert(0 && "Can't store this register to stack slot");
166 void SparcInstrInfo::storeRegToAddr(MachineFunction
&MF
, unsigned SrcReg
,
168 SmallVectorImpl
<MachineOperand
> &Addr
,
169 const TargetRegisterClass
*RC
,
170 SmallVectorImpl
<MachineInstr
*> &NewMIs
) const {
172 DebugLoc DL
= DebugLoc::getUnknownLoc();
173 if (RC
== SP::IntRegsRegisterClass
)
175 else if (RC
== SP::FPRegsRegisterClass
)
177 else if (RC
== SP::DFPRegsRegisterClass
)
180 assert(0 && "Can't load this register");
181 MachineInstrBuilder MIB
= BuildMI(MF
, DL
, get(Opc
));
182 for (unsigned i
= 0, e
= Addr
.size(); i
!= e
; ++i
)
183 MIB
.addOperand(Addr
[i
]);
184 MIB
.addReg(SrcReg
, false, false, isKill
);
185 NewMIs
.push_back(MIB
);
189 void SparcInstrInfo::
190 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
191 unsigned DestReg
, int FI
,
192 const TargetRegisterClass
*RC
) const {
193 DebugLoc DL
= DebugLoc::getUnknownLoc();
194 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
196 if (RC
== SP::IntRegsRegisterClass
)
197 BuildMI(MBB
, I
, DL
, get(SP::LDri
), DestReg
).addFrameIndex(FI
).addImm(0);
198 else if (RC
== SP::FPRegsRegisterClass
)
199 BuildMI(MBB
, I
, DL
, get(SP::LDFri
), DestReg
).addFrameIndex(FI
).addImm(0);
200 else if (RC
== SP::DFPRegsRegisterClass
)
201 BuildMI(MBB
, I
, DL
, get(SP::LDDFri
), DestReg
).addFrameIndex(FI
).addImm(0);
203 assert(0 && "Can't load this register from stack slot");
206 void SparcInstrInfo::loadRegFromAddr(MachineFunction
&MF
, unsigned DestReg
,
207 SmallVectorImpl
<MachineOperand
> &Addr
,
208 const TargetRegisterClass
*RC
,
209 SmallVectorImpl
<MachineInstr
*> &NewMIs
) const {
211 if (RC
== SP::IntRegsRegisterClass
)
213 else if (RC
== SP::FPRegsRegisterClass
)
215 else if (RC
== SP::DFPRegsRegisterClass
)
218 assert(0 && "Can't load this register");
219 DebugLoc DL
= DebugLoc::getUnknownLoc();
220 MachineInstrBuilder MIB
= BuildMI(MF
, DL
, get(Opc
), DestReg
);
221 for (unsigned i
= 0, e
= Addr
.size(); i
!= e
; ++i
)
222 MIB
.addOperand(Addr
[i
]);
223 NewMIs
.push_back(MIB
);
227 MachineInstr
*SparcInstrInfo::foldMemoryOperandImpl(MachineFunction
&MF
,
229 const SmallVectorImpl
<unsigned> &Ops
,
231 if (Ops
.size() != 1) return NULL
;
233 unsigned OpNum
= Ops
[0];
234 bool isFloat
= false;
235 MachineInstr
*NewMI
= NULL
;
236 switch (MI
->getOpcode()) {
238 if (MI
->getOperand(1).isReg() && MI
->getOperand(1).getReg() == SP::G0
&&
239 MI
->getOperand(0).isReg() && MI
->getOperand(2).isReg()) {
240 if (OpNum
== 0) // COPY -> STORE
241 NewMI
= BuildMI(MF
, MI
->getDebugLoc(), get(SP::STri
))
244 .addReg(MI
->getOperand(2).getReg());
246 NewMI
= BuildMI(MF
, MI
->getDebugLoc(), get(SP::LDri
),
247 MI
->getOperand(0).getReg())
256 if (OpNum
== 0) { // COPY -> STORE
257 unsigned SrcReg
= MI
->getOperand(1).getReg();
258 bool isKill
= MI
->getOperand(1).isKill();
259 NewMI
= BuildMI(MF
, MI
->getDebugLoc(),
260 get(isFloat
? SP::STFri
: SP::STDFri
))
263 .addReg(SrcReg
, false, false, isKill
);
264 } else { // COPY -> LOAD
265 unsigned DstReg
= MI
->getOperand(0).getReg();
266 bool isDead
= MI
->getOperand(0).isDead();
267 NewMI
= BuildMI(MF
, MI
->getDebugLoc(),
268 get(isFloat
? SP::LDFri
: SP::LDDFri
))
269 .addReg(DstReg
, true, false, false, isDead
)