git subrepo pull --force deps/lightning
[pcsx_rearmed.git] / deps / lightning / lib / jit_hppa-cpu.c
index db5a36a..013460c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2013-2019  Free Software Foundation, Inc.
+ * Copyright (C) 2013-2022  Free Software Foundation, Inc.
  *
  * This file is part of GNU lightning.
  *
@@ -648,18 +648,23 @@ static void _movr(jit_state_t*,jit_int32_t,jit_int32_t);
 static void _movi(jit_state_t*,jit_int32_t,jit_word_t);
 #define movi_p(r0,i0)          _movi_p(_jit,r0,i0)
 static jit_word_t _movi_p(jit_state_t*,jit_int32_t,jit_word_t);
+#  define movnr(r0,r1,r2)              _movnr(_jit,r0,r1,r2)
+static void _movnr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
+#  define movzr(r0,r1,r2)              _movzr(_jit,r0,r1,r2)
+static void _movzr(jit_state_t*,jit_int32_t,jit_int32_t,jit_int32_t);
+#  define casx(r0, r1, r2, r3, i0)     _casx(_jit, r0, r1, r2, r3, i0)
+static void _casx(jit_state_t *_jit,jit_int32_t,jit_int32_t,
+                 jit_int32_t,jit_int32_t,jit_word_t);
+#define casr(r0, r1, r2, r3)           casx(r0, r1, r2, r3, 0)
+#define casi(r0, i0, r1, r2)           casx(r0, _NOREG, r1, r2, i0)
 #define comr(r0,r1)            UADDCM(_R0_REGNO,r1,r0)
 #define negr(r0,r1)            SUB(_R0_REGNO,r1,r0)
 #define extr_c(r0,r1)          EXTRWR(r1,31,8,r0)
 #define extr_uc(r0,r1)         EXTRWR_U(r1,31,8,r0)
 #define extr_s(r0,r1)          EXTRWR(r1,31,16,r0)
 #define extr_us(r0,r1)         EXTRWR_U(r1,31,16,r0)
-#if __BYTE_ORDER == __BIG_ENDIAN
-#  define htonr_us(r0,r1)      extr_us(r0,r1)
-#  define htonr_ui(r0,r1)      movr(r0,r1)
-#else
-#  error need htonr implementation
-#endif
+#define bswapr_us(r0,r1)       generic_bswapr_us(_jit,r0,r1)
+#define bswapr_ui(r0,r1)       generic_bswapr_ui(_jit,r0,r1)
 #define addr(r0,r1,r2)         ADD(r1,r2,r0)
 #define addi(r0,r1,i0)         _addi(_jit,r0,r1,i0)
 static void _addi(jit_state_t*,jit_int32_t,jit_int32_t,jit_word_t);
@@ -1633,6 +1638,72 @@ _movi_p(jit_state_t *_jit, jit_int32_t r0, jit_word_t i0)
     return (w);
 }
 
+static void
+_movnr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t w;
+    w = beqi(_jit->pc.w, r2, 0);
+    COPY(r1, r0);
+    patch_at(w, _jit->pc.w);
+}
+
+static void
+_movzr(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_int32_t r2)
+{
+    jit_word_t w;
+    w = bnei(_jit->pc.w, r2, 0);
+    COPY(r1, r0);
+    patch_at(w, _jit->pc.w);
+}
+
+static void
+_casx(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1,
+      jit_int32_t r2, jit_int32_t r3, jit_word_t i0)
+{
+#if defined(__linux__) && defined(SYS_atomic_cmpxchg_32) &&  __WORDSIZE == 32
+    /* Not defined, and unlikely to ever be defined, but could be a way to do it */
+    movi(_R26_REGNO, SYS_atomic_cmpxchg_32);
+    if (r1 == _NOREG)
+       movi(_R25_REGNO, i0);
+    else
+       movr(_R25_REGNO, r1);
+    movr(_R24_REGNO, r2);
+    movr(_R23_REGNO, r3);
+    /* Should only fail for an invalid or unaligned address.
+     * Do not handle this condition. */
+    calli(syscall);
+    movr(r0, _R28_REGNO);
+#else
+    /*
+     * The only atomic operations are LDCW and LDCD, that load a value,
+     * and store zero at the address atomically. The (semaphore) address
+     * must be 16 byte aligned.
+     */
+    fallback_casx(r0, r1, r2, r3, i0);
+    /*
+     * It is important to be aware of the delayed nature of cache flush and
+     *  purge operations, and to use SYNC instructions to force completion
+     * where necessary. The following example illustrates this.
+     * Consider two processes sharing a memory location x which is protected
+     * by a semaphore s.
+     *
+     * process A on Processor 1 |  process B on Processor 2 |  note
+     * -------------------------+---------------------------+------------
+     * LDCW s                   |                           | A acquires semaphore
+     * PDC x                    |                           | A executes purge
+     * SYNC                     |                           | Force completion of purge
+     * STW s                    |                           | A releases semaphore
+     *                          | LDCW s                    | B acquires semaphore
+     *                          | STW x
+     *
+     * In the absence of the SYNC instruction, it would be possible for
+     *  process B's store to x to complete before the purge of x is completed
+     * (since the purge may have been delayed). The purge of x could then
+     * destroy the new value.
+     */
+#endif
+}
+
 static void
 _addi(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_word_t i0)
 {