1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-02 04:40:29 +02:00

add jit_allocai for SPARC

Patches applied:

 * lcourtes@laas.fr--2005-libre/lightning--stable--1.2--patch-28
   Implemented `jit_allocai' for SPARC.

 * lcourtes@laas.fr--2005-libre/lightning--stable--1.2--patch-29
   tests/allocai.c: New test case.

 * lcourtes@laas.fr--2005-libre/lightning--stable--1.2--patch-30
   Fixed `_d22 ()' on SPARC (fixes "displacement too large" errors).

git-archimport-id: bonzini@gnu.org--2004b/lightning--stable--1.2--patch-35
This commit is contained in:
Paolo Bonzini 2006-11-06 08:28:04 +00:00
parent 54c573d8d7
commit 4290adb33a
5 changed files with 169 additions and 6 deletions

View file

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

View file

@ -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())

View file

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

109
tests/allocai.c Normal file
View file

@ -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:
*/

2
tests/allocai.ok Normal file
View file

@ -0,0 +1,2 @@
received 7777
succeeded