1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 03:23:01 +02:00

bpf: refactor inst patterns with better inheritance

Arithmetic and jump instructions, load and store instructions are sharing
the same 8-bit code field encoding,

A better instruction pattern implemention could be the following inheritance
relationships, and each layer only encoding those fields which start to
diverse from that layer. This avoids some redundant code.

  InstBPF -> TYPE_ALU_JMP -> ALU/JMP
  InstBPF -> TYPE_LD_ST -> Load/Store

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: 313959
This commit is contained in:
Yonghong Song 2017-09-22 04:36:34 +00:00
parent e7fa849142
commit b655bb5721

View File

@ -88,38 +88,67 @@ def BPF_CC_LTU : PatLeaf<(i64 imm),
def BPF_CC_LEU : PatLeaf<(i64 imm),
[{return (N->getZExtValue() == ISD::SETULE);}]>;
// For arithmetic and jump instructions the 8-bit 'code'
// field is divided into three parts:
//
// +----------------+--------+--------------------+
// | 4 bits | 1 bit | 3 bits |
// | operation code | source | instruction class |
// +----------------+--------+--------------------+
// (MSB) (LSB)
class TYPE_ALU_JMP<bits<4> op, bits<1> srctype,
dag outs, dag ins, string asmstr, list<dag> pattern>
: InstBPF<outs, ins, asmstr, pattern> {
let Inst{63-60} = op;
let Inst{59} = srctype;
}
//For load and store instructions the 8-bit 'code' field is divided as:
//
// +--------+--------+-------------------+
// | 3 bits | 2 bits | 3 bits |
// | mode | size | instruction class |
// +--------+--------+-------------------+
// (MSB) (LSB)
class TYPE_LD_ST<bits<3> mode, bits<2> size,
dag outs, dag ins, string asmstr, list<dag> pattern>
: InstBPF<outs, ins, asmstr, pattern> {
let Inst{63-61} = mode;
let Inst{60-59} = size;
}
// jump instructions
class JMP_RR<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
: InstBPF<(outs), (ins GPR:$dst, GPR:$src, brtarget:$BrDst),
"if $dst "#OpcodeStr#" $src goto $BrDst",
[(BPFbrcc i64:$dst, i64:$src, Cond, bb:$BrDst)]> {
: TYPE_ALU_JMP<Opc.Value, BPF_X.Value,
(outs),
(ins GPR:$dst, GPR:$src, brtarget:$BrDst),
"if $dst "#OpcodeStr#" $src goto $BrDst",
[(BPFbrcc i64:$dst, i64:$src, Cond, bb:$BrDst)]> {
bits<4> dst;
bits<4> src;
bits<16> BrDst;
let Inst{63-60} = Opc.Value;
let Inst{59} = BPF_X.Value;
let Inst{55-52} = src;
let Inst{51-48} = dst;
let Inst{47-32} = BrDst;
let BPFClass = BPF_JMP;
}
class JMP_RI<BPFJumpOp Opc, string OpcodeStr, PatLeaf Cond>
: InstBPF<(outs), (ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
"if $dst "#OpcodeStr#" $imm goto $BrDst",
[(BPFbrcc i64:$dst, i64immSExt32:$imm, Cond, bb:$BrDst)]> {
: TYPE_ALU_JMP<Opc.Value, BPF_K.Value,
(outs),
(ins GPR:$dst, i64imm:$imm, brtarget:$BrDst),
"if $dst "#OpcodeStr#" $imm goto $BrDst",
[(BPFbrcc i64:$dst, i64immSExt32:$imm, Cond, bb:$BrDst)]> {
bits<4> dst;
bits<16> BrDst;
bits<32> imm;
let Inst{63-60} = Opc.Value;
let Inst{59} = BPF_K.Value;
let Inst{51-48} = dst;
let Inst{47-32} = BrDst;
let Inst{31-0} = imm;
let BPFClass = BPF_JMP;
}
@ -144,32 +173,30 @@ defm JSLE : J<BPF_JSLE, "s<=", BPF_CC_LE>;
// ALU instructions
class ALU_RI<BPFArithOp Opc, string OpcodeStr, SDNode OpNode>
: InstBPF<(outs GPR:$dst), (ins GPR:$src2, i64imm:$imm),
"$dst "#OpcodeStr#" $imm",
[(set GPR:$dst, (OpNode GPR:$src2, i64immSExt32:$imm))]> {
: 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))]> {
bits<4> dst;
bits<32> imm;
let Inst{63-60} = Opc.Value;
let Inst{59} = BPF_K.Value;
let Inst{51-48} = dst;
let Inst{31-0} = imm;
let BPFClass = BPF_ALU64;
}
class ALU_RR<BPFArithOp Opc, string OpcodeStr, SDNode OpNode>
: InstBPF<(outs GPR:$dst), (ins GPR:$src2, GPR:$src),
"$dst "#OpcodeStr#" $src",
[(set GPR:$dst, (OpNode i64:$src2, i64:$src))]> {
: 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))]> {
bits<4> dst;
bits<4> src;
let Inst{63-60} = Opc.Value;
let Inst{59} = BPF_X.Value;
let Inst{55-52} = src;
let Inst{51-48} = dst;
let BPFClass = BPF_ALU64;
}
@ -194,50 +221,47 @@ let isAsCheapAsAMove = 1 in {
}
class MOV_RR<string OpcodeStr>
: InstBPF<(outs GPR:$dst), (ins GPR:$src),
"$dst "#OpcodeStr#" $src",
[]> {
: 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{63-60} = BPF_MOV.Value;
let Inst{59} = BPF_X.Value;
let Inst{55-52} = src;
let Inst{51-48} = dst;
let BPFClass = BPF_ALU64;
}
class MOV_RI<string OpcodeStr>
: InstBPF<(outs GPR:$dst), (ins i64imm:$imm),
"$dst "#OpcodeStr#" $imm",
[(set GPR:$dst, (i64 i64immSExt32:$imm))]> {
: 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{63-60} = BPF_MOV.Value;
let Inst{59} = BPF_K.Value;
let Inst{51-48} = dst;
let Inst{31-0} = imm;
let BPFClass = BPF_ALU64;
}
class LD_IMM64<bits<4> Pseudo, string OpcodeStr>
: InstBPF<(outs GPR:$dst), (ins u64imm:$imm),
"$dst "#OpcodeStr#" ${imm} ll",
[(set GPR:$dst, (i64 imm:$imm))]> {
: TYPE_LD_ST<BPF_IMM.Value, BPF_DW.Value,
(outs GPR:$dst),
(ins u64imm:$imm),
"$dst "#OpcodeStr#" ${imm} ll",
[(set GPR:$dst, (i64 imm:$imm))]> {
bits<4> dst;
bits<64> imm;
let Inst{63-61} = BPF_IMM.Value;
let Inst{60-59} = BPF_DW.Value;
let Inst{51-48} = dst;
let Inst{55-52} = Pseudo;
let Inst{47-32} = 0;
let Inst{31-0} = imm{31-0};
let BPFClass = BPF_LD;
}
@ -248,13 +272,13 @@ def MOV_ri : MOV_RI<"=">;
}
def FI_ri
: InstBPF<(outs GPR:$dst), (ins MEMri:$addr),
"lea\t$dst, $addr",
[(set i64:$dst, FIri:$addr)]> {
: TYPE_LD_ST<BPF_IMM.Value, BPF_DW.Value,
(outs GPR:$dst),
(ins MEMri:$addr),
"lea\t$dst, $addr",
[(set i64:$dst, FIri:$addr)]> {
// This is a tentative instruction, and will be replaced
// with MOV_rr and ADD_ri in PEI phase
let Inst{63-61} = 0;
let Inst{60-59} = 3;
let Inst{51-48} = 0;
let Inst{55-52} = 2;
let Inst{47-32} = 0;
@ -262,39 +286,37 @@ def FI_ri
let BPFClass = BPF_LD;
}
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))]> {
: TYPE_LD_ST<BPF_IMM.Value, BPF_DW.Value,
(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<4> dst;
bits<64> imm;
bits<4> pseudo;
let Inst{63-61} = BPF_IMM.Value;
let Inst{60-59} = BPF_DW.Value;
let Inst{51-48} = dst;
let Inst{55-52} = pseudo;
let Inst{47-32} = 0;
let Inst{31-0} = imm{31-0};
let BPFClass = BPF_LD;
}
// STORE instructions
class STORE<BPFWidthModifer SizeOp, string OpcodeStr, list<dag> Pattern>
: InstBPF<(outs), (ins GPR:$src, MEMri:$addr),
"*("#OpcodeStr#" *)($addr) = $src", Pattern> {
: TYPE_LD_ST<BPF_MEM.Value, SizeOp.Value,
(outs),
(ins GPR:$src, MEMri:$addr),
"*("#OpcodeStr#" *)($addr) = $src",
Pattern> {
bits<4> src;
bits<20> addr;
let Inst{63-61} = BPF_MEM.Value;
let Inst{60-59} = SizeOp.Value;
let Inst{51-48} = addr{19-16}; // base reg
let Inst{55-52} = src;
let Inst{47-32} = addr{15-0}; // offset
let BPFClass = BPF_STX;
}
@ -308,17 +330,17 @@ def STD : STOREi64<BPF_DW, "u64", store>;
// LOAD instructions
class LOAD<BPFWidthModifer SizeOp, string OpcodeStr, list<dag> Pattern>
: InstBPF<(outs GPR:$dst), (ins MEMri:$addr),
"$dst = *("#OpcodeStr#" *)($addr)", Pattern> {
: TYPE_LD_ST<BPF_MEM.Value, SizeOp.Value,
(outs GPR:$dst),
(ins MEMri:$addr),
"$dst = *("#OpcodeStr#" *)($addr)",
Pattern> {
bits<4> dst;
bits<20> addr;
let Inst{63-61} = BPF_MEM.Value;
let Inst{60-59} = SizeOp.Value;
let Inst{51-48} = dst;
let Inst{55-52} = addr{19-16};
let Inst{47-32} = addr{15-0};
let BPFClass = BPF_LDX;
}
@ -331,26 +353,26 @@ def LDB : LOADi64<BPF_B, "u8", zextloadi8>;
def LDD : LOADi64<BPF_DW, "u64", load>;
class BRANCH<BPFJumpOp Opc, string OpcodeStr, list<dag> Pattern>
: InstBPF<(outs), (ins brtarget:$BrDst),
!strconcat(OpcodeStr, " $BrDst"), Pattern> {
: TYPE_ALU_JMP<Opc.Value, BPF_K.Value,
(outs),
(ins brtarget:$BrDst),
!strconcat(OpcodeStr, " $BrDst"),
Pattern> {
bits<16> BrDst;
let Inst{63-60} = Opc.Value;
let Inst{59} = BPF_K.Value;
let Inst{47-32} = BrDst;
let BPFClass = BPF_JMP;
}
class CALL<string OpcodeStr>
: InstBPF<(outs), (ins calltarget:$BrDst),
!strconcat(OpcodeStr, " $BrDst"), []> {
: TYPE_ALU_JMP<BPF_CALL.Value, BPF_K.Value,
(outs),
(ins calltarget:$BrDst),
!strconcat(OpcodeStr, " $BrDst"),
[]> {
bits<32> BrDst;
let Inst{63-60} = BPF_CALL.Value;
let Inst{59} = BPF_K.Value;
let Inst{31-0} = BrDst;
let BPFClass = BPF_JMP;
}
@ -367,14 +389,14 @@ let isCall=1, hasDelaySlot=0, Uses = [R11],
}
class NOP_I<string OpcodeStr>
: InstBPF<(outs), (ins i32imm:$imm),
!strconcat(OpcodeStr, "\t$imm"), []> {
: TYPE_ALU_JMP<BPF_MOV.Value, BPF_X.Value,
(outs),
(ins i32imm:$imm),
!strconcat(OpcodeStr, "\t$imm"),
[]> {
// mov r0, r0 == nop
let Inst{63-60} = BPF_MOV.Value;
let Inst{59} = BPF_X.Value;
let Inst{55-52} = 0;
let Inst{51-48} = 0;
let BPFClass = BPF_ALU64;
}
@ -382,12 +404,12 @@ let hasSideEffects = 0 in
def NOP : NOP_I<"nop">;
class RET<string OpcodeStr>
: InstBPF<(outs), (ins),
!strconcat(OpcodeStr, ""), [(BPFretflag)]> {
let Inst{63-60} = BPF_EXIT.Value;
let Inst{59} = 0;
: TYPE_ALU_JMP<BPF_EXIT.Value, BPF_K.Value,
(outs),
(ins),
!strconcat(OpcodeStr, ""),
[(BPFretflag)]> {
let Inst{31-0} = 0;
let BPFClass = BPF_JMP;
}
@ -438,18 +460,17 @@ def : Pat<(extloadi32 ADDRri:$src), (i64 (LDW ADDRri:$src))>;
// Atomics
class XADD<BPFWidthModifer SizeOp, string OpcodeStr, PatFrag OpNode>
: InstBPF<(outs GPR:$dst), (ins MEMri:$addr, GPR:$val),
"lock *("#OpcodeStr#" *)($addr) += $val",
[(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val))]> {
: TYPE_LD_ST<BPF_XADD.Value, SizeOp.Value,
(outs GPR:$dst),
(ins MEMri:$addr, GPR:$val),
"lock *("#OpcodeStr#" *)($addr) += $val",
[(set GPR:$dst, (OpNode ADDRri:$addr, GPR:$val))]> {
bits<4> dst;
bits<20> addr;
let Inst{63-61} = BPF_XADD.Value;
let Inst{60-59} = SizeOp.Value;
let Inst{51-48} = addr{19-16}; // base reg
let Inst{55-52} = dst;
let Inst{47-32} = addr{15-0}; // offset
let BPFClass = BPF_STX;
}
@ -462,19 +483,16 @@ def XADD64 : XADD<BPF_DW, "u64", atomic_load_add_64>;
// bswap16, bswap32, bswap64
class BSWAP<bits<32> SizeOp, string OpcodeStr, list<dag> Pattern>
: InstBPF<(outs GPR:$dst), (ins GPR:$src),
!strconcat(OpcodeStr, "\t$dst"),
Pattern> {
: TYPE_ALU_JMP<BPF_END.Value, BPF_TO_BE.Value,
(outs GPR:$dst),
(ins GPR:$src),
!strconcat(OpcodeStr, "\t$dst"),
Pattern> {
bits<4> dst;
bits<32> imm;
let Inst{63-60} = BPF_END.Value;
let Inst{59} = BPF_TO_BE.Value; // (TODO: use BPF_TO_LE for big-endian target)
let Inst{51-48} = dst;
let Inst{31-0} = imm;
let Inst{31-0} = SizeOp;
let BPFClass = BPF_ALU;
let imm = SizeOp;
}
let Constraints = "$dst = $src" in {
@ -486,28 +504,26 @@ def BSWAP64 : BSWAP<64, "bswap64", [(set GPR:$dst, (bswap GPR:$src))]>;
let Defs = [R0, R1, R2, R3, R4, R5], Uses = [R6], hasSideEffects = 1,
hasExtraDefRegAllocReq = 1, hasExtraSrcRegAllocReq = 1, mayLoad = 1 in {
class LOAD_ABS<BPFWidthModifer SizeOp, string OpcodeStr, Intrinsic OpNode>
: InstBPF<(outs), (ins GPR:$skb, i64imm:$imm),
"r0 = *("#OpcodeStr#" *)skb[$imm]",
[(set R0, (OpNode GPR:$skb, i64immSExt32:$imm))]> {
: TYPE_LD_ST<BPF_ABS.Value, SizeOp.Value,
(outs),
(ins GPR:$skb, i64imm:$imm),
"r0 = *("#OpcodeStr#" *)skb[$imm]",
[(set R0, (OpNode GPR:$skb, i64immSExt32:$imm))]> {
bits<32> imm;
let Inst{63-61} = BPF_ABS.Value;
let Inst{60-59} = SizeOp.Value;
let Inst{31-0} = imm;
let BPFClass = BPF_LD;
}
class LOAD_IND<BPFWidthModifer SizeOp, string OpcodeStr, Intrinsic OpNode>
: InstBPF<(outs), (ins GPR:$skb, GPR:$val),
"r0 = *("#OpcodeStr#" *)skb[$val]",
[(set R0, (OpNode GPR:$skb, GPR:$val))]> {
: TYPE_LD_ST<BPF_IND.Value, SizeOp.Value,
(outs),
(ins GPR:$skb, GPR:$val),
"r0 = *("#OpcodeStr#" *)skb[$val]",
[(set R0, (OpNode GPR:$skb, GPR:$val))]> {
bits<4> val;
let Inst{63-61} = BPF_IND.Value;
let Inst{60-59} = SizeOp.Value;
let Inst{55-52} = val;
let BPFClass = BPF_LD;
}
}