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:
parent
e7fa849142
commit
b655bb5721
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user