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 "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "SparcGenInstrInfo.inc"
23 #include "SparcMachineFunctionInfo.h"
26 SparcInstrInfo::SparcInstrInfo(SparcSubtarget
&ST
)
27 : TargetInstrInfoImpl(SparcInsts
, array_lengthof(SparcInsts
)),
28 RI(ST
, *this), Subtarget(ST
) {
31 static bool isZeroImm(const MachineOperand
&op
) {
32 return op
.isImm() && op
.getImm() == 0;
35 /// Return true if the instruction is a register to register move and
36 /// leave the source and dest operands in the passed parameters.
38 bool SparcInstrInfo::isMoveInstr(const MachineInstr
&MI
,
39 unsigned &SrcReg
, unsigned &DstReg
,
40 unsigned &SrcSR
, unsigned &DstSR
) const {
41 SrcSR
= DstSR
= 0; // No sub-registers.
43 // We look for 3 kinds of patterns here:
46 // fmovs or FpMOVD (pseudo double move).
47 if (MI
.getOpcode() == SP::ORrr
|| MI
.getOpcode() == SP::ADDrr
) {
48 if (MI
.getOperand(1).getReg() == SP::G0
) {
49 DstReg
= MI
.getOperand(0).getReg();
50 SrcReg
= MI
.getOperand(2).getReg();
52 } else if (MI
.getOperand(2).getReg() == SP::G0
) {
53 DstReg
= MI
.getOperand(0).getReg();
54 SrcReg
= MI
.getOperand(1).getReg();
57 } else if ((MI
.getOpcode() == SP::ORri
|| MI
.getOpcode() == SP::ADDri
) &&
58 isZeroImm(MI
.getOperand(2)) && MI
.getOperand(1).isReg()) {
59 DstReg
= MI
.getOperand(0).getReg();
60 SrcReg
= MI
.getOperand(1).getReg();
62 } else if (MI
.getOpcode() == SP::FMOVS
|| MI
.getOpcode() == SP::FpMOVD
||
63 MI
.getOpcode() == SP::FMOVD
) {
64 SrcReg
= MI
.getOperand(1).getReg();
65 DstReg
= MI
.getOperand(0).getReg();
71 /// isLoadFromStackSlot - If the specified machine instruction is a direct
72 /// load from a stack slot, return the virtual or physical register number of
73 /// the destination along with the FrameIndex of the loaded stack slot. If
74 /// not, return 0. This predicate must return 0 if the instruction has
75 /// any side effects other than loading from the stack slot.
76 unsigned SparcInstrInfo::isLoadFromStackSlot(const MachineInstr
*MI
,
77 int &FrameIndex
) const {
78 if (MI
->getOpcode() == SP::LDri
||
79 MI
->getOpcode() == SP::LDFri
||
80 MI
->getOpcode() == SP::LDDFri
) {
81 if (MI
->getOperand(1).isFI() && MI
->getOperand(2).isImm() &&
82 MI
->getOperand(2).getImm() == 0) {
83 FrameIndex
= MI
->getOperand(1).getIndex();
84 return MI
->getOperand(0).getReg();
90 /// isStoreToStackSlot - If the specified machine instruction is a direct
91 /// store to a stack slot, return the virtual or physical register number of
92 /// the source reg along with the FrameIndex of the loaded stack slot. If
93 /// not, return 0. This predicate must return 0 if the instruction has
94 /// any side effects other than storing to the stack slot.
95 unsigned SparcInstrInfo::isStoreToStackSlot(const MachineInstr
*MI
,
96 int &FrameIndex
) const {
97 if (MI
->getOpcode() == SP::STri
||
98 MI
->getOpcode() == SP::STFri
||
99 MI
->getOpcode() == SP::STDFri
) {
100 if (MI
->getOperand(0).isFI() && MI
->getOperand(1).isImm() &&
101 MI
->getOperand(1).getImm() == 0) {
102 FrameIndex
= MI
->getOperand(0).getIndex();
103 return MI
->getOperand(2).getReg();
110 SparcInstrInfo::InsertBranch(MachineBasicBlock
&MBB
,MachineBasicBlock
*TBB
,
111 MachineBasicBlock
*FBB
,
112 const SmallVectorImpl
<MachineOperand
> &Cond
)const{
113 // FIXME this should probably take a DebugLoc argument
114 DebugLoc dl
= DebugLoc::getUnknownLoc();
115 // Can only insert uncond branches so far.
116 assert(Cond
.empty() && !FBB
&& TBB
&& "Can only handle uncond branches!");
117 BuildMI(&MBB
, dl
, get(SP::BA
)).addMBB(TBB
);
121 bool SparcInstrInfo::copyRegToReg(MachineBasicBlock
&MBB
,
122 MachineBasicBlock::iterator I
,
123 unsigned DestReg
, unsigned SrcReg
,
124 const TargetRegisterClass
*DestRC
,
125 const TargetRegisterClass
*SrcRC
) const {
126 if (DestRC
!= SrcRC
) {
127 // Not yet supported!
131 DebugLoc DL
= DebugLoc::getUnknownLoc();
132 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
134 if (DestRC
== SP::IntRegsRegisterClass
)
135 BuildMI(MBB
, I
, DL
, get(SP::ORrr
), DestReg
).addReg(SP::G0
).addReg(SrcReg
);
136 else if (DestRC
== SP::FPRegsRegisterClass
)
137 BuildMI(MBB
, I
, DL
, get(SP::FMOVS
), DestReg
).addReg(SrcReg
);
138 else if (DestRC
== SP::DFPRegsRegisterClass
)
139 BuildMI(MBB
, I
, DL
, get(Subtarget
.isV9() ? SP::FMOVD
: SP::FpMOVD
),DestReg
)
142 // Can't copy this register
148 void SparcInstrInfo::
149 storeRegToStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
150 unsigned SrcReg
, bool isKill
, int FI
,
151 const TargetRegisterClass
*RC
) const {
152 DebugLoc DL
= DebugLoc::getUnknownLoc();
153 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
155 // On the order of operands here: think "[FrameIdx + 0] = SrcReg".
156 if (RC
== SP::IntRegsRegisterClass
)
157 BuildMI(MBB
, I
, DL
, get(SP::STri
)).addFrameIndex(FI
).addImm(0)
158 .addReg(SrcReg
, getKillRegState(isKill
));
159 else if (RC
== SP::FPRegsRegisterClass
)
160 BuildMI(MBB
, I
, DL
, get(SP::STFri
)).addFrameIndex(FI
).addImm(0)
161 .addReg(SrcReg
, getKillRegState(isKill
));
162 else if (RC
== SP::DFPRegsRegisterClass
)
163 BuildMI(MBB
, I
, DL
, get(SP::STDFri
)).addFrameIndex(FI
).addImm(0)
164 .addReg(SrcReg
, getKillRegState(isKill
));
166 llvm_unreachable("Can't store this register to stack slot");
169 void SparcInstrInfo::
170 loadRegFromStackSlot(MachineBasicBlock
&MBB
, MachineBasicBlock::iterator I
,
171 unsigned DestReg
, int FI
,
172 const TargetRegisterClass
*RC
) const {
173 DebugLoc DL
= DebugLoc::getUnknownLoc();
174 if (I
!= MBB
.end()) DL
= I
->getDebugLoc();
176 if (RC
== SP::IntRegsRegisterClass
)
177 BuildMI(MBB
, I
, DL
, get(SP::LDri
), DestReg
).addFrameIndex(FI
).addImm(0);
178 else if (RC
== SP::FPRegsRegisterClass
)
179 BuildMI(MBB
, I
, DL
, get(SP::LDFri
), DestReg
).addFrameIndex(FI
).addImm(0);
180 else if (RC
== SP::DFPRegsRegisterClass
)
181 BuildMI(MBB
, I
, DL
, get(SP::LDDFri
), DestReg
).addFrameIndex(FI
).addImm(0);
183 llvm_unreachable("Can't load this register from stack slot");
186 MachineInstr
*SparcInstrInfo::foldMemoryOperandImpl(MachineFunction
&MF
,
188 const SmallVectorImpl
<unsigned> &Ops
,
190 if (Ops
.size() != 1) return NULL
;
192 unsigned OpNum
= Ops
[0];
193 bool isFloat
= false;
194 MachineInstr
*NewMI
= NULL
;
195 switch (MI
->getOpcode()) {
197 if (MI
->getOperand(1).isReg() && MI
->getOperand(1).getReg() == SP::G0
&&
198 MI
->getOperand(0).isReg() && MI
->getOperand(2).isReg()) {
199 if (OpNum
== 0) // COPY -> STORE
200 NewMI
= BuildMI(MF
, MI
->getDebugLoc(), get(SP::STri
))
203 .addReg(MI
->getOperand(2).getReg());
205 NewMI
= BuildMI(MF
, MI
->getDebugLoc(), get(SP::LDri
),
206 MI
->getOperand(0).getReg())
215 if (OpNum
== 0) { // COPY -> STORE
216 unsigned SrcReg
= MI
->getOperand(1).getReg();
217 bool isKill
= MI
->getOperand(1).isKill();
218 bool isUndef
= MI
->getOperand(1).isUndef();
219 NewMI
= BuildMI(MF
, MI
->getDebugLoc(),
220 get(isFloat
? SP::STFri
: SP::STDFri
))
223 .addReg(SrcReg
, getKillRegState(isKill
) | getUndefRegState(isUndef
));
224 } else { // COPY -> LOAD
225 unsigned DstReg
= MI
->getOperand(0).getReg();
226 bool isDead
= MI
->getOperand(0).isDead();
227 bool isUndef
= MI
->getOperand(0).isUndef();
228 NewMI
= BuildMI(MF
, MI
->getDebugLoc(),
229 get(isFloat
? SP::LDFri
: SP::LDDFri
))
230 .addReg(DstReg
, RegState::Define
|
231 getDeadRegState(isDead
) | getUndefRegState(isUndef
))
241 unsigned SparcInstrInfo::getGlobalBaseReg(MachineFunction
*MF
) const
243 SparcMachineFunctionInfo
*SparcFI
= MF
->getInfo
<SparcMachineFunctionInfo
>();
244 unsigned GlobalBaseReg
= SparcFI
->getGlobalBaseReg();
245 if (GlobalBaseReg
!= 0)
246 return GlobalBaseReg
;
248 // Insert the set of GlobalBaseReg into the first MBB of the function
249 MachineBasicBlock
&FirstMBB
= MF
->front();
250 MachineBasicBlock::iterator MBBI
= FirstMBB
.begin();
251 MachineRegisterInfo
&RegInfo
= MF
->getRegInfo();
253 GlobalBaseReg
= RegInfo
.createVirtualRegister(&SP::IntRegsRegClass
);
256 DebugLoc dl
= DebugLoc::getUnknownLoc();
258 BuildMI(FirstMBB
, MBBI
, dl
, get(SP::GETPCX
), GlobalBaseReg
);
259 SparcFI
->setGlobalBaseReg(GlobalBaseReg
);
260 return GlobalBaseReg
;