From e1074e1a978fccfdb2bc50ed25bfd3864155b073 Mon Sep 17 00:00:00 2001
From: wzx <wuzx1226@qq.com>
Date: Wed, 23 Nov 2022 14:05:30 +0800
Subject: [PATCH] Add sw64 architecture

Signed-off-by: wzx <wuzx1226@qq.com>
---
 nspr/configure                  |  8 ++++
 nspr/configure.in               |  6 +++
 nspr/pr/include/gencfg.c        |  2 +-
 nspr/pr/include/md/_freebsd.cfg |  2 +-
 nspr/pr/include/md/_freebsd.h   |  2 +
 nspr/pr/include/md/_linux.cfg   |  2 +-
 nspr/pr/include/md/_linux.h     | 83 ++++++++++++++++++++++++++++++++-
 nspr/pr/include/md/_netbsd.cfg  |  2 +-
 nspr/pr/include/md/_netbsd.h    |  4 +-
 nspr/pr/include/md/_openbsd.cfg |  2 +-
 nspr/pr/include/md/_openbsd.h   |  4 +-
 nspr/pr/include/pratom.h        |  2 +-
 nspr/pr/src/md/unix/unix.c      |  2 +-
 13 files changed, 110 insertions(+), 11 deletions(-)

diff --git a/nspr/configure b/nspr/configure
index 2c6d7d6..a7d9c48 100755
--- a/nspr/configure
+++ b/nspr/configure
@@ -6808,6 +6808,14 @@ tools are selected during the Xcode/Developer Tools installation." "$LINENO" 5
     fi
     CPU_ARCH_TAG=_${CPU_ARCH}
     case "${target_cpu}" in
+    sw_64)
+        $as_echo "#define _SW_64_ 1" >>confdefs.h
+
+        $as_echo "#define __sw_64 1" >>confdefs.h
+
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+        ;;
     alpha)
         $as_echo "#define _ALPHA_ 1" >>confdefs.h
 
diff --git a/nspr/configure.in b/nspr/configure.in
index d0c1769..6b74d66 100644
--- a/nspr/configure.in
+++ b/nspr/configure.in
@@ -1675,6 +1675,12 @@ tools are selected during the Xcode/Developer Tools installation.])
     fi
     CPU_ARCH_TAG=_${CPU_ARCH}
     case "${target_cpu}" in
+    sw_64)
+        AC_DEFINE(_SW_64_)
+        AC_DEFINE(__sw_64)
+        CFLAGS="$CFLAGS -mieee"
+        CXXFLAGS="$CXXFLAGS -mieee"
+        ;;
     alpha)
         AC_DEFINE(_ALPHA_)
         AC_DEFINE(__alpha)
diff --git a/nspr/pr/include/gencfg.c b/nspr/pr/include/gencfg.c
index 3a67e91..34a332a 100644
--- a/nspr/pr/include/gencfg.c
+++ b/nspr/pr/include/gencfg.c
@@ -17,7 +17,7 @@ error - HPUX is not defined
 #endif
 #endif
 
-#if defined(__alpha)
+#if defined(__alpha) || defined(__sw_64)
 #if !(defined(_WIN32)) && !(defined(__linux)) && !(defined(__FreeBSD__))
 error - None of _WIN32, __linux, or __FreeBSD__ is defined
 #endif
diff --git a/nspr/pr/include/md/_freebsd.cfg b/nspr/pr/include/md/_freebsd.cfg
index 1d1039a..13282da 100644
--- a/nspr/pr/include/md/_freebsd.cfg
+++ b/nspr/pr/include/md/_freebsd.cfg
@@ -65,7 +65,7 @@
 #define PR_ALIGN_OF_DOUBLE  4
 #define PR_ALIGN_OF_POINTER 4
 
-#elif defined(__alpha__)
+#elif defined(__alpha__) || defined(__sw_64__)
 
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
diff --git a/nspr/pr/include/md/_freebsd.h b/nspr/pr/include/md/_freebsd.h
index 118cb9f..bf4edb9 100644
--- a/nspr/pr/include/md/_freebsd.h
+++ b/nspr/pr/include/md/_freebsd.h
@@ -17,6 +17,8 @@
 #define _PR_SI_SYSNAME  "FREEBSD"
 #if defined(__i386__)
 #define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__sw_64__)
+#define _PR_SI_ARCHITECTURE "sw_64"
 #elif defined(__alpha__)
 #define _PR_SI_ARCHITECTURE "alpha"
 #elif defined(__sparc__)
diff --git a/nspr/pr/include/md/_linux.cfg b/nspr/pr/include/md/_linux.cfg
index 23b160f..d26e2cc 100644
--- a/nspr/pr/include/md/_linux.cfg
+++ b/nspr/pr/include/md/_linux.cfg
@@ -128,7 +128,7 @@
 #define PR_BYTES_PER_WORD_LOG2   2
 #define PR_BYTES_PER_DWORD_LOG2  3
 
-#elif defined(__alpha)
+#elif defined(__alpha) || defined(__sw_64)
 
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
diff --git a/nspr/pr/include/md/_linux.h b/nspr/pr/include/md/_linux.h
index 619b04f..b34d9d3 100644
--- a/nspr/pr/include/md/_linux.h
+++ b/nspr/pr/include/md/_linux.h
@@ -23,6 +23,8 @@
 #define _PR_SI_ARCHITECTURE "ppc64"
 #elif defined(__powerpc__)
 #define _PR_SI_ARCHITECTURE "ppc"
+#elif defined(__sw_64)
+#define _PR_SI_ARCHITECTURE "sw_64"
 #elif defined(__alpha)
 #define _PR_SI_ARCHITECTURE "alpha"
 #elif defined(__ia64__)
@@ -264,6 +266,83 @@ extern PRInt32 _PR_ppc_AtomicSet(PRInt32 *val, PRInt32 newval);
 })
 #endif
 
+#if defined(__sw_64)
+#define _PR_HAVE_ATOMIC_OPS
+#define _MD_INIT_ATOMIC()
+#define _MD_ATOMIC_ADD(ptr, i) ({               \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    PRInt32 __atomic_tmp1, __atomic_tmp2;   \
+    __asm__ __volatile__(                       \
+    "1: ldi    %[tmp1],%[val]      \n"     \
+    "   ldi    %[tmp2],1          \n"     \
+    "   lldw   %[ret], 0(%[tmp1])          \n"     \
+    "   wr_f   %[tmp2]          \n"     \
+    "   addw   %[ret], %[inc], %[tmp]  \n"     \
+    "   addw    %[ret], %[inc], %[ret]  \n"     \
+    "   lstw   %[tmp], 0(%[tmp1])          \n"     \
+    "   rd_f   %[tmp]        \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r" (__atomic_tmp),               \
+      [tmp1] "=&r" (__atomic_tmp1),               \
+      [tmp2] "=&r" (__atomic_tmp2),               \
+      [val] "=m" (*ptr)                         \
+    : [inc] "Ir" (i), "m" (*ptr));              \
+    __atomic_ret;                               \
+})
+#define _MD_ATOMIC_INCREMENT(ptr) _MD_ATOMIC_ADD(ptr, 1)
+#define _MD_ATOMIC_DECREMENT(ptr) ({            \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    PRInt32 __atomic_tmp1, __atomic_tmp2;   \
+    __asm__ __volatile__(                       \
+    "1: ldi    %[tmp1],%[val]      \n"     \
+    "   ldi    %[tmp2],1          \n"     \
+    "   lldw   %[ret], 0(%[tmp1])          \n"     \
+    "   wr_f   %[tmp2]          \n"     \
+    "   subw    %[ret], 1, %[tmp]       \n"     \
+    "   subw    %[ret], 1, %[ret]       \n"     \
+    "   lstw   %[tmp], 0(%[tmp1])          \n"     \
+    "   rd_f   %[tmp]        \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r" (__atomic_tmp),               \
+      [tmp1] "=&r" (__atomic_tmp1),               \
+      [tmp2] "=&r" (__atomic_tmp2),               \
+      [val] "=m" (*ptr)                         \
+    : "m" (*ptr));                              \
+    __atomic_ret;                               \
+})
+#define _MD_ATOMIC_SET(ptr, n) ({               \
+    PRInt32 __atomic_tmp, __atomic_ret;   \
+    PRInt32 __atomic_tmp1, __atomic_tmp2;   \
+    __asm__ __volatile__(                       \
+    "1: ldi    %[tmp1],%[val]      \n"     \
+    "   ldi    %[tmp2],1          \n"     \
+    "   lldw   %[ret], 0(%[tmp1])          \n"     \
+    "   wr_f   %[tmp2]          \n"     \
+    "   mov     %[newval], %[tmp]       \n"     \
+    "   lstw   %[tmp], 0(%[tmp1])          \n"     \
+    "   rd_f   %[tmp]        \n"     \
+    "   beq     %[tmp], 2f              \n"     \
+    ".subsection 2                      \n"     \
+    "2: br      1b                      \n"     \
+    ".previous"                                 \
+    : [ret] "=&r" (__atomic_ret),               \
+      [tmp] "=&r"(__atomic_tmp),                \
+      [tmp1] "=&r" (__atomic_tmp1),               \
+      [tmp2] "=&r" (__atomic_tmp2),               \
+      [val] "=m" (*ptr)                         \
+    : [newval] "Ir" (n), "m" (*ptr));           \
+    __atomic_ret;                               \
+})
+#endif
+
 #if defined(__arm__) || defined(__aarch64__)
 #if defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)
 /* Use GCC built-in functions */
@@ -326,7 +405,7 @@ static inline PRInt32 _MD_ATOMIC_SET(PRInt32 *ptr, PRInt32 nv)
 #endif
 #undef _PR_USE_POLL
 #define _PR_STAT_HAS_ONLY_ST_ATIME
-#if defined(__alpha) || defined(__ia64__)
+#if defined(__alpha) || defined(__sw_64) || defined(__ia64__)
 #define _PR_HAVE_LARGE_OFF_T
 #elif (__GLIBC__ > 2) || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) \
     || defined(ANDROID)
@@ -383,7 +462,7 @@ extern void _MD_CleanupBeforeExit(void);
 /* aix = 64, macos = 70 */
 #define PR_NUM_GCREGS  64
 
-#elif defined(__alpha)
+#elif defined(__alpha) || defined(__sw_64)
 /* Alpha based Linux */
 
 #if defined(__GLIBC__) && __GLIBC__ >= 2
diff --git a/nspr/pr/include/md/_netbsd.cfg b/nspr/pr/include/md/_netbsd.cfg
index 1326556..e1dfb00 100644
--- a/nspr/pr/include/md/_netbsd.cfg
+++ b/nspr/pr/include/md/_netbsd.cfg
@@ -157,7 +157,7 @@
 #define PR_ALIGN_OF_DOUBLE  8
 #define PR_ALIGN_OF_POINTER 4
 
-#elif defined(__alpha__)
+#elif defined(__alpha__) || defined(__sw_64__)
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 #define	HAVE_ALIGNED_DOUBLES
diff --git a/nspr/pr/include/md/_netbsd.h b/nspr/pr/include/md/_netbsd.h
index 1ec0fe6..2d91868 100644
--- a/nspr/pr/include/md/_netbsd.h
+++ b/nspr/pr/include/md/_netbsd.h
@@ -13,6 +13,8 @@
 #define _PR_SI_SYSNAME  "NetBSD"
 #if defined(__i386__)
 #define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__sw_64__)
+#define _PR_SI_ARCHITECTURE "sw_64"
 #elif defined(__alpha__)
 #define _PR_SI_ARCHITECTURE "alpha"
 #elif defined(__amd64__)
@@ -75,7 +77,7 @@
 #define JB_SP_INDEX 2
 #elif defined(__mips__)
 #define JB_SP_INDEX 4
-#elif defined(__alpha__)
+#elif defined(__alpha__) || defined(__sw_64__)
 #define JB_SP_INDEX 34
 #elif defined(__arm32__)
 /*
diff --git a/nspr/pr/include/md/_openbsd.cfg b/nspr/pr/include/md/_openbsd.cfg
index b68d6e9..f3d1f5f 100644
--- a/nspr/pr/include/md/_openbsd.cfg
+++ b/nspr/pr/include/md/_openbsd.cfg
@@ -206,7 +206,7 @@
 #define PR_ALIGN_OF_DOUBLE  8
 #define PR_ALIGN_OF_POINTER 4
 
-#elif defined(__alpha__)
+#elif defined(__alpha__) || defined(__sw_64__)
 #define IS_LITTLE_ENDIAN 1
 #undef  IS_BIG_ENDIAN
 #define	HAVE_ALIGNED_DOUBLES
diff --git a/nspr/pr/include/md/_openbsd.h b/nspr/pr/include/md/_openbsd.h
index 1949631..40bbb73 100644
--- a/nspr/pr/include/md/_openbsd.h
+++ b/nspr/pr/include/md/_openbsd.h
@@ -12,6 +12,8 @@
 #define _PR_SI_SYSNAME  "OPENBSD"
 #if defined(__i386__)
 #define _PR_SI_ARCHITECTURE "x86"
+#elif defined(__sw_64__)
+#define _PR_SI_ARCHITECTURE "sw_64"
 #elif defined(__alpha__)
 #define _PR_SI_ARCHITECTURE "alpha"
 #elif defined(__amd64__)
@@ -65,7 +67,7 @@
 #define JB_SP_INDEX 2
 #elif defined(__powerpc__)
 #define JB_SP_INDEX 1
-#elif defined(__alpha__)
+#elif defined(__alpha__) || defined(__sw_64__)
 #define JB_SP_INDEX 34
 #elif defined(__amd64__)
 #define JB_SP_INDEX 6
diff --git a/nspr/pr/include/pratom.h b/nspr/pr/include/pratom.h
index 11a8aae..6591dc8 100644
--- a/nspr/pr/include/pratom.h
+++ b/nspr/pr/include/pratom.h
@@ -107,7 +107,7 @@ NSPR_API(PRInt32)   PR_AtomicAdd(PRInt32 *ptr, PRInt32 val);
            defined(__powerpc__) || \
            (defined(__arm__) && \
            defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)) || \
-           defined(__aarch64__) || defined(__alpha) || \
+           defined(__aarch64__) || defined(__alpha) ||  defined(__sw_64) ||\
            (defined(__mips__) && \
            defined(__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4)))))
 
diff --git a/nspr/pr/src/md/unix/unix.c b/nspr/pr/src/md/unix/unix.c
index 56b58aa..c15c275 100644
--- a/nspr/pr/src/md/unix/unix.c
+++ b/nspr/pr/src/md/unix/unix.c
@@ -2901,7 +2901,7 @@ from_heap:
      * to be made executable because longjmp/signal seem
      * to put machine instructions on the stack.
      */
-#if defined(LINUX) && defined(__alpha)
+#if defined(LINUX) && (defined(__alpha) || defined(__sw_64))
     prot |= PROT_EXEC;
 #endif
     rv = mmap((vaddr != 0) ? vaddr : lastaddr, size, prot,
-- 
2.33.0

