diff --git a/llvm/lib/Target/BPF/BPF.td b/llvm/lib/Target/BPF/BPF.td --- a/llvm/lib/Target/BPF/BPF.td +++ b/llvm/lib/Target/BPF/BPF.td @@ -21,6 +21,7 @@ def : Proc<"v1", []>; def : Proc<"v2", []>; def : Proc<"v3", []>; +def : Proc<"v4", []>; def : Proc<"probe", []>; def DummyFeature : SubtargetFeature<"dummy", "isDummyMode", diff --git a/llvm/lib/Target/BPF/BPFInstrFormats.td b/llvm/lib/Target/BPF/BPFInstrFormats.td --- a/llvm/lib/Target/BPF/BPFInstrFormats.td +++ b/llvm/lib/Target/BPF/BPFInstrFormats.td @@ -86,7 +86,15 @@ def BPF_ABS : BPFModeModifer<0x1>; def BPF_IND : BPFModeModifer<0x2>; def BPF_MEM : BPFModeModifer<0x3>; -def BPF_XADD : BPFModeModifer<0x6>; +def BPF_XMEM : BPFModeModifer<0x6>; + +class BPFXMemOp val> { + bits<8> Value = val; +} + +def BPF_XADD : BPFXMemOp<0x0>; +def BPF_XCHG : BPFXMemOp<0x1>; +def BPF_CMPXCHG : BPFXMemOp<0x2>; class InstBPF pattern> : Instruction { diff --git a/llvm/lib/Target/BPF/BPFInstrInfo.td b/llvm/lib/Target/BPF/BPFInstrInfo.td --- a/llvm/lib/Target/BPF/BPFInstrInfo.td +++ b/llvm/lib/Target/BPF/BPFInstrInfo.td @@ -53,6 +53,7 @@ def BPFIsBigEndian : Predicate<"!CurDAG->getDataLayout().isLittleEndian()">; def BPFHasALU32 : Predicate<"Subtarget->getHasAlu32()">; def BPFNoALU32 : Predicate<"!Subtarget->getHasAlu32()">; +def BPFHasAtomicExt : Predicate<"Subtarget->getHasAtomicExt()">; def brtarget : Operand { let PrintMethod = "printBrTargetOperand"; @@ -617,9 +618,9 @@ def : Pat<(i64 (extloadi32 ADDRri:$src)), (i64 (LDW ADDRri:$src))>; } -// Atomics +// Atomic XADD class XADD - : TYPE_LD_ST - : TYPE_LD_ST; } +// Atomic Exchange +class XCHG + : TYPE_LD_ST { + bits<4> dst; + bits<20> addr; + + let Inst{51-48} = addr{19-16}; // base reg + let Inst{55-52} = dst; + let Inst{47-32} = addr{15-0}; // offset + let Inst{7-0} = BPF_XCHG.Value; + let BPFClass = BPF_STX; +} + +class XCHG32 + : TYPE_LD_ST { + bits<4> dst; + bits<20> addr; + + let Inst{51-48} = addr{19-16}; // base reg + let Inst{55-52} = dst; + let Inst{47-32} = addr{15-0}; // offset + let Inst{7-0} = BPF_XCHG.Value; + let BPFClass = BPF_STX; +} + +let Predicates = [BPFHasAtomicExt], Constraints = "$dst = $val" in { + let Predicates = [BPFNoALU32] in { + def XCHGB : XCHG; + def XCHGH : XCHG; + def XCHGW : XCHG; + } + + let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in { + def XCHGB32 : XCHG32; + def XCHGH32 : XCHG32; + def XCHGW32 : XCHG32; + } + + def XCHGD : XCHG; +} + +// Compare-And-Exchange +class CMPXCHG + : TYPE_LD_ST { + bits<4> dst; + bits<20> addr; + bits<4> new; + + let Inst{51-48} = addr{19-16}; // base reg + let Inst{55-52} = dst; + let Inst{47-32} = addr{15-0}; // offset + let Inst{11-8} = new; + let Inst{7-0} = BPF_CMPXCHG.Value; + let BPFClass = BPF_STX; +} + +class CMPXCHG32 + : TYPE_LD_ST { + bits<4> dst; + bits<20> addr; + bits<4> new; + + let Inst{51-48} = addr{19-16}; // base reg + let Inst{55-52} = dst; + let Inst{47-32} = addr{15-0}; // offset + let Inst{11-8} = new; + let Inst{7-0} = BPF_CMPXCHG.Value; + let BPFClass = BPF_STX; +} + +let Predicates = [BPFHasAtomicExt], Constraints = "$dst = $old" in { + let Predicates = [BPFNoALU32] in { + def CMPXCHGB : CMPXCHG; + def CMPXCHGH : CMPXCHG; + def CMPXCHGW : CMPXCHG; + } + + let Predicates = [BPFHasALU32], DecoderNamespace = "BPFALU32" in { + def CMPXCHGB32 : CMPXCHG32; + def CMPXCHGH32 : CMPXCHG32; + def CMPXCHGW32 : CMPXCHG32; + } + + def CMPXCHGD : CMPXCHG; +} + // bswap16, bswap32, bswap64 class BSWAP SizeOp, string OpcodeStr, BPFSrcType SrcType, list Pattern> : TYPE_ALU_JMP