shithub: drawcpu

Download patch

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
--