]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/BPF/BPFInstrInfo.cpp
Update DTS files from Linux 4.12
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / BPF / BPFInstrInfo.cpp
1 //===-- BPFInstrInfo.cpp - BPF 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 BPF implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "BPF.h"
15 #include "BPFInstrInfo.h"
16 #include "llvm/ADT/SmallVector.h"
17 #include "llvm/CodeGen/MachineBasicBlock.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/IR/DebugLoc.h"
20 #include "llvm/Support/ErrorHandling.h"
21 #include <cassert>
22 #include <iterator>
23
24 #define GET_INSTRINFO_CTOR_DTOR
25 #include "BPFGenInstrInfo.inc"
26
27 using namespace llvm;
28
29 BPFInstrInfo::BPFInstrInfo()
30     : BPFGenInstrInfo(BPF::ADJCALLSTACKDOWN, BPF::ADJCALLSTACKUP) {}
31
32 void BPFInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
33                                MachineBasicBlock::iterator I,
34                                const DebugLoc &DL, unsigned DestReg,
35                                unsigned SrcReg, bool KillSrc) const {
36   if (BPF::GPRRegClass.contains(DestReg, SrcReg))
37     BuildMI(MBB, I, DL, get(BPF::MOV_rr), DestReg)
38         .addReg(SrcReg, getKillRegState(KillSrc));
39   else
40     llvm_unreachable("Impossible reg-to-reg copy");
41 }
42
43 void BPFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
44                                        MachineBasicBlock::iterator I,
45                                        unsigned SrcReg, bool IsKill, int FI,
46                                        const TargetRegisterClass *RC,
47                                        const TargetRegisterInfo *TRI) const {
48   DebugLoc DL;
49   if (I != MBB.end())
50     DL = I->getDebugLoc();
51
52   if (RC == &BPF::GPRRegClass)
53     BuildMI(MBB, I, DL, get(BPF::STD))
54         .addReg(SrcReg, getKillRegState(IsKill))
55         .addFrameIndex(FI)
56         .addImm(0);
57   else
58     llvm_unreachable("Can't store this register to stack slot");
59 }
60
61 void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
62                                         MachineBasicBlock::iterator I,
63                                         unsigned DestReg, int FI,
64                                         const TargetRegisterClass *RC,
65                                         const TargetRegisterInfo *TRI) const {
66   DebugLoc DL;
67   if (I != MBB.end())
68     DL = I->getDebugLoc();
69
70   if (RC == &BPF::GPRRegClass)
71     BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0);
72   else
73     llvm_unreachable("Can't load this register from stack slot");
74 }
75
76 bool BPFInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
77                                  MachineBasicBlock *&TBB,
78                                  MachineBasicBlock *&FBB,
79                                  SmallVectorImpl<MachineOperand> &Cond,
80                                  bool AllowModify) const {
81   // Start from the bottom of the block and work up, examining the
82   // terminator instructions.
83   MachineBasicBlock::iterator I = MBB.end();
84   while (I != MBB.begin()) {
85     --I;
86     if (I->isDebugValue())
87       continue;
88
89     // Working from the bottom, when we see a non-terminator
90     // instruction, we're done.
91     if (!isUnpredicatedTerminator(*I))
92       break;
93
94     // A terminator that isn't a branch can't easily be handled
95     // by this analysis.
96     if (!I->isBranch())
97       return true;
98
99     // Handle unconditional branches.
100     if (I->getOpcode() == BPF::JMP) {
101       if (!AllowModify) {
102         TBB = I->getOperand(0).getMBB();
103         continue;
104       }
105
106       // If the block has any instructions after a J, delete them.
107       while (std::next(I) != MBB.end())
108         std::next(I)->eraseFromParent();
109       Cond.clear();
110       FBB = nullptr;
111
112       // Delete the J if it's equivalent to a fall-through.
113       if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
114         TBB = nullptr;
115         I->eraseFromParent();
116         I = MBB.end();
117         continue;
118       }
119
120       // TBB is used to indicate the unconditinal destination.
121       TBB = I->getOperand(0).getMBB();
122       continue;
123     }
124     // Cannot handle conditional branches
125     return true;
126   }
127
128   return false;
129 }
130
131 unsigned BPFInstrInfo::insertBranch(MachineBasicBlock &MBB,
132                                     MachineBasicBlock *TBB,
133                                     MachineBasicBlock *FBB,
134                                     ArrayRef<MachineOperand> Cond,
135                                     const DebugLoc &DL,
136                                     int *BytesAdded) const {
137   assert(!BytesAdded && "code size not handled");
138
139   // Shouldn't be a fall through.
140   assert(TBB && "insertBranch must not be told to insert a fallthrough");
141
142   if (Cond.empty()) {
143     // Unconditional branch
144     assert(!FBB && "Unconditional branch with multiple successors!");
145     BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB);
146     return 1;
147   }
148
149   llvm_unreachable("Unexpected conditional branch");
150 }
151
152 unsigned BPFInstrInfo::removeBranch(MachineBasicBlock &MBB,
153                                     int *BytesRemoved) const {
154   assert(!BytesRemoved && "code size not handled");
155
156   MachineBasicBlock::iterator I = MBB.end();
157   unsigned Count = 0;
158
159   while (I != MBB.begin()) {
160     --I;
161     if (I->isDebugValue())
162       continue;
163     if (I->getOpcode() != BPF::JMP)
164       break;
165     // Remove the branch.
166     I->eraseFromParent();
167     I = MBB.end();
168     ++Count;
169   }
170
171   return Count;
172 }