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 "BPF.h" 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" 25 26 #define GET_INSTRINFO_CTOR_DTOR 27 #include "BPFGenInstrInfo.inc" 28 29 using namespace llvm; 30 31 BPFInstrInfo::BPFInstrInfo() 32 : BPFGenInstrInfo(BPF::ADJCALLSTACKDOWN, BPF::ADJCALLSTACKUP) {} 33 34 void BPFInstrInfo::copyPhysReg(MachineBasicBlock &MBB, 35 MachineBasicBlock::iterator I, DebugLoc DL, 36 unsigned DestReg, unsigned SrcReg, 37 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)); 41 else 42 llvm_unreachable("Impossible reg-to-reg copy"); 43 } 44 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 { 50 DebugLoc DL; 51 if (I != MBB.end()) 52 DL = I->getDebugLoc(); 53 54 if (RC == &BPF::GPRRegClass) 55 BuildMI(MBB, I, DL, get(BPF::STD)) 56 .addReg(SrcReg, getKillRegState(IsKill)) 57 .addFrameIndex(FI) 58 .addImm(0); 59 else 60 llvm_unreachable("Can't store this register to stack slot"); 61 } 62 63 void BPFInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB, 64 MachineBasicBlock::iterator I, 65 unsigned DestReg, int FI, 66 const TargetRegisterClass *RC, 67 const TargetRegisterInfo *TRI) const { 68 DebugLoc DL; 69 if (I != MBB.end()) 70 DL = I->getDebugLoc(); 71 72 if (RC == &BPF::GPRRegClass) 73 BuildMI(MBB, I, DL, get(BPF::LDD), DestReg).addFrameIndex(FI).addImm(0); 74 else 75 llvm_unreachable("Can't load this register from stack slot"); 76 } 77 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()) { 87 --I; 88 if (I->isDebugValue()) 89 continue; 90 91 // Working from the bottom, when we see a non-terminator 92 // instruction, we're done. 93 if (!isUnpredicatedTerminator(I)) 94 break; 95 96 // A terminator that isn't a branch can't easily be handled 97 // by this analysis. 98 if (!I->isBranch()) 99 return true; 100 101 // Handle unconditional branches. 102 if (I->getOpcode() == BPF::JMP) { 103 if (!AllowModify) { 104 TBB = I->getOperand(0).getMBB(); 105 continue; 106 } 107 108 // If the block has any instructions after a J, delete them. 109 while (std::next(I) != MBB.end()) 110 std::next(I)->eraseFromParent(); 111 Cond.clear(); 112 FBB = 0; 113 114 // Delete the J if it's equivalent to a fall-through. 115 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) { 116 TBB = 0; 117 I->eraseFromParent(); 118 I = MBB.end(); 119 continue; 120 } 121 122 // TBB is used to indicate the unconditinal destination. 123 TBB = I->getOperand(0).getMBB(); 124 continue; 125 } 126 // Cannot handle conditional branches 127 return true; 128 } 129 130 return false; 131 } 132 133 unsigned BPFInstrInfo::InsertBranch(MachineBasicBlock &MBB, 134 MachineBasicBlock *TBB, 135 MachineBasicBlock *FBB, 136 ArrayRef<MachineOperand> Cond, 137 DebugLoc DL) const { 138 // Shouldn't be a fall through. 139 assert(TBB && "InsertBranch must not be told to insert a fallthrough"); 140 141 if (Cond.empty()) { 142 // Unconditional branch 143 assert(!FBB && "Unconditional branch with multiple successors!"); 144 BuildMI(&MBB, DL, get(BPF::JMP)).addMBB(TBB); 145 return 1; 146 } 147 148 llvm_unreachable("Unexpected conditional branch"); 149 } 150 151 unsigned BPFInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const { 152 MachineBasicBlock::iterator I = MBB.end(); 153 unsigned Count = 0; 154 155 while (I != MBB.begin()) { 156 --I; 157 if (I->isDebugValue()) 158 continue; 159 if (I->getOpcode() != BPF::JMP) 160 break; 161 // Remove the branch. 162 I->eraseFromParent(); 163 I = MBB.end(); 164 ++Count; 165 } 166 167 return Count; 168 } 169