1 //===-- BPFInstrInfo.cpp - BPF 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 BPF implementation of the TargetInstrInfo class.
12 //===----------------------------------------------------------------------===//
15 #include "BPFInstrInfo.h"
16 #include "BPFSubtarget.h"
17 #include "BPFTargetMachine.h"
18 #include "llvm/CodeGen/MachineFunctionPass.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineRegisterInfo.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/TargetRegistry.h"
23 #include "llvm/ADT/STLExtras.h"
24 #include "llvm/ADT/SmallVector.h"
26 #define GET_INSTRINFO_CTOR_DTOR
27 #include "BPFGenInstrInfo.inc"
31 BPFInstrInfo::BPFInstrInfo()
32 : BPFGenInstrInfo(BPF::ADJCALLSTACKDOWN, BPF::ADJCALLSTACKUP) {}
34 void BPFInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
35 MachineBasicBlock::iterator I,
36 const DebugLoc &DL, unsigned DestReg,
37 unsigned SrcReg, bool KillSrc) const {
38 if (BPF::GPRRegClass.contains(DestReg, SrcReg))
39 BuildMI(MBB, I, DL, get(BPF::MOV_rr), DestReg)
40 .addReg(SrcReg, getKillRegState(KillSrc));
42 llvm_unreachable("Impossible reg-to-reg copy");
45 void BPFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
46 MachineBasicBlock::iterator I,
47 unsigned SrcReg, bool IsKill, int FI,
48 const TargetRegisterClass *RC,
49 const TargetRegisterInfo *TRI) const {
52 DL = I->getDebugLoc();
54 if (RC == &BPF::GPRRegClass)
55 BuildMI(MBB, I, DL, get(BPF::STD))
56 .addReg(SrcReg, getKillRegState(IsKill))
60 llvm_unreachable("Can't store this register to stack slot");
63 void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
64 MachineBasicBlock::iterator I,
65 unsigned DestReg, int FI,
66 const TargetRegisterClass *RC,
67 const TargetRegisterInfo *TRI) const {
70 DL = I->getDebugLoc();
72 if (RC == &BPF::GPRRegClass)
73 BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0);
75 llvm_unreachable("Can't load this register from stack slot");
78 bool BPFInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
79 MachineBasicBlock *&TBB,
80 MachineBasicBlock *&FBB,
81 SmallVectorImpl<MachineOperand> &Cond,
82 bool AllowModify) const {
83 // Start from the bottom of the block and work up, examining the
84 // terminator instructions.
85 MachineBasicBlock::iterator I = MBB.end();
86 while (I != MBB.begin()) {
88 if (I->isDebugValue())
91 // Working from the bottom, when we see a non-terminator
92 // instruction, we're done.
93 if (!isUnpredicatedTerminator(*I))
96 // A terminator that isn't a branch can't easily be handled
101 // Handle unconditional branches.
102 if (I->getOpcode() == BPF::JMP) {
104 TBB = I->getOperand(0).getMBB();
108 // If the block has any instructions after a J, delete them.
109 while (std::next(I) != MBB.end())
110 std::next(I)->eraseFromParent();
114 // Delete the J if it's equivalent to a fall-through.
115 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
117 I->eraseFromParent();
122 // TBB is used to indicate the unconditinal destination.
123 TBB = I->getOperand(0).getMBB();
126 // Cannot handle conditional branches
133 unsigned BPFInstrInfo::InsertBranch(MachineBasicBlock &MBB,
134 MachineBasicBlock *TBB,
135 MachineBasicBlock *FBB,
136 ArrayRef<MachineOperand> Cond,
137 const DebugLoc &DL) const {
138 // Shouldn't be a fall through.
139 assert(TBB && "InsertBranch must not be told to insert a fallthrough");
142 // Unconditional branch
143 assert(!FBB && "Unconditional branch with multiple successors!");
144 BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB);
148 llvm_unreachable("Unexpected conditional branch");
151 unsigned BPFInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
152 MachineBasicBlock::iterator I = MBB.end();
155 while (I != MBB.begin()) {
157 if (I->isDebugValue())
159 if (I->getOpcode() != BPF::JMP)
161 // Remove the branch.
162 I->eraseFromParent();