summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYonghong Song <yhs@fb.com>2017-09-22 04:36:36 +0000
committerYonghong Song <yhs@fb.com>2017-09-22 04:36:36 +0000
commitd2e0d1fa11ab51da2e859eea6eba594eb44e5542 (patch)
tree06a8ccde564f75bec55d89c8dcd0d3602863dcbb
parent3c63b101deb53ba28f7074be49416d289b98d9ee (diff)
downloadbcm5719-llvm-d2e0d1fa11ab51da2e859eea6eba594eb44e5542.tar.gz
bcm5719-llvm-d2e0d1fa11ab51da2e859eea6eba594eb44e5542.zip
bpf: initial 32-bit ALU encoding support in assembler
This patch adds instruction patterns for operations in BPF_ALU. After this, assembler could recognize some 32-bit ALU statement. For example, those listed int the unit test file. Separate MOV patterns are unnecessary as MOV is ALU operation that could reuse ALU encoding infrastructure, this patch removed those redundant patterns. Acked-by: Jakub Kicinski <jakub.kicinski@netronome.com> Signed-off-by: Jiong Wang <jiong.wang@netronome.com> Reviewed-by: Yonghong Song <yhs@fb.com> llvm-svn: 313961
-rw-r--r--llvm/lib/Target/BPF/BPFInstrInfo.td94
-rw-r--r--llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp15
-rw-r--r--llvm/test/MC/BPF/insn-unit-32.s53
3 files changed, 116 insertions, 46 deletions
diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td
index 0319cfe04ae..e1f233e4d45 100644
--- a/llvm/lib/Target/BPF/BPFInstrInfo.td
+++ b/llvm/lib/Target/BPF/BPFInstrInfo.td
@@ -172,37 +172,49 @@ defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE>;
}
// ALU instructions
-class ALU_RI<BPFArithOp Opc, string OpcodeStr, SDNode OpNode>
- : TYPE_ALU_JMP<Opc.Value, BPF_K.Value,
- (outs GPR:$dst),
- (ins GPR:$src2, i64imm:$imm),
- "$dst "#OpcodeStr#" $imm",
- [(set GPR:$dst, (OpNode GPR:$src2, i64immSExt32:$imm))]> {
+class ALU_RI<BPFOpClass Class, BPFArithOp Opc,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : TYPE_ALU_JMP<Opc.Value, BPF_K.Value, outs, ins, asmstr, pattern> {
bits<4> dst;
bits<32> imm;
let Inst{51-48} = dst;
let Inst{31-0} = imm;
- let BPFClass = BPF_ALU64;
+ let BPFClass = Class;
}
-class ALU_RR<BPFArithOp Opc, string OpcodeStr, SDNode OpNode>
- : TYPE_ALU_JMP<Opc.Value, BPF_X.Value,
- (outs GPR:$dst),
- (ins GPR:$src2, GPR:$src),
- "$dst "#OpcodeStr#" $src",
- [(set GPR:$dst, (OpNode i64:$src2, i64:$src))]> {
+class ALU_RR<BPFOpClass Class, BPFArithOp Opc,
+ dag outs, dag ins, string asmstr, list<dag> pattern>
+ : TYPE_ALU_JMP<Opc.Value, BPF_X.Value, outs, ins, asmstr, pattern> {
bits<4> dst;
bits<4> src;
let Inst{55-52} = src;
let Inst{51-48} = dst;
- let BPFClass = BPF_ALU64;
+ let BPFClass = Class;
}
multiclass ALU<BPFArithOp Opc, string OpcodeStr, SDNode OpNode> {
- def _rr : ALU_RR<Opc, OpcodeStr, OpNode>;
- def _ri : ALU_RI<Opc, OpcodeStr, OpNode>;
+ def _rr : ALU_RR<BPF_ALU64, Opc,
+ (outs GPR:$dst),
+ (ins GPR:$src2, GPR:$src),
+ "$dst "#OpcodeStr#" $src",
+ [(set GPR:$dst, (OpNode i64:$src2, i64:$src))]>;
+ def _ri : ALU_RI<BPF_ALU64, Opc,
+ (outs GPR:$dst),
+ (ins GPR:$src2, i64imm:$imm),
+ "$dst "#OpcodeStr#" $imm",
+ [(set GPR:$dst, (OpNode GPR:$src2, i64immSExt32:$imm))]>;
+ def _rr_32 : ALU_RR<BPF_ALU, Opc,
+ (outs GPR32:$dst),
+ (ins GPR32:$src2, GPR32:$src),
+ "$dst "#OpcodeStr#" $src",
+ [(set GPR32:$dst, (OpNode i32:$src2, i32:$src))]>;
+ def _ri_32 : ALU_RI<BPF_ALU, Opc,
+ (outs GPR32:$dst),
+ (ins GPR32:$src2, i32imm:$imm),
+ "$dst "#OpcodeStr#" $imm",
+ [(set GPR32:$dst, (OpNode GPR32:$src2, i32:$imm))]>;
}
let Constraints = "$dst = $src2" in {
@@ -220,34 +232,6 @@ let isAsCheapAsAMove = 1 in {
defm DIV : ALU<BPF_DIV, "/=", udiv>;
}
-class MOV_RR<string OpcodeStr>
- : TYPE_ALU_JMP<BPF_MOV.Value, BPF_X.Value,
- (outs GPR:$dst),
- (ins GPR:$src),
- "$dst "#OpcodeStr#" $src",
- []> {
- bits<4> dst;
- bits<4> src;
-
- let Inst{55-52} = src;
- let Inst{51-48} = dst;
- let BPFClass = BPF_ALU64;
-}
-
-class MOV_RI<string OpcodeStr>
- : TYPE_ALU_JMP<BPF_MOV.Value, BPF_K.Value,
- (outs GPR:$dst),
- (ins i64imm:$imm),
- "$dst "#OpcodeStr#" $imm",
- [(set GPR:$dst, (i64 i64immSExt32:$imm))]> {
- bits<4> dst;
- bits<32> imm;
-
- let Inst{51-48} = dst;
- let Inst{31-0} = imm;
- let BPFClass = BPF_ALU64;
-}
-
class LD_IMM64<bits<4> Pseudo, string OpcodeStr>
: TYPE_LD_ST<BPF_IMM.Value, BPF_DW.Value,
(outs GPR:$dst),
@@ -267,8 +251,26 @@ class LD_IMM64<bits<4> Pseudo, string OpcodeStr>
let isReMaterializable = 1, isAsCheapAsAMove = 1 in {
def LD_imm64 : LD_IMM64<0, "=">;
-def MOV_rr : MOV_RR<"=">;
-def MOV_ri : MOV_RI<"=">;
+def MOV_rr : ALU_RR<BPF_ALU64, BPF_MOV,
+ (outs GPR:$dst),
+ (ins GPR:$src),
+ "$dst = $src",
+ []>;
+def MOV_ri : ALU_RI<BPF_ALU64, BPF_MOV,
+ (outs GPR:$dst),
+ (ins i64imm:$imm),
+ "$dst = $imm",
+ [(set GPR:$dst, (i64 i64immSExt32:$imm))]>;
+def MOV_rr_32 : ALU_RR<BPF_ALU, BPF_MOV,
+ (outs GPR32:$dst),
+ (ins GPR32:$src),
+ "$dst = $src",
+ []>;
+def MOV_ri_32 : ALU_RI<BPF_ALU, BPF_MOV,
+ (outs GPR32:$dst),
+ (ins i32imm:$imm),
+ "$dst = $imm",
+ [(set GPR32:$dst, (i32 i32:$imm))]>;
}
def FI_ri
diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
index a1d732c339e..f5b621f9f8f 100644
--- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
+++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp
@@ -79,6 +79,21 @@ static DecodeStatus DecodeGPRRegisterClass(MCInst &Inst, unsigned RegNo,
return MCDisassembler::Success;
}
+static const unsigned GPR32DecoderTable[] = {
+ BPF::W0, BPF::W1, BPF::W2, BPF::W3, BPF::W4, BPF::W5,
+ BPF::W6, BPF::W7, BPF::W8, BPF::W9, BPF::W10, BPF::W11};
+
+static DecodeStatus DecodeGPR32RegisterClass(MCInst &Inst, unsigned RegNo,
+ uint64_t /*Address*/,
+ const void * /*Decoder*/) {
+ if (RegNo > 11)
+ return MCDisassembler::Fail;
+
+ unsigned Reg = GPR32DecoderTable[RegNo];
+ Inst.addOperand(MCOperand::createReg(Reg));
+ return MCDisassembler::Success;
+}
+
static DecodeStatus decodeMemoryOpValue(MCInst &Inst, unsigned Insn,
uint64_t Address, const void *Decoder) {
unsigned Register = (Insn >> 16) & 0xf;
diff --git a/llvm/test/MC/BPF/insn-unit-32.s b/llvm/test/MC/BPF/insn-unit-32.s
new file mode 100644
index 00000000000..956f5bcb07b
--- /dev/null
+++ b/llvm/test/MC/BPF/insn-unit-32.s
@@ -0,0 +1,53 @@
+# RUN: llvm-mc -triple bpfel -filetype=obj -o %t %s
+# RUN: llvm-objdump -d -r %t | FileCheck %s
+
+// ======== BPF_ALU Class ========
+ w0 += w1 // BPF_ADD | BPF_X
+ w1 -= w2 // BPF_SUB | BPF_X
+ w2 *= w3 // BPF_MUL | BPF_X
+ w3 /= w4 // BPF_DIV | BPF_X
+// CHECK: 0c 10 00 00 00 00 00 00 w0 += w1
+// CHECK: 1c 21 00 00 00 00 00 00 w1 -= w2
+// CHECK: 2c 32 00 00 00 00 00 00 w2 *= w3
+// CHECK: 3c 43 00 00 00 00 00 00 w3 /= w4
+
+ w4 |= w5 // BPF_OR | BPF_X
+ w5 &= w6 // BPF_AND | BPF_X
+ w6 <<= w7 // BPF_LSH | BPF_X
+ w7 >>= w8 // BPF_RSH | BPF_X
+ w8 ^= w9 // BPF_XOR | BPF_X
+ w9 = w10 // BPF_MOV | BPF_X
+ w10 s>>= w0 // BPF_ARSH | BPF_X
+// CHECK: 4c 54 00 00 00 00 00 00 w4 |= w5
+// CHECK: 5c 65 00 00 00 00 00 00 w5 &= w6
+// CHECK: 6c 76 00 00 00 00 00 00 w6 <<= w7
+// CHECK: 7c 87 00 00 00 00 00 00 w7 >>= w8
+// CHECK: ac 98 00 00 00 00 00 00 w8 ^= w9
+// CHECK: bc a9 00 00 00 00 00 00 w9 = w10
+// CHECK: cc 0a 00 00 00 00 00 00 w10 s>>= w0
+
+ w0 += 1 // BPF_ADD | BPF_K
+ w1 -= 0x1 // BPF_SUB | BPF_K
+ w2 *= -4 // BPF_MUL | BPF_K
+ w3 /= 5 // BPF_DIV | BPF_K
+// CHECK: 04 00 00 00 01 00 00 00 w0 += 1
+// CHECK: 14 01 00 00 01 00 00 00 w1 -= 1
+// CHECK: 24 02 00 00 fc ff ff ff w2 *= -4
+// CHECK: 34 03 00 00 05 00 00 00 w3 /= 5
+
+ w4 |= 0xff // BPF_OR | BPF_K
+ w5 &= 0xFF // BPF_AND | BPF_K
+ w6 <<= 63 // BPF_LSH | BPF_K
+ w7 >>= 32 // BPF_RSH | BPF_K
+ w8 ^= 0 // BPF_XOR | BPF_K
+ w9 = 1 // BPF_MOV | BPF_K
+ w9 = 0xffffffff // BPF_MOV | BPF_K
+ w10 s>>= 64 // BPF_ARSH | BPF_K
+// CHECK: 44 04 00 00 ff 00 00 00 w4 |= 255
+// CHECK: 54 05 00 00 ff 00 00 00 w5 &= 255
+// CHECK: 64 06 00 00 3f 00 00 00 w6 <<= 63
+// CHECK: 74 07 00 00 20 00 00 00 w7 >>= 32
+// CHECK: a4 08 00 00 00 00 00 00 w8 ^= 0
+// CHECK: b4 09 00 00 01 00 00 00 w9 = 1
+// CHECK: b4 09 00 00 ff ff ff ff w9 = -1
+// CHECK: c4 0a 00 00 40 00 00 00 w10 s>>= 64
OpenPOWER on IntegriCloud