[llvm] r313593 - bpf: add inline-asm support
Yonghong Song via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 18 16:29:36 PDT 2017
Author: yhs
Date: Mon Sep 18 16:29:36 2017
New Revision: 313593
URL: http://llvm.org/viewvc/llvm-project?rev=313593&view=rev
Log:
bpf: add inline-asm support
Signed-off-by: Yonghong Song <yhs at fb.com>
Acked-by: Alexei Starovoitov <ast at kernel.org>
Added:
llvm/trunk/test/CodeGen/BPF/inline_asm.ll
Modified:
llvm/trunk/lib/Target/BPF/BPFAsmPrinter.cpp
llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp
llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp
llvm/trunk/lib/Target/BPF/BPFISelLowering.h
Modified: llvm/trunk/lib/Target/BPF/BPFAsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFAsmPrinter.cpp?rev=313593&r1=313592&r2=313593&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFAsmPrinter.cpp (original)
+++ llvm/trunk/lib/Target/BPF/BPFAsmPrinter.cpp Mon Sep 18 16:29:36 2017
@@ -40,11 +40,88 @@ public:
: AsmPrinter(TM, std::move(Streamer)) {}
StringRef getPassName() const override { return "BPF Assembly Printer"; }
+ void printOperand(const MachineInstr *MI, int OpNum, raw_ostream &O);
+ bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O) override;
+ bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNum,
+ unsigned AsmVariant, const char *ExtraCode,
+ raw_ostream &O) override;
void EmitInstruction(const MachineInstr *MI) override;
};
} // namespace
+void BPFAsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
+ raw_ostream &O) {
+ const MachineOperand &MO = MI->getOperand(OpNum);
+
+ switch (MO.getType()) {
+ case MachineOperand::MO_Register:
+ O << BPFInstPrinter::getRegisterName(MO.getReg());
+ break;
+
+ case MachineOperand::MO_Immediate:
+ O << MO.getImm();
+ break;
+
+ case MachineOperand::MO_MachineBasicBlock:
+ O << *MO.getMBB()->getSymbol();
+ break;
+
+ case MachineOperand::MO_GlobalAddress:
+ O << *getSymbol(MO.getGlobal());
+ break;
+
+ case MachineOperand::MO_BlockAddress: {
+ MCSymbol *BA = GetBlockAddressSymbol(MO.getBlockAddress());
+ O << BA->getName();
+ break;
+ }
+
+ case MachineOperand::MO_ExternalSymbol:
+ O << *GetExternalSymbolSymbol(MO.getSymbolName());
+ break;
+
+ case MachineOperand::MO_JumpTableIndex:
+ case MachineOperand::MO_ConstantPoolIndex:
+ default:
+ llvm_unreachable("<unknown operand type>");
+ }
+}
+
+bool BPFAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
+ unsigned /*AsmVariant*/,
+ const char *ExtraCode, raw_ostream &O) {
+ if (ExtraCode && ExtraCode[0])
+ return true; // BPF does not have special modifiers
+
+ printOperand(MI, OpNo, O);
+ return false;
+}
+
+bool BPFAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
+ unsigned OpNum, unsigned AsmVariant,
+ const char *ExtraCode,
+ raw_ostream &O) {
+ assert(OpNum + 1 < MI->getNumOperands() && "Insufficient operands");
+ const MachineOperand &BaseMO = MI->getOperand(OpNum);
+ const MachineOperand &OffsetMO = MI->getOperand(OpNum + 1);
+ assert(BaseMO.isReg() && "Unexpected base pointer for inline asm memory operand.");
+ assert(OffsetMO.isImm() && "Unexpected offset for inline asm memory operand.");
+ int Offset = OffsetMO.getImm();
+
+ if (ExtraCode)
+ return true; // Unknown modifier.
+
+ if (Offset < 0)
+ O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " - " << -Offset << ")";
+ else
+ O << "(" << BPFInstPrinter::getRegisterName(BaseMO.getReg()) << " + " << Offset << ")";
+
+ return false;
+}
+
void BPFAsmPrinter::EmitInstruction(const MachineInstr *MI) {
BPFMCInstLower MCInstLowering(OutContext, *this);
Modified: llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp?rev=313593&r1=313592&r2=313593&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp (original)
+++ llvm/trunk/lib/Target/BPF/BPFISelDAGToDAG.cpp Mon Sep 18 16:29:36 2017
@@ -48,6 +48,10 @@ public:
void PreprocessISelDAG() override;
+ bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode,
+ std::vector<SDValue> &OutOps) override;
+
+
private:
// Include the pieces autogenerated from the target description.
#include "BPFGenDAGISel.inc"
@@ -145,6 +149,26 @@ bool BPFDAGToDAGISel::SelectFIAddr(SDVal
return false;
}
+bool BPFDAGToDAGISel::SelectInlineAsmMemoryOperand(
+ const SDValue &Op, unsigned ConstraintCode, std::vector<SDValue> &OutOps) {
+ SDValue Op0, Op1;
+ switch (ConstraintCode) {
+ default:
+ return true;
+ case InlineAsm::Constraint_m: // memory
+ if (!SelectAddr(Op, Op0, Op1))
+ return true;
+ break;
+ }
+
+ SDLoc DL(Op);
+ SDValue AluOp = CurDAG->getTargetConstant(ISD::ADD, DL, MVT::i32);;
+ OutOps.push_back(Op0);
+ OutOps.push_back(Op1);
+ OutOps.push_back(AluOp);
+ return false;
+}
+
void BPFDAGToDAGISel::Select(SDNode *Node) {
unsigned Opcode = Node->getOpcode();
Modified: llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp?rev=313593&r1=313592&r2=313593&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/BPF/BPFISelLowering.cpp Mon Sep 18 16:29:36 2017
@@ -139,6 +139,22 @@ bool BPFTargetLowering::isOffsetFoldingL
return false;
}
+std::pair<unsigned, const TargetRegisterClass *>
+BPFTargetLowering::getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
+ StringRef Constraint,
+ MVT VT) const {
+ if (Constraint.size() == 1)
+ // GCC Constraint Letters
+ switch (Constraint[0]) {
+ case 'r': // GENERAL_REGS
+ return std::make_pair(0U, &BPF::GPRRegClass);
+ default:
+ break;
+ }
+
+ return TargetLowering::getRegForInlineAsmConstraint(TRI, Constraint, VT);
+}
+
SDValue BPFTargetLowering::LowerOperation(SDValue Op, SelectionDAG &DAG) const {
switch (Op.getOpcode()) {
case ISD::BR_CC:
Modified: llvm/trunk/lib/Target/BPF/BPFISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/BPF/BPFISelLowering.h?rev=313593&r1=313592&r2=313593&view=diff
==============================================================================
--- llvm/trunk/lib/Target/BPF/BPFISelLowering.h (original)
+++ llvm/trunk/lib/Target/BPF/BPFISelLowering.h Mon Sep 18 16:29:36 2017
@@ -46,6 +46,10 @@ public:
// with the given GlobalAddress is legal.
bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const override;
+ std::pair<unsigned, const TargetRegisterClass *>
+ getRegForInlineAsmConstraint(const TargetRegisterInfo *TRI,
+ StringRef Constraint, MVT VT) const override;
+
MachineBasicBlock *
EmitInstrWithCustomInserter(MachineInstr &MI,
MachineBasicBlock *BB) const override;
Added: llvm/trunk/test/CodeGen/BPF/inline_asm.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/BPF/inline_asm.ll?rev=313593&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/BPF/inline_asm.ll (added)
+++ llvm/trunk/test/CodeGen/BPF/inline_asm.ll Mon Sep 18 16:29:36 2017
@@ -0,0 +1,54 @@
+; RUN: llc < %s -march=bpfel -verify-machineinstrs | FileCheck %s
+; RUN: llc < %s -march=bpfeb -verify-machineinstrs | FileCheck %s
+
+; Source code:
+; int g[2];
+;
+; int test(void *ctx) {
+; int a = 4, b;
+; unsigned long long c = 333333333333ULL;
+; asm volatile("r0 = *(u16 *)skb[%0]" : : "i"(2));
+; asm volatile("r0 = *(u16 *)skb[%0]" : : "r"(a));
+; asm volatile("%0 = %1" : "=r"(b) : "i"(4));
+; asm volatile("%0 = %1 ll" : "=r"(b) : "i"(c));
+; asm volatile("%0 = *(u16 *) %1" : "=r"(b) : "m"(a));
+; asm volatile("%0 = *(u32 *) %1" : "=r"(b) : "m"(g[1]));
+; return b;
+; }
+;
+
+ at g = common global [2 x i32] zeroinitializer, align 4
+
+; Function Attrs: nounwind
+define i32 @test(i8* nocapture readnone %ctx) local_unnamed_addr #0 {
+entry:
+ %a = alloca i32, align 4
+ %0 = bitcast i32* %a to i8*
+ call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %0) #2
+ store i32 4, i32* %a, align 4
+ tail call void asm sideeffect "r0 = *(u16 *)skb[$0]", "i"(i32 2) #2
+; CHECK: r0 = *(u16 *)skb[2]
+ tail call void asm sideeffect "r0 = *(u16 *)skb[$0]", "r"(i32 4) #2
+; CHECK: r0 = *(u16 *)skb[r1]
+ %1 = tail call i32 asm sideeffect "$0 = $1", "=r,i"(i32 4) #2
+; CHECK: r1 = 4
+ %2 = tail call i32 asm sideeffect "$0 = $1 ll", "=r,i"(i64 333333333333) #2
+; CHECK: r1 = 333333333333 ll
+ %3 = call i32 asm sideeffect "$0 = *(u16 *) $1", "=r,*m"(i32* nonnull %a) #2
+; CHECK: r1 = *(u16 *) (r10 - 4)
+ %4 = call i32 asm sideeffect "$0 = *(u32 *) $1", "=r,*m"(i32* getelementptr inbounds ([2 x i32], [2 x i32]* @g, i64 0, i64 1)) #2
+; CHECK: r1 = g ll
+; CHECK: r0 = *(u32 *) (r1 + 4)
+ call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %0) #2
+ ret i32 %4
+}
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1
+
+; Function Attrs: argmemonly nounwind
+declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1
+
+attributes #0 = { nounwind }
+attributes #1 = { argmemonly nounwind }
+attributes #2 = { nounwind }
More information about the llvm-commits
mailing list