[llvm] [BPF] Add asm support for JSET insn (PR #73161)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 22 11:45:52 PST 2023


https://github.com/yonghong-song created https://github.com/llvm/llvm-project/pull/73161

BPF upstream reported that JSET insn is not supported in inline asm ([1]). BPF_JSET insn is part of BPF ISA so let us add asm support for it now.

  [1] https://lore.kernel.org/bpf/2e8a1584-a289-4b2e-800c-8b463e734bcb@linux.dev/

>From e25a5f7170d0d244ba52055d28f673415aa6b153 Mon Sep 17 00:00:00 2001
From: Yonghong Song <yonghong.song at linux.dev>
Date: Wed, 22 Nov 2023 11:32:12 -0800
Subject: [PATCH] [BPF] Add asm support for JSET insn

BPF upstream reported that JSET insn is not supported in inline asm ([1]).
BPF_JSET insn is part of BPF ISA so let us add asm support for it now.

  [1] https://lore.kernel.org/bpf/2e8a1584-a289-4b2e-800c-8b463e734bcb@linux.dev/
---
 llvm/lib/Target/BPF/BPFInstrFormats.td |  1 +
 llvm/lib/Target/BPF/BPFInstrInfo.td    | 68 ++++++++++++++++++++++++++
 llvm/test/MC/BPF/insn-unit-32.s        |  5 ++
 llvm/test/MC/BPF/insn-unit.s           |  5 ++
 4 files changed, 79 insertions(+)

diff --git a/llvm/lib/Target/BPF/BPFInstrFormats.td b/llvm/lib/Target/BPF/BPFInstrFormats.td
index 841d97efc01c5c1..6ed83d877ac0f23 100644
--- a/llvm/lib/Target/BPF/BPFInstrFormats.td
+++ b/llvm/lib/Target/BPF/BPFInstrFormats.td
@@ -63,6 +63,7 @@ def BPF_JA   : BPFJumpOp<0x0>;
 def BPF_JEQ  : BPFJumpOp<0x1>;
 def BPF_JGT  : BPFJumpOp<0x2>;
 def BPF_JGE  : BPFJumpOp<0x3>;
+def BPF_JSET : BPFJumpOp<0x4>;
 def BPF_JNE  : BPFJumpOp<0x5>;
 def BPF_JSGT : BPFJumpOp<0x6>;
 def BPF_JSGE : BPFJumpOp<0x7>;
diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
index 305cbbd34d2707d..9e75f35efe70cb3 100644
--- a/llvm/lib/Target/BPF/BPFInstrInfo.td
+++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -246,6 +246,70 @@ class JMP_RI_32<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
   let BPFClass = BPF_JMP32;
 }
 
+class JSET_RR<string OpcodeStr>
+    : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
+                   (outs),
+                   (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
+                   "if $dst "#OpcodeStr#" $src goto $BrDst",
+                   []> {
+  bits<4> dst;
+  bits<4> src;
+  bits<16> BrDst;
+
+  let Inst{55-52} = src;
+  let Inst{51-48} = dst;
+  let Inst{47-32} = BrDst;
+  let BPFClass = BPF_JMP;
+}
+
+class JSET_RI<string OpcodeStr>
+    : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
+                   (outs),
+                   (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
+                   "if $dst "#OpcodeStr#" $imm goto $BrDst",
+                   []> {
+  bits<4> dst;
+  bits<16> BrDst;
+  bits<32> imm;
+
+  let Inst{51-48} = dst;
+  let Inst{47-32} = BrDst;
+  let Inst{31-0} = imm;
+  let BPFClass = BPF_JMP;
+}
+
+class JSET_RR_32<string OpcodeStr>
+    : TYPE_ALU_JMP<BPF_JSET.Value, BPF_X.Value,
+                   (outs),
+                   (ins GPR32:$dst, GPR32:$src, brtarget:$BrDst),
+                   "if $dst "#OpcodeStr#" $src goto $BrDst",
+                   []> {
+  bits<4> dst;
+  bits<4> src;
+  bits<16> BrDst;
+
+  let Inst{55-52} = src;
+  let Inst{51-48} = dst;
+  let Inst{47-32} = BrDst;
+  let BPFClass = BPF_JMP32;
+}
+
+class JSET_RI_32<string OpcodeStr>
+    : TYPE_ALU_JMP<BPF_JSET.Value, BPF_K.Value,
+                   (outs),
+                   (ins GPR32:$dst, i32imm:$imm, brtarget:$BrDst),
+                   "if $dst "#OpcodeStr#" $imm goto $BrDst",
+                   []> {
+  bits<4> dst;
+  bits<16> BrDst;
+  bits<32> imm;
+
+  let Inst{51-48} = dst;
+  let Inst{47-32} = BrDst;
+  let Inst{31-0} = imm;
+  let BPFClass = BPF_JMP32;
+}
+
 multiclass J<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond, PatLeaf Cond32> {
   def _rr : JMP_RR<Opc, OpcodeStr, Cond>;
   def _ri : JMP_RI<Opc, OpcodeStr, Cond>;
@@ -265,6 +329,10 @@ defm JULT : J<BPF_JLT, "<", BPF_CC_LTU, BPF_CC_LTU_32>;
 defm JULE : J<BPF_JLE, "<=", BPF_CC_LEU, BPF_CC_LEU_32>;
 defm JSLT : J<BPF_JSLT, "s<", BPF_CC_LT, BPF_CC_LT_32>;
 defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE, BPF_CC_LE_32>;
+def JSET_RR    : JSET_RR<"&">;
+def JSET_RI    : JSET_RI<"&">;
+def JSET_RR_32 : JSET_RR_32<"&">;
+def JSET_RI_32 : JSET_RI_32<"&">;
 }
 
 // ALU instructions
diff --git a/llvm/test/MC/BPF/insn-unit-32.s b/llvm/test/MC/BPF/insn-unit-32.s
index e53c686a4fa3e33..09b89d72e507c0e 100644
--- a/llvm/test/MC/BPF/insn-unit-32.s
+++ b/llvm/test/MC/BPF/insn-unit-32.s
@@ -55,6 +55,11 @@
 // CHECK: b4 09 00 00 ff ff ff ff      w9 = -1
 // CHECK: c4 0a 00 00 40 00 00 00      w10 s>>= 64
 
+  if w1 & w2 goto Llabel0    // BPF_JSET | BPF_X
+  if w1 & 0xff goto Llabel0  // BPF_JSET | BPF_K
+// CHECK: 4e 21 0d 00 00 00 00 00      if w1 & w2 goto +13
+// CHECK: 46 01 0c 00 ff 00 00 00      if w1 & 255 goto +12
+
   if w0 == w1 goto Llabel0   // BPF_JEQ  | BPF_X
   if w3 != w4 goto Llabel0   // BPF_JNE  | BPF_X
 // CHECK: 1e 10 0b 00 00 00 00 00 	if w0 == w1 goto +11
diff --git a/llvm/test/MC/BPF/insn-unit.s b/llvm/test/MC/BPF/insn-unit.s
index 94c46e9013bac78..58342cda7cc0ad0 100644
--- a/llvm/test/MC/BPF/insn-unit.s
+++ b/llvm/test/MC/BPF/insn-unit.s
@@ -62,6 +62,11 @@
 // CHECK: db a3 e2 ff 00 00 00 00 	lock *(u64 *)(r3 - 30) += r10
 
 // ======== BPF_JMP Class ========
+  if r1 & r2 goto Llabel0    // BPF_JSET  | BPF_X
+  if r1 & 0xffff goto Llabel0    // BPF_JSET  | BPF_K
+// CHECK: 4d 21 1d 00 00 00 00 00 	if r1 & r2 goto +29
+// CHECK: 45 01 1c 00 ff ff 00 00 	if r1 & 65535 goto +28
+
   goto Llabel0               // BPF_JA
   call 1                     // BPF_CALL
   exit                       // BPF_EXIT



More information about the llvm-commits mailing list