]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/ARC/ARCInstrInfo.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / ARC / ARCInstrInfo.cpp
1 //===- ARCInstrInfo.cpp - ARC Instruction Information -----------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the ARC implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "ARCInstrInfo.h"
15 #include "ARC.h"
16 #include "ARCMachineFunctionInfo.h"
17 #include "ARCSubtarget.h"
18 #include "MCTargetDesc/ARCInfo.h"
19 #include "llvm/CodeGen/MachineFrameInfo.h"
20 #include "llvm/CodeGen/MachineInstrBuilder.h"
21 #include "llvm/CodeGen/MachineMemOperand.h"
22 #include "llvm/Support/Debug.h"
23 #include "llvm/Support/TargetRegistry.h"
24
25 using namespace llvm;
26
27 #define GET_INSTRINFO_CTOR_DTOR
28 #include "ARCGenInstrInfo.inc"
29
30 #define DEBUG_TYPE "arc-inst-info"
31 // Pin the vtable to this file.
32 void ARCInstrInfo::anchor() {}
33
34 ARCInstrInfo::ARCInstrInfo()
35     : ARCGenInstrInfo(ARC::ADJCALLSTACKDOWN, ARC::ADJCALLSTACKUP), RI() {}
36
37 static bool isZeroImm(const MachineOperand &Op) {
38   return Op.isImm() && Op.getImm() == 0;
39 }
40
41 static bool isLoad(int Opcode) {
42   return Opcode == ARC::LD_rs9 || Opcode == ARC::LDH_rs9 ||
43          Opcode == ARC::LDB_rs9;
44 }
45
46 static bool isStore(int Opcode) {
47   return Opcode == ARC::ST_rs9 || Opcode == ARC::STH_rs9 ||
48          Opcode == ARC::STB_rs9;
49 }
50
51 /// If the specified machine instruction is a direct
52 /// load from a stack slot, return the virtual or physical register number of
53 /// the destination along with the FrameIndex of the loaded stack slot.  If
54 /// not, return 0.  This predicate must return 0 if the instruction has
55 /// any side effects other than loading from the stack slot.
56 unsigned ARCInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
57                                            int &FrameIndex) const {
58   int Opcode = MI.getOpcode();
59   if (isLoad(Opcode)) {
60     if ((MI.getOperand(1).isFI()) &&  // is a stack slot
61         (MI.getOperand(2).isImm()) && // the imm is zero
62         (isZeroImm(MI.getOperand(2)))) {
63       FrameIndex = MI.getOperand(1).getIndex();
64       return MI.getOperand(0).getReg();
65     }
66   }
67   return 0;
68 }
69
70 /// If the specified machine instruction is a direct
71 /// store to a stack slot, return the virtual or physical register number of
72 /// the source reg along with the FrameIndex of the loaded stack slot.  If
73 /// not, return 0.  This predicate must return 0 if the instruction has
74 /// any side effects other than storing to the stack slot.
75 unsigned ARCInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
76                                           int &FrameIndex) const {
77   int Opcode = MI.getOpcode();
78   if (isStore(Opcode)) {
79     if ((MI.getOperand(1).isFI()) &&  // is a stack slot
80         (MI.getOperand(2).isImm()) && // the imm is zero
81         (isZeroImm(MI.getOperand(2)))) {
82       FrameIndex = MI.getOperand(1).getIndex();
83       return MI.getOperand(0).getReg();
84     }
85   }
86   return 0;
87 }
88
89 /// Return the inverse of passed condition, i.e. turning COND_E to COND_NE.
90 static ARCCC::CondCode GetOppositeBranchCondition(ARCCC::CondCode CC) {
91   switch (CC) {
92   default:
93     llvm_unreachable("Illegal condition code!");
94   case ARCCC::EQ:
95     return ARCCC::NE;
96   case ARCCC::NE:
97     return ARCCC::EQ;
98   case ARCCC::LO:
99     return ARCCC::HS;
100   case ARCCC::HS:
101     return ARCCC::LO;
102   case ARCCC::GT:
103     return ARCCC::LE;
104   case ARCCC::GE:
105     return ARCCC::LT;
106   case ARCCC::VS:
107     return ARCCC::VC;
108   case ARCCC::VC:
109     return ARCCC::VS;
110   case ARCCC::LT:
111     return ARCCC::GE;
112   case ARCCC::LE:
113     return ARCCC::GT;
114   case ARCCC::HI:
115     return ARCCC::LS;
116   case ARCCC::LS:
117     return ARCCC::HI;
118   case ARCCC::NZ:
119     return ARCCC::Z;
120   case ARCCC::Z:
121     return ARCCC::NZ;
122   }
123 }
124
125 static bool isUncondBranchOpcode(int Opc) { return Opc == ARC::BR; }
126
127 static bool isCondBranchOpcode(int Opc) {
128   return Opc == ARC::BRcc_rr_p || Opc == ARC::BRcc_ru6_p;
129 }
130
131 static bool isJumpOpcode(int Opc) { return Opc == ARC::J; }
132
133 /// Analyze the branching code at the end of MBB, returning
134 /// true if it cannot be understood (e.g. it's a switch dispatch or isn't
135 /// implemented for a target).  Upon success, this returns false and returns
136 /// with the following information in various cases:
137 ///
138 /// 1. If this block ends with no branches (it just falls through to its succ)
139 ///    just return false, leaving TBB/FBB null.
140 /// 2. If this block ends with only an unconditional branch, it sets TBB to be
141 ///    the destination block.
142 /// 3. If this block ends with a conditional branch and it falls through to a
143 ///    successor block, it sets TBB to be the branch destination block and a
144 ///    list of operands that evaluate the condition. These operands can be
145 ///    passed to other TargetInstrInfo methods to create new branches.
146 /// 4. If this block ends with a conditional branch followed by an
147 ///    unconditional branch, it returns the 'true' destination in TBB, the
148 ///    'false' destination in FBB, and a list of operands that evaluate the
149 ///    condition.  These operands can be passed to other TargetInstrInfo
150 ///    methods to create new branches.
151 ///
152 /// Note that RemoveBranch and InsertBranch must be implemented to support
153 /// cases where this method returns success.
154 ///
155 /// If AllowModify is true, then this routine is allowed to modify the basic
156 /// block (e.g. delete instructions after the unconditional branch).
157
158 bool ARCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
159                                  MachineBasicBlock *&TBB,
160                                  MachineBasicBlock *&FBB,
161                                  SmallVectorImpl<MachineOperand> &Cond,
162                                  bool AllowModify) const {
163   TBB = FBB = nullptr;
164   MachineBasicBlock::iterator I = MBB.end();
165   if (I == MBB.begin())
166     return false;
167   --I;
168
169   while (isPredicated(*I) || I->isTerminator() || I->isDebugValue()) {
170     // Flag to be raised on unanalyzeable instructions. This is useful in cases
171     // where we want to clean up on the end of the basic block before we bail
172     // out.
173     bool CantAnalyze = false;
174
175     // Skip over DEBUG values and predicated nonterminators.
176     while (I->isDebugInstr() || !I->isTerminator()) {
177       if (I == MBB.begin())
178         return false;
179       --I;
180     }
181
182     if (isJumpOpcode(I->getOpcode())) {
183       // Indirect branches and jump tables can't be analyzed, but we still want
184       // to clean up any instructions at the tail of the basic block.
185       CantAnalyze = true;
186     } else if (isUncondBranchOpcode(I->getOpcode())) {
187       TBB = I->getOperand(0).getMBB();
188     } else if (isCondBranchOpcode(I->getOpcode())) {
189       // Bail out if we encounter multiple conditional branches.
190       if (!Cond.empty())
191         return true;
192
193       assert(!FBB && "FBB should have been null.");
194       FBB = TBB;
195       TBB = I->getOperand(0).getMBB();
196       Cond.push_back(I->getOperand(1));
197       Cond.push_back(I->getOperand(2));
198       Cond.push_back(I->getOperand(3));
199     } else if (I->isReturn()) {
200       // Returns can't be analyzed, but we should run cleanup.
201       CantAnalyze = !isPredicated(*I);
202     } else {
203       // We encountered other unrecognized terminator. Bail out immediately.
204       return true;
205     }
206
207     // Cleanup code - to be run for unpredicated unconditional branches and
208     //                returns.
209     if (!isPredicated(*I) && (isUncondBranchOpcode(I->getOpcode()) ||
210                               isJumpOpcode(I->getOpcode()) || I->isReturn())) {
211       // Forget any previous condition branch information - it no longer
212       // applies.
213       Cond.clear();
214       FBB = nullptr;
215
216       // If we can modify the function, delete everything below this
217       // unconditional branch.
218       if (AllowModify) {
219         MachineBasicBlock::iterator DI = std::next(I);
220         while (DI != MBB.end()) {
221           MachineInstr &InstToDelete = *DI;
222           ++DI;
223           InstToDelete.eraseFromParent();
224         }
225       }
226     }
227
228     if (CantAnalyze)
229       return true;
230
231     if (I == MBB.begin())
232       return false;
233
234     --I;
235   }
236
237   // We made it past the terminators without bailing out - we must have
238   // analyzed this branch successfully.
239   return false;
240 }
241
242 unsigned ARCInstrInfo::removeBranch(MachineBasicBlock &MBB,
243                                     int *BytesRemoved) const {
244   assert(!BytesRemoved && "Code size not handled");
245   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
246   if (I == MBB.end())
247     return 0;
248
249   if (!isUncondBranchOpcode(I->getOpcode()) &&
250       !isCondBranchOpcode(I->getOpcode()))
251     return 0;
252
253   // Remove the branch.
254   I->eraseFromParent();
255
256   I = MBB.end();
257
258   if (I == MBB.begin())
259     return 1;
260   --I;
261   if (!isCondBranchOpcode(I->getOpcode()))
262     return 1;
263
264   // Remove the branch.
265   I->eraseFromParent();
266   return 2;
267 }
268
269 void ARCInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
270                                MachineBasicBlock::iterator I,
271                                const DebugLoc &dl, unsigned DestReg,
272                                unsigned SrcReg, bool KillSrc) const {
273   assert(ARC::GPR32RegClass.contains(SrcReg) &&
274          "Only GPR32 src copy supported.");
275   assert(ARC::GPR32RegClass.contains(DestReg) &&
276          "Only GPR32 dest copy supported.");
277   BuildMI(MBB, I, dl, get(ARC::MOV_rr), DestReg)
278       .addReg(SrcReg, getKillRegState(KillSrc));
279 }
280
281 void ARCInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
282                                        MachineBasicBlock::iterator I,
283                                        unsigned SrcReg, bool isKill,
284                                        int FrameIndex,
285                                        const TargetRegisterClass *RC,
286                                        const TargetRegisterInfo *TRI) const {
287   DebugLoc dl = MBB.findDebugLoc(I);
288   MachineFunction &MF = *MBB.getParent();
289   MachineFrameInfo &MFI = MF.getFrameInfo();
290   unsigned Align = MFI.getObjectAlignment(FrameIndex);
291
292   MachineMemOperand *MMO = MF.getMachineMemOperand(
293       MachinePointerInfo::getFixedStack(MF, FrameIndex),
294       MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex), Align);
295
296   assert(MMO && "Couldn't get MachineMemOperand for store to stack.");
297   assert(TRI->getSpillSize(*RC) == 4 &&
298          "Only support 4-byte stores to stack now.");
299   assert(ARC::GPR32RegClass.hasSubClassEq(RC) &&
300          "Only support GPR32 stores to stack now.");
301   LLVM_DEBUG(dbgs() << "Created store reg=" << printReg(SrcReg, TRI)
302                     << " to FrameIndex=" << FrameIndex << "\n");
303   BuildMI(MBB, I, dl, get(ARC::ST_rs9))
304       .addReg(SrcReg, getKillRegState(isKill))
305       .addFrameIndex(FrameIndex)
306       .addImm(0)
307       .addMemOperand(MMO);
308 }
309
310 void ARCInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
311                                         MachineBasicBlock::iterator I,
312                                         unsigned DestReg, int FrameIndex,
313                                         const TargetRegisterClass *RC,
314                                         const TargetRegisterInfo *TRI) const {
315   DebugLoc dl = MBB.findDebugLoc(I);
316   MachineFunction &MF = *MBB.getParent();
317   MachineFrameInfo &MFI = MF.getFrameInfo();
318   unsigned Align = MFI.getObjectAlignment(FrameIndex);
319   MachineMemOperand *MMO = MF.getMachineMemOperand(
320       MachinePointerInfo::getFixedStack(MF, FrameIndex),
321       MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex), Align);
322
323   assert(MMO && "Couldn't get MachineMemOperand for store to stack.");
324   assert(TRI->getSpillSize(*RC) == 4 &&
325          "Only support 4-byte loads from stack now.");
326   assert(ARC::GPR32RegClass.hasSubClassEq(RC) &&
327          "Only support GPR32 stores to stack now.");
328   LLVM_DEBUG(dbgs() << "Created load reg=" << printReg(DestReg, TRI)
329                     << " from FrameIndex=" << FrameIndex << "\n");
330   BuildMI(MBB, I, dl, get(ARC::LD_rs9))
331       .addReg(DestReg, RegState::Define)
332       .addFrameIndex(FrameIndex)
333       .addImm(0)
334       .addMemOperand(MMO);
335 }
336
337 /// Return the inverse opcode of the specified Branch instruction.
338 bool ARCInstrInfo::reverseBranchCondition(
339     SmallVectorImpl<MachineOperand> &Cond) const {
340   assert((Cond.size() == 3) && "Invalid ARC branch condition!");
341   Cond[2].setImm(GetOppositeBranchCondition((ARCCC::CondCode)Cond[2].getImm()));
342   return false;
343 }
344
345 MachineBasicBlock::iterator
346 ARCInstrInfo::loadImmediate(MachineBasicBlock &MBB,
347                             MachineBasicBlock::iterator MI, unsigned Reg,
348                             uint64_t Value) const {
349   DebugLoc dl = MBB.findDebugLoc(MI);
350   if (isInt<12>(Value)) {
351     return BuildMI(MBB, MI, dl, get(ARC::MOV_rs12), Reg)
352         .addImm(Value)
353         .getInstr();
354   }
355   llvm_unreachable("Need Arc long immediate instructions.");
356 }
357
358 unsigned ARCInstrInfo::insertBranch(MachineBasicBlock &MBB,
359                                     MachineBasicBlock *TBB,
360                                     MachineBasicBlock *FBB,
361                                     ArrayRef<MachineOperand> Cond,
362                                     const DebugLoc &dl, int *BytesAdded) const {
363   assert(!BytesAdded && "Code size not handled.");
364
365   // Shouldn't be a fall through.
366   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
367   assert((Cond.size() == 3 || Cond.size() == 0) &&
368          "ARC branch conditions have two components!");
369
370   if (Cond.empty()) {
371     BuildMI(&MBB, dl, get(ARC::BR)).addMBB(TBB);
372     return 1;
373   }
374   int BccOpc = Cond[1].isImm() ? ARC::BRcc_ru6_p : ARC::BRcc_rr_p;
375   MachineInstrBuilder MIB = BuildMI(&MBB, dl, get(BccOpc));
376   MIB.addMBB(TBB);
377   for (unsigned i = 0; i < 3; i++) {
378     MIB.add(Cond[i]);
379   }
380
381   // One-way conditional branch.
382   if (!FBB) {
383     return 1;
384   }
385
386   // Two-way conditional branch.
387   BuildMI(&MBB, dl, get(ARC::BR)).addMBB(FBB);
388   return 2;
389 }
390
391 unsigned ARCInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
392   if (MI.getOpcode() == TargetOpcode::INLINEASM) {
393     const MachineFunction *MF = MI.getParent()->getParent();
394     const char *AsmStr = MI.getOperand(0).getSymbolName();
395     return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
396   }
397   return MI.getDesc().getSize();
398 }