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 "BPFInstrInfo.h" 15 #include "BPF.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 } 173