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 if (BPF::GPR32RegClass.contains(DestReg, SrcReg)) 40 BuildMI(MBB, I, DL, get(BPF::MOV_rr_32), DestReg) 41 .addReg(SrcReg, getKillRegState(KillSrc)); 42 else 43 llvm_unreachable("Impossible reg-to-reg copy"); 44 } 45 46 void BPFInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB, 47 MachineBasicBlock::iterator I, 48 unsigned SrcReg, bool IsKill, int FI, 49 const TargetRegisterClass *RC, 50 const TargetRegisterInfo *TRI) const { 51 DebugLoc DL; 52 if (I != MBB.end()) 53 DL = I->getDebugLoc(); 54 55 if (RC == &BPF::GPRRegClass) 56 BuildMI(MBB, I, DL, get(BPF::STD)) 57 .addReg(SrcReg, getKillRegState(IsKill)) 58 .addFrameIndex(FI) 59 .addImm(0); 60 else if (RC == &BPF::GPR32RegClass) 61 BuildMI(MBB, I, DL, get(BPF::STW32)) 62 .addReg(SrcReg, getKillRegState(IsKill)) 63 .addFrameIndex(FI) 64 .addImm(0); 65 else 66 llvm_unreachable("Can't store this register to stack slot"); 67 } 68 69 void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 70 MachineBasicBlock::iterator I, 71 unsigned DestReg, int FI, 72 const TargetRegisterClass *RC, 73 const TargetRegisterInfo *TRI) const { 74 DebugLoc DL; 75 if (I != MBB.end()) 76 DL = I->getDebugLoc(); 77 78 if (RC == &BPF::GPRRegClass) 79 BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0); 80 else if (RC == &BPF::GPR32RegClass) 81 BuildMI(MBB, I, DL, get(BPF::LDW32), DestReg).addFrameIndex(FI).addImm(0); 82 else 83 llvm_unreachable("Can't load this register from stack slot"); 84 } 85 86 bool BPFInstrInfo::analyzeBranch(MachineBasicBlock &MBB, 87 MachineBasicBlock *&TBB, 88 MachineBasicBlock *&FBB, 89 SmallVectorImpl<MachineOperand> &Cond, 90 bool AllowModify) const { 91 // Start from the bottom of the block and work up, examining the 92 // terminator instructions. 93 MachineBasicBlock::iterator I = MBB.end(); 94 while (I != MBB.begin()) { 95 --I; 96 if (I->isDebugInstr()) 97 continue; 98 99 // Working from the bottom, when we see a non-terminator 100 // instruction, we're done. 101 if (!isUnpredicatedTerminator(*I)) 102 break; 103 104 // A terminator that isn't a branch can't easily be handled 105 // by this analysis. 106 if (!I->isBranch()) 107 return true; 108 109 // Handle unconditional branches. 110 if (I->getOpcode() == BPF::JMP) { 111 if (!AllowModify) { 112 TBB = I->getOperand(0).getMBB(); 113 continue; 114 } 115 116 // If the block has any instructions after a J, delete them. 117 while (std::next(I) != MBB.end()) 118 std::next(I)->eraseFromParent(); 119 Cond.clear(); 120 FBB = nullptr; 121 122 // Delete the J if it's equivalent to a fall-through. 123 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { 124 TBB = nullptr; 125 I->eraseFromParent(); 126 I = MBB.end(); 127 continue; 128 } 129 130 // TBB is used to indicate the unconditinal destination. 131 TBB = I->getOperand(0).getMBB(); 132 continue; 133 } 134 // Cannot handle conditional branches 135 return true; 136 } 137 138 return false; 139 } 140 141 unsigned BPFInstrInfo::insertBranch(MachineBasicBlock &MBB, 142 MachineBasicBlock *TBB, 143 MachineBasicBlock *FBB, 144 ArrayRef<MachineOperand> Cond, 145 const DebugLoc &DL, 146 int *BytesAdded) const { 147 assert(!BytesAdded && "code size not handled"); 148 149 // Shouldn't be a fall through. 150 assert(TBB && "insertBranch must not be told to insert a fallthrough"); 151 152 if (Cond.empty()) { 153 // Unconditional branch 154 assert(!FBB && "Unconditional branch with multiple successors!"); 155 BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB); 156 return 1; 157 } 158 159 llvm_unreachable("Unexpected conditional branch"); 160 } 161 162 unsigned BPFInstrInfo::removeBranch(MachineBasicBlock &MBB, 163 int *BytesRemoved) const { 164 assert(!BytesRemoved && "code size not handled"); 165 166 MachineBasicBlock::iterator I = MBB.end(); 167 unsigned Count = 0; 168 169 while (I != MBB.begin()) { 170 --I; 171 if (I->isDebugInstr()) 172 continue; 173 if (I->getOpcode() != BPF::JMP) 174 break; 175 // Remove the branch. 176 I->eraseFromParent(); 177 I = MBB.end(); 178 ++Count; 179 } 180 181 return Count; 182 } 183