ref: 09a85257b0254babd5e225d00dde49fe63ffb12f
parent: dd193a6e22c0911760aa56bbf0df06b4b75772ca
author: halfwit <michaelmisch1985@gmail.com>
date: Thu Jul 24 08:05:05 EDT 2025
add generated cas
--- a/posix-386/Makefile
+++ b/posix-386/Makefile
@@ -7,6 +7,7 @@
OFILES=\
getcallerpc.$O\
tas.$O\
+ cas.$O\
default: $(LIB)
$(LIB): $(OFILES)
--- /dev/null
+++ b/posix-386/cas.c
@@ -1,0 +1,23 @@
+#include "u.h"
+#include "libc.h"
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+int
+cas(int *x, int old, int new)
+{+#if __has_builtin(__atomic_compare_exchange_n)
+ return __atomic_compare_exchange_n(x, &old, new, 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
+#else
+ int result;
+ __asm__ __volatile__(
+ "lock cmpxchg %2, %1\n\t"
+ "sete %0"
+ : "=r" (result), "+m" (*x), "+r" (new)
+ : "a" (old)
+ : "cc");
+ return result;
+#endif
+}
\ No newline at end of file
--- /dev/null
+++ b/posix-amd64/cas.c
@@ -1,0 +1,23 @@
+#include "u.h"
+#include "libc.h"
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+int
+cas(int *x, int old, int new)
+{+#if __has_builtin(__atomic_compare_exchange_n)
+ return __atomic_compare_exchange_n(x, &old, new, 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
+#else
+ int result;
+ __asm__ __volatile__(
+ "lock cmpxchg %2, %1\n\t"
+ "sete %0"
+ : "=r" (result), "+m" (*x), "+r" (new)
+ : "a" (old)
+ : "cc");
+ return result;
+#endif
+}
\ No newline at end of file
--- a/posix-mips/Makefile
+++ b/posix-mips/Makefile
@@ -7,6 +7,7 @@
OFILES=\
getcallerpc.$O\
tas.$O\
+ cas.$O\
default: $(LIB)
$(LIB): $(OFILES)
--- /dev/null
+++ b/posix-mips/cas.c
@@ -1,0 +1,26 @@
+#include "u.h"
+#include "libc.h"
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+int
+cas(int *x, int old, int new)
+{+#if __has_builtin(__atomic_compare_exchange_n)
+ return __atomic_compare_exchange_n(x, &old, new, 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
+#else
+ int result;
+ __asm__ __volatile__(
+ "ll %0, 0(%2)\n"
+ "bne %0, %3, 1f\n"
+ "move %0, %4\n"
+ "sc %0, 0(%2)\n"
+ "1:"
+ : "=&r" (result), "=m" (*x)
+ : "r" (x), "r" (old), "r" (new)
+ : "memory");
+ return result;
+#endif
+}
\ No newline at end of file
--- a/posix-power/Makefile
+++ b/posix-power/Makefile
@@ -9,6 +9,7 @@
OFILES=\
getcallerpc.$O\
tas.$O\
+ cas.$O\
default: $(LIB)
$(LIB): $(OFILES)
--- /dev/null
+++ b/posix-power/cas.c
@@ -1,0 +1,30 @@
+#include "u.h"
+#include "libc.h"
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+int
+cas(int *x, int old, int new)
+{+#if __has_builtin(__atomic_compare_exchange_n)
+ return __atomic_compare_exchange_n(x, &old, new, 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
+#else
+ int result;
+ __asm__ __volatile__(
+ "lwarx %0, 0, %2\n"
+ "cmpw %0, %3\n"
+ "bne 1f\n"
+ "stwcx. %4, 0, %2\n"
+ "bne 1f\n"
+ "li %0, 1\n"
+ "b 2f\n"
+ "1: li %0, 0\n"
+ "2:"
+ : "=&r" (result), "=m" (*x)
+ : "r" (x), "r" (old), "r" (new)
+ : "cc", "cr0");
+ return result;
+#endif
+}
\ No newline at end of file
--- a/posix-riscv64/Makefile
+++ b/posix-riscv64/Makefile
@@ -7,6 +7,7 @@
OFILES=\
getcallerpc.$O\
tas.$O\
+ cas.$O\
default: $(LIB)
$(LIB): $(OFILES)
--- /dev/null
+++ b/posix-riscv64/cas.c
@@ -1,0 +1,26 @@
+#include "u.h"
+#include "libc.h"
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+int
+cas(int *x, int old, int new)
+{+#if __has_builtin(__atomic_compare_exchange_n)
+ return __atomic_compare_exchange_n(x, &old, new, 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
+#else
+ int result;
+ __asm__ __volatile__(
+ "lr.w %0, %2\n"
+ "bne %0, %3, 1f\n"
+ "sc.w %0, %4, %2\n"
+ "seqz %0, %0\n"
+ "1:"
+ : "=&r" (result), "=m" (*x)
+ : "m" (*x), "r" (old), "r" (new)
+ : "cc");
+ return result;
+#endif
+}
\ No newline at end of file
--- a/posix-sun4u/Makefile
+++ b/posix-sun4u/Makefile
@@ -4,7 +4,8 @@
OFILES=\
getcallerpc.$O\
- tas.$O
+ tas.$O\
+ cas.$O\
default: $(LIB)
$(LIB): $(OFILES)
--- /dev/null
+++ b/posix-sun4u/cas.c
@@ -1,0 +1,25 @@
+#include "u.h"
+#include "libc.h"
+
+#ifndef __has_builtin
+#define __has_builtin(x) 0
+#endif
+
+int
+cas(int *x, int old, int new)
+{+#if __has_builtin(__atomic_compare_exchange_n)
+ return __atomic_compare_exchange_n(x, &old, new, 0, __ATOMIC_ACQ_REL, __ATOMIC_ACQUIRE);
+#else
+ int result;
+ __asm__ __volatile__(
+ "casa [%2] %%asi, %3, %1\n"
+ "cmp %3, %1\n"
+ "mov %4, %0\n"
+ "movne %4, 0, %0"
+ : "=&r" (result), "+r" (new), "+m" (*x)
+ : "r" (x), "r" (old)
+ : "cc");
+ return result;
+#endif
+}
\ No newline at end of file
--- a/win32-386/Makefile
+++ b/win32-386/Makefile
@@ -4,7 +4,8 @@
OFILES=\
getcallerpc.$O\
- tas.$O
+ tas.$O\
+ cas.$O
default: $(LIB)
$(LIB): $(OFILES)
--- /dev/null
+++ b/win32-386/cas.c
@@ -1,0 +1,9 @@
+#include "u.h"
+#include "libc.h"
+#include <windows.h>
+
+int
+cas(int *x, int old, int new)
+{+ return InterlockedCompareExchange((volatile LONG *)x, new, old) == old;
+}
\ No newline at end of file
--
⑨