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 @@ -82,11 +82,12 @@ bits<3> Value = val; } -def BPF_IMM : BPFModeModifer<0x0>; -def BPF_ABS : BPFModeModifer<0x1>; -def BPF_IND : BPFModeModifer<0x2>; -def BPF_MEM : BPFModeModifer<0x3>; -def BPF_XADD : BPFModeModifer<0x6>; +def BPF_IMM : BPFModeModifer<0x0>; +def BPF_ABS : BPFModeModifer<0x1>; +def BPF_IND : BPFModeModifer<0x2>; +def BPF_MEM : BPFModeModifer<0x3>; +def BPF_XADD : BPFModeModifer<0x6>; +def BPF_CMPXCHG : BPFModeModifer<0x7>; 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 @@ -688,6 +688,64 @@ } } +// Compare-And-Exchange +class CMPXCHG Pattern> + : 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{3-0} = new; + let BPFClass = BPF_STX; +} + +class CMPXCHG32 Pattern> + : 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{3-0} = new; + let BPFClass = BPF_STX; +} + +let 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; +} + let Defs = [R0, R1, R2, R3, R4, R5], Uses = [R6], hasSideEffects = 1, hasExtraDefRegAllocReq = 1, hasExtraSrcRegAllocReq = 1, mayLoad = 1 in { class LOAD_ABS diff --git a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp --- a/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp +++ b/llvm/lib/Target/BPF/Disassembler/BPFDisassembler.cpp @@ -52,13 +52,14 @@ }; enum BPF_MODE { - BPF_IMM = 0x0, - BPF_ABS = 0x1, - BPF_IND = 0x2, - BPF_MEM = 0x3, - BPF_LEN = 0x4, - BPF_MSH = 0x5, - BPF_XADD = 0x6 + BPF_IMM = 0x0, + BPF_ABS = 0x1, + BPF_IND = 0x2, + BPF_MEM = 0x3, + BPF_LEN = 0x4, + BPF_MSH = 0x5, + BPF_XADD = 0x6, + BPF_CMPXCHG = 0x7 }; BPFDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx) @@ -175,7 +176,8 @@ uint8_t InstMode = getInstMode(Insn); if ((InstClass == BPF_LDX || InstClass == BPF_STX) && getInstSize(Insn) != BPF_DW && - (InstMode == BPF_MEM || InstMode == BPF_XADD) && + (InstMode == BPF_MEM || InstMode == BPF_XADD || + InstMode == BPF_CMPXCHG) && STI.getFeatureBits()[BPF::ALU32]) Result = decodeInstruction(DecoderTableBPFALU3264, Instr, Insn, Address, this, STI);