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 "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"
24 #define GET_INSTRINFO_CTOR_DTOR
25 #include "BPFGenInstrInfo.inc"
29 BPFInstrInfo::BPFInstrInfo()
30 : BPFGenInstrInfo(BPF::ADJCALLSTACKDOWN, BPF::ADJCALLSTACKUP) {}
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));
40 llvm_unreachable("Impossible reg-to-reg copy");
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 {
50 DL = I->getDebugLoc();
52 if (RC == &BPF::GPRRegClass)
53 BuildMI(MBB, I, DL, get(BPF::STD))
54 .addReg(SrcReg, getKillRegState(IsKill))
58 llvm_unreachable("Can't store this register to stack slot");
61 void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
62 MachineBasicBlock::iterator I,
63 unsigned DestReg, int FI,
64 const TargetRegisterClass *RC,
65 const TargetRegisterInfo *TRI) const {
68 DL = I->getDebugLoc();
70 if (RC == &BPF::GPRRegClass)
71 BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0);
73 llvm_unreachable("Can't load this register from stack slot");
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()) {
86 if (I->isDebugValue())
89 // Working from the bottom, when we see a non-terminator
90 // instruction, we're done.
91 if (!isUnpredicatedTerminator(*I))
94 // A terminator that isn't a branch can't easily be handled
99 // Handle unconditional branches.
100 if (I->getOpcode() == BPF::JMP) {
102 TBB = I->getOperand(0).getMBB();
106 // If the block has any instructions after a J, delete them.
107 while (std::next(I) != MBB.end())
108 std::next(I)->eraseFromParent();
112 // Delete the J if it's equivalent to a fall-through.
113 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
115 I->eraseFromParent();
120 // TBB is used to indicate the unconditinal destination.
121 TBB = I->getOperand(0).getMBB();
124 // Cannot handle conditional branches
131 unsigned BPFInstrInfo::insertBranch(MachineBasicBlock &MBB,
132 MachineBasicBlock *TBB,
133 MachineBasicBlock *FBB,
134 ArrayRef<MachineOperand> Cond,
136 int *BytesAdded) const {
137 assert(!BytesAdded && "code size not handled");
139 // Shouldn't be a fall through.
140 assert(TBB && "insertBranch must not be told to insert a fallthrough");
143 // Unconditional branch
144 assert(!FBB && "Unconditional branch with multiple successors!");
145 BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB);
149 llvm_unreachable("Unexpected conditional branch");
152 unsigned BPFInstrInfo::removeBranch(MachineBasicBlock &MBB,
153 int *BytesRemoved) const {
154 assert(!BytesRemoved && "code size not handled");
156 MachineBasicBlock::iterator I = MBB.end();
159 while (I != MBB.begin()) {
161 if (I->isDebugValue())
163 if (I->getOpcode() != BPF::JMP)
165 // Remove the branch.
166 I->eraseFromParent();