| //===-- BPFRegisterInfo.cpp - BPF Register Information ----------*- C++ -*-===// | |
| // | |
| // The LLVM Compiler Infrastructure | |
| // | |
| // This file is distributed under the University of Illinois Open Source | |
| // License. See LICENSE.TXT for details. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| // | |
| // This file contains the BPF implementation of the TargetRegisterInfo class. | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "BPFRegisterInfo.h" | |
| #include "BPF.h" | |
| #include "BPFSubtarget.h" | |
| #include "llvm/CodeGen/MachineFrameInfo.h" | |
| #include "llvm/CodeGen/MachineFunction.h" | |
| #include "llvm/CodeGen/MachineInstrBuilder.h" | |
| #include "llvm/CodeGen/RegisterScavenging.h" | |
| #include "llvm/CodeGen/TargetFrameLowering.h" | |
| #include "llvm/CodeGen/TargetInstrInfo.h" | |
| #include "llvm/IR/DiagnosticInfo.h" | |
| #include "llvm/Support/ErrorHandling.h" | |
| #define GET_REGINFO_TARGET_DESC | |
| #include "BPFGenRegisterInfo.inc" | |
| using namespace llvm; | |
| BPFRegisterInfo::BPFRegisterInfo() | |
| : BPFGenRegisterInfo(BPF::R0) {} | |
| const MCPhysReg * | |
| BPFRegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const { | |
| return CSR_SaveList; | |
| } | |
| BitVector BPFRegisterInfo::getReservedRegs(const MachineFunction &MF) const { | |
| BitVector Reserved(getNumRegs()); | |
| markSuperRegs(Reserved, BPF::W10); // [W|R]10 is read only frame pointer | |
| markSuperRegs(Reserved, BPF::W11); // [W|R]11 is pseudo stack pointer | |
| return Reserved; | |
| } | |
| static void WarnSize(int Offset, MachineFunction &MF, DebugLoc& DL) | |
| { | |
| if (Offset <= -512) { | |
| const Function &F = MF.getFunction(); | |
| DiagnosticInfoUnsupported DiagStackSize(F, | |
| "Looks like the BPF stack limit of 512 bytes is exceeded. " | |
| "Please move large on stack variables into BPF per-cpu array map.\n", | |
| DL); | |
| F.getContext().diagnose(DiagStackSize); | |
| } | |
| } | |
| void BPFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, | |
| int SPAdj, unsigned FIOperandNum, | |
| RegScavenger *RS) const { | |
| assert(SPAdj == 0 && "Unexpected"); | |
| unsigned i = 0; | |
| MachineInstr &MI = *II; | |
| MachineBasicBlock &MBB = *MI.getParent(); | |
| MachineFunction &MF = *MBB.getParent(); | |
| DebugLoc DL = MI.getDebugLoc(); | |
| if (!DL) | |
| /* try harder to get some debug loc */ | |
| for (auto &I : MBB) | |
| if (I.getDebugLoc()) { | |
| DL = I.getDebugLoc(); | |
| break; | |
| } | |
| while (!MI.getOperand(i).isFI()) { | |
| ++i; | |
| assert(i < MI.getNumOperands() && "Instr doesn't have FrameIndex operand!"); | |
| } | |
| unsigned FrameReg = getFrameRegister(MF); | |
| int FrameIndex = MI.getOperand(i).getIndex(); | |
| const TargetInstrInfo &TII = *MF.getSubtarget().getInstrInfo(); | |
| if (MI.getOpcode() == BPF::MOV_rr) { | |
| int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex); | |
| WarnSize(Offset, MF, DL); | |
| MI.getOperand(i).ChangeToRegister(FrameReg, false); | |
| unsigned reg = MI.getOperand(i - 1).getReg(); | |
| BuildMI(MBB, ++II, DL, TII.get(BPF::ADD_ri), reg) | |
| .addReg(reg) | |
| .addImm(Offset); | |
| return; | |
| } | |
| int Offset = MF.getFrameInfo().getObjectOffset(FrameIndex) + | |
| MI.getOperand(i + 1).getImm(); | |
| if (!isInt<32>(Offset)) | |
| llvm_unreachable("bug in frame offset"); | |
| WarnSize(Offset, MF, DL); | |
| if (MI.getOpcode() == BPF::FI_ri) { | |
| // architecture does not really support FI_ri, replace it with | |
| // MOV_rr <target_reg>, frame_reg | |
| // ADD_ri <target_reg>, imm | |
| unsigned reg = MI.getOperand(i - 1).getReg(); | |
| BuildMI(MBB, ++II, DL, TII.get(BPF::MOV_rr), reg) | |
| .addReg(FrameReg); | |
| BuildMI(MBB, II, DL, TII.get(BPF::ADD_ri), reg) | |
| .addReg(reg) | |
| .addImm(Offset); | |
| // Remove FI_ri instruction | |
| MI.eraseFromParent(); | |
| } else { | |
| MI.getOperand(i).ChangeToRegister(FrameReg, false); | |
| MI.getOperand(i + 1).ChangeToImmediate(Offset); | |
| } | |
| } | |
| unsigned BPFRegisterInfo::getFrameRegister(const MachineFunction &MF) const { | |
| return BPF::R10; | |
| } |