mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-02 13:00:26 +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:
parent
54c573d8d7
commit
4290adb33a
5 changed files with 169 additions and 6 deletions
|
@ -50,8 +50,8 @@
|
||||||
typedef unsigned int jit_insn;
|
typedef unsigned int jit_insn;
|
||||||
|
|
||||||
#ifndef LIGHTNING_DEBUG
|
#ifndef LIGHTNING_DEBUG
|
||||||
#define _d30(BD) ((_jit_UL(BD) - _jit_UL(_jit.x.pc))>>2)
|
#define _d30(BD) (_ck_d (30, ((_jit_SL (_jit_UL (BD) - _jit_UL (_jit.x.pc))) >> 2)))
|
||||||
#define _d22(BD) _ck_d(22, _d30(BD))
|
#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 _HI(I) (_jit_UL(I) >> (10))
|
||||||
#define _LO(I) (_jit_UL(I) & _MASK(10))
|
#define _LO(I) (_jit_UL(I) & _MASK(10))
|
||||||
|
|
|
@ -41,6 +41,8 @@
|
||||||
#define JIT_BIG _Rg(1) /* %g1 used to make 32-bit operands */
|
#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_BIG2 _Ro(7) /* %o7 used to make 32-bit compare operands */
|
||||||
#define JIT_SP _Ro(6)
|
#define JIT_SP _Ro(6)
|
||||||
|
#define JIT_FP _Ri(6)
|
||||||
|
|
||||||
#define JIT_RZERO _Rg(0)
|
#define JIT_RZERO _Rg(0)
|
||||||
#define JIT_RET _Ri(0)
|
#define JIT_RET _Ri(0)
|
||||||
|
|
||||||
|
@ -59,12 +61,60 @@
|
||||||
* `--- _jit.x.pc
|
* `--- _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 {
|
struct jit_local_state {
|
||||||
int nextarg_put; /* Next %o reg. to be written */
|
int nextarg_put; /* Next %o reg. to be written */
|
||||||
int nextarg_get; /* Next %i reg. to be read */
|
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;
|
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, \
|
#define jit_fill_delay_after(branch) (_jitl.delay = *--_jit.x.pc, \
|
||||||
((branch) == _jit.x.pc /* check if NOP was inserted */ \
|
((branch) == _jit.x.pc /* check if NOP was inserted */ \
|
||||||
? (_jit.x.pc[-1] ^= 1<<29) /* no if branch, toggle annul bit */ \
|
? (_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_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_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_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_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_pusharg_i(rs) (--_jitl.nextarg_put, MOVrr((rs), _Ro(_jitl.nextarg_put)))
|
||||||
#define jit_ret() (RET(), RESTORE())
|
#define jit_ret() (RET(), RESTORE())
|
||||||
|
|
|
@ -1,11 +1,13 @@
|
||||||
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lightning/$(cpu)
|
AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir) -I$(top_srcdir)/lightning/$(cpu)
|
||||||
|
|
||||||
check_PROGRAMS = fibit incr printf printf2 rpn fib fibdelay \
|
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 \
|
noinst_DATA = fibit.ok incr.ok printf.ok printf2.ok rpn.ok \
|
||||||
fib.ok fibdelay.ok testfp.ok funcfp.ok rpnfp.ok add.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
|
EXTRA_DIST = $(noinst_DATA) run-test
|
||||||
|
|
||||||
|
@ -15,7 +17,7 @@ endif
|
||||||
|
|
||||||
if REGRESSION_TESTING
|
if REGRESSION_TESTING
|
||||||
TESTS = fib fibit fibdelay incr printf printf2 rpn add bp \
|
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
|
TESTS_ENVIRONMENT=$(srcdir)/run-test
|
||||||
endif
|
endif
|
||||||
|
|
109
tests/allocai.c
Normal file
109
tests/allocai.c
Normal 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
2
tests/allocai.ok
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
received 7777
|
||||||
|
succeeded
|
Loading…
Add table
Add a link
Reference in a new issue