From 4193093152f5fd86479ee2313982bfbb6239fda2 Mon Sep 17 00:00:00 2001 From: Alexei Starovoitov Date: Fri, 27 Mar 2015 18:51:42 +0000 Subject: [PATCH] [bpf] add support for bpf pseudo instruction Expose bpf pseudo load instruction via intrinsic. It is used by front-ends that can encode file descriptors directly into IR instead of relying on relocations. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@233396 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/IntrinsicsBPF.td | 2 ++ lib/Target/BPF/BPFInstrInfo.td | 23 +++++++++++++++++++ .../BPF/MCTargetDesc/BPFMCCodeEmitter.cpp | 2 +- test/CodeGen/BPF/intrinsics.ll | 15 +++++++++++- 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/include/llvm/IR/IntrinsicsBPF.td b/include/llvm/IR/IntrinsicsBPF.td index 6b5110beda3..94eca8e4033 100644 --- a/include/llvm/IR/IntrinsicsBPF.td +++ b/include/llvm/IR/IntrinsicsBPF.td @@ -19,4 +19,6 @@ let TargetPrefix = "bpf" in { // All intrinsics start with "llvm.bpf." Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty], [IntrReadMem]>; def int_bpf_load_word : GCCBuiltin<"__builtin_bpf_load_word">, Intrinsic<[llvm_i64_ty], [llvm_ptr_ty, llvm_i64_ty], [IntrReadMem]>; + def int_bpf_pseudo : GCCBuiltin<"__builtin_bpf_pseudo">, + Intrinsic<[llvm_i64_ty], [llvm_i64_ty, llvm_i64_ty]>; } diff --git a/lib/Target/BPF/BPFInstrInfo.td b/lib/Target/BPF/BPFInstrInfo.td index 47001f01ff0..1ab7a7754cd 100644 --- a/lib/Target/BPF/BPFInstrInfo.td +++ b/lib/Target/BPF/BPFInstrInfo.td @@ -257,6 +257,29 @@ class LD_IMM64 Pseudo, string OpcodeStr> } def LD_imm64 : LD_IMM64<0, "ld_64">; +def LD_pseudo + : InstBPF<(outs GPR:$dst), (ins i64imm:$pseudo, u64imm:$imm), + "ld_pseudo\t$dst, $pseudo, $imm", + [(set GPR:$dst, (int_bpf_pseudo imm:$pseudo, imm:$imm))]> { + + bits<3> mode; + bits<2> size; + bits<4> dst; + bits<64> imm; + bits<4> pseudo; + + let Inst{63-61} = mode; + let Inst{60-59} = size; + let Inst{51-48} = dst; + let Inst{55-52} = pseudo; + let Inst{47-32} = 0; + let Inst{31-0} = imm{31-0}; + + let mode = 0; // BPF_IMM + let size = 3; // BPF_DW + let BPFClass = 0; // BPF_LD +} + // STORE instructions class STORE SizeOp, string OpcodeStr, list Pattern> : InstBPF<(outs), (ins GPR:$src, MEMri:$addr), diff --git a/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp b/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp index 9c51d66dbc2..280d2f1e57f 100644 --- a/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp +++ b/lib/Target/BPF/MCTargetDesc/BPFMCCodeEmitter.cpp @@ -125,7 +125,7 @@ void BPFMCCodeEmitter::EncodeInstruction(const MCInst &MI, raw_ostream &OS, // Keep track of the current byte being emitted unsigned CurByte = 0; - if (Opcode == BPF::LD_imm64) { + if (Opcode == BPF::LD_imm64 || Opcode == BPF::LD_pseudo) { uint64_t Value = getBinaryCodeForInstr(MI, Fixups, STI); EmitByte(Value >> 56, CurByte, OS); EmitByte(((Value >> 48) & 0xff), CurByte, OS); diff --git a/test/CodeGen/BPF/intrinsics.ll b/test/CodeGen/BPF/intrinsics.ll index e0f050e83f9..01ba4c770da 100644 --- a/test/CodeGen/BPF/intrinsics.ll +++ b/test/CodeGen/BPF/intrinsics.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s -march=bpf | FileCheck %s +; RUN: llc < %s -march=bpf -show-mc-encoding | FileCheck %s ; Function Attrs: nounwind uwtable define i32 @ld_b(i64 %foo, i64* nocapture %bar, i8* %ctx, i8* %ctx2) #0 { @@ -48,3 +48,16 @@ define i32 @ld_w(i8* %ctx, i8* %ctx2, i32 %foo) #0 { } declare i64 @llvm.bpf.load.word(i8*, i64) #1 + +define i32 @ld_pseudo() #0 { +entry: + %call = tail call i64 @llvm.bpf.pseudo(i64 2, i64 3) + tail call void @bar(i64 %call, i32 4) #2 + ret i32 0 +; CHECK-LABEL: ld_pseudo: +; CHECK: ld_pseudo r1, 2, 3 # encoding: [0x18,0x21,0x00,0x00,0x03,0x00 +} + +declare void @bar(i64, i32) #1 + +declare i64 @llvm.bpf.pseudo(i64, i64) #2