Implement a simple compare and swap atomic operation. - lightning.git - Portable just-in-time compiler library

index : lightning.git
Portable just-in-time compiler library
summary refs log tree commit diff
path: root/lib/jit_fallback.c
diff options
context:
space:
mode:
authorpcpa <paulo.cesar.pereira.de.andrade@gmail.com>2022年09月08日 16:48:43 -0300
committerpcpa <paulo.cesar.pereira.de.andrade@gmail.com>2022年09月08日 16:48:43 -0300
commitd5a7c8e4ad719e84dbb4904c532f906a1ef5a77b (patch)
tree58f01a849950cef4f32cbfbf4fd036d17ece66d7 /lib/jit_fallback.c
parente7a4ea8828be7c71140b5a0ca4f891d0053c64a5 (diff)
downloadlightning-d5a7c8e4ad719e84dbb4904c532f906a1ef5a77b.tar.gz
Implement a simple compare and swap atomic operation.
* lib/jit_fallback.c: Implement fallback compare and swap with pthreads. * check/Makefile.am: Update for new cas{r,i} simple test. * check/catomic.c, check/catomic.ok: New test case for simple compare and swap atomic operation. * check/lightning.c: Add entries to be able to use the new compare and swap atomic operation. Still missing a general test, only the basic C version. * include/lightning.h.in: Include pthread.h, even if not needing a fallback compare and swap. * include/lightning/jit_private.h: Add support for a register pair in second argument. Required by the new casr and casi operations. * lib/jit_aarch64-cpu.c, lib/jit_aarch64-sz.c, lib/jit_aarch64.c, lib/jit_ppc-cpu.c, lib/jit_ppc-sz.c, lib/jit_ppc.c, lib/jit_x86-cpu.c, lib/jit_x86-sz.c, lib/jit_x86.c: Implement inline code for compare and swap. * lib/jit_arm-cpu.c, lib/jit_arm-sz.c, lib/jit_arm.c: Implement inline code for compare and swap if cpu is armv7, otherwise, use a fallback with pthreads. * lib/jit_alpha-cpu.c, lib/jit_alpha-sz.c, lib/jit_alpha.c, lib/jit_hppa-cpu.c, lib/jit_hppa-sz.c, lib/jit_hppa.c, lib/jit_ia64-cpu.c, lib/jit_ia64-sz.c, lib/jit_ia64.c, lib/jit_mips-cpu.c, lib/jit_mips-sz.c, lib/jit_mips.c, lib/jit_riscv-cpu.c, lib/jit_riscv-sz.c, lib/jit_riscv.c, lib/jit_s390-cpu.c, lib/jit_s390-sz.c, lib/jit_s390.c, lib/jit_sparc-cpu.c, lib/jit_sparc-sz.c, lib/jit_sparc.c: Implement fallback compare and swap with pthreads. At least some of these should be updated for inline code generation. * lib/jit_names.c, lib/jit_print.c: lib/lightning.c: Update for the new compare and swap operation. * doc/body.texi: Add simple documentation of the compare and swap new operation.
Diffstat (limited to 'lib/jit_fallback.c')
-rw-r--r--lib/jit_fallback.c 178
1 files changed, 178 insertions, 0 deletions
diff --git a/lib/jit_fallback.c b/lib/jit_fallback.c
new file mode 100644
index 0000000..89a6295
--- /dev/null
+++ b/lib/jit_fallback.c
@@ -0,0 +1,178 @@
+#if PROTO
+#define fallback_save(r0) _fallback_save(_jit, r0)
+static void _fallback_save(jit_state_t*, jit_int32_t);
+#define fallback_load(r0) _fallback_load(_jit, r0)
+static void _fallback_load(jit_state_t*, jit_int32_t);
+#define fallback_save_regs(r0) _fallback_save_regs(_jit, r0)
+static void _fallback_save_regs(jit_state_t*, jit_int32_t);
+#define fallback_load_regs(r0) _fallback_load_regs(_jit, r0)
+static void _fallback_load_regs(jit_state_t*, jit_int32_t);
+#define fallback_calli(i0, i1) _fallback_calli(_jit, i0, i1)
+static void _fallback_calli(jit_state_t*, jit_word_t, jit_word_t);
+#define fallback_casx(r0,r1,r2,r3,im) _fallback_casx(_jit,r0,r1,r2,r3,im)
+static void _fallback_casx(jit_state_t *, jit_int32_t, jit_int32_t,
+ jit_int32_t, jit_int32_t, jit_word_t);
+#endif
+
+#if CODE
+static void
+_fallback_save(jit_state_t *_jit, jit_int32_t r0)
+{
+ jit_int32_t offset, regno, spec;
+ for (offset = 0; offset < JIT_R_NUM; offset++) {
+ spec = _rvs[offset].spec;
+ regno = jit_regno(spec);
+ if (regno == r0) {
+ if (!(spec & jit_class_sav))
+ stxi(_jitc->function->regoff[offset], rn(JIT_FP), regno);
+ break;
+ }
+ }
+}
+
+static void
+_fallback_load(jit_state_t *_jit, jit_int32_t r0)
+{
+ jit_int32_t offset, regno, spec;
+ for (offset = 0; offset < JIT_R_NUM; offset++) {
+ spec = _rvs[offset].spec;
+ regno = jit_regno(spec);
+ if (regno == r0) {
+ if (!(spec & jit_class_sav))
+ ldxi(regno, rn(JIT_FP), _jitc->function->regoff[offset]);
+ break;
+ }
+ }
+}
+
+static void
+_fallback_save_regs(jit_state_t *_jit, jit_int32_t r0)
+{
+ jit_int32_t offset, regno, spec;
+ for (offset = 0; offset < JIT_R_NUM; offset++) {
+ regno = JIT_R(offset);
+ spec = _rvs[regno].spec;
+ if ((spec & jit_class_gpr) && regno == r0)
+ continue;
+ if (!(spec & jit_class_sav)) {
+ if (!_jitc->function->regoff[regno]) {
+ _jitc->function->regoff[regno] =
+ jit_allocai(sizeof(jit_word_t));
+ _jitc->again = 1;
+ }
+ jit_regset_setbit(&_jitc->regsav, regno);
+ emit_stxi(_jitc->function->regoff[regno], JIT_FP, regno);
+ }
+ }
+ /* If knew for certain float registers are not used by
+ * pthread_mutex_lock and pthread_mutex_unlock, could skip this */
+ for (offset = 0; offset < JIT_F_NUM; offset++) {
+ regno = JIT_F(offset);
+ spec = _rvs[regno].spec;
+ if (!(spec & jit_class_sav)) {
+ if (!_jitc->function->regoff[regno]) {
+ _jitc->function->regoff[regno] =
+ jit_allocai(sizeof(jit_word_t));
+ _jitc->again = 1;
+ }
+ jit_regset_setbit(&_jitc->regsav, regno);
+ emit_stxi_d(_jitc->function->regoff[regno], JIT_FP, regno);
+ }
+ }
+}
+
+static void
+_fallback_load_regs(jit_state_t *_jit, jit_int32_t r0)
+{
+ jit_int32_t offset, regno, spec;
+ for (offset = 0; offset < JIT_R_NUM; offset++) {
+ regno = JIT_R(offset);
+ spec = _rvs[regno].spec;
+ if ((spec & jit_class_gpr) && regno == r0)
+ continue;
+ if (!(spec & jit_class_sav)) {
+ jit_regset_clrbit(&_jitc->regsav, regno);
+ emit_ldxi(regno, JIT_FP, _jitc->function->regoff[regno]);
+ }
+ }
+ /* If knew for certain float registers are not used by
+ * pthread_mutex_lock and pthread_mutex_unlock, could skip this */
+ for (offset = 0; offset < JIT_F_NUM; offset++) {
+ regno = JIT_F(offset);
+ spec = _rvs[regno].spec;
+ if (!(spec & jit_class_sav)) {
+ jit_regset_clrbit(&_jitc->regsav, regno);
+ emit_ldxi_d(regno, JIT_FP, _jitc->function->regoff[regno]);
+ }
+ }
+}
+
+static void
+_fallback_calli(jit_state_t *_jit, jit_word_t i0, jit_word_t i1)
+{
+# if defined(__mips__)
+ movi(rn(_A0), i1);
+# elif defined(__arm__)
+ movi(rn(_R0), i1);
+# elif defined(__sparc__)
+ movi(rn(_O0), i1);
+# elif defined(__ia64__)
+ /* avoid confusion with pushargi patching */
+ if (i1 >= -2097152 && i0 <= 2097151)
+ MOVI(_jitc->rout, i1);
+ else
+ MOVL(_jitc->rout, i1);
+# elif defined(__hppa__)
+ movi(_R26_REGNO, i1);
+# elif defined(__s390__) || defined(__s390x__)
+ movi(rn(_R2), i1);
+# elif defined(__alpha__)
+ movi(rn(_A0), i1);
+# elif defined(__riscv__)
+ movi(rn(JIT_RA0), i1);
+# endif
+ calli(i0);
+}
+
+static void
+_fallback_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)
+{
+ jit_int32_t r1_reg, iscasi;
+ jit_word_t jump, done;
+ /* XXX only attempts to fallback cas for lightning jit code */
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+ if ((iscasi = r1 == _NOREG)) {
+ r1_reg = jit_get_reg(jit_class_gpr);
+ r1 = rn(r1_reg);
+ }
+ fallback_save_regs(r0);
+ if (iscasi)
+ movi(r1, i0);
+ fallback_calli((jit_word_t)pthread_mutex_lock, (jit_word_t)&mutex);
+ fallback_load(r1);
+ ldr(r0, r1);
+ fallback_load(r2);
+ eqr(r0, r0, r2);
+ fallback_save(r0);
+ jump = bnei(_jit->pc.w, r0, 1);
+ fallback_load(r3);
+# if __WORDSIZE == 32
+ str_i(r1, r3);
+# else
+ str_l(r1, r3);
+# endif
+ /* done: */
+ done = _jit->pc.w;
+ fallback_calli((jit_word_t)pthread_mutex_unlock, (jit_word_t)&mutex);
+ fallback_load(r0);
+# if defined(__arm__)
+ patch_at(arm_patch_jump, jump, done);
+# else
+ patch_at(jump, done);
+# endif
+ fallback_load_regs(r0);
+ if (iscasi)
+ jit_unget_reg(r1_reg);
+}
+#endif
generated by cgit v1.2.3 (git 2.39.1) at 2025年09月16日 21:58:33 +0000

AltStyle によって変換されたページ (->オリジナル) /