1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-20 10:40:19 +02:00

Add new varargs test and correct related test case failures in all ports.

This commit is contained in:
pcpa 2012-12-13 18:26:57 -02:00
parent 0b89a17ca2
commit 6227bf5bf9
9 changed files with 430 additions and 81 deletions

View file

@ -1,3 +1,24 @@
2012-12-13 Paulo Andrade <pcpa@gnu.org>
* check/varargs.ok, check/varargs.tst: New test cases implementing
simple varargs calls with a large amount of arguments to exercise
excess arguments on stack.
* include/lightning.h: Include config.h if HAVE_CONFIG_H is
defined.
* lib/jit_arm.c: Allocate a fpr register, not a gpr one for
temporary when pushing varargs arguments in the stack.
* lib/jit_arm-swf.c: Correct code changing the wrong offset
in jit_absr_d and jit_negr_d in software float.
* lib/jit_mips.c: Correct calculation of offsets of arguments
on stack.
* lib/jit_ppc.c: Correct bogus logic for "next" offset of arguments
on stack and adjust for fixed offset of stack arguments.
2012-12-12 Paulo Andrade <pcpa@gnu.org> 2012-12-12 Paulo Andrade <pcpa@gnu.org>
* include/lightning.h, lib/jit_arm.c, lib/jit_mips.c, * include/lightning.h, lib/jit_arm.c, lib/jit_mips.c,

View file

@ -57,6 +57,7 @@ EXTRA_DIST = \
alu_rsh.tst alu_rsh.ok \ alu_rsh.tst alu_rsh.ok \
alu_com.tst alu_com.ok \ alu_com.tst alu_com.ok \
alu_neg.tst alu_neg.ok \ alu_neg.tst alu_neg.ok \
varargs.tst varargs.ok \
check.sh run-test \ check.sh run-test \
all.tst all.tst
@ -71,7 +72,8 @@ TESTS = 3to2 add allocai \
alu_mul alu_div alu_rem \ alu_mul alu_div alu_rem \
alu_and alu_or alu_xor \ alu_and alu_or alu_xor \
alu_lsh alu_rsh \ alu_lsh alu_rsh \
alu_com alu_neg alu_com alu_neg \
varargs
CLEANFILES = $(TESTS) CLEANFILES = $(TESTS)

3
check/varargs.ok Normal file
View file

@ -0,0 +1,3 @@
0 1 2 3 4 5 6 7 8 9
0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
0 0.0 1 1.0 2 2.0 3 3.0 4 4.0 5 5.0 6 6.0 7 7.0 8 8.0 9 9.0

283
check/varargs.tst Normal file
View file

@ -0,0 +1,283 @@
.data 1024
ifmt:
.c "%d %d %d %d %d %d %d %d %d %d\n"
.align 4
ichk:
.i 9 8 7 6 5 4 3 2 1 0
dfmt:
.c "%.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f %.1f\n"
lfmt:
.c "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n"
dchk:
.align 8
.d 9.0 8.0 7.0 6.0 5.0 4.0 3.0 2.0 1.0 0.0
idfmt:
.c "%d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f %d %.1f\n"
ldfmt:
.c "%d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf %d %lf\n"
buff:
.align 4
.size 256
.code
jmpi main
main:
prolog
/*
sprintf(buff, "%d %d %d %d %d %d %d %d %d %d\n",
0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
*/
prepare
pushargi buff
pushargi ifmt
ellipsis
pushargi 0
pushargi 1
pushargi 2
pushargi 3
pushargi 4
pushargi 5
pushargi 6
pushargi 7
pushargi 8
pushargi 9
finishi @sprintf
/*
sscanf(buff, "%d %d %d %d %d %d %d %d %d %d\n",
ichk+0, ichk+1, ichk+2, ichk+3, ichk+4,
ichk+5, ichk+6, ichk+7, ichk+8, ichk+9);
*/
movi %v0 ichk
prepare
pushargi buff
pushargi ifmt
ellipsis
pushargr %v0 /* 0 */
addi %v0 %v0 4
pushargr %v0 /* 1 */
addi %v0 %v0 4
pushargr %v0 /* 2 */
addi %v0 %v0 4
pushargr %v0 /* 3 */
addi %v0 %v0 4
pushargr %v0 /* 4 */
addi %v0 %v0 4
pushargr %v0 /* 5 */
addi %v0 %v0 4
pushargr %v0 /* 6 */
addi %v0 %v0 4
pushargr %v0 /* 7 */
addi %v0 %v0 4
pushargr %v0 /* 8 */
addi %v0 %v0 4
pushargr %v0 /* 9 */
finishi @sscanf
movi %v0 ichk
movi %r0 0
loopi:
ldr_i %r1 %v0
beqr nexti %r0 %r1
calli @abort
nexti:
addi %r0 %r0 1
bgei outi %r0 10
addi %v0 %v0 4
jmpi loopi
outi:
prepare
pushargi buff
ellipsis
finishi @printf
/*
sprintf(buff,
"%.1f %.1f %.1f %.1f %.1f "
"%.1f %.1f %.1f %.1f %.1f\n",
0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0);
*/
prepare
pushargi buff
pushargi dfmt
ellipsis
pushargi_d 0.0
pushargi_d 1.0
pushargi_d 2.0
pushargi_d 3.0
pushargi_d 4.0
pushargi_d 5.0
pushargi_d 6.0
pushargi_d 7.0
pushargi_d 8.0
pushargi_d 9.0
finishi @sprintf
/*
sscanf(buff, "%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf\n",
dchk+0, dchk+1, dchk+2, dchk+3, dchk+4,
dchk+5, dchk+6, dchk+7, dchk+8, dchk+9);
*/
movi %v0 dchk
prepare
pushargi buff
pushargi lfmt
ellipsis
pushargr %v0 /* 0 */
addi %v0 %v0 8
pushargr %v0 /* 1 */
addi %v0 %v0 8
pushargr %v0 /* 2 */
addi %v0 %v0 8
pushargr %v0 /* 3 */
addi %v0 %v0 8
pushargr %v0 /* 4 */
addi %v0 %v0 8
pushargr %v0 /* 5 */
addi %v0 %v0 8
pushargr %v0 /* 6 */
addi %v0 %v0 8
pushargr %v0 /* 7 */
addi %v0 %v0 8
pushargr %v0 /* 8 */
addi %v0 %v0 8
pushargr %v0 /* 9 */
finishi @sscanf
movi %v0 dchk
movi_d %f0 0.0
loopd:
ldr_d %f1 %v0
beqr_d nextd %f0 %f1
calli @abort
nextd:
addi_d %f0 %f0 1.0
bgei_d outd %f0 10.0
addi %v0 %v0 8
jmpi loopd
outd:
prepare
pushargi buff
ellipsis
finishi @printf
/*
sprintf(buff,
"%d %.1f %d %.1f %d %.1f %d %.1f %d %.1f "
"%d %.1f %d %.1f %d %.1f %d %.1f %d %.1f\n",
0, 0.0, 1, 1.0, 2, 2.0, 3, 3.0, 4, 4.0,
5, 5.0, 6, 6.0, 7, 7.0, 8, 8.0, 9, 9.0);
*/
prepare
pushargi buff
pushargi idfmt
ellipsis
pushargi 0
pushargi_d 0.0
pushargi 1
pushargi_d 1.0
pushargi 2
pushargi_d 2.0
pushargi 3
pushargi_d 3.0
pushargi 4
pushargi_d 4.0
pushargi 5
pushargi_d 5.0
pushargi 6
pushargi_d 6.0
pushargi 7
pushargi_d 7.0
pushargi 8
pushargi_d 8.0
pushargi 9
pushargi_d 9.0
finishi @sprintf
/*
sscanf(buff,
"%d %lf %d %lf %d %lf %d %lf %d %lf "
"%d %lf %d %lf %d %lf %d %lf %d %lf\n",
ichk+0, dchk+0, ichk+1, dchk+1, ichk+2,
dchk+2, ichk+3, dchk+3, ichk+4, dchk+4,
ichk+5, dchk+5, ichk+6, dchk+6, ichk+7,
dchk+7, ichk+8, dchk+8, ichk+9, dchk+9);
*/
movi %v0 ichk
movi %v1 dchk
prepare
pushargi buff
pushargi ldfmt
ellipsis
pushargr %v0 /* 0 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 1 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 2 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 3 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 4 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 5 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 6 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 7 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 8 */
addi %v0 %v0 4
pushargr %v1
addi %v1 %v1 8
pushargr %v0 /* 9 */
pushargr %v1
finishi @sscanf
movi %v0 ichk
movi %v1 dchk
movi %r0 0
movi_d %f0 0.0
loopid:
ldr_i %r1 %v0
beqr checkd %r0 %r1
calli @abort
checkd:
ldr_d %f1 %v1
beqr_d nextid %f0 %f1
calli @abort
nextid:
addi %r0 %r0 1
addi_d %f0 %f0 1.0
bgei outid %r0 10
addi %v0 %v0 4
addi %v1 %v1 8
jmpi loopid
outid:
prepare
pushargi buff
ellipsis
finishi @printf
ret
epilog

View file

@ -18,6 +18,10 @@
#ifndef _lightning_h #ifndef _lightning_h
#define _lightning_h #define _lightning_h
#if HAVE_CONFIG_H
# include "config.h"
#endif
#include <unistd.h> #include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdint.h> #include <stdint.h>

View file

@ -1740,25 +1740,25 @@ _swf_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
if (jit_fpr_p(r1)) { if (jit_fpr_p(r1)) {
if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() && if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() &&
r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) { r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) {
LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8); LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 4);
swf_bici(rn(reg), rn(reg), 0x80000000); swf_bici(rn(reg), rn(reg), 0x80000000);
STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8); STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 4);
jit_unget_reg_pair(reg); jit_unget_reg_pair(reg);
} }
else { else {
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4);
swf_bici(rn(reg), rn(reg), 0x80000000); swf_bici(rn(reg), rn(reg), 0x80000000);
if (jit_fpr_p(r0)) { if (jit_fpr_p(r0)) {
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
if (r0 != r1) {
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4);
if (r0 != r1) {
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
} }
} }
else { else {
movr(r0, rn(reg)); movr(r0, rn(reg));
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4); swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
movr(r0 + 1, rn(reg)); movr(r0 + 1, rn(reg));
} }
jit_unget_reg(reg); jit_unget_reg(reg);
@ -1768,9 +1768,9 @@ _swf_absr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
movr(rn(reg), r1); movr(rn(reg), r1);
swf_bici(rn(reg), rn(reg), 0x80000000); swf_bici(rn(reg), rn(reg), 0x80000000);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
movr(rn(reg), r1 + 1);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4);
movr(rn(reg), r1 + 1);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
jit_unget_reg(reg); jit_unget_reg(reg);
} }
else { else {
@ -1812,25 +1812,25 @@ _swf_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
if (jit_fpr_p(r1)) { if (jit_fpr_p(r1)) {
if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() && if (jit_fpr_p(r0) && !jit_thumb_p() && jit_armv5e_p() &&
r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) { r0 != r1 && (reg = jit_get_reg_pair()) != JIT_NOREG) {
LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 8); LDRDIN(rn(reg), _FP_REGNO, swf_off(r1) + 4);
EORI(rn(reg), rn(reg), encode_arm_immediate(0x80000000)); EORI(rn(reg), rn(reg), encode_arm_immediate(0x80000000));
STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 8); STRDIN(rn(reg), _FP_REGNO, swf_off(r0) + 4);
jit_unget_reg_pair(reg); jit_unget_reg_pair(reg);
} }
else { else {
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8); swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4);
xori(rn(reg), rn(reg), 0x80000000); xori(rn(reg), rn(reg), 0x80000000);
if (jit_fpr_p(r0)) { if (jit_fpr_p(r0)) {
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
if (r0 != r1) {
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4);
if (r0 != r1) {
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
} }
} }
else { else {
movr(r0, rn(reg)); movr(r0, rn(reg));
swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 4); swf_ldrin(rn(reg), _FP_REGNO, swf_off(r1) + 8);
movr(r0 + 1, rn(reg)); movr(r0 + 1, rn(reg));
} }
jit_unget_reg(reg); jit_unget_reg(reg);
@ -1840,9 +1840,9 @@ _swf_negr_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
reg = jit_get_reg(jit_class_gpr); reg = jit_get_reg(jit_class_gpr);
movr(rn(reg), r1); movr(rn(reg), r1);
xori(rn(reg), rn(reg), 0x80000000); xori(rn(reg), rn(reg), 0x80000000);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
movr(rn(reg), r1 + 1);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4); swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 4);
movr(rn(reg), r1 + 1);
swf_strin(rn(reg), _FP_REGNO, swf_off(r0) + 8);
jit_unget_reg(reg); jit_unget_reg(reg);
} }
else { else {

View file

@ -563,7 +563,7 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
return; return;
} }
} }
regno = jit_get_reg(jit_class_gpr); regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u); jit_movi_f(regno, u);
jit_stxi_f(_jit->function->call.size, JIT_SP, regno); jit_stxi_f(_jit->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
@ -624,7 +624,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
} }
if (_jit->function->call.size & 7) if (_jit->function->call.size & 7)
_jit->function->call.size += 4; _jit->function->call.size += 4;
regno = jit_get_reg(jit_class_gpr); regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u); jit_movi_d(regno, u);
jit_stxi_d(_jit->function->call.size, JIT_SP, regno); jit_stxi_d(_jit->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);

View file

@ -421,17 +421,17 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_int32_t v)
void void
_jit_pushargr(jit_state_t *_jit, jit_int32_t u) _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
{ {
jit_word_t offset;
assert(_jit->function); assert(_jit->function);
if (_jit->function->call.argf) { offset = _jit->function->call.size >> 2;
_jit->function->call.argi = _jit->function->call.argf; if (_jit->function->call.argf)
_jit->function->call.argf = 0; _jit->function->call.argf = 0;
} if (offset < 4)
if (_jit->function->call.argi < 4) { jit_movr(_A0 - offset, u);
jit_movr(_A0 - _jit->function->call.argi, u);
++_jit->function->call.argi;
}
else else
jit_stxi(_jit->function->call.size, JIT_SP, u); jit_stxi(_jit->function->call.size, JIT_SP, u);
_jit->function->call.argi = offset + 1;
_jit->function->call.size += sizeof(jit_word_t); _jit->function->call.size += sizeof(jit_word_t);
} }
@ -439,40 +439,51 @@ void
_jit_pushargi(jit_state_t *_jit, jit_word_t u) _jit_pushargi(jit_state_t *_jit, jit_word_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
jit_word_t offset;
assert(_jit->function); assert(_jit->function);
if (_jit->function->call.argf) { offset = _jit->function->call.size >> 2;
_jit->function->call.argi = _jit->function->call.argf; if (_jit->function->call.argf)
_jit->function->call.argf = 0; _jit->function->call.argf = 0;
} if (offset < 4)
if (_jit->function->call.argi < 4) { jit_movi(_A0 - offset, u);
jit_movi(_A0 - _jit->function->call.argi, u);
++_jit->function->call.argi;
}
else { else {
regno = jit_get_reg(jit_class_gpr); regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u); jit_movi(regno, u);
jit_stxi(_jit->function->call.size, JIT_SP, regno); jit_stxi(_jit->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
_jit->function->call.argi = offset + 1;
_jit->function->call.size += sizeof(jit_word_t); _jit->function->call.size += sizeof(jit_word_t);
} }
void void
_jit_pushargr_f(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_f(jit_state_t *_jit, jit_int32_t u)
{ {
jit_word_t offset;
assert(_jit->function); assert(_jit->function);
if (_jit->function->call.argi) { offset = _jit->function->call.size >> 2;
jit_new_node_ww(jit_code_pushargr_f, if (offset < 3) {
_A0 - _jit->function->call.argi, u); if (offset & 1) {
_jit->function->call.argi += 2; ++offset;
_jit->function->call.size += 4;
} }
else if (_jit->function->call.argf < 4) { if (_jit->function->call.argi)
jit_movr_f(_F12 - (_jit->function->call.argf >> 1), u); jit_new_node_ww(jit_code_pushargr_f, _A0 - offset, u);
_jit->function->call.argf += 2; else
jit_movr_f(_F12 - (offset >> 1), u);
} }
else else
jit_stxi_f(_jit->function->call.size, JIT_SP, u); jit_stxi_f(_jit->function->call.size, JIT_SP, u);
if (offset < 3) {
if (!_jit->function->call.argi)
_jit->function->call.argf = offset + 2;
else
_jit->function->call.argi = offset + 2;
}
else
_jit->function->call.argi = offset + 1;
_jit->function->call.size += sizeof(jit_float32_t); _jit->function->call.size += sizeof(jit_float32_t);
} }
@ -480,17 +491,19 @@ void
_jit_pushargi_f(jit_state_t *_jit, jit_float32_t u) _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
jit_word_t offset;
if (_jit->function->call.argi) { assert(_jit->function);
if (_jit->function->call.argi & 1) offset = _jit->function->call.size >> 2;
++_jit->function->call.argi; if (offset < 3) {
jit_new_node_wf(jit_code_pushargi_f, if (offset & 1) {
_A0 - _jit->function->call.argi, u); ++offset;
_jit->function->call.argi += 2; _jit->function->call.size += 4;
} }
else if (_jit->function->call.argf < 4) { if (_jit->function->call.argi)
jit_movi_f(_F12 - (_jit->function->call.argf >> 1), u); jit_new_node_ww(jit_code_pushargi_f, _A0 - offset, u);
_jit->function->call.argf += 2; else
jit_movi_f(_F12 - (offset >> 1), u);
} }
else { else {
assert(_jit->function); assert(_jit->function);
@ -499,26 +512,38 @@ _jit_pushargi_f(jit_state_t *_jit, jit_float32_t u)
jit_stxi_f(_jit->function->call.size, JIT_SP, regno); jit_stxi_f(_jit->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
if (offset < 3) {
if (!_jit->function->call.argi)
_jit->function->call.argf = offset + 2;
else
_jit->function->call.argi = offset + 2;
}
else
_jit->function->call.argi = offset + 1;
_jit->function->call.size += sizeof(jit_float32_t); _jit->function->call.size += sizeof(jit_float32_t);
} }
void void
_jit_pushargr_d(jit_state_t *_jit, jit_int32_t u) _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
{ {
jit_word_t offset;
assert(_jit->function); assert(_jit->function);
if (_jit->function->call.argi) { if (_jit->function->call.size & 7)
if (_jit->function->call.argi & 1) _jit->function->call.size += 4;
++_jit->function->call.argi; offset = _jit->function->call.size >> 2;
jit_new_node_ww(jit_code_pushargr_d, if (offset < 3) {
_A0 - _jit->function->call.argi, u); if (_jit->function->call.argi)
_jit->function->call.argi += 2; jit_new_node_ww(jit_code_pushargr_d, _A0 - offset, u);
} else
else if (_jit->function->call.argf < 4) { jit_movr_d(_F12 - (offset >> 1), u);
jit_movr_d(_F12 - (_jit->function->call.argf >> 1), u);
_jit->function->call.argf += 2;
} }
else else
jit_stxi_d(_jit->function->call.size, JIT_SP, u); jit_stxi_d(_jit->function->call.size, JIT_SP, u);
if (offset < 3 && !_jit->function->call.argi)
_jit->function->call.argf = offset + 2;
else
_jit->function->call.argi = offset + 2;
_jit->function->call.size += sizeof(jit_float64_t); _jit->function->call.size += sizeof(jit_float64_t);
} }
@ -526,25 +551,28 @@ void
_jit_pushargi_d(jit_state_t *_jit, jit_float64_t u) _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
{ {
jit_int32_t regno; jit_int32_t regno;
jit_word_t offset;
if (_jit->function->call.argi) { assert(_jit->function);
if (_jit->function->call.argi & 1) if (_jit->function->call.size & 7)
++_jit->function->call.argi; _jit->function->call.size += 4;
jit_new_node_wd(jit_code_pushargi_d, offset = _jit->function->call.size >> 2;
_A0 - _jit->function->call.argi, u); if (offset < 3) {
_jit->function->call.argi += 2; if (_jit->function->call.argi)
} jit_new_node_ww(jit_code_pushargi_d, _A0 - offset, u);
else if (_jit->function->call.argf < 4) { else
jit_movi_d(_F12 - (_jit->function->call.argf >> 1), u); jit_movi_d(_F12 - (offset >> 1), u);
_jit->function->call.argf += 2;
} }
else { else {
assert(_jit->function);
regno = jit_get_reg(jit_class_fpr); regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u); jit_movi_d(regno, u);
jit_stxi_f(_jit->function->call.size, JIT_SP, regno); jit_stxi_d(_jit->function->call.size, JIT_SP, regno);
jit_unget_reg(regno); jit_unget_reg(regno);
} }
if (offset < 3 && !_jit->function->call.argi)
_jit->function->call.argf = offset + 2;
else
_jit->function->call.argi = offset + 2;
_jit->function->call.size += sizeof(jit_float64_t); _jit->function->call.size += sizeof(jit_float64_t);
} }

View file

@ -379,6 +379,8 @@ _jit_pushargr(jit_state_t *_jit, jit_int32_t u)
++_jit->function->call.argi; ++_jit->function->call.argi;
} }
else { else {
if (!_jit->function->call.size)
_jit->function->call.size = 56;
jit_stxi(_jit->function->call.size, JIT_SP, u); jit_stxi(_jit->function->call.size, JIT_SP, u);
_jit->function->call.size += sizeof(jit_word_t); _jit->function->call.size += sizeof(jit_word_t);
} }
@ -394,6 +396,8 @@ _jit_pushargi(jit_state_t *_jit, jit_word_t u)
++_jit->function->call.argi; ++_jit->function->call.argi;
} }
else { else {
if (!_jit->function->call.size)
_jit->function->call.size = 56;
regno = jit_get_reg(jit_class_gpr); regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u); jit_movi(regno, u);
jit_stxi(_jit->function->call.size, JIT_SP, regno); jit_stxi(_jit->function->call.size, JIT_SP, regno);
@ -424,7 +428,7 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
if (!(_jit->function->call.kind & jit_call_varargs)) if (!(_jit->function->call.kind & jit_call_varargs))
return; return;
} }
if (_jit->function->call.argi < 6) { if (_jit->function->call.argi < 8) {
jit_stxi_d(-8, JIT_FP, u); jit_stxi_d(-8, JIT_FP, u);
jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, -8); jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, -8);
_jit->function->call.argi++; _jit->function->call.argi++;
@ -432,8 +436,10 @@ _jit_pushargr_d(jit_state_t *_jit, jit_int32_t u)
_jit->function->call.argi++; _jit->function->call.argi++;
} }
else { else {
if (!_jit->function->call.size)
_jit->function->call.size = 56;
jit_stxi_d(_jit->function->call.size, JIT_SP, u); jit_stxi_d(_jit->function->call.size, JIT_SP, u);
_jit->function->call.size += (sizeof(jit_float64_t) + 8) & -8; _jit->function->call.size += sizeof(jit_float64_t);
} }
} }
@ -451,7 +457,7 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
} }
regno = jit_get_reg(jit_class_fpr); regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u); jit_movi_d(regno, u);
if (_jit->function->call.argi < 6) { if (_jit->function->call.argi < 8) {
jit_stxi_d(-8, JIT_FP, regno); jit_stxi_d(-8, JIT_FP, regno);
jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, -8); jit_ldxi(JIT_RA0 - _jit->function->call.argi, JIT_FP, -8);
_jit->function->call.argi++; _jit->function->call.argi++;
@ -459,8 +465,10 @@ _jit_pushargi_d(jit_state_t *_jit, jit_float64_t u)
_jit->function->call.argi++; _jit->function->call.argi++;
} }
else { else {
if (!_jit->function->call.size)
_jit->function->call.size = 56;
jit_stxi_d(_jit->function->call.size, JIT_SP, regno); jit_stxi_d(_jit->function->call.size, JIT_SP, regno);
_jit->function->call.size += (sizeof(jit_float64_t) + 8) & -8; _jit->function->call.size += sizeof(jit_float64_t);
} }
jit_unget_reg(regno); jit_unget_reg(regno);
} }