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 //===----------------------------------------------------------------------===//
14 #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));
39 else if (BPF::GPR32RegClass.contains(DestReg, SrcReg))
40 BuildMI(MBB, I, DL, get(BPF::MOV_rr_32), DestReg)
41 .addReg(SrcReg, getKillRegState(KillSrc));
43 llvm_unreachable("Impossible reg-to-reg copy");
46 void BPFInstrInfo::expandMEMCPY(MachineBasicBlock::iterator MI) const {
47 unsigned DstReg = MI->getOperand(0).getReg();
48 unsigned SrcReg = MI->getOperand(1).getReg();
49 uint64_t CopyLen = MI->getOperand(2).getImm();
50 uint64_t Alignment = MI->getOperand(3).getImm();
51 unsigned ScratchReg = MI->getOperand(4).getReg();
52 MachineBasicBlock *BB = MI->getParent();
53 DebugLoc dl = MI->getDebugLoc();
54 unsigned LdOpc, StOpc;
74 llvm_unreachable("unsupported memcpy alignment");
77 unsigned IterationNum = CopyLen >> Log2_64(Alignment);
78 for(unsigned I = 0; I < IterationNum; ++I) {
79 BuildMI(*BB, MI, dl, get(LdOpc))
80 .addReg(ScratchReg, RegState::Define).addReg(SrcReg)
81 .addImm(I * Alignment);
82 BuildMI(*BB, MI, dl, get(StOpc))
83 .addReg(ScratchReg, RegState::Kill).addReg(DstReg)
84 .addImm(I * Alignment);
87 unsigned BytesLeft = CopyLen & (Alignment - 1);
88 unsigned Offset = IterationNum * Alignment;
89 bool Hanging4Byte = BytesLeft & 0x4;
90 bool Hanging2Byte = BytesLeft & 0x2;
91 bool Hanging1Byte = BytesLeft & 0x1;
93 BuildMI(*BB, MI, dl, get(BPF::LDW))
94 .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset);
95 BuildMI(*BB, MI, dl, get(BPF::STW))
96 .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset);
100 BuildMI(*BB, MI, dl, get(BPF::LDH))
101 .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset);
102 BuildMI(*BB, MI, dl, get(BPF::STH))
103 .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset);
107 BuildMI(*BB, MI, dl, get(BPF::LDB))
108 .addReg(ScratchReg, RegState::Define).addReg(SrcReg).addImm(Offset);
109 BuildMI(*BB, MI, dl, get(BPF::STB))
110 .addReg(ScratchReg, RegState::Kill).addReg(DstReg).addImm(Offset);
116 bool BPFInstrInfo::expandPostRAPseudo(MachineInstr &MI) const {
117 if (MI.getOpcode() == BPF::MEMCPY) {
125 void BPFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
126 MachineBasicBlock::iterator I,
127 unsigned SrcReg, bool IsKill, int FI,
128 const TargetRegisterClass *RC,
129 const TargetRegisterInfo *TRI) const {
132 DL = I->getDebugLoc();
134 if (RC == &BPF::GPRRegClass)
135 BuildMI(MBB, I, DL, get(BPF::STD))
136 .addReg(SrcReg, getKillRegState(IsKill))
139 else if (RC == &BPF::GPR32RegClass)
140 BuildMI(MBB, I, DL, get(BPF::STW32))
141 .addReg(SrcReg, getKillRegState(IsKill))
145 llvm_unreachable("Can't store this register to stack slot");
148 void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
149 MachineBasicBlock::iterator I,
150 unsigned DestReg, int FI,
151 const TargetRegisterClass *RC,
152 const TargetRegisterInfo *TRI) const {
155 DL = I->getDebugLoc();
157 if (RC == &BPF::GPRRegClass)
158 BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0);
159 else if (RC == &BPF::GPR32RegClass)
160 BuildMI(MBB, I, DL, get(BPF::LDW32), DestReg).addFrameIndex(FI).addImm(0);
162 llvm_unreachable("Can't load this register from stack slot");
165 bool BPFInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
166 MachineBasicBlock *&TBB,
167 MachineBasicBlock *&FBB,
168 SmallVectorImpl<MachineOperand> &Cond,
169 bool AllowModify) const {
170 // Start from the bottom of the block and work up, examining the
171 // terminator instructions.
172 MachineBasicBlock::iterator I = MBB.end();
173 while (I != MBB.begin()) {
175 if (I->isDebugInstr())
178 // Working from the bottom, when we see a non-terminator
179 // instruction, we're done.
180 if (!isUnpredicatedTerminator(*I))
183 // A terminator that isn't a branch can't easily be handled
188 // Handle unconditional branches.
189 if (I->getOpcode() == BPF::JMP) {
191 TBB = I->getOperand(0).getMBB();
195 // If the block has any instructions after a J, delete them.
196 while (std::next(I) != MBB.end())
197 std::next(I)->eraseFromParent();
201 // Delete the J if it's equivalent to a fall-through.
202 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
204 I->eraseFromParent();
209 // TBB is used to indicate the unconditinal destination.
210 TBB = I->getOperand(0).getMBB();
213 // Cannot handle conditional branches
220 unsigned BPFInstrInfo::insertBranch(MachineBasicBlock &MBB,
221 MachineBasicBlock *TBB,
222 MachineBasicBlock *FBB,
223 ArrayRef<MachineOperand> Cond,
225 int *BytesAdded) const {
226 assert(!BytesAdded && "code size not handled");
228 // Shouldn't be a fall through.
229 assert(TBB && "insertBranch must not be told to insert a fallthrough");
232 // Unconditional branch
233 assert(!FBB && "Unconditional branch with multiple successors!");
234 BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB);
238 llvm_unreachable("Unexpected conditional branch");
241 unsigned BPFInstrInfo::removeBranch(MachineBasicBlock &MBB,
242 int *BytesRemoved) const {
243 assert(!BytesRemoved && "code size not handled");
245 MachineBasicBlock::iterator I = MBB.end();
248 while (I != MBB.begin()) {
250 if (I->isDebugInstr())
252 if (I->getOpcode() != BPF::JMP)
254 // Remove the branch.
255 I->eraseFromParent();