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 "BPF.h" 15#include "BPFRegisterInfo.h" 16#include "BPFSubtarget.h" 17#include "llvm/CodeGen/MachineInstrBuilder.h" 18#include "llvm/CodeGen/MachineFrameInfo.h" 19#include "llvm/CodeGen/MachineFunction.h" 20#include "llvm/CodeGen/RegisterScavenging.h" 21#include "llvm/Support/ErrorHandling.h" 22#include "llvm/Target/TargetFrameLowering.h" 23#include "llvm/Target/TargetInstrInfo.h" 24 25#define GET_REGINFO_TARGET_DESC 26#include "BPFGenRegisterInfo.inc" 27using namespace llvm; 28 29BPFRegisterInfo::BPFRegisterInfo() 30 : BPFGenRegisterInfo(BPF::R0) {} 31 32const MCPhysReg * 33BPFRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { 34 return CSR_SaveList; 35} 36 37BitVector BPFRegisterInfo::getReservedRegs(const MachineFunction &MF) const { 38 BitVector Reserved(getNumRegs()); 39 Reserved.set(BPF::R10); // R10 is read only frame pointer 40 Reserved.set(BPF::R11); // R11 is pseudo stack pointer 41 return Reserved; 42} 43 44void BPFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, 45 int SPAdj, unsigned FIOperandNum, 46 RegScavenger *RS) const { 47 assert(SPAdj == 0 && "Unexpected"); 48 49 unsigned i = 0; 50 MachineInstr &MI = *II; 51 MachineFunction &MF = *MI.getParent()->getParent(); 52 DebugLoc DL = MI.getDebugLoc(); 53 54 while (!MI.getOperand(i).isFI()) { 55 ++i; 56 assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); 57 } 58 59 unsigned FrameReg = getFrameRegister(MF); 60 int FrameIndex = MI.getOperand(i).getIndex(); 61 const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); 62 MachineBasicBlock &MBB = *MI.getParent(); 63 64 if (MI.getOpcode() == BPF::MOV_rr) { 65 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex); 66 67 MI.getOperand(i).ChangeToRegister(FrameReg, false); 68 unsigned reg = MI.getOperand(i - 1).getReg(); 69 BuildMI(MBB, ++II, DL, TII.get(BPF::ADD_ri), reg) 70 .addReg(reg) 71 .addImm(Offset); 72 return; 73 } 74 75 int Offset = MF.getFrameInfo()->getObjectOffset(FrameIndex) + 76 MI.getOperand(i + 1).getImm(); 77 78 if (!isInt<32>(Offset)) 79 llvm_unreachable("bug in frame offset"); 80 81 if (MI.getOpcode() == BPF::FI_ri) { 82 // architecture does not really support FI_ri, replace it with 83 // MOV_rr <target_reg>, frame_reg 84 // ADD_ri <target_reg>, imm 85 unsigned reg = MI.getOperand(i - 1).getReg(); 86 87 BuildMI(MBB, ++II, DL, TII.get(BPF::MOV_rr), reg) 88 .addReg(FrameReg); 89 BuildMI(MBB, II, DL, TII.get(BPF::ADD_ri), reg) 90 .addReg(reg) 91 .addImm(Offset); 92 93 // Remove FI_ri instruction 94 MI.eraseFromParent(); 95 } else { 96 MI.getOperand(i).ChangeToRegister(FrameReg, false); 97 MI.getOperand(i + 1).ChangeToImmediate(Offset); 98 } 99} 100 101unsigned BPFRegisterInfo::getFrameRegister(const MachineFunction &MF) const { 102 return BPF::R10; 103} 104