mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-30 00:40:20 +02:00
Make it clear stdarg like abstraction is not supported.
* include/lightning.h, include/lightning/jit_private.h, lib/jit_arm.c, lib/jit_mips.c, lib/jit_ppc.c, lib/jit_x86.c, lib/lightning.c: Make jit_ellipsis implementation not backend specific. It is not intended to handle va_list like objects at runtime, as jit_arg* and jit_getarg* return constant values resolved at parse time, so, effectively it is not possible to create printf like jit functions, as there is no va_start, va_arg, va_end, etc, abstraction. This limitation should be kept for the sake of making new ports easier.
This commit is contained in:
parent
074056499f
commit
03559bb8cc
8 changed files with 67 additions and 45 deletions
13
ChangeLog
13
ChangeLog
|
@ -1,3 +1,16 @@
|
|||
2012-12-14 Paulo Andrade <pcpa@gnu.org>
|
||||
|
||||
* include/lightning.h, include/lightning/jit_private.h,
|
||||
lib/jit_arm.c, lib/jit_mips.c, lib/jit_ppc.c, lib/jit_x86.c,
|
||||
lib/lightning.c: Make jit_ellipsis implementation not
|
||||
backend specific. It is not intended to handle va_list
|
||||
like objects at runtime, as jit_arg* and jit_getarg*
|
||||
return constant values resolved at parse time, so, effectively
|
||||
it is not possible to create printf like jit functions, as
|
||||
there is no va_start, va_arg, va_end, etc, abstraction. This
|
||||
limitation should be kept for the sake of making new ports
|
||||
easier.
|
||||
|
||||
2012-12-14 Paulo Andrade <pcpa@gnu.org>
|
||||
|
||||
* include/lightning.h, lib/lightning.c: Add two extra wrapper
|
||||
|
|
|
@ -95,13 +95,6 @@ typedef jit_int32_t jit_fpr_t;
|
|||
#define jit_class(reg) ((reg) & 0xffff0000)
|
||||
#define jit_regno(reg) ((reg) & 0x00007fff)
|
||||
|
||||
#define jit_call_default 0
|
||||
/* assume only varags functions called are printf like, that is,
|
||||
* without a declared float/double argument */
|
||||
/* FIXME currently no way to create a varargs (or non varargs) jit function
|
||||
* if calling sequence changes for float/double arguments */
|
||||
#define jit_call_varargs 1
|
||||
|
||||
typedef struct jit_node jit_node_t;
|
||||
typedef struct jit_state jit_state_t;
|
||||
|
||||
|
|
|
@ -61,6 +61,9 @@
|
|||
* returned by a "user" call
|
||||
* to jit_get_reg() */
|
||||
|
||||
#define jit_call_default 0
|
||||
#define jit_call_varargs 1
|
||||
|
||||
#define jit_kind_register 1
|
||||
#define jit_kind_code 2
|
||||
#define jit_kind_word 3
|
||||
|
@ -194,12 +197,13 @@ struct jit_function {
|
|||
jit_int32_t size;
|
||||
jit_int32_t aoff;
|
||||
jit_int32_t alen;
|
||||
jit_int32_t call;
|
||||
} self;
|
||||
struct {
|
||||
jit_int32_t argi;
|
||||
jit_int32_t argf;
|
||||
jit_int32_t size;
|
||||
jit_int32_t kind;
|
||||
jit_int32_t call;
|
||||
} call;
|
||||
jit_node_t *prolog;
|
||||
jit_node_t *epilog;
|
||||
|
@ -220,6 +224,7 @@ struct jit_state {
|
|||
jit_node_t *tail;
|
||||
jit_uint32_t emit : 1; /* emit state entered */
|
||||
jit_uint32_t again : 1; /* start over emiting function */
|
||||
jit_uint32_t prepare : 1; /* inside prepare/finish* block */
|
||||
jit_int32_t reglen; /* number of registers */
|
||||
jit_regset_t regarg; /* cannot allocate */
|
||||
jit_regset_t regsav; /* automatic spill only once */
|
||||
|
|
|
@ -228,6 +228,7 @@ _jit_prolog(jit_state_t *_jit)
|
|||
_jit->function->self.aoff = -64;
|
||||
else
|
||||
_jit->function->self.aoff = 0;
|
||||
_jit->function->self.call = jit_call_default;
|
||||
_jit->function->regoff = calloc(_jit->reglen, sizeof(jit_int32_t));
|
||||
|
||||
_jit->function->prolog = jit_new_node_no_link(jit_code_prolog);
|
||||
|
@ -243,12 +244,6 @@ _jit_prolog(jit_state_t *_jit)
|
|||
jit_regset_new(_jit->function->regset);
|
||||
}
|
||||
|
||||
void
|
||||
_jit_ellipsis(jit_state_t *_jit)
|
||||
{
|
||||
_jit->function->call.kind = jit_call_varargs;
|
||||
}
|
||||
|
||||
jit_int32_t
|
||||
_jit_allocai(jit_state_t *_jit, jit_int32_t length)
|
||||
{
|
||||
|
@ -355,7 +350,7 @@ jit_int32_t
|
|||
_jit_arg_f(jit_state_t *_jit)
|
||||
{
|
||||
jit_int32_t offset;
|
||||
if (jit_cpu.abi) {
|
||||
if (jit_cpu.abi && !(_jit->function->self.call & jit_call_varargs)) {
|
||||
if (_jit->function->self.argf < 16)
|
||||
offset = _jit->function->self.argf++;
|
||||
else {
|
||||
|
@ -378,7 +373,7 @@ jit_int32_t
|
|||
_jit_arg_d(jit_state_t *_jit)
|
||||
{
|
||||
jit_int32_t offset;
|
||||
if (jit_cpu.abi) {
|
||||
if (jit_cpu.abi && !(_jit->function->self.call & jit_call_varargs)) {
|
||||
if (_jit->function->self.argf < 15) {
|
||||
if (_jit->function->self.argf & 1)
|
||||
++_jit->function->self.argf;
|
||||
|
@ -525,7 +520,7 @@ void
|
|||
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
|
||||
{
|
||||
assert(_jit->function);
|
||||
if (jit_cpu.abi && !(_jit->function->call.kind & jit_call_varargs)) {
|
||||
if (jit_cpu.abi && !(_jit->function->call.call & jit_call_varargs)) {
|
||||
if (_jit->function->call.argf < 16) {
|
||||
jit_movr_f(JIT_FA0 - _jit->function->call.argf, u);
|
||||
++_jit->function->call.argf;
|
||||
|
@ -549,7 +544,7 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
|
|||
jit_int32_t regno;
|
||||
|
||||
assert(_jit->function);
|
||||
if (jit_cpu.abi && !(_jit->function->call.kind & jit_call_varargs)) {
|
||||
if (jit_cpu.abi && !(_jit->function->call.call & jit_call_varargs)) {
|
||||
if (_jit->function->call.argf < 16) {
|
||||
jit_movi_f(JIT_FA0 - _jit->function->call.argf, u);
|
||||
++_jit->function->call.argf;
|
||||
|
@ -574,7 +569,7 @@ void
|
|||
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
|
||||
{
|
||||
assert(_jit->function);
|
||||
if (jit_cpu.abi && !(_jit->function->call.kind & jit_call_varargs)) {
|
||||
if (jit_cpu.abi && !(_jit->function->call.call & jit_call_varargs)) {
|
||||
if (_jit->function->call.argf < 15) {
|
||||
if (_jit->function->call.argf & 1)
|
||||
++_jit->function->call.argf;
|
||||
|
@ -604,7 +599,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
|
|||
jit_int32_t regno;
|
||||
|
||||
assert(_jit->function);
|
||||
if (jit_cpu.abi && !(_jit->function->call.kind & jit_call_varargs)) {
|
||||
if (jit_cpu.abi && !(_jit->function->call.call & jit_call_varargs)) {
|
||||
if (_jit->function->call.argf < 15) {
|
||||
if (_jit->function->call.argf & 1)
|
||||
++_jit->function->call.argf;
|
||||
|
@ -664,6 +659,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
|
|||
node->w.w = _jit->function->call.argf;
|
||||
_jit->function->call.argi = _jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
_jit->prepare = 0;
|
||||
}
|
||||
|
||||
jit_node_t *
|
||||
|
@ -679,6 +675,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
|
|||
node->w.w = _jit->function->call.argf;
|
||||
_jit->function->call.argi = _jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
_jit->prepare = 0;
|
||||
return (node);
|
||||
}
|
||||
|
||||
|
|
|
@ -135,6 +135,7 @@ _jit_prolog(jit_state_t *_jit)
|
|||
_jit->function->self.size = stack_framesize;
|
||||
_jit->function->self.argi = _jit->function->self.argf =
|
||||
_jit->function->self.aoff = _jit->function->self.alen = 0;
|
||||
_jit->function->self.call = jit_call_default;
|
||||
_jit->function->regoff = calloc(_jit->reglen, sizeof(jit_int32_t));
|
||||
|
||||
_jit->function->prolog = jit_new_node_no_link(jit_code_prolog);
|
||||
|
@ -150,12 +151,6 @@ _jit_prolog(jit_state_t *_jit)
|
|||
jit_regset_new(_jit->function->regset);
|
||||
}
|
||||
|
||||
void
|
||||
_jit_ellipsis(jit_state_t *_jit)
|
||||
{
|
||||
_jit->function->call.kind = jit_call_varargs;
|
||||
}
|
||||
|
||||
jit_int32_t
|
||||
_jit_allocai(jit_state_t *_jit, jit_int32_t length)
|
||||
{
|
||||
|
@ -612,6 +607,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
|
|||
call->w.w = _jit->function->self.argf;
|
||||
_jit->function->call.argi = _jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
_jit->prepare = 0;
|
||||
}
|
||||
|
||||
jit_node_t *
|
||||
|
@ -629,7 +625,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
|
|||
call->w.w = _jit->function->call.argf;
|
||||
_jit->function->call.argi = _jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
|
||||
_jit->prepare = 0;
|
||||
return (node);
|
||||
}
|
||||
|
||||
|
|
|
@ -141,6 +141,7 @@ _jit_prolog(jit_state_t *_jit)
|
|||
_jit->function->self.aoff = _jit->function->self.alen = 0;
|
||||
/* float conversion */
|
||||
_jit->function->self.aoff = -8;
|
||||
_jit->function->self.call = jit_call_default;
|
||||
_jit->function->regoff = calloc(_jit->reglen, sizeof(jit_int32_t));
|
||||
|
||||
_jit->function->prolog = jit_new_node_no_link(jit_code_prolog);
|
||||
|
@ -156,12 +157,6 @@ _jit_prolog(jit_state_t *_jit)
|
|||
jit_regset_new(_jit->function->regset);
|
||||
}
|
||||
|
||||
void
|
||||
_jit_ellipsis(jit_state_t *_jit)
|
||||
{
|
||||
_jit->function->call.kind = jit_call_varargs;
|
||||
}
|
||||
|
||||
jit_int32_t
|
||||
_jit_allocai(jit_state_t *_jit, jit_int32_t length)
|
||||
{
|
||||
|
@ -425,7 +420,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
|
|||
if (_jit->function->call.argf < 8) {
|
||||
jit_movr_d(JIT_FA0 - _jit->function->call.argf, u);
|
||||
++_jit->function->call.argf;
|
||||
if (!(_jit->function->call.kind & jit_call_varargs))
|
||||
if (!(_jit->function->call.call & jit_call_varargs))
|
||||
return;
|
||||
}
|
||||
if (_jit->function->call.argi < 8) {
|
||||
|
@ -452,7 +447,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
|
|||
if (_jit->function->call.argf < 8) {
|
||||
jit_movi_d(JIT_FA0 - _jit->function->call.argf, u);
|
||||
++_jit->function->call.argf;
|
||||
if (!(_jit->function->call.kind & jit_call_varargs))
|
||||
if (!(_jit->function->call.call & jit_call_varargs))
|
||||
return;
|
||||
}
|
||||
regno = jit_get_reg(jit_class_fpr);
|
||||
|
@ -505,6 +500,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
|
|||
call->w.w = _jit->function->call.argf;
|
||||
_jit->function->call.argi = _jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
_jit->prepare = 0;
|
||||
}
|
||||
|
||||
jit_node_t *
|
||||
|
@ -519,6 +515,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
|
|||
node->w.w = _jit->function->call.argf;
|
||||
_jit->function->call.argi = _jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
_jit->prepare = 0;
|
||||
return (node);
|
||||
}
|
||||
|
||||
|
|
|
@ -305,6 +305,7 @@ _jit_prolog(jit_state_t *_jit)
|
|||
_jit->function->self.aoff = _jit->function->self.alen = 0;
|
||||
/* sse/x87 conversion */
|
||||
_jit->function->self.aoff = -8;
|
||||
_jit->function->self.call = jit_call_default;
|
||||
_jit->function->regoff = calloc(_jit->reglen, sizeof(jit_int32_t));
|
||||
|
||||
_jit->function->prolog = jit_new_node_no_link(jit_code_prolog);
|
||||
|
@ -320,12 +321,6 @@ _jit_prolog(jit_state_t *_jit)
|
|||
jit_regset_new(_jit->function->regset);
|
||||
}
|
||||
|
||||
void
|
||||
_jit_ellipsis(jit_state_t *_jit)
|
||||
{
|
||||
_jit->function->call.kind = jit_call_varargs;
|
||||
}
|
||||
|
||||
jit_int32_t
|
||||
_jit_allocai(jit_state_t *_jit, jit_int32_t length)
|
||||
{
|
||||
|
@ -732,7 +727,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
|
|||
if (_jit->function->self.alen < _jit->function->call.size)
|
||||
_jit->function->self.alen = _jit->function->call.size;
|
||||
#if __WORDSIZE == 64
|
||||
if (_jit->function->call.kind & jit_call_varargs) {
|
||||
if (_jit->function->call.call & jit_call_varargs) {
|
||||
if (jit_regno(reg) == _RAX) {
|
||||
reg = jit_get_reg(jit_class_gpr);
|
||||
jit_movr(reg, _RAX);
|
||||
|
@ -750,6 +745,7 @@ _jit_finishr(jit_state_t *_jit, jit_int32_t r0)
|
|||
call->w.w = _jit->function->call.argf;
|
||||
_jit->function->call.argi = _jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
_jit->prepare = 0;
|
||||
}
|
||||
|
||||
jit_node_t *
|
||||
|
@ -764,13 +760,13 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
|
|||
if (_jit->function->self.alen < _jit->function->call.size)
|
||||
_jit->function->self.alen = _jit->function->call.size;
|
||||
#if __WORDSIZE == 64
|
||||
if (_jit->function->call.kind & jit_call_varargs)
|
||||
if (_jit->function->call.call & jit_call_varargs)
|
||||
jit_regset_setbit(_jit->regarg, _RAX);
|
||||
reg = jit_get_reg(jit_class_gpr);
|
||||
node = jit_movi(reg, (jit_word_t)i0);
|
||||
jit_finishr(reg);
|
||||
jit_unget_reg(reg);
|
||||
if (_jit->function->call.kind & jit_call_varargs)
|
||||
if (_jit->function->call.call & jit_call_varargs)
|
||||
jit_regset_clrbit(_jit->regarg, _RAX);
|
||||
#else
|
||||
node = jit_calli(i0);
|
||||
|
@ -779,6 +775,7 @@ _jit_finishi(jit_state_t *_jit, jit_pointer_t i0)
|
|||
#endif
|
||||
_jit->function->call.argi = _jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
_jit->prepare = 0;
|
||||
return (node);
|
||||
}
|
||||
|
||||
|
|
|
@ -725,10 +725,34 @@ void
|
|||
_jit_prepare(jit_state_t *_jit)
|
||||
{
|
||||
assert(_jit->function);
|
||||
_jit->function->call.kind = jit_call_default;
|
||||
_jit->function->call.call = jit_call_default;
|
||||
_jit->function->call.argi =
|
||||
_jit->function->call.argf =
|
||||
_jit->function->call.size = 0;
|
||||
_jit->prepare = 1;
|
||||
}
|
||||
|
||||
/* If declaring a jit function as varargs, in most backends it does
|
||||
* not change anything. Currently only exception is arm backend, that
|
||||
* if running in hardware float abi, switches to software float abi
|
||||
* if "self" function is varargs. Otherwise, there is no logic to
|
||||
* handle va_list like objects that need to parse runtime state, and
|
||||
* that is mainly because jit_arg* and jit_getarg* work only with
|
||||
* constants values, and one must not expect them to be handled at
|
||||
* runtime, they are parsed only once (same applies to jit_allocai,
|
||||
* that has no jit_allocar counterpart).
|
||||
*/
|
||||
void
|
||||
_jit_ellipsis(jit_state_t *_jit)
|
||||
{
|
||||
if (_jit->prepare) {
|
||||
assert(!_jit->function->call.call & jit_call_varargs);
|
||||
_jit->function->call.call |= jit_call_varargs;
|
||||
}
|
||||
else {
|
||||
assert(!_jit->function->self.call & jit_call_varargs);
|
||||
_jit->function->self.call |= jit_call_varargs;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue