1 //===-- BPFRegisterInfo.cpp - BPF Register Information ----------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file contains the BPF implementation of the TargetRegisterInfo class.
11 //===----------------------------------------------------------------------===//
13 #include "BPFRegisterInfo.h"
15 #include "BPFSubtarget.h"
16 #include "llvm/CodeGen/MachineFrameInfo.h"
17 #include "llvm/CodeGen/MachineFunction.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/RegisterScavenging.h"
20 #include "llvm/CodeGen/TargetFrameLowering.h"
21 #include "llvm/CodeGen/TargetInstrInfo.h"
22 #include "llvm/IR/DiagnosticInfo.h"
23 #include "llvm/Support/ErrorHandling.h"
25 #define GET_REGINFO_TARGET_DESC
26 #include "BPFGenRegisterInfo.inc"
29 BPFRegisterInfo::BPFRegisterInfo()
30 : BPFGenRegisterInfo(BPF::R0
) {}
33 BPFRegisterInfo::getCalleeSavedRegs(const MachineFunction
*MF
) const {
37 BitVector
BPFRegisterInfo::getReservedRegs(const MachineFunction
&MF
) const {
38 BitVector
Reserved(getNumRegs());
39 markSuperRegs(Reserved
, BPF::W10
); // [W|R]10 is read only frame pointer
40 markSuperRegs(Reserved
, BPF::W11
); // [W|R]11 is pseudo stack pointer
44 static void WarnSize(int Offset
, MachineFunction
&MF
, DebugLoc
& DL
)
47 const Function
&F
= MF
.getFunction();
48 DiagnosticInfoUnsupported
DiagStackSize(F
,
49 "Looks like the BPF stack limit of 512 bytes is exceeded. "
50 "Please move large on stack variables into BPF per-cpu array map.\n",
52 F
.getContext().diagnose(DiagStackSize
);
56 void BPFRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II
,
57 int SPAdj
, unsigned FIOperandNum
,
58 RegScavenger
*RS
) const {
59 assert(SPAdj
== 0 && "Unexpected");
62 MachineInstr
&MI
= *II
;
63 MachineBasicBlock
&MBB
= *MI
.getParent();
64 MachineFunction
&MF
= *MBB
.getParent();
65 DebugLoc DL
= MI
.getDebugLoc();
68 /* try harder to get some debug loc */
70 if (I
.getDebugLoc()) {
75 while (!MI
.getOperand(i
).isFI()) {
77 assert(i
< MI
.getNumOperands() && "Instr doesn't have FrameIndex operand!");
80 unsigned FrameReg
= getFrameRegister(MF
);
81 int FrameIndex
= MI
.getOperand(i
).getIndex();
82 const TargetInstrInfo
&TII
= *MF
.getSubtarget().getInstrInfo();
84 if (MI
.getOpcode() == BPF::MOV_rr
) {
85 int Offset
= MF
.getFrameInfo().getObjectOffset(FrameIndex
);
87 WarnSize(Offset
, MF
, DL
);
88 MI
.getOperand(i
).ChangeToRegister(FrameReg
, false);
89 unsigned reg
= MI
.getOperand(i
- 1).getReg();
90 BuildMI(MBB
, ++II
, DL
, TII
.get(BPF::ADD_ri
), reg
)
96 int Offset
= MF
.getFrameInfo().getObjectOffset(FrameIndex
) +
97 MI
.getOperand(i
+ 1).getImm();
99 if (!isInt
<32>(Offset
))
100 llvm_unreachable("bug in frame offset");
102 WarnSize(Offset
, MF
, DL
);
104 if (MI
.getOpcode() == BPF::FI_ri
) {
105 // architecture does not really support FI_ri, replace it with
106 // MOV_rr <target_reg>, frame_reg
107 // ADD_ri <target_reg>, imm
108 unsigned reg
= MI
.getOperand(i
- 1).getReg();
110 BuildMI(MBB
, ++II
, DL
, TII
.get(BPF::MOV_rr
), reg
)
112 BuildMI(MBB
, II
, DL
, TII
.get(BPF::ADD_ri
), reg
)
116 // Remove FI_ri instruction
117 MI
.eraseFromParent();
119 MI
.getOperand(i
).ChangeToRegister(FrameReg
, false);
120 MI
.getOperand(i
+ 1).ChangeToImmediate(Offset
);
124 Register
BPFRegisterInfo::getFrameRegister(const MachineFunction
&MF
) const {