1 //===-- BPFRegisterInfo.cpp - BPF Register 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 TargetRegisterInfo class. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #include "BPFRegisterInfo.h" 15 #include "BPF.h" 16 #include "BPFSubtarget.h" 17 #include "llvm/CodeGen/MachineFrameInfo.h" 18 #include "llvm/CodeGen/MachineFunction.h" 19 #include "llvm/CodeGen/MachineInstrBuilder.h" 20 #include "llvm/CodeGen/RegisterScavenging.h" 21 #include "llvm/CodeGen/TargetFrameLowering.h" 22 #include "llvm/CodeGen/TargetInstrInfo.h" 23 #include "llvm/IR/DiagnosticInfo.h" 24 #include "llvm/Support/ErrorHandling.h" 25 26 #define GET_REGINFO_TARGET_DESC 27 #include "BPFGenRegisterInfo.inc" 28 using namespace llvm; 29 30 BPFRegisterInfo::BPFRegisterInfo() 31 : BPFGenRegisterInfo(BPF::R0) {} 32 33 const MCPhysReg * 34 BPFRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 35 return CSR_SaveList; 36 } 37 38 BitVector BPFRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 39 BitVector Reserved(getNumRegs()); 40 markSuperRegs(Reserved, BPF::W10); // [W|R]10 is read only frame pointer 41 markSuperRegs(Reserved, BPF::W11); // [W|R]11 is pseudo stack pointer 42 return Reserved; 43 } 44 45 static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL) 46 { 47 if (Offset <= -512) { 48 const Function &F = MF.getFunction(); 49 DiagnosticInfoUnsupported DiagStackSize(F, 50 "Looks like the BPF stack limit of 512 bytes is exceeded. " 51 "Please move large on stack variables into BPF per-cpu array map.\n", 52 DL); 53 F.getContext().diagnose(DiagStackSize); 54 } 55 } 56 57 void BPFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 58 int SPAdj, unsigned FIOperandNum, 59 RegScavenger *RS) const { 60 assert(SPAdj == 0 && "Unexpected"); 61 62 unsigned i = 0; 63 MachineInstr &MI = *II; 64 MachineBasicBlock &MBB = *MI.getParent(); 65 MachineFunction &MF = *MBB.getParent(); 66 DebugLoc DL = MI.getDebugLoc(); 67 68 if (!DL) 69 /* try harder to get some debug loc */ 70 for (auto &I : MBB) 71 if (I.getDebugLoc()) { 72 DL = I.getDebugLoc(); 73 break; 74 } 75 76 while (!MI.getOperand(i).isFI()) { 77 ++i; 78 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 79 } 80 81 unsigned FrameReg = getFrameRegister(MF); 82 int FrameIndex = MI.getOperand(i).getIndex(); 83 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 84 85 if (MI.getOpcode() == BPF::MOV_rr) { 86 int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex); 87 88 WarnSize(Offset, MF, DL); 89 MI.getOperand(i).ChangeToRegister(FrameReg, false); 90 unsigned reg = MI.getOperand(i - 1).getReg(); 91 BuildMI(MBB, ++II, DL, TII.get(BPF::ADD_ri), reg) 92 .addReg(reg) 93 .addImm(Offset); 94 return; 95 } 96 97 int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) + 98 MI.getOperand(i + 1).getImm(); 99 100 if (!isInt<32>(Offset)) 101 llvm_unreachable("bug in frame offset"); 102 103 WarnSize(Offset, MF, DL); 104 105 if (MI.getOpcode() == BPF::FI_ri) { 106 // architecture does not really support FI_ri, replace it with 107 // MOV_rr <target_reg>, frame_reg 108 // ADD_ri <target_reg>, imm 109 unsigned reg = MI.getOperand(i - 1).getReg(); 110 111 BuildMI(MBB, ++II, DL, TII.get(BPF::MOV_rr), reg) 112 .addReg(FrameReg); 113 BuildMI(MBB, II, DL, TII.get(BPF::ADD_ri), reg) 114 .addReg(reg) 115 .addImm(Offset); 116 117 // Remove FI_ri instruction 118 MI.eraseFromParent(); 119 } else { 120 MI.getOperand(i).ChangeToRegister(FrameReg, false); 121 MI.getOperand(i + 1).ChangeToImmediate(Offset); 122 } 123 } 124 125 unsigned BPFRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 126 return BPF::R10; 127 } 128