guile-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Guile-commits] 33/437: add jit_allocai for SPARC


From: Andy Wingo
Subject: [Guile-commits] 33/437: add jit_allocai for SPARC
Date: Mon, 2 Jul 2018 05:13:39 -0400 (EDT)

wingo pushed a commit to branch lightning
in repository guile.

commit 4290adb33a5d36a044cb6cda5e96aa784b24558d
Author: Paolo Bonzini <address@hidden>
Date:   Mon Nov 6 08:28:04 2006 +0000

    add jit_allocai for SPARC
    
    Patches applied:
    
     * address@hidden/lightning--stable--1.2--patch-28
       Implemented `jit_allocai' for SPARC.
    
     * address@hidden/lightning--stable--1.2--patch-29
       tests/allocai.c: New test case.
    
     * address@hidden/lightning--stable--1.2--patch-30
       Fixed `_d22 ()' on SPARC (fixes "displacement too large" errors).
    
    git-archimport-id: address@hidden/lightning--stable--1.2--patch-35
---
 lightning/sparc/asm.h  |   4 +-
 lightning/sparc/core.h |  52 ++++++++++++++++++++++-
 tests/Makefile.am      |   8 ++--
 tests/allocai.c        | 109 +++++++++++++++++++++++++++++++++++++++++++++++++
 tests/allocai.ok       |   2 +
 5 files changed, 169 insertions(+), 6 deletions(-)

diff --git a/lightning/sparc/asm.h b/lightning/sparc/asm.h
index 9cc7ee7..0992f50 100644
--- a/lightning/sparc/asm.h
+++ b/lightning/sparc/asm.h
@@ -50,8 +50,8 @@
 typedef unsigned int jit_insn;
 
 #ifndef LIGHTNING_DEBUG
-#define _d30(BD)       ((_jit_UL(BD) - _jit_UL(_jit.x.pc))>>2)
-#define _d22(BD)       _ck_d(22, _d30(BD))
+#define _d30(BD)       (_ck_d (30, ((_jit_SL (_jit_UL (BD) - _jit_UL 
(_jit.x.pc))) >> 2)))
+#define _d22(BD)       (_ck_d (22, ((_jit_SL (_jit_UL (BD) - _jit_UL 
(_jit.x.pc)) >> 2))))
 
 #define _HI(I)         (_jit_UL(I) >>     (10))
 #define _LO(I)         (_jit_UL(I) & _MASK(10))
diff --git a/lightning/sparc/core.h b/lightning/sparc/core.h
index 2795a4a..10ca155 100644
--- a/lightning/sparc/core.h
+++ b/lightning/sparc/core.h
@@ -41,6 +41,8 @@
 #define JIT_BIG                        _Rg(1)  /* %g1 used to make 32-bit 
operands */
 #define JIT_BIG2               _Ro(7)  /* %o7 used to make 32-bit compare 
operands */
 #define JIT_SP                 _Ro(6)
+#define JIT_FP                 _Ri(6)
+
 #define JIT_RZERO              _Rg(0)
 #define JIT_RET                        _Ri(0)
 
@@ -59,12 +61,60 @@
  *             `--- _jit.x.pc                  
  */
 
+
+/* Implementation of `allocai'.
+ *
+ * The SysV ABI for SPARC is specified in "System V Application Binary
+ * Interface, SPARC Processor Supplement, Third Edition", available from
+ * http://www.sparc.org/resource.htm .
+ *
+ * According to the SysV ABI specs: "At all times the stack pointer must
+ * point to a doubleword aligned, 16- word window save area." (p 3-12).  The
+ * stack layout is shown in Figure 3-16 and the layout of a C stack frame is
+ * given in Figure 3-47: the area between %sp and %sp+104 is reserved for
+ * specific purposes, and automatic variables go between %sp+104 and %fp and
+ * are typically addressed using negative offsets relative to %fp.
+ *
+ * Stack space may be allocated dynamically as decribed in Section
+ * "Allocating Stack Space Dynamically", p. 3-36, and shown in Figure 3-49.
+ * `allocai' is implementing by patching a function prolog's `save'
+ * instruction in order to increase the initial frame size.  Thus,
+ * %fp and below is used for the memory allocated via `allocai'.  */
+
+
 struct jit_local_state {
   int  nextarg_put;    /* Next %o reg. to be written */
   int  nextarg_get;    /* Next %i reg. to be read */
+  jit_insn *save;      /* Pointer to the `save' instruction */
+  unsigned  frame_size;        /* Current frame size as allocated by `save' */
+  int       alloca_offset; /* Current offset to the alloca'd memory (negative
+                             offset relative to %fp) */
   jit_insn delay;
 };
 
+/* Minimum size of a stack frame.  */
+#define JIT_SPARC_MIN_FRAME_SIZE  104
+
+
+/* Round AMOUNT to the closest higher multiple of 2^ALIGNMENT.  */
+#define _jit_round(alignment, amount)                          \
+  (((amount) & (_MASK (alignment)))                            \
+   ? (((amount) & (~_MASK (alignment))) + (1 << (alignment)))  \
+   : (amount))
+
+/* Patch a `save' instruction (with immediate operand) so that it increases
+   %sp by AMOUNT.  AMOUNT is rounded so that %sp remains 8-octet aligned.  */
+#define jit_patch_save(amount)                                 \
+  (* (_jitl).save &= ~_MASK (13),                              \
+   * (_jitl).save |= _ck_d (13, -_jit_round (3, amount)))
+
+/* Allocate AMOUNT octets on the frame by patching the `save' instruction.  */
+#define jit_allocai(amount)                            \
+  (jit_patch_save ((_jitl).frame_size + (amount)),     \
+   (_jitl).frame_size += (amount),                     \
+   (_jitl).alloca_offset -= (amount),                  \
+   (_jitl).alloca_offset)
+
 #define jit_fill_delay_after(branch) (_jitl.delay = *--_jit.x.pc,              
                         \
        ((branch) == _jit.x.pc                                    /* check if 
NOP was inserted */                \
                ? (_jit.x.pc[-1] ^= 1<<29)                        /* no if 
branch, toggle annul bit  */  \
@@ -240,7 +290,7 @@ struct jit_local_state {
 #define jit_patch_at(delay_pc, pv)     jit_patch_ (((delay_pc) - 1) , (pv))
 #define jit_popr_i(rs)                 (LDmr(JIT_SP, 0, (rs)), ADDrir(JIT_SP, 
8, JIT_SP))
 #define jit_prepare_i(num)             (_jitl.nextarg_put += (num))
-#define jit_prolog(numargs)            (SAVErir(JIT_SP, -120, JIT_SP), 
_jitl.nextarg_get = _Ri(0))
+#define jit_prolog(numargs)            (_jitl.save = (jit_insn *) _jit.x.pc, 
SAVErir (JIT_SP, -JIT_SPARC_MIN_FRAME_SIZE, JIT_SP), _jitl.frame_size = 
JIT_SPARC_MIN_FRAME_SIZE, _jitl.alloca_offset = 0, _jitl.nextarg_get = _Ri(0), 
_jitl.next_push = 0)
 #define jit_pushr_i(rs)                        (STrm((rs), JIT_SP, -8), 
SUBrir(JIT_SP, 8, JIT_SP))
 #define jit_pusharg_i(rs)              (--_jitl.nextarg_put, MOVrr((rs), 
_Ro(_jitl.nextarg_put)))
 #define jit_ret()                      (RET(), RESTORE())
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 69cc039..4b38437 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -1,11 +1,13 @@
 AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) 
-I$(top_srcdir)/lightning/$(cpu)
 
 check_PROGRAMS = fibit incr printf printf2 rpn fib fibdelay    \
-       add bp testfp funcfp rpnfp modi ldxi divi movi ret
+       add bp testfp funcfp rpnfp modi ldxi divi movi ret      \
+       allocai
 
 noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok     \
        fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.ok  \
-       bp.ok modi.ok ldxi.ok divi.ok movi.ok ret.ok
+       bp.ok modi.ok ldxi.ok divi.ok movi.ok ret.ok            \
+       allocai.ok
 
 EXTRA_DIST = $(noinst_DATA) run-test
 
@@ -15,7 +17,7 @@ endif
 
 if REGRESSION_TESTING
 TESTS = fib fibit fibdelay incr printf printf2 rpn add bp      \
-       testfp funcfp rpnfp modi ldxi divi movi ret
+       testfp funcfp rpnfp modi ldxi divi movi ret allocai
 
 TESTS_ENVIRONMENT=$(srcdir)/run-test
 endif
diff --git a/tests/allocai.c b/tests/allocai.c
new file mode 100644
index 0000000..c9947b4
--- /dev/null
+++ b/tests/allocai.c
@@ -0,0 +1,109 @@
+/******************************** -*- C -*- ****************************
+ *
+ *     Test `jit_allocai'
+ *
+ ***********************************************************************/
+
+
+/* Contributed by Ludovic Court�s.  */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include "lightning.h"
+
+typedef int (* int_return_int_t) (int);
+
+static int
+identity (int arg)
+{
+  printf ("received %i\n", arg);
+  return arg;
+}
+
+static int_return_int_t
+generate_function_proxy (int_return_int_t func)
+{
+  static const char failure_message[] = "numbers don't add up to zero\n";
+  static char buffer[1024];
+
+  int_return_int_t result;
+  int arg, arg_offset, argneg_offset;
+  jit_insn *branch;
+
+  result = (int_return_int_t)(jit_set_ip (buffer).ptr);
+  jit_prolog (1);
+  arg = jit_arg_i ();
+  jit_getarg_i (JIT_R1, arg);
+
+  /* Store the argument on the stack.  */
+  arg_offset = jit_allocai (sizeof (int));
+  jit_stxi_i (arg_offset, JIT_FP, JIT_R1);
+
+  /* Store the negative of the argument on the stack.  */
+  argneg_offset = jit_allocai (sizeof (int));
+  jit_negr_i (JIT_R2, JIT_R1);
+  jit_stxi_i (argneg_offset, JIT_FP, JIT_R2);
+
+  /* Invoke FUNC.  */
+  jit_prepare (1);
+  jit_pusharg_i (JIT_R1);
+  (void)jit_finish (func);
+
+  /* Ignore the result.  */
+
+  /* Restore the negative and the argument from the stack.  */
+  jit_ldxi_i (JIT_R2, JIT_FP, argneg_offset);
+  jit_ldxi_i (JIT_V1, JIT_FP, arg_offset);
+
+  /* Make sure they still add to zero.  */
+  jit_addr_i (JIT_R0, JIT_V1, JIT_R2);
+  branch = jit_bnei_i (jit_forward (), JIT_R0, 0);
+
+  /* Return it.  */
+  jit_movr_i (JIT_RET, JIT_V1);
+  jit_ret ();
+
+  /* Display a failure message.  */
+  jit_patch (branch);
+  jit_movi_p (JIT_R2, failure_message);
+  jit_prepare (1);
+  jit_pusharg_p (JIT_R2);
+  jit_finish (printf);
+
+  /* Leave.  */
+  jit_movr_i (JIT_RET, JIT_V1);
+  jit_ret ();
+
+  jit_flush_code (buffer, jit_get_ip ().ptr);
+
+  return result;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+  int_return_int_t identity_func;
+
+  identity_func = generate_function_proxy (identity);
+  if (identity_func (7777) != 7777)
+    {
+      printf ("failed: got %i instead of %i\n",
+             identity_func (7777), 7777);
+      return 1;
+    }
+  else
+    printf ("succeeded\n");
+
+  return 0;
+}
+
+/*
+   Local Variables:
+   coding: latin-1
+   End:
+ */
diff --git a/tests/allocai.ok b/tests/allocai.ok
new file mode 100644
index 0000000..2962f7a
--- /dev/null
+++ b/tests/allocai.ok
@@ -0,0 +1,2 @@
+received 7777
+succeeded



reply via email to

[Prev in Thread] Current Thread [Next in Thread]