mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-16 00:30:21 +02:00
Add new test case to check stack integrity on complex stack frames.
* check/stack.ok, check/stack.tst: New files to test data integrity on a deep chain of stack frames. * lib/jit_arm.c, lib/jit_arm-cpu.c, lib/jit_mips.c, lib/jit_mips-cpu.c, lib/jit_ppc.c, lib/jit_ppc-cpu.c, lib/jit_x86.c, lib/jit_x86-cpu.c: Calculate _jit->function->stack in the emit stage, otherwise it will calculate it wrong if need to jit_allocai space to spill registers. * lib/lightning.c: Correct wrong offset when updating the "current" jit function pointer in the code that may need to allocate stack space to spill registers. * check/lightning.c: Correct off by one data space check. * check/Makefile.am: Update for new test case.
This commit is contained in:
parent
b43ea1f908
commit
a74318a1d7
14 changed files with 387 additions and 29 deletions
19
ChangeLog
19
ChangeLog
|
@ -1,3 +1,22 @@
|
||||||
|
2012-12-18 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
|
* check/stack.ok, check/stack.tst: New files to test data
|
||||||
|
integrity on a deep chain of stack frames.
|
||||||
|
|
||||||
|
* lib/jit_arm.c, lib/jit_arm-cpu.c, lib/jit_mips.c,
|
||||||
|
lib/jit_mips-cpu.c, lib/jit_ppc.c, lib/jit_ppc-cpu.c,
|
||||||
|
lib/jit_x86.c, lib/jit_x86-cpu.c: Calculate _jit->function->stack
|
||||||
|
in the emit stage, otherwise it will calculate it wrong if
|
||||||
|
need to jit_allocai space to spill registers.
|
||||||
|
|
||||||
|
* lib/lightning.c: Correct wrong offset when updating the
|
||||||
|
"current" jit function pointer in the code that may need to
|
||||||
|
allocate stack space to spill registers.
|
||||||
|
|
||||||
|
* check/lightning.c: Correct off by one data space check.
|
||||||
|
|
||||||
|
* check/Makefile.am: Update for new test case.
|
||||||
|
|
||||||
2012-12-17 Paulo Andrade <pcpa@gnu.org>
|
2012-12-17 Paulo Andrade <pcpa@gnu.org>
|
||||||
|
|
||||||
* check/fop_abs.ok, check/fop_abs.tst, check/fop_sqrt.ok,
|
* check/fop_abs.ok, check/fop_abs.tst, check/fop_sqrt.ok,
|
||||||
|
|
|
@ -60,6 +60,7 @@ EXTRA_DIST = \
|
||||||
fop_abs.tst fop_abs.ok \
|
fop_abs.tst fop_abs.ok \
|
||||||
fop_sqrt.tst fop_sqrt.ok \
|
fop_sqrt.tst fop_sqrt.ok \
|
||||||
varargs.tst varargs.ok \
|
varargs.tst varargs.ok \
|
||||||
|
stack.tst stack.ok \
|
||||||
check.sh \
|
check.sh \
|
||||||
check.x87.sh \
|
check.x87.sh \
|
||||||
check.arm.sh check.swf.sh \
|
check.arm.sh check.swf.sh \
|
||||||
|
@ -79,7 +80,7 @@ base_TESTS = \
|
||||||
alu_lsh alu_rsh \
|
alu_lsh alu_rsh \
|
||||||
alu_com alu_neg \
|
alu_com alu_neg \
|
||||||
fop_abs fop_sqrt \
|
fop_abs fop_sqrt \
|
||||||
varargs
|
varargs stack
|
||||||
|
|
||||||
$(base_TESTS): check.sh
|
$(base_TESTS): check.sh
|
||||||
$(LN_S) $(srcdir)/check.sh $@
|
$(LN_S) $(srcdir)/check.sh $@
|
||||||
|
|
|
@ -37,7 +37,7 @@
|
||||||
|
|
||||||
#define check_data(length) \
|
#define check_data(length) \
|
||||||
do { \
|
do { \
|
||||||
if (data_offset + length >= data_length) \
|
if (data_offset + length > data_length) \
|
||||||
error(".data too small (%ld < %ld)", \
|
error(".data too small (%ld < %ld)", \
|
||||||
data_length, data_offset + length); \
|
data_length, data_offset + length); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
1
check/stack.ok
Normal file
1
check/stack.ok
Normal file
|
@ -0,0 +1 @@
|
||||||
|
ok
|
326
check/stack.tst
Normal file
326
check/stack.tst
Normal file
|
@ -0,0 +1,326 @@
|
||||||
|
#define szof_c 1
|
||||||
|
#define szof_uc szof_c
|
||||||
|
#define szof_s 2
|
||||||
|
#define szof_us szof_s
|
||||||
|
#define szof_i 4
|
||||||
|
#if __WORDSIZE == 64
|
||||||
|
# define szof_ui szof_i
|
||||||
|
# define szof_l 8
|
||||||
|
#endif
|
||||||
|
#define szof_f 4
|
||||||
|
#define szof_d 8
|
||||||
|
|
||||||
|
#define FILL(T) \
|
||||||
|
fill##T: \
|
||||||
|
prolog \
|
||||||
|
arg $argp \
|
||||||
|
getarg %v0 $argp \
|
||||||
|
arg $argi \
|
||||||
|
getarg %r0 $argi \
|
||||||
|
muli %r0 %r0 szof##T \
|
||||||
|
addr %v1 %v0 %r0 \
|
||||||
|
movi %r0 0 \
|
||||||
|
fill##T##loop: \
|
||||||
|
bger fill##T##done %v0 %v1 \
|
||||||
|
str##T %v0 %r0 \
|
||||||
|
addi %r0 %r0 1 \
|
||||||
|
addi %v0 %v0 szof##T \
|
||||||
|
jmpi fill##T##loop \
|
||||||
|
fill##T##done: \
|
||||||
|
ret \
|
||||||
|
epilog
|
||||||
|
#define FILLF(T) \
|
||||||
|
fill##T: \
|
||||||
|
prolog \
|
||||||
|
arg $argp \
|
||||||
|
getarg %v0 $argp \
|
||||||
|
arg $argi \
|
||||||
|
getarg %r0 $argi \
|
||||||
|
muli %r0 %r0 szof##T \
|
||||||
|
addr %v1 %v0 %r0 \
|
||||||
|
movi##T %f0 0.0 \
|
||||||
|
fill##T##loop: \
|
||||||
|
bger fill##T##done %v0 %v1 \
|
||||||
|
str##T %v0 %f0 \
|
||||||
|
addi##T %f0 %f0 1.0 \
|
||||||
|
addi %v0 %v0 szof##T \
|
||||||
|
jmpi fill##T##loop \
|
||||||
|
fill##T##done: \
|
||||||
|
ret \
|
||||||
|
epilog
|
||||||
|
|
||||||
|
#define fill_uc fill_c
|
||||||
|
#define fill_us fill_s
|
||||||
|
#define fill_ui fill_i
|
||||||
|
|
||||||
|
#define ARG( T, N) arg $arg##T##N
|
||||||
|
#define ARGF( T, N) arg##T $arg##T##N
|
||||||
|
#define ARG1( K, T) ARG##K(T, 0)
|
||||||
|
#define ARG2( K, T) ARG1( K, T) ARG##K(T, 1)
|
||||||
|
#define ARG3( K, T) ARG2( K, T) ARG##K(T, 2)
|
||||||
|
#define ARG4( K, T) ARG3( K, T) ARG##K(T, 3)
|
||||||
|
#define ARG5( K, T) ARG4( K, T) ARG##K(T, 4)
|
||||||
|
#define ARG6( K, T) ARG5( K, T) ARG##K(T, 5)
|
||||||
|
#define ARG7( K, T) ARG6( K, T) ARG##K(T, 6)
|
||||||
|
#define ARG8( K, T) ARG7( K, T) ARG##K(T, 7)
|
||||||
|
#define ARG9( K, T) ARG8( K, T) ARG##K(T, 8)
|
||||||
|
#define ARG10(K, T) ARG9( K, T) ARG##K(T, 9)
|
||||||
|
#define ARG11(K, T) ARG10(K, T) ARG##K(T, 10)
|
||||||
|
#define ARG12(K, T) ARG11(K, T) ARG##K(T, 11)
|
||||||
|
#define ARG13(K, T) ARG12(K, T) ARG##K(T, 12)
|
||||||
|
#define ARG14(K, T) ARG13(K, T) ARG##K(T, 13)
|
||||||
|
#define ARG15(K, T) ARG14(K, T) ARG##K(T, 14)
|
||||||
|
#define ARG16(K, T) ARG15(K, T) ARG##K(T, 15)
|
||||||
|
#define ARG_c(N) ARG##N( , _c)
|
||||||
|
#define ARG_uc(N) ARG##N( , _uc)
|
||||||
|
#define ARG_s(N) ARG##N( , _s)
|
||||||
|
#define ARG_us(N) ARG##N( , _us)
|
||||||
|
#define ARG_i(N) ARG##N( , _i)
|
||||||
|
#define ARG_ui(N) ARG##N( , _ui)
|
||||||
|
#define ARG_l(N) ARG##N( , _l)
|
||||||
|
#define ARG_f(N) ARG##N(F, _f)
|
||||||
|
#define ARG_d(N) ARG##N(F, _d)
|
||||||
|
|
||||||
|
#define CHK(N, T, V) \
|
||||||
|
getarg %r0 $arg##T##V \
|
||||||
|
ldxi##T %r1 %v0 $(V * szof##T) \
|
||||||
|
beqr N##T##V %r0 %r1 \
|
||||||
|
calli @abort \
|
||||||
|
N##T##V:
|
||||||
|
#define CHKF(N, T, V) \
|
||||||
|
getarg##T %f0 $arg##T##V \
|
||||||
|
ldxi##T %f1 %v0 $(V * szof##T) \
|
||||||
|
beqr##T N##T##V %f0 %f1 \
|
||||||
|
calli @abort \
|
||||||
|
N##T##V:
|
||||||
|
|
||||||
|
#define GET1( K, N, T, V) CHK##K(N, T, 0)
|
||||||
|
#define GET2( K, N, T, V) GET1( K, N, T, V) CHK##K(N, T, 1)
|
||||||
|
#define GET3( K, N, T, V) GET2( K, N, T, V) CHK##K(N, T, 2)
|
||||||
|
#define GET4( K, N, T, V) GET3( K, N, T, V) CHK##K(N, T, 3)
|
||||||
|
#define GET5( K, N, T, V) GET4( K, N, T, V) CHK##K(N, T, 4)
|
||||||
|
#define GET6( K, N, T, V) GET5( K, N, T, V) CHK##K(N, T, 5)
|
||||||
|
#define GET7( K, N, T, V) GET6( K, N, T, V) CHK##K(N, T, 6)
|
||||||
|
#define GET8( K, N, T, V) GET7( K, N, T, V) CHK##K(N, T, 7)
|
||||||
|
#define GET9( K, N, T, V) GET8( K, N, T, V) CHK##K(N, T, 8)
|
||||||
|
#define GET10(K, N, T, V) GET9( K, N, T, V) CHK##K(N, T, 9)
|
||||||
|
#define GET11(K, N, T, V) GET10(K, N, T, V) CHK##K(N, T, 10)
|
||||||
|
#define GET12(K, N, T, V) GET11(K, N, T, V) CHK##K(N, T, 11)
|
||||||
|
#define GET13(K, N, T, V) GET12(K, N, T, V) CHK##K(N, T, 12)
|
||||||
|
#define GET14(K, N, T, V) GET13(K, N, T, V) CHK##K(N, T, 13)
|
||||||
|
#define GET15(K, N, T, V) GET14(K, N, T, V) CHK##K(N, T, 14)
|
||||||
|
#define GET16(K, N, T, V) GET15(K, N, T, V) CHK##K(N, T, 15)
|
||||||
|
|
||||||
|
#define GET_c(N, M) GET##N( , c##N, _c, M)
|
||||||
|
#define GET_uc(N, M) GET##N( , uc##N, _uc, M)
|
||||||
|
#define GET_s(N, M) GET##N( , s##N, _s, M)
|
||||||
|
#define GET_us(N, M) GET##N( , us##N, _us, M)
|
||||||
|
#define GET_i(N, M) GET##N( , i##N, _i, M)
|
||||||
|
#define GET_ui(N, M) GET##N( , ui##N, _ui, M)
|
||||||
|
#define GET_l(N, M) GET##N( , l##N, _l, M)
|
||||||
|
#define GET_f(N, M) GET##N(F, f##N, _f, M)
|
||||||
|
#define GET_d(N, M) GET##N(F, d##N, _d, M)
|
||||||
|
|
||||||
|
#define PUSH( T, V) pushargi V
|
||||||
|
#define PUSHF( T, V) pushargi##T V
|
||||||
|
#define PUSH0( K, T) /**/
|
||||||
|
#define PUSH1( K, T) PUSH##K(T, 0)
|
||||||
|
#define PUSH2( K, T) PUSH1( K, T) PUSH##K(T, 1)
|
||||||
|
#define PUSH3( K, T) PUSH2( K, T) PUSH##K(T, 2)
|
||||||
|
#define PUSH4( K, T) PUSH3( K, T) PUSH##K(T, 3)
|
||||||
|
#define PUSH5( K, T) PUSH4( K, T) PUSH##K(T, 4)
|
||||||
|
#define PUSH6( K, T) PUSH5( K, T) PUSH##K(T, 5)
|
||||||
|
#define PUSH7( K, T) PUSH6( K, T) PUSH##K(T, 6)
|
||||||
|
#define PUSH8( K, T) PUSH7( K, T) PUSH##K(T, 7)
|
||||||
|
#define PUSH9( K, T) PUSH8( K, T) PUSH##K(T, 8)
|
||||||
|
#define PUSH10(K, T) PUSH9( K, T) PUSH##K(T, 9)
|
||||||
|
#define PUSH11(K, T) PUSH10(K, T) PUSH##K(T, 10)
|
||||||
|
#define PUSH12(K, T) PUSH11(K, T) PUSH##K(T, 11)
|
||||||
|
#define PUSH13(K, T) PUSH12(K, T) PUSH##K(T, 12)
|
||||||
|
#define PUSH14(K, T) PUSH13(K, T) PUSH##K(T, 13)
|
||||||
|
#define PUSH15(K, T) PUSH14(K, T) PUSH##K(T, 14)
|
||||||
|
#define PUSH16(K, T) PUSH15(K, T) PUSH##K(T, 15)
|
||||||
|
|
||||||
|
#define PUSH_c( N) PUSH##N( , _c)
|
||||||
|
#define PUSH_uc(N) PUSH##N( , _uc)
|
||||||
|
#define PUSH_s( N) PUSH##N( , _s)
|
||||||
|
#define PUSH_us(N) PUSH##N( , _us)
|
||||||
|
#define PUSH_i( N) PUSH##N( , _i)
|
||||||
|
#define PUSH_ui(N) PUSH##N( , _ui)
|
||||||
|
#define PUSH_l( N) PUSH##N( , _l)
|
||||||
|
#define PUSH_f( N) PUSH##N(F, _f)
|
||||||
|
#define PUSH_d( N) PUSH##N(F, _d)
|
||||||
|
|
||||||
|
/* bottom function */
|
||||||
|
#define DEF0(T) \
|
||||||
|
test##T##_0: \
|
||||||
|
prolog \
|
||||||
|
ret \
|
||||||
|
epilog
|
||||||
|
|
||||||
|
#define DEFN(N, M, T) \
|
||||||
|
test##T##_##N: \
|
||||||
|
prolog \
|
||||||
|
arg $argp \
|
||||||
|
/* stack buffer in %v0 */ \
|
||||||
|
getarg %v0 $argp \
|
||||||
|
ARG##T(N) \
|
||||||
|
/* validate arguments */ \
|
||||||
|
GET##T(N, M) \
|
||||||
|
/* heap buffer in %v1 */ \
|
||||||
|
prepare \
|
||||||
|
pushargi $(N * szof##T) \
|
||||||
|
finishi @malloc \
|
||||||
|
retval %v1 \
|
||||||
|
/* copy stack bufer to heap buffer */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v1 \
|
||||||
|
pushargr %v0 \
|
||||||
|
pushargi $(N * szof##T) \
|
||||||
|
finishi @memcpy \
|
||||||
|
/* stack buffer for next function in %v2 */ \
|
||||||
|
allocai $(M * szof##T) $index \
|
||||||
|
addi %v2 %fp $index \
|
||||||
|
/* fill stack buffer for next function */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v2 \
|
||||||
|
pushargi M \
|
||||||
|
finishi fill##T \
|
||||||
|
/* call next function */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v2 \
|
||||||
|
PUSH##T(M) \
|
||||||
|
finishi test##T##_##M \
|
||||||
|
/* validate stack buffer */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v1 \
|
||||||
|
pushargr %v0 \
|
||||||
|
pushargi $(N * szof##T) \
|
||||||
|
finishi @memcmp \
|
||||||
|
retval %r0 \
|
||||||
|
beqi test##T##_##N##_done %r0 0 \
|
||||||
|
calli @abort \
|
||||||
|
test##T##_##N##_done: \
|
||||||
|
/* release heap bufer */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v1 \
|
||||||
|
finishi @free \
|
||||||
|
ret \
|
||||||
|
epilog
|
||||||
|
|
||||||
|
/* top function */
|
||||||
|
#define DEFX(T) \
|
||||||
|
test##T##_17: \
|
||||||
|
prolog \
|
||||||
|
/* heap buffer in %v1 */ \
|
||||||
|
prepare \
|
||||||
|
pushargi $(16 * szof##T) \
|
||||||
|
finishi @malloc \
|
||||||
|
retval %v1 \
|
||||||
|
/* stack buffer for next function in %v2 */ \
|
||||||
|
allocai $(16 * szof##T) $index \
|
||||||
|
addi %v2 %fp $index \
|
||||||
|
/* fill stack buffer for next function */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v2 \
|
||||||
|
pushargi 16 \
|
||||||
|
finishi fill##T \
|
||||||
|
/* copy stack buffer to heap buffer */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v1 \
|
||||||
|
pushargr %v2 \
|
||||||
|
pushargi $(16 * szof##T) \
|
||||||
|
finishi @memcpy \
|
||||||
|
/* call next function */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v2 \
|
||||||
|
PUSH##T(16) \
|
||||||
|
finishi test##T##_16 \
|
||||||
|
/* validate stack buffer */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v1 \
|
||||||
|
pushargr %v2 \
|
||||||
|
pushargi $(16 * szof##T) \
|
||||||
|
finishi @memcmp \
|
||||||
|
retval %r0 \
|
||||||
|
beqi test##T##_17_done %r0 0 \
|
||||||
|
calli @abort \
|
||||||
|
test##T##_17_done: \
|
||||||
|
/* release heap bufer */ \
|
||||||
|
prepare \
|
||||||
|
pushargr %v1 \
|
||||||
|
finishi @free \
|
||||||
|
ret \
|
||||||
|
epilog
|
||||||
|
|
||||||
|
#define DEF( T) \
|
||||||
|
DEF0( T) \
|
||||||
|
DEFN( 1, 0, T) \
|
||||||
|
DEFN( 2, 1, T) \
|
||||||
|
DEFN( 3, 2, T) \
|
||||||
|
DEFN( 4, 3, T) \
|
||||||
|
DEFN( 5, 4, T) \
|
||||||
|
DEFN( 6, 5, T) \
|
||||||
|
DEFN( 7, 6, T) \
|
||||||
|
DEFN( 8, 7, T) \
|
||||||
|
DEFN( 9, 8, T) \
|
||||||
|
DEFN(10, 9, T) \
|
||||||
|
DEFN(11, 10, T) \
|
||||||
|
DEFN(12, 11, T) \
|
||||||
|
DEFN(13, 12, T) \
|
||||||
|
DEFN(14, 13, T) \
|
||||||
|
DEFN(15, 14, T) \
|
||||||
|
DEFN(16, 15, T) \
|
||||||
|
DEFX(T)
|
||||||
|
|
||||||
|
#define CALL(T) calli test##T##_17
|
||||||
|
|
||||||
|
.data 16
|
||||||
|
ok:
|
||||||
|
.c "ok\n"
|
||||||
|
.code
|
||||||
|
jmpi main
|
||||||
|
|
||||||
|
FILL(_c)
|
||||||
|
FILL(_s)
|
||||||
|
FILL(_i)
|
||||||
|
#if __WORDSIZE == 64
|
||||||
|
FILL(_l)
|
||||||
|
#endif
|
||||||
|
FILLF(_f)
|
||||||
|
FILLF(_d)
|
||||||
|
|
||||||
|
DEF(_c)
|
||||||
|
DEF(_uc)
|
||||||
|
DEF(_s)
|
||||||
|
DEF(_us)
|
||||||
|
DEF(_i)
|
||||||
|
#if __WORDSIZE == 64
|
||||||
|
DEF(_ui)
|
||||||
|
DEF(_l)
|
||||||
|
#endif
|
||||||
|
DEF(_f)
|
||||||
|
DEF(_d)
|
||||||
|
|
||||||
|
main:
|
||||||
|
prolog
|
||||||
|
|
||||||
|
CALL(_c)
|
||||||
|
CALL(_uc)
|
||||||
|
CALL(_s)
|
||||||
|
CALL(_us)
|
||||||
|
CALL(_i)
|
||||||
|
#if __WORDSIZE == 64
|
||||||
|
CALL(_ui)
|
||||||
|
CALL(_l)
|
||||||
|
#endif
|
||||||
|
CALL(_f)
|
||||||
|
CALL(_d)
|
||||||
|
|
||||||
|
prepare
|
||||||
|
pushargi ok
|
||||||
|
ellipsis
|
||||||
|
finishi @printf
|
||||||
|
|
||||||
|
ret
|
||||||
|
epilog
|
|
@ -3564,6 +3564,10 @@ _calli_p(jit_state_t *_jit, jit_word_t i0)
|
||||||
static void
|
static void
|
||||||
_prolog(jit_state_t *_jit, jit_node_t *node)
|
_prolog(jit_state_t *_jit, jit_node_t *node)
|
||||||
{
|
{
|
||||||
|
_jit->function->stack = ((_jit->function->self.alen -
|
||||||
|
/* align stack at 8 bytes */
|
||||||
|
_jit->function->self.aoff) + 7) & -8;
|
||||||
|
|
||||||
if (jit_thumb_p()) {
|
if (jit_thumb_p()) {
|
||||||
/* switch to thumb mode (better approach would be to
|
/* switch to thumb mode (better approach would be to
|
||||||
* ORR 1 address being called, but no clear distinction
|
* ORR 1 address being called, but no clear distinction
|
||||||
|
|
|
@ -322,9 +322,6 @@ void
|
||||||
_jit_epilog(jit_state_t *_jit)
|
_jit_epilog(jit_state_t *_jit)
|
||||||
{
|
{
|
||||||
assert(_jit->function);
|
assert(_jit->function);
|
||||||
_jit->function->stack = ((_jit->function->self.alen -
|
|
||||||
/* align stack at 8 bytes */
|
|
||||||
_jit->function->self.aoff) + 7) & -8;
|
|
||||||
assert(_jit->function->epilog->next == NULL);
|
assert(_jit->function->epilog->next == NULL);
|
||||||
jit_link(_jit->function->epilog);
|
jit_link(_jit->function->epilog);
|
||||||
_jit->function = NULL;
|
_jit->function = NULL;
|
||||||
|
|
|
@ -2697,6 +2697,11 @@ _calli(jit_state_t *_jit, jit_word_t i0)
|
||||||
static void
|
static void
|
||||||
_prolog(jit_state_t *_jit, jit_node_t *node)
|
_prolog(jit_state_t *_jit, jit_node_t *node)
|
||||||
{
|
{
|
||||||
|
_jit->function->stack = ((/* first 16 bytes must be allocated */
|
||||||
|
(_jit->function->self.alen > 16 ?
|
||||||
|
_jit->function->self.alen : 16) -
|
||||||
|
/* align stack at 8 bytes */
|
||||||
|
_jit->function->self.aoff) + 7) & -8;
|
||||||
/* callee save registers */
|
/* callee save registers */
|
||||||
subi(_SP_REGNO, _SP_REGNO, stack_framesize);
|
subi(_SP_REGNO, _SP_REGNO, stack_framesize);
|
||||||
#if __WORDSIZE == 32
|
#if __WORDSIZE == 32
|
||||||
|
|
|
@ -224,12 +224,6 @@ void
|
||||||
_jit_epilog(jit_state_t *_jit)
|
_jit_epilog(jit_state_t *_jit)
|
||||||
{
|
{
|
||||||
assert(_jit->function);
|
assert(_jit->function);
|
||||||
|
|
||||||
_jit->function->stack = ((/* first 16 bytes must be allocated */
|
|
||||||
(_jit->function->self.alen > 16 ?
|
|
||||||
_jit->function->self.alen : 16) -
|
|
||||||
/* align stack at 8 bytes */
|
|
||||||
_jit->function->self.aoff) + 7) & -8;
|
|
||||||
assert(_jit->function->epilog->next == NULL);
|
assert(_jit->function->epilog->next == NULL);
|
||||||
jit_link(_jit->function->epilog);
|
jit_link(_jit->function->epilog);
|
||||||
_jit->function = NULL;
|
_jit->function = NULL;
|
||||||
|
@ -266,13 +260,20 @@ _jit_arg_f(jit_state_t *_jit)
|
||||||
|
|
||||||
assert(_jit->function);
|
assert(_jit->function);
|
||||||
offset = (_jit->function->self.size - stack_framesize) >> 2;
|
offset = (_jit->function->self.size - stack_framesize) >> 2;
|
||||||
if (offset < 4) {
|
if (offset < 3) {
|
||||||
if (!_jit->function->self.argi) {
|
if (!_jit->function->self.argi) {
|
||||||
offset += 4;
|
offset += 4;
|
||||||
_jit->function->self.argf += 2;
|
_jit->function->self.argf += 2;
|
||||||
|
assert(!(offset & 1));
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
_jit->function->self.argi += 2;
|
_jit->function->self.argi += 2;
|
||||||
|
if (offset & 1) {
|
||||||
|
++_jit->function->self.argi;
|
||||||
|
++offset;
|
||||||
|
_jit->function->self.size += sizeof(jit_float32_t);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
offset = _jit->function->self.size;
|
offset = _jit->function->self.size;
|
||||||
|
@ -395,7 +396,7 @@ void
|
||||||
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
|
_jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
|
||||||
{
|
{
|
||||||
if (v < 4)
|
if (v < 4)
|
||||||
jit_new_node_ww(jit_code_getarg_f, u, _A0 - (v >> 1));
|
jit_new_node_ww(jit_code_getarg_f, u, _A0 - v);
|
||||||
else if (v < 8)
|
else if (v < 8)
|
||||||
jit_movr_f(u, _F12 - ((v - 4) >> 1));
|
jit_movr_f(u, _F12 - ((v - 4) >> 1));
|
||||||
else
|
else
|
||||||
|
@ -406,7 +407,7 @@ void
|
||||||
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
|
_jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
|
||||||
{
|
{
|
||||||
if (v < 4)
|
if (v < 4)
|
||||||
jit_new_node_ww(jit_code_getarg_d, u, _A0 - (v >> 1));
|
jit_new_node_ww(jit_code_getarg_d, u, _A0 - v);
|
||||||
else if (v < 8)
|
else if (v < 8)
|
||||||
jit_movr_d(u, _F12 - ((v - 4) >> 1));
|
jit_movr_d(u, _F12 - ((v - 4) >> 1));
|
||||||
else
|
else
|
||||||
|
|
|
@ -2363,6 +2363,9 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
|
||||||
{
|
{
|
||||||
unsigned long regno;
|
unsigned long regno;
|
||||||
|
|
||||||
|
_jit->function->stack = ((_jit->function->self.alen -
|
||||||
|
_jit->function->self.aoff) + 15) & -16;
|
||||||
|
|
||||||
/* return address */
|
/* return address */
|
||||||
MFLR(_R0_REGNO);
|
MFLR(_R0_REGNO);
|
||||||
|
|
||||||
|
|
|
@ -230,8 +230,6 @@ void
|
||||||
_jit_epilog(jit_state_t *_jit)
|
_jit_epilog(jit_state_t *_jit)
|
||||||
{
|
{
|
||||||
assert(_jit->function);
|
assert(_jit->function);
|
||||||
_jit->function->stack = ((_jit->function->self.alen -
|
|
||||||
_jit->function->self.aoff) + 15) & -16;
|
|
||||||
assert(_jit->function->epilog->next == NULL);
|
assert(_jit->function->epilog->next == NULL);
|
||||||
jit_link(_jit->function->epilog);
|
jit_link(_jit->function->epilog);
|
||||||
_jit->function = NULL;
|
_jit->function = NULL;
|
||||||
|
|
|
@ -20,8 +20,6 @@
|
||||||
|
|
||||||
#if PROTO
|
#if PROTO
|
||||||
# if __WORDSIZE == 32
|
# if __WORDSIZE == 32
|
||||||
# define stack_alignment 4
|
|
||||||
# define stack_framesize 20
|
|
||||||
# define ldi(u, v) ldi_i(u, v)
|
# define ldi(u, v) ldi_i(u, v)
|
||||||
# define ldxi(u, v, w) ldxi_i(u, v, w)
|
# define ldxi(u, v, w) ldxi_i(u, v, w)
|
||||||
# define sti(u, v) sti_i(u, v)
|
# define sti(u, v) sti_i(u, v)
|
||||||
|
@ -32,8 +30,6 @@
|
||||||
# define reg8_p(rn) \
|
# define reg8_p(rn) \
|
||||||
((rn) >= _RAX_REGNO && (rn) <= _RBX_REGNO)
|
((rn) >= _RAX_REGNO && (rn) <= _RBX_REGNO)
|
||||||
# else
|
# else
|
||||||
# define stack_alignment 8
|
|
||||||
# define stack_framesize 56
|
|
||||||
# define ldi(u, v) ldi_l(u, v)
|
# define ldi(u, v) ldi_l(u, v)
|
||||||
# define ldxi(u, v, w) ldxi_l(u, v, w)
|
# define ldxi(u, v, w) ldxi_l(u, v, w)
|
||||||
# define sti(u, v) sti_l(u, v)
|
# define sti(u, v) sti_l(u, v)
|
||||||
|
@ -3070,6 +3066,14 @@ _jmpi(jit_state_t *_jit, jit_word_t i0)
|
||||||
static void
|
static void
|
||||||
_prolog(jit_state_t *_jit, jit_node_t *node)
|
_prolog(jit_state_t *_jit, jit_node_t *node)
|
||||||
{
|
{
|
||||||
|
#if __WORDSIZE == 32
|
||||||
|
_jit->function->stack = (((_jit->function->self.alen -
|
||||||
|
_jit->function->self.aoff) + 15) & -16) + 12;
|
||||||
|
#else
|
||||||
|
_jit->function->stack = (((_jit->function->self.alen -
|
||||||
|
_jit->function->self.aoff) + 15) & -16) + 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
/* callee save registers */
|
/* callee save registers */
|
||||||
subi(_RSP_REGNO, _RSP_REGNO, stack_framesize - sizeof(jit_word_t));
|
subi(_RSP_REGNO, _RSP_REGNO, stack_framesize - sizeof(jit_word_t));
|
||||||
#if __WORDSIZE == 32
|
#if __WORDSIZE == 32
|
||||||
|
|
|
@ -268,8 +268,10 @@ jit_get_cpu(void)
|
||||||
void
|
void
|
||||||
_jit_init(jit_state_t *_jit)
|
_jit_init(jit_state_t *_jit)
|
||||||
{
|
{
|
||||||
|
#if __WORDSIZE == 32
|
||||||
jit_int32_t regno;
|
jit_int32_t regno;
|
||||||
static jit_bool_t first = 1;
|
static jit_bool_t first = 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
_jit->reglen = jit_size(_rvs) - 1;
|
_jit->reglen = jit_size(_rvs) - 1;
|
||||||
#if __WORDSIZE == 32
|
#if __WORDSIZE == 32
|
||||||
|
@ -400,13 +402,6 @@ void
|
||||||
_jit_epilog(jit_state_t *_jit)
|
_jit_epilog(jit_state_t *_jit)
|
||||||
{
|
{
|
||||||
assert(_jit->function);
|
assert(_jit->function);
|
||||||
#if __WORDSIZE == 32
|
|
||||||
_jit->function->stack = (((_jit->function->self.alen -
|
|
||||||
_jit->function->self.aoff) + 15) & -16) + 12;
|
|
||||||
#else
|
|
||||||
_jit->function->stack = (((_jit->function->self.alen -
|
|
||||||
_jit->function->self.aoff) + 15) & -16) + 8;
|
|
||||||
#endif
|
|
||||||
assert(_jit->function->epilog->next == NULL);
|
assert(_jit->function->epilog->next == NULL);
|
||||||
jit_link(_jit->function->epilog);
|
jit_link(_jit->function->epilog);
|
||||||
_jit->function = NULL;
|
_jit->function = NULL;
|
||||||
|
@ -448,7 +443,11 @@ _jit_arg_f(jit_state_t *_jit)
|
||||||
return (_jit->function->self.argf++);
|
return (_jit->function->self.argf++);
|
||||||
#endif
|
#endif
|
||||||
offset = _jit->function->self.size;
|
offset = _jit->function->self.size;
|
||||||
|
#if __WORDSIZE == 32
|
||||||
_jit->function->self.size += sizeof(jit_float32_t);
|
_jit->function->self.size += sizeof(jit_float32_t);
|
||||||
|
#else
|
||||||
|
_jit->function->self.size += sizeof(jit_float64_t);
|
||||||
|
#endif
|
||||||
return (offset);
|
return (offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2298,7 +2298,7 @@ _patch_registers(jit_state_t *_jit)
|
||||||
node->link = NULL;
|
node->link = NULL;
|
||||||
break;
|
break;
|
||||||
case jit_code_prolog:
|
case jit_code_prolog:
|
||||||
_jit->function = _jit->functions.ptr + node->u.w;
|
_jit->function = _jit->functions.ptr + node->w.w;
|
||||||
break;
|
break;
|
||||||
case jit_code_epilog:
|
case jit_code_epilog:
|
||||||
_jit->function = NULL;
|
_jit->function = NULL;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue