bpf: Add atomic compare-and-exchange instructions
authorDavid Faust <david.faust@oracle.com>
Mon, 24 Jul 2023 21:50:34 +0000 (14:50 -0700)
committerDavid Faust <david.faust@oracle.com>
Tue, 25 Jul 2023 20:40:06 +0000 (13:40 -0700)
This patch adds the two remaining BPF v3 atomic instructions:
- BPF_INSN_ACMP{,32}: atomic compare-and-swap
- BPF_INSN_AXCHG{,32}: atomic (non-conditional) exchange

Tests and documentation are also updated.

gas/
* doc/c-bpf.texi (BPF Instructions): Document atomic exchange and
atomic compare-and-swap instructions.
* testsuite/gas/bpf/atomic.s: Test ACMP, ACMP32, AXCHG, AXCGH32
instructions.
* testsuite/gas/bpf/atomic.d: Likewise.
* testsuite/gas/bpf/atomic-be.d: Likewise.
* testsuite/gas/bpf/atomic-pseudoc.s: Likewise.
* testsuite/gas/bpf/atomic-pseudoc.d: Likewise.
* testsuite/gas/bpf/atomic-be-pseudoc.d: Likewise.

include/
* opcode/bpf.h (BPF_IMM32_ACMP): Fix typo.
(enum bpf_insn_id): New entries for BPF_INSN_ACMP{,32} and
BPF_INSN_AXCHG{,32}.

opcodes/
* bpf-opc.c (bpf_opcodes): Add entries for ACMP{,32} and
AXCHG{,32} instructions.

gas/doc/c-bpf.texi
gas/testsuite/gas/bpf/atomic-be-pseudoc.d
gas/testsuite/gas/bpf/atomic-be.d
gas/testsuite/gas/bpf/atomic-pseudoc.d
gas/testsuite/gas/bpf/atomic-pseudoc.s
gas/testsuite/gas/bpf/atomic.d
gas/testsuite/gas/bpf/atomic.s
include/opcode/bpf.h
opcodes/bpf-opc.c

index 689786e81d5b78bae91b8aa0e3b0b203ff956048..8f39ab314a7aea35c1fd817a9b39f4ef59093478 100644 (file)
@@ -745,8 +745,26 @@ Jump if signed lesser or equal.
 
 @subsection Atomic instructions
 
-Atomic exchange-and-add instructions are provided in two flavors: one
-for swapping 64-bit quantities and another for 32-bit quantities.
+Atomic exchange instructions are provided in two flavors: one for
+compare-and-swap, one for unconditional exchange.
+
+@table @code
+@item acmp [rd + offset16], rs
+@itemx r0 = cmpxchg_64 (rd + offset16, r0, rs)
+Atomic compare-and-swap.  Compares value in @code{r0} to value
+addressed by @code{rd + offset16}.  On match, the value addressed by
+@code{rd + offset16} is replaced with the value in @code{rs}.
+Regardless, the value that was at @code{rd + offset16} is
+zero-extended and loaded into @code{r0}.
+
+@item axchg [rd + offset16], rs
+@itemx rs = xchg_64 (rd + offset16, rs)
+Atomic exchange.  Atomically exchanges the value in @code{rs} with
+the value addressed by @code{rd + offset16}.
+@end table
+
+@noindent
+The following instructions provide atomic arithmetic operations.
 
 @table @code
 @item aadd [rd + offset16], rs
@@ -798,8 +816,26 @@ Alias to @code{aadd}.
 
 @subsection 32-bit atomic instructions
 
-Atomic exchange-and-add instructions are provided in two flavors: one
-for swapping 32-bit quantities and another for 32-bit quantities.
+32-bit atomic exchange instructions are provided in two flavors: one
+for compare-and-swap, one for unconditional exchange.
+
+@table @code
+@item acmp32 [rd + offset16], rs
+@itemx w0 = cmpxchg32_32 (rd + offset16, w0, ws)
+Atomic compare-and-swap.  Compares value in @code{w0} to value
+addressed by @code{rd + offset16}.  On match, the value addressed by
+@code{rd + offset16} is replaced with the value in @code{ws}.
+Regardless, the value that was at @code{rd + offset16} is
+zero-extended and loaded into @code{w0}.
+
+@item axchg [rd + offset16], rs
+@itemx ws = xchg32_32 (rd + offset16, ws)
+Atomic exchange.  Atomically exchanges the value in @code{ws} with
+the value addressed by @code{rd + offset16}.
+@end table
+
+@noindent
+The following instructions provide 32-bit atomic arithmetic operations.
 
 @table @code
 @item aadd32 [rd + offset16], rs
index e0da408ca5a41047b8786925a69d358fa1de4ec6..30c40fa2d124e4acb10405cca467a5dd47247672 100644 (file)
@@ -26,3 +26,7 @@ Disassembly of section .text:
   78:  c3 12 1e ef 00 00 00 41         w2=atomic_fetch_or\(\(u32\*\)\(r1\+0x1eef\),w2\)
   80:  db 12 1e ef 00 00 00 a1         r2=atomic_fetch_xor\(\(u64\*\)\(r1\+0x1eef\),r2\)
   88:  c3 12 1e ef 00 00 00 a1         w2=atomic_fetch_xor\(\(u32\*\)\(r1\+0x1eef\),w2\)
+  90:  db 12 00 04 00 00 00 f1         r0=cmpxchg_64\(r1\+0x4,r0,r2\)
+  98:  c3 23 00 04 00 00 00 f1         w0=cmpxchg32_32\(r2\+0x4,w0,w3\)
+  a0:  db 12 00 08 00 00 00 e1         r2=xchg_64\(r1\+0x8,r2\)
+  a8:  c3 13 00 08 00 00 00 e1         w3=xchg32_32\(r1\+0x8,w3\)
index 42a0037035e13f565b8e7288dfe44dcccac166c4..7a04753da638a616447320252e4f24d36f2c95b3 100644 (file)
@@ -24,3 +24,7 @@ Disassembly of section .text:
   68:  c3 12 1e ef 00 00 00 41         afor32 \[%r1\+0x1eef\],%r2
   70:  db 12 1e ef 00 00 00 a1         afxor \[%r1\+0x1eef\],%r2
   78:  c3 12 1e ef 00 00 00 a1         afxor32 \[%r1\+0x1eef\],%r2
+  80:  db 12 00 04 00 00 00 f1         acmp \[%r1\+0x4\],%r2
+  88:  c3 23 00 04 00 00 00 f1         acmp32 \[%r2\+0x4\],%r3
+  90:  db 12 00 08 00 00 00 e1         axchg \[%r1\+0x8\],%r2
+  98:  c3 13 00 08 00 00 00 e1         axchg32 \[%r1\+0x8\],%r3
index 30bfba6438091521bdd2005c713f46940921928e..2b3739ee47e1d0ae1ef9d2875047c92dc3578543 100644 (file)
@@ -26,3 +26,7 @@ Disassembly of section .text:
   78:  c3 21 ef 1e 41 00 00 00         w2=atomic_fetch_or\(\(u32\*\)\(r1\+0x1eef\),w2\)
   80:  db 21 ef 1e a1 00 00 00         r2=atomic_fetch_xor\(\(u64\*\)\(r1\+0x1eef\),r2\)
   88:  c3 21 ef 1e a1 00 00 00         w2=atomic_fetch_xor\(\(u32\*\)\(r1\+0x1eef\),w2\)
+  90:  db 21 04 00 f1 00 00 00         r0=cmpxchg_64\(r1\+0x4,r0,r2\)
+  98:  c3 32 04 00 f1 00 00 00         w0=cmpxchg32_32\(r2\+0x4,w0,w3\)
+  a0:  db 21 08 00 e1 00 00 00         r2=xchg_64\(r1\+0x8,r2\)
+  a8:  c3 31 08 00 e1 00 00 00         w3=xchg32_32\(r1\+0x8,w3\)
index 514cfa91fb736a2276589fad168146339e4131d6..6994fd103679f5970e0dd7485c32fed3ad750a54 100644 (file)
@@ -18,3 +18,7 @@
        w2 = atomic_fetch_or((u32*)(r1+0x1eef),w2)
        r2 = atomic_fetch_xor((u64*)(r1+0x1eef),r2)
        w2 = atomic_fetch_xor((u32*)(r1+0x1eef),w2)
+       r0 = cmpxchg_64(r1+0x4,r0,r2)
+       w0 = cmpxchg32_32(r2+0x4,w0,w3)
+       r2 = xchg_64(r1+0x8,r2)
+       w3 = xchg32_32(r1+0x8,w3)
index f7925b330ac8e39c71cea6f2153730f63117babe..121ab35a92b1a35d0f35a6cece0827d548582d1f 100644 (file)
@@ -24,3 +24,7 @@ Disassembly of section .text:
   68:  c3 21 ef 1e 41 00 00 00         afor32 \[%r1\+0x1eef\],%r2
   70:  db 21 ef 1e a1 00 00 00         afxor \[%r1\+0x1eef\],%r2
   78:  c3 21 ef 1e a1 00 00 00         afxor32 \[%r1\+0x1eef\],%r2
+  80:  db 21 04 00 f1 00 00 00         acmp \[%r1\+0x4\],%r2
+  88:  c3 32 04 00 f1 00 00 00         acmp32 \[%r2\+0x4\],%r3
+  90:  db 21 08 00 e1 00 00 00         axchg \[%r1\+0x8\],%r2
+  98:  c3 31 08 00 e1 00 00 00         axchg32 \[%r1\+0x8\],%r3
index 781a2e965acd983cba903540c1cb00df134259dd..39ad5ce42f03f3c99d3e941ec1a555a04bc4774b 100644 (file)
@@ -17,3 +17,8 @@
         afor32 [%r1+0x1eef], %r2
         afxor  [%r1+0x1eef], %r2
         afxor32        [%r1+0x1eef], %r2
+
+        acmp   [%r1+4], %r2
+        acmp32 [%r2+4], %r3
+        axchg  [%r1+8], %r2
+        axchg32        [%r1+8], %r3
index ed344427f1b31c491e978d9daa97eadfa89a15a7..20e323a065b5555c4b9e2b4a651e4e4dbb4a04fd 100644 (file)
@@ -153,7 +153,7 @@ typedef uint64_t bpf_insn_word;
 #define BPF_IMM32_AFAND ((uint64_t)0x00000051)
 #define BPF_IMM32_AFXOR ((uint64_t)0x000000a1)
 #define BPF_IMM32_AXCHG ((uint64_t)0x000000e1)
-#define BPF_IMM32_ACMP  ((uint64_t)b0x000000f1)
+#define BPF_IMM32_ACMP  ((uint64_t)0x000000f1)
 
 /* Unique identifiers for BPF instructions.  */
 
@@ -225,6 +225,10 @@ enum bpf_insn_id
   BPF_INSN_AADD32, BPF_INSN_AOR32, BPF_INSN_AAND32, BPF_INSN_AXOR32,
   /* Atomic instructions with fetching (32-bit.)  */
   BPF_INSN_AFADD32, BPF_INSN_AFOR32, BPF_INSN_AFAND32, BPF_INSN_AFXOR32,
+  /* Atomic compare-and-swap, atomic exchange.  */
+  BPF_INSN_ACMP, BPF_INSN_AXCHG,
+  /* Atomic compare-and-swap, atomic exchange (32-bit).  */
+  BPF_INSN_ACMP32, BPF_INSN_AXCHG32,
   /* GNU simulator specific instruction.  */
   BPF_INSN_BRKPT,
 };
index ee6719bdc06250a54f054657508e770b16cfd69c..26db795903c9d05ce7468f5b5297580b3c65bbeb 100644 (file)
@@ -403,6 +403,18 @@ const struct bpf_opcode bpf_opcodes[] =
   {BPF_INSN_AFXOR32, "afxor32%W[ %dr %o16 ] , %sr", "%sw = atomic_fetch_xor ( ( u32 * ) ( %dr %o16 ) , %sw )",
    BPF_V3, BPF_CODE|BPF_IMM32, BPF_CLASS_STX|BPF_SIZE_W|BPF_MODE_ATOMIC|BPF_IMM32_AFXOR},
 
+  /* Atomic compare-and-swap, atomic exchange.  */
+  {BPF_INSN_ACMP, "acmp%W[ %dr %o16 ] , %sr", "r0 = cmpxchg_64 ( %dr %o16 , r0 , %sr )",
+   BPF_V3, BPF_CODE|BPF_IMM32, BPF_CLASS_STX|BPF_SIZE_DW|BPF_MODE_ATOMIC|BPF_IMM32_ACMP},
+  {BPF_INSN_AXCHG, "axchg%W[ %dr %o16 ] , %sr", "%sr = xchg_64 ( %dr %o16 , %sr )",
+   BPF_V3, BPF_CODE|BPF_IMM32, BPF_CLASS_STX|BPF_SIZE_DW|BPF_MODE_ATOMIC|BPF_IMM32_AXCHG},
+
+  /* Atomic compare-and-swap, atomic exchange (32-bit).  */
+  {BPF_INSN_ACMP32, "acmp32%W[ %dr %o16 ], %sr", "w0 = cmpxchg32_32 ( %dr %o16 , w0 , %sw )",
+   BPF_V3, BPF_CODE|BPF_IMM32, BPF_CLASS_STX|BPF_SIZE_W|BPF_MODE_ATOMIC|BPF_IMM32_ACMP},
+  {BPF_INSN_AXCHG32, "axchg32%W[ %dr %o16 ], %sr", "%sw = xchg32_32 ( %dr %o16 , %sw )",
+   BPF_V3, BPF_CODE|BPF_IMM32, BPF_CLASS_STX|BPF_SIZE_W|BPF_MODE_ATOMIC|BPF_IMM32_AXCHG},
+
   /* Old versions of aadd and aadd32.  */
   {BPF_INSN_AADD, "xadddw%W[ %dr %o16 ] , %sr", "* ( u64 * ) ( %dr %o16 ) += %sr",
    BPF_V1, BPF_CODE|BPF_IMM32, BPF_CLASS_STX|BPF_SIZE_DW|BPF_MODE_ATOMIC|BPF_IMM32_AADD},