1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-17 03:00:21 +02:00

Intermediate, fully functional, rework for variadic functions

* check/cva_list.c: New file implementing a test to ensure
	the value returned by jit_va_start is a valid C va_list.

	* check/va_list.ok: New simple helper file, as now the
	va_list.tst test is enabled.

	* check/va_list.tst: Rewritten for an extensive variadic
	jit functions test.

	* check/Makefile.am: Update for the new tests.

	* lib/jit_arm-cpu.c, lib/jit_arm-swf.c, lib/jit_arm-vfp.c,
	lib/jit_arm.c: Correct broken software float in a previous
	commit. Note that the hard float abi implementation is known
	broken at this time, for special cases involving variadic
	functions, and should be corrected next.

	lib/jit_x86-cpu.c, lib/jit_x86-sz.c, lib/jit_x86.c: Correct
	the jit_va_list_t semantics to match C va_list.
This commit is contained in:
pcpa 2015-05-25 15:20:24 -03:00
parent 237c90295a
commit 0b6cc01eea
12 changed files with 2107 additions and 233 deletions

View file

@ -1,3 +1,25 @@
2015-06-25 Paulo Andrade <pcpa@gnu.org>
* check/cva_list.c: New file implementing a test to ensure
the value returned by jit_va_start is a valid C va_list.
* check/va_list.ok: New simple helper file, as now the
va_list.tst test is enabled.
* check/va_list.tst: Rewritten for an extensive variadic
jit functions test.
* check/Makefile.am: Update for the new tests.
* lib/jit_arm-cpu.c, lib/jit_arm-swf.c, lib/jit_arm-vfp.c,
lib/jit_arm.c: Correct broken software float in a previous
commit. Note that the hard float abi implementation is known
broken at this time, for special cases involving variadic
functions, and should be corrected next.
lib/jit_x86-cpu.c, lib/jit_x86-sz.c, lib/jit_x86.c: Correct
the jit_va_list_t semantics to match C va_list.
2015-06-24 Paulo Andrade <pcpa@gnu.org>
* lib/Makefile.am: Bump library major. This is a preparation

View file

@ -16,7 +16,7 @@
AM_CFLAGS = -I$(top_srcdir)/include -D_GNU_SOURCE
check_PROGRAMS = lightning ccall self setcode nodata ctramp carg
check_PROGRAMS = lightning ccall self setcode nodata ctramp carg cva_list
lightning_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
lightning_SOURCES = lightning.c
@ -39,6 +39,9 @@ ctramp_SOURCES = ctramp.c
carg_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
carg_SOURCES = carg.c
cva_list_LDADD = $(top_builddir)/lib/liblightning.la -lm $(SHLIB)
cva_list_SOURCES = cva_list.c
$(top_builddir)/lib/liblightning.la:
cd $(top_builddir)/lib; $(MAKE) $(AM_MAKEFLAGS) liblightning.la
@ -96,6 +99,7 @@ EXTRA_DIST = \
ranger.tst ranger.ok \
ret.tst ret.ok \
tramp.tst tramp.ok \
va_list.tst va_list.ok \
check.sh \
check.x87.sh \
check.arm.sh check.swf.sh \
@ -123,7 +127,8 @@ base_TESTS = \
clobber carry call \
float jmpr put \
qalu_mul qalu_div \
range ranger ret tramp
range ranger ret tramp \
va_list
$(base_TESTS): check.sh
$(LN_S) $(srcdir)/check.sh $@
@ -148,7 +153,8 @@ x87_TESTS = \
fop_abs.x87 fop_sqrt.x87 \
varargs.x87 stack.x87 \
clobber.x87 carry.x87 call.x87 \
float.x87 jmpr.x87 put.x87
float.x87 jmpr.x87 put.x87 \
va_list.x87
$(x87_TESTS): check.x87.sh
$(LN_S) $(srcdir)/check.x87.sh $@
TESTS += $(x87_TESTS)
@ -170,7 +176,8 @@ x87_nodata_TESTS = \
fop_abs.x87.nodata fop_sqrt.x87.nodata \
varargs.x87.nodata stack.x87.nodata \
clobber.x87.nodata carry.x87.nodata call.x87.nodata \
float.x87.nodata jmpr.x87.nodata put.x87.nodata
float.x87.nodata jmpr.x87.nodata put.x87.nodata \
va_list.x87.nodata
$(x87_nodata_TESTS): check.x87.nodata.sh
$(LN_S) $(srcdir)/check.x87.nodata.sh $@
TESTS += $(x87_nodata_TESTS)
@ -195,7 +202,7 @@ arm_TESTS = \
varargs.arm stack.arm \
clobber.arm carry.arm call.arm \
float.arm jmpr.arm tramp.arm range.arm \
ranger.arm put.arm
ranger.arm put.arm va_list.arm
$(arm_TESTS): check.arm.sh
$(LN_S) $(srcdir)/check.arm.sh $@
TESTS += $(arm_TESTS)
@ -220,7 +227,7 @@ swf_TESTS = \
varargs.swf stack.swf \
clobber.swf carry.swf call.swf \
float.swf jmpr.swf tramp.swf range.swf \
ranger.swf put.swf
ranger.swf put.swf va_list.swf
$(swf_TESTS): check.swf.sh
$(LN_S) $(srcdir)/check.swf.sh $@
TESTS += $(swf_TESTS)
@ -243,7 +250,7 @@ arm_swf_TESTS = \
varargs.arm.swf stack.arm.swf \
clobber.arm.swf carry.arm.swf call.arm.swf \
float.arm.swf jmpr.arm.swf tramp.arm.swf range.arm.swf \
ranger.arm.swf put.arm.swf
ranger.arm.swf put.arm.swf va_list.arm.swf
$(arm_swf_TESTS): check.arm.swf.sh
$(LN_S) $(srcdir)/check.arm.swf.sh $@
TESTS += $(arm_swf_TESTS)
@ -267,7 +274,8 @@ arm4_swf_TESTS = \
varargs.arm4.swf stack.arm4.swf \
clobber.arm4.swf carry.arm4.swf call.arm4.swf \
float.arm4.swf jmpr.arm4.swf tramp.arm4.swf \
range.arm4.swf ranger.arm4.swf put.arm4.swf
range.arm4.swf ranger.arm4.swf put.arm4.swf \
va_list.arm4.swf
$(arm4_swf_TESTS): check.arm4.swf.sh
$(LN_S) $(srcdir)/check.arm4.swf.sh $@
TESTS += $(arm4_swf_TESTS)
@ -293,13 +301,14 @@ nodata_TESTS = \
varargs.nodata stack.nodata \
clobber.nodata carry.nodata call.nodata \
float.nodata jmpr.nodata tramp.nodata \
range.nodata ranger.nodata put.nodata
range.nodata ranger.nodata put.nodata \
va_list.nodata
$(nodata_TESTS): check.nodata.sh
$(LN_S) $(srcdir)/check.nodata.sh $@
TESTS += $(nodata_TESTS)
endif
TESTS += ccall self setcode nodata ctramp carg
TESTS += ccall self setcode nodata ctramp carg cva_list
CLEANFILES = $(TESTS)
#TESTS_ENVIRONMENT=$(srcdir)/run-test;

1187
check/cva_list.c Normal file

File diff suppressed because it is too large Load diff

1
check/va_list.ok Normal file
View file

@ -0,0 +1 @@
ok

View file

@ -1,30 +1,743 @@
.data 16
fmt:
.c "%d %f\n"
.data 8
ok:
.c "ok\n"
.code
jmpi main
varargs:
#define BEGIN(L) \
L: \
prolog
ellipsis
#define VA_START() \
ellipsis \
va_start %v0
va_arg %r0 %v0
va_arg_d %f0 %v0
va_end %v0
prepare
pushargi fmt
ellipsis
pushargr %r0
pushargr_d %f0
finishi @printf
ret
#define VARG(L,N) \
va_arg %r0 %v0 \
beqi L##N %r0 N \
calli @abort \
L##N:
#define VARGD(L,N) \
va_arg_d %f0 %v0 \
beqi_d L##N %f0 N \
calli @abort \
L##N:
#define VA_END() \
va_end %v0 \
ret \
epilog
#define ARG(N) arg $arg##N
#define ARGD(N) arg_d $arg##N
#define GET(L,N) \
getarg %r0 $arg##N \
beqi L##N %r0 N \
calli @abort \
L##N:
#define GETD(L,N) \
getarg_d %f0 $arg##N \
beqi_d L##N %f0 N \
calli @abort \
L##N:
#define ARG1() ARG(1)
#define ARG2() ARG1() ARG(2)
#define ARG3() ARG2() ARG(3)
#define ARG4() ARG3() ARG(4)
#define ARG5() ARG4() ARG(5)
#define ARG6() ARG5() ARG(6)
#define ARG7() ARG6() ARG(7)
#define ARG8() ARG7() ARG(8)
#define ARG9() ARG8() ARG(9)
#define GET1(L) GET(L,1)
#define GET2(L) GET1(L) GET(L,2)
#define GET3(L) GET2(L) GET(L,3)
#define GET4(L) GET3(L) GET(L,4)
#define GET5(L) GET4(L) GET(L,5)
#define GET6(L) GET5(L) GET(L,6)
#define GET7(L) GET6(L) GET(L,7)
#define GET8(L) GET7(L) GET(L,8)
#define GET9(L) GET8(L) GET(L,9)
#define ARGD1() ARGD(1)
#define ARGD2() ARGD1() ARGD(2)
#define ARGD3() ARGD2() ARGD(3)
#define ARGD4() ARGD3() ARGD(4)
#define ARGD5() ARGD4() ARGD(5)
#define ARGD6() ARGD5() ARGD(6)
#define ARGD7() ARGD6() ARGD(7)
#define ARGD8() ARGD7() ARGD(8)
#define ARGD9() ARGD8() ARGD(9)
#define GETD1(L) GETD(L,1)
#define GETD2(L) GETD1(L) GETD(L,2)
#define GETD3(L) GETD2(L) GETD(L,3)
#define GETD4(L) GETD3(L) GETD(L,4)
#define GETD5(L) GETD4(L) GETD(L,5)
#define GETD6(L) GETD5(L) GETD(L,6)
#define GETD7(L) GETD6(L) GETD(L,7)
#define GETD8(L) GETD7(L) GETD(L,8)
#define GETD9(L) GETD8(L) GETD(L,9)
#define IDARG1() ARG(1)
#define IDARG2() IDARG1() ARGD(2)
#define IDARG3() IDARG2() ARG(3)
#define IDARG4() IDARG3() ARGD(4)
#define IDARG5() IDARG4() ARG(5)
#define IDARG6() IDARG5() ARGD(6)
#define IDARG7() IDARG6() ARG(7)
#define IDARG8() IDARG7() ARGD(8)
#define IDARG9() IDARG8() ARG(9)
#define IDGET1(L) GET(L,1)
#define IDGET2(L) IDGET1(L) GETD(L,2)
#define IDGET3(L) IDGET2(L) GET(L,3)
#define IDGET4(L) IDGET3(L) GETD(L,4)
#define IDGET5(L) IDGET4(L) GET(L,5)
#define IDGET6(L) IDGET5(L) GETD(L,6)
#define IDGET7(L) IDGET6(L) GET(L,7)
#define IDGET8(L) IDGET7(L) GETD(L,8)
#define IDGET9(L) IDGET8(L) GET(L,9)
#define DIARG1() ARGD(1)
#define DIARG2() DIARG1() ARG(2)
#define DIARG3() DIARG2() ARGD(3)
#define DIARG4() DIARG3() ARG(4)
#define DIARG5() DIARG4() ARGD(5)
#define DIARG6() DIARG5() ARG(6)
#define DIARG7() DIARG6() ARGD(7)
#define DIARG8() DIARG7() ARG(8)
#define DIARG9() DIARG8() ARGD(9)
#define DIGET1(L) GETD(L,1)
#define DIGET2(L) DIGET1(L) GET(L,2)
#define DIGET3(L) DIGET2(L) GETD(L,3)
#define DIGET4(L) DIGET3(L) GET(L,4)
#define DIGET5(L) DIGET4(L) GETD(L,5)
#define DIGET6(L) DIGET5(L) GET(L,6)
#define DIGET7(L) DIGET6(L) GETD(L,7)
#define DIGET8(L) DIGET7(L) GET(L,8)
#define DIGET9(L) DIGET8(L) GETD(L,9)
#define VARG1(L) \
VARG(L, 10)
#define VARG2(L) \
VARG(L, 9) \
VARG1(L)
#define VARG3(L) \
VARG(L, 8) \
VARG2(L)
#define VARG4(L) \
VARG(L, 7) \
VARG3(L)
#define VARG5(L) \
VARG(L, 6) \
VARG4(L)
#define VARG6(L) \
VARG(L, 5) \
VARG5(L)
#define VARG7(L) \
VARG(L, 4) \
VARG6(L)
#define VARG8(L) \
VARG(L, 3) \
VARG7(L)
#define VARG9(L) \
VARG(L, 2) \
VARG8(L)
#define VARG10(L) \
VARG(L, 1) \
VARG9(L)
#define VARGD1(L) \
VARGD(L, 10)
#define VARGD2(L) \
VARGD(L, 9) \
VARGD1(L)
#define VARGD3(L) \
VARGD(L, 8) \
VARGD2(L)
#define VARGD4(L) \
VARGD(L, 7) \
VARGD3(L)
#define VARGD5(L) \
VARGD(L, 6) \
VARGD4(L)
#define VARGD6(L) \
VARGD(L, 5) \
VARGD5(L)
#define VARGD7(L) \
VARGD(L, 4) \
VARGD6(L)
#define VARGD8(L) \
VARGD(L, 3) \
VARGD7(L)
#define VARGD9(L) \
VARGD(L, 2) \
VARGD8(L)
#define VARGD10(L) \
VARGD(L, 1) \
VARGD9(L)
#define IDVARG1(L) \
VARGD(L, 10)
#define IDVARG2(L) \
VARG(L, 9) \
IDVARG1(L)
#define IDVARG3(L) \
VARGD(L, 8) \
IDVARG2(L)
#define IDVARG4(L) \
VARG(L, 7) \
IDVARG3(L)
#define IDVARG5(L) \
VARGD(L, 6) \
IDVARG4(L)
#define IDVARG6(L) \
VARG(L, 5) \
IDVARG5(L)
#define IDVARG7(L) \
VARGD(L, 4) \
IDVARG6(L)
#define IDVARG8(L) \
VARG(L, 3) \
IDVARG7(L)
#define IDVARG9(L) \
VARGD(L, 2) \
IDVARG8(L)
#define IDVARG10(L) \
VARG(L, 1) \
IDVARG9(L)
#define DIVARG1(L) \
VARG(L, 10)
#define DIVARG2(L) \
VARGD(L, 9) \
DIVARG1(L)
#define DIVARG3(L) \
VARG(L, 8) \
DIVARG2(L)
#define DIVARG4(L) \
VARGD(L, 7) \
DIVARG3(L)
#define DIVARG5(L) \
VARG(L, 6) \
DIVARG4(L)
#define DIVARG6(L) \
VARGD(L, 5) \
DIVARG5(L)
#define DIVARG7(L) \
VARG(L, 4) \
DIVARG6(L)
#define DIVARG8(L) \
VARGD(L, 3) \
DIVARG7(L)
#define DIVARG9(L) \
VARG(L, 2) \
DIVARG8(L)
#define DIVARG10(L) \
VARGD(L, 1) \
DIVARG9(L)
BEGIN(_iiiiiiiiii)
VA_START()
VARG10(_iiiiiiiiii)
VA_END()
BEGIN(i_iiiiiiiii)
ARG1()
GET1(i_iiiiiiiii)
VA_START()
VARG9(i_iiiiiiiii)
VA_END()
BEGIN(ii_iiiiiiii)
ARG2()
GET2(ii_iiiiiiii)
VA_START()
VARG8(ii_iiiiiiii)
VA_END()
BEGIN(iii_iiiiiii)
ARG3()
GET3(iii_iiiiiii)
VA_START()
VARG7(iii_iiiiiii)
VA_END()
BEGIN(iiii_iiiiii)
ARG4()
GET4(iiii_iiiiii)
VA_START()
VARG6(iiii_iiiiii)
VA_END()
BEGIN(iiiii_iiiii)
ARG5()
GET5(iiiii_iiiii)
VA_START()
VARG5(iiiii_iiiii)
VA_END()
BEGIN(iiiiii_iiii)
ARG6()
GET6(iiiiii_iiii)
VA_START()
VARG4(iiiiii_iiii)
VA_END()
BEGIN(iiiiiii_iii)
ARG7()
GET7(iiiiiii_iii)
VA_START()
VARG3(iiiiiii_iii)
VA_END()
BEGIN(iiiiiiii_ii)
ARG8()
GET8(iiiiiiii_ii)
VA_START()
VARG2(iiiiiiii_ii)
VA_END()
BEGIN(iiiiiiiii_i)
ARG9()
GET9(iiiiiiiii_i)
VA_START()
VARG1(iiiiiiiii_i)
VA_END()
BEGIN(_dddddddddd)
VA_START()
VARGD10(_dddddddddd)
VA_END()
BEGIN(d_ddddddddd)
ARGD1()
GETD1(d_ddddddddd)
VA_START()
VARGD9(d_ddddddddd)
VA_END()
BEGIN(dd_dddddddd)
ARGD2()
GETD2(dd_dddddddd)
VA_START()
VARGD8(dd_dddddddd)
VA_END()
BEGIN(ddd_ddddddd)
ARGD3()
GETD3(ddd_ddddddd)
VA_START()
VARGD7(ddd_ddddddd)
VA_END()
BEGIN(dddd_dddddd)
ARGD4()
GETD4(dddd_dddddd)
VA_START()
VARGD6(dddd_dddddd)
VA_END()
BEGIN(ddddd_ddddd)
ARGD5()
GETD5(ddddd_ddddd)
VA_START()
VARGD5(ddddd_ddddd)
VA_END()
BEGIN(dddddd_dddd)
ARGD6()
GETD6(dddddd_dddd)
VA_START()
VARGD4(dddddd_dddd)
VA_END()
BEGIN(ddddddd_ddd)
ARGD7()
GETD7(ddddddd_ddd)
VA_START()
VARGD3(ddddddd_ddd)
VA_END()
BEGIN(dddddddd_dd)
ARGD8()
GETD8(dddddddd_dd)
VA_START()
VARGD2(dddddddd_dd)
VA_END()
BEGIN(ddddddddd_d)
ARGD9()
GETD9(ddddddddd_d)
VA_START()
VARGD1(ddddddddd_d)
VA_END()
BEGIN(_ididididid)
VA_START()
IDVARG10(_ididididid)
VA_END()
BEGIN(i_didididid)
IDARG1()
IDGET1(i_didididid)
VA_START()
IDVARG9(i_didididid)
VA_END()
BEGIN(id_idididid)
IDARG2()
IDGET2(id_idididid)
VA_START()
IDVARG8(id_idididid)
VA_END()
BEGIN(idi_dididid)
IDARG3()
IDGET3(idi_dididid)
VA_START()
IDVARG7(idi_dididid)
VA_END()
BEGIN(idid_ididid)
IDARG4()
IDGET4(idid_ididid)
VA_START()
IDVARG6(idid_ididid)
VA_END()
BEGIN(ididi_didid)
IDARG5()
IDGET5(ididi_didid)
VA_START()
IDVARG5(ididi_didid)
VA_END()
BEGIN(ididid_idid)
IDARG6()
IDGET6(ididid_idid)
VA_START()
IDVARG4(ididid_idid)
VA_END()
BEGIN(idididi_did)
IDARG7()
IDGET7(idididi_did)
VA_START()
IDVARG3(idididi_did)
VA_END()
BEGIN(idididid_id)
IDARG8()
IDGET8(idididid_id)
VA_START()
IDVARG2(idididid_id)
VA_END()
BEGIN(ididididi_d)
IDARG9()
IDGET9(ididididi_d)
VA_START()
IDVARG1(ididididi_d)
VA_END()
BEGIN(_dididididi)
VA_START()
DIVARG10(_dididididi)
VA_END()
BEGIN(d_ididididi)
DIARG1()
DIGET1(d_ididididi)
VA_START()
DIVARG9(d_ididididi)
VA_END()
BEGIN(di_didididi)
DIARG2()
DIGET2(di_didididi)
VA_START()
DIVARG8(di_didididi)
VA_END()
BEGIN(did_idididi)
DIARG3()
DIGET3(did_idididi)
VA_START()
DIVARG7(did_idididi)
VA_END()
BEGIN(didi_dididi)
DIARG4()
DIGET4(didi_dididi)
VA_START()
DIVARG6(didi_dididi)
VA_END()
BEGIN(didid_ididi)
DIARG5()
DIGET5(didid_ididi)
VA_START()
DIVARG5(didid_ididi)
VA_END()
BEGIN(dididi_didi)
DIARG6()
DIGET6(dididi_didi)
VA_START()
DIVARG4(dididi_didi)
VA_END()
BEGIN(dididid_idi)
DIARG7()
DIGET7(dididid_idi)
VA_START()
DIVARG3(dididid_idi)
VA_END()
BEGIN(didididi_di)
DIARG8()
DIGET8(didididi_di)
VA_START()
DIVARG2(didididi_di)
VA_END()
BEGIN(didididid_i)
DIARG9()
DIGET9(didididid_i)
VA_START()
DIVARG1(didididid_i)
VA_END()
#define PUSH1() pushargi 1
#define PUSH2() PUSH1() pushargi 2
#define PUSH3() PUSH2() pushargi 3
#define PUSH4() PUSH3() pushargi 4
#define PUSH5() PUSH4() pushargi 5
#define PUSH6() PUSH5() pushargi 6
#define PUSH7() PUSH6() pushargi 7
#define PUSH8() PUSH7() pushargi 8
#define PUSH9() PUSH8() pushargi 9
#define VPUSH1() pushargi 1 VPUSH2()
#define VPUSH2() pushargi 2 VPUSH3()
#define VPUSH3() pushargi 3 VPUSH4()
#define VPUSH4() pushargi 4 VPUSH5()
#define VPUSH5() pushargi 5 VPUSH6()
#define VPUSH6() pushargi 6 VPUSH7()
#define VPUSH7() pushargi 7 VPUSH8()
#define VPUSH8() pushargi 8 VPUSH9()
#define VPUSH9() pushargi 9 VPUSH10()
#define VPUSH10() pushargi 10
#define PUSHD1() pushargi_d 1
#define PUSHD2() PUSHD1() pushargi_d 2
#define PUSHD3() PUSHD2() pushargi_d 3
#define PUSHD4() PUSHD3() pushargi_d 4
#define PUSHD5() PUSHD4() pushargi_d 5
#define PUSHD6() PUSHD5() pushargi_d 6
#define PUSHD7() PUSHD6() pushargi_d 7
#define PUSHD8() PUSHD7() pushargi_d 8
#define PUSHD9() PUSHD8() pushargi_d 9
#define VPUSHD1() pushargi_d 1 VPUSHD2()
#define VPUSHD2() pushargi_d 2 VPUSHD3()
#define VPUSHD3() pushargi_d 3 VPUSHD4()
#define VPUSHD4() pushargi_d 4 VPUSHD5()
#define VPUSHD5() pushargi_d 5 VPUSHD6()
#define VPUSHD6() pushargi_d 6 VPUSHD7()
#define VPUSHD7() pushargi_d 7 VPUSHD8()
#define VPUSHD8() pushargi_d 8 VPUSHD9()
#define VPUSHD9() pushargi_d 9 VPUSHD10()
#define VPUSHD10() pushargi_d 10
#define IDPUSH1() pushargi 1
#define IDPUSH2() IDPUSH1() pushargi_d 2
#define IDPUSH3() IDPUSH2() pushargi 3
#define IDPUSH4() IDPUSH3() pushargi_d 4
#define IDPUSH5() IDPUSH4() pushargi 5
#define IDPUSH6() IDPUSH5() pushargi_d 6
#define IDPUSH7() IDPUSH6() pushargi 7
#define IDPUSH8() IDPUSH7() pushargi_d 8
#define IDPUSH9() IDPUSH8() pushargi 9
#define IDVPUSH1() pushargi 1 IDVPUSH2()
#define IDVPUSH2() pushargi_d 2 IDVPUSH3()
#define IDVPUSH3() pushargi 3 IDVPUSH4()
#define IDVPUSH4() pushargi_d 4 IDVPUSH5()
#define IDVPUSH5() pushargi 5 IDVPUSH6()
#define IDVPUSH6() pushargi_d 6 IDVPUSH7()
#define IDVPUSH7() pushargi 7 IDVPUSH8()
#define IDVPUSH8() pushargi_d 8 IDVPUSH9()
#define IDVPUSH9() pushargi 9 IDVPUSH10()
#define IDVPUSH10() pushargi_d 10
#define DIPUSH1() pushargi_d 1
#define DIPUSH2() DIPUSH1() pushargi 2
#define DIPUSH3() DIPUSH2() pushargi_d 3
#define DIPUSH4() DIPUSH3() pushargi 4
#define DIPUSH5() DIPUSH4() pushargi_d 5
#define DIPUSH6() DIPUSH5() pushargi 6
#define DIPUSH7() DIPUSH6() pushargi_d 7
#define DIPUSH8() DIPUSH7() pushargi 8
#define DIPUSH9() DIPUSH8() pushargi_d 9
#define DIVPUSH1() pushargi_d 1 DIVPUSH2()
#define DIVPUSH2() pushargi 2 DIVPUSH3()
#define DIVPUSH3() pushargi_d 3 DIVPUSH4()
#define DIVPUSH4() pushargi 4 DIVPUSH5()
#define DIVPUSH5() pushargi_d 5 DIVPUSH6()
#define DIVPUSH6() pushargi 6 DIVPUSH7()
#define DIVPUSH7() pushargi_d 7 DIVPUSH8()
#define DIVPUSH8() pushargi 8 DIVPUSH9()
#define DIVPUSH9() pushargi_d 9 DIVPUSH10()
#define DIVPUSH10() pushargi 10
main:
prolog
prepare
ellipsis
pushargi 1
pushargi_d 2
finishi varargs
VPUSH1()
finishi _iiiiiiiiii
prepare
PUSH1()
ellipsis
VPUSH2()
finishi i_iiiiiiiii
prepare
PUSH2()
ellipsis
VPUSH3()
finishi ii_iiiiiiii
prepare
PUSH3()
ellipsis
VPUSH4()
finishi iii_iiiiiii
prepare
PUSH4()
ellipsis
VPUSH5()
finishi iiii_iiiiii
prepare
PUSH5()
ellipsis
VPUSH6()
finishi iiiii_iiiii
prepare
PUSH6()
ellipsis
VPUSH7()
finishi iiiiii_iiii
prepare
PUSH7()
ellipsis
VPUSH8()
finishi iiiiiii_iii
prepare
PUSH8()
ellipsis
VPUSH9()
finishi iiiiiiii_ii
prepare
PUSH9()
ellipsis
VPUSH10()
finishi iiiiiiiii_i
prepare
ellipsis
VPUSHD1()
finishi _dddddddddd
prepare
PUSHD1()
ellipsis
VPUSHD2()
finishi d_ddddddddd
prepare
PUSHD2()
ellipsis
VPUSHD3()
finishi dd_dddddddd
prepare
PUSHD3()
ellipsis
VPUSHD4()
finishi ddd_ddddddd
prepare
PUSHD4()
ellipsis
VPUSHD5()
finishi dddd_dddddd
prepare
PUSHD5()
ellipsis
VPUSHD6()
finishi ddddd_ddddd
prepare
PUSHD6()
ellipsis
VPUSHD7()
finishi dddddd_dddd
prepare
PUSHD7()
ellipsis
VPUSHD8()
finishi ddddddd_ddd
prepare
PUSHD8()
ellipsis
VPUSHD9()
finishi dddddddd_dd
prepare
PUSHD9()
ellipsis
VPUSHD10()
finishi ddddddddd_d
prepare
ellipsis
IDVPUSH1()
finishi _ididididid
prepare
IDPUSH1()
ellipsis
IDVPUSH2()
finishi i_didididid
prepare
IDPUSH2()
ellipsis
IDVPUSH3()
finishi id_idididid
prepare
IDPUSH3()
ellipsis
IDVPUSH4()
finishi idi_dididid
prepare
IDPUSH4()
ellipsis
IDVPUSH5()
finishi idid_ididid
prepare
IDPUSH5()
ellipsis
IDVPUSH6()
finishi ididi_didid
prepare
IDPUSH6()
ellipsis
IDVPUSH7()
finishi ididid_idid
prepare
IDPUSH7()
ellipsis
IDVPUSH8()
finishi idididi_did
prepare
IDPUSH8()
ellipsis
IDVPUSH9()
finishi idididid_id
prepare
IDPUSH9()
ellipsis
IDVPUSH10()
finishi ididididi_d
prepare
ellipsis
DIVPUSH1()
finishi _dididididi
prepare
DIPUSH1()
ellipsis
DIVPUSH2()
finishi d_ididididi
prepare
DIPUSH2()
ellipsis
DIVPUSH3()
finishi di_didididi
prepare
DIPUSH3()
ellipsis
DIVPUSH4()
finishi did_idididi
prepare
DIPUSH4()
ellipsis
DIVPUSH5()
finishi didi_dididi
prepare
DIPUSH5()
ellipsis
DIVPUSH6()
finishi didid_ididi
prepare
DIPUSH6()
ellipsis
DIVPUSH7()
finishi dididi_didi
prepare
DIPUSH7()
ellipsis
DIVPUSH8()
finishi dididid_idi
prepare
DIPUSH8()
ellipsis
DIVPUSH9()
finishi didididi_di
prepare
DIPUSH9()
ellipsis
DIVPUSH10()
finishi didididid_i
prepare
pushargi ok
ellipsis
finishi @printf
ret
epilog

View file

@ -3778,42 +3778,25 @@ _prolog(jit_state_t *_jit, jit_node_t *node)
BX(_R12_REGNO);
if (!_jitc->thumb)
_jitc->thumb = _jit->pc.w;
/* If the jit function is varargs, do a slightly more
* costly prolog to save first the 4 argument registers. */
if (jit_cpu.abi) {
if (_jitc->function->self.call & jit_call_varargs)
T2_PUSH(0xf);
T2_PUSH(0xf);
T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
VPUSH_F64(_D8_REGNO, 8);
if (!(_jitc->function->self.call & jit_call_varargs))
T2_PUSH(0xf);
}
else {
if (_jitc->function->self.call & jit_call_varargs) {
T2_PUSH(0xf);
T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
}
else
T2_PUSH(0x3ff|(1<<_FP_REGNO)|(1<<_LR_REGNO));
T2_PUSH(0xf);
T2_PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
}
}
else {
if (jit_cpu.abi) {
if (_jitc->function->self.call & jit_call_varargs)
PUSH(0xf);
PUSH(0xf);
PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
VPUSH_F64(_D8_REGNO, 8);
if (!(_jitc->function->self.call & jit_call_varargs))
PUSH(0xf);
}
else {
if (_jitc->function->self.call & jit_call_varargs) {
PUSH(0xf);
PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
}
else
PUSH(0x3ff|(1<<_FP_REGNO)|(1<<_LR_REGNO));
PUSH(0xf);
PUSH(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
}
}
movr(_FP_REGNO, _SP_REGNO);
@ -3833,35 +3816,18 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
if (_jitc->function->assume_frame)
return;
/* If the jit function is varargs, need a different
* epilog, that also does not directly restore the
* pc, but instead branch to the lr, after correcting
* the stack. */
if (_jitc->function->self.call & jit_call_varargs)
movr(_SP_REGNO, _FP_REGNO);
else
addi(_SP_REGNO, _FP_REGNO, 16);
movr(_SP_REGNO, _FP_REGNO);
if (jit_cpu.abi)
VPOP_F64(_D8_REGNO, 8);
if (jit_thumb_p()) {
if (!(_jitc->function->self.call & jit_call_varargs))
T2_POP(0x3f0|(1<<_FP_REGNO)|(1<<_PC_REGNO));
else
T2_POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
}
else {
if (!(_jitc->function->self.call & jit_call_varargs))
POP(0x3f0|(1<<_FP_REGNO)|(1<<_PC_REGNO));
else
POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
}
if (_jitc->function->self.call & jit_call_varargs) {
addi(_SP_REGNO, _SP_REGNO, 16);
if (jit_thumb_p())
T1_BX(_LR_REGNO);
else
BX(_LR_REGNO);
}
if (jit_thumb_p())
T2_POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
else
POP(0x3f0|(1<<_FP_REGNO)|(1<<_LR_REGNO));
addi(_SP_REGNO, _SP_REGNO, 16);
if (jit_thumb_p())
T1_BX(_LR_REGNO);
else
BX(_LR_REGNO);
if (jit_thumb_p() && (_jit->pc.w & 2))
T1_NOP();
}
@ -3869,45 +3835,26 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
static void
_vastart(jit_state_t *_jit, jit_int32_t r0)
{
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
/* Return jit_va_list_t in the register argument */
addi(r0, _FP_REGNO, _jitc->function->vaoff);
reg = jit_get_reg(jit_class_gpr);
/* Initialize stack pointer to the first stack argument.
* The -16 is to account for the 4 argument registers
* always saved, and _jitc->function->vagp is to account
* for declared arguments. */
addi(rn(reg), _FP_REGNO, _jitc->function->self.size -
addi(r0, _FP_REGNO, _jitc->function->self.size -
16 + _jitc->function->vagp);
stxi(offsetof(jit_va_list_t, stack), r0, rn(reg));
jit_unget_reg(reg);
}
static void
_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
reg = jit_get_reg(jit_class_gpr);
/* Load stack pointer. */
ldxi(rn(reg), r1, offsetof(jit_va_list_t, stack));
/* Load argument. */
ldr(r0, rn(reg));
ldr(r0, r1);
/* Update stack pointer. */
addi(rn(reg), rn(reg), sizeof(jit_word_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(reg));
jit_unget_reg(reg);
addi(r1, r1, sizeof(jit_word_t));
}
static void

View file

@ -2620,27 +2620,21 @@ _swf_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
static void
_swf_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t rg0, rg1;
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
rg0 = jit_get_reg(jit_class_gpr);
/* Load stack pointer. */
ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
rg1 = jit_get_reg(jit_class_gpr);
andi(rn(rg1), rn(rg0), 7);
addr(rn(rg0), rn(rg0), rn(rg1));
jit_unget_reg(rg1);
/* Adjust pointer. */
reg = jit_get_reg(jit_class_gpr);
andi(rn(reg), r1, 7);
addr(r1, r1, rn(reg));
jit_unget_reg(reg);
/* Load argument. */
swf_ldr_d(r0, rn(rg0));
swf_ldr_d(r0, r1);
/* Update stack pointer. */
addi(rn(rg0), rn(rg0), sizeof(jit_float64_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
jit_unget_reg(rg0);
addi(r1, r1, sizeof(jit_float64_t));
}
#endif

View file

@ -2307,27 +2307,21 @@ _vfp_stxi_d(jit_state_t *_jit, jit_word_t i0, jit_int32_t r0, jit_int32_t r1)
static void
_vfp_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
jit_int32_t rg0, rg1;
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
rg0 = jit_get_reg(jit_class_gpr);
/* Load stack pointer. */
ldxi(rn(rg0), r1, offsetof(jit_va_list_t, stack));
rg1 = jit_get_reg(jit_class_gpr);
andi(rn(rg1), rn(rg0), 7);
addr(rn(rg0), rn(rg0), rn(rg1));
jit_unget_reg(rg1);
/* Adjust pointer. */
reg = jit_get_reg(jit_class_gpr);
andi(rn(reg), r1, 7);
addr(r1, r1, rn(reg));
jit_unget_reg(reg);
/* Load argument. */
vfp_ldr_d(r0, rn(rg0));
vfp_ldr_d(r0, r1);
/* Update stack pointer. */
addi(rn(rg0), rn(rg0), sizeof(jit_float64_t));
stxi(offsetof(jit_va_list_t, stack), r1, rn(rg0));
jit_unget_reg(rg0);
addi(r1, r1, sizeof(jit_float64_t));
}
# undef dbopi
# undef fbopi

View file

@ -34,6 +34,11 @@
#define jit_fpr_p(rn) ((rn) > 15)
#define arg_base() \
(stack_framesize - 16 + (jit_cpu.abi ? 64 : 0))
#define arg_offset(n) \
((n) < 4 ? arg_base() + ((n) << 2) : (n))
/* Assume functions called never match jit instruction set, that is
* libc, gmp, mpfr, etc functions are in thumb mode and jit is in
* arm mode, what may cause a crash upon return of that function
@ -51,9 +56,7 @@ typedef union _jit_thumb_t {
jit_int16_t s[2];
} jit_thumb_t;
typedef struct jit_va_list {
jit_pointer_t stack;
} jit_va_list_t;
typedef jit_pointer_t jit_va_list;
/*
* Prototypes
@ -420,9 +423,6 @@ _jit_ellipsis(jit_state_t *_jit)
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
/* Allocate va_list like object in the stack. */
_jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
/* First 4 stack addresses are always spilled r0-r3 */
if (jit_arg_reg_p(_jitc->function->self.argi))
_jitc->function->vagp = _jitc->function->self.argi * 4;
@ -504,7 +504,7 @@ _jit_getarg_c(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
if (jit_swf_p())
jit_ldxi_c(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
jit_ldxi_c(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_c(u, JIT_RA0 - v->u.w);
else
@ -516,7 +516,7 @@ _jit_getarg_uc(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
if (jit_swf_p())
jit_ldxi_uc(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
jit_ldxi_uc(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_uc(u, JIT_RA0 - v->u.w);
else
@ -528,7 +528,7 @@ _jit_getarg_s(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
if (jit_swf_p())
jit_ldxi_s(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
jit_ldxi_s(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_s(u, JIT_RA0 - v->u.w);
else
@ -540,7 +540,7 @@ _jit_getarg_us(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
if (jit_swf_p())
jit_ldxi_us(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
jit_ldxi_us(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_extr_us(u, JIT_RA0 - v->u.w);
else
@ -552,7 +552,7 @@ _jit_getarg_i(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
if (jit_swf_p())
jit_ldxi_i(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
jit_ldxi_i(u, JIT_FP, arg_offset(v->u.w));
else if (jit_arg_reg_p(v->u.w))
jit_movr(u, JIT_RA0 - v->u.w);
else
@ -564,7 +564,7 @@ _jit_putargr(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
{
assert(v->code == jit_code_arg);
if (jit_swf_p())
jit_stxi(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, u);
jit_stxi(arg_offset(v->u.w), JIT_FP, u);
else if (jit_arg_reg_p(v->u.w))
jit_movr(JIT_RA0 - v->u.w, u);
else
@ -579,7 +579,7 @@ _jit_putargi(jit_state_t *_jit, jit_word_t u, jit_node_t *v)
if (jit_swf_p()) {
regno = jit_get_reg(jit_class_gpr);
jit_movi(regno, u);
jit_stxi(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, regno);
jit_stxi(arg_offset(v->u.w), JIT_FP, regno);
jit_unget_reg(regno);
}
else if (jit_arg_reg_p(v->u.w))
@ -603,7 +603,7 @@ _jit_getarg_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
jit_ldxi_f(u, JIT_FP, v->u.w);
}
else if (jit_swf_p())
jit_ldxi_f(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
jit_ldxi_f(u, JIT_FP, arg_offset(v->u.w));
else {
if (jit_arg_reg_p(v->u.w))
jit_movr_w_f(u, JIT_RA0 - v->u.w);
@ -623,7 +623,7 @@ _jit_putargr_f(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
jit_stxi_f(v->u.w, JIT_FP, u);
}
else if (jit_swf_p())
jit_stxi_f(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, u);
jit_stxi_f(arg_offset(v->u.w), JIT_FP, u);
else {
if (jit_arg_reg_p(v->u.w))
jit_movr_f_w(JIT_RA0 - v->u.w, u);
@ -650,7 +650,7 @@ _jit_putargi_f(jit_state_t *_jit, jit_float32_t u, jit_node_t *v)
else if (jit_swf_p()) {
regno = jit_get_reg(jit_class_fpr);
jit_movi_f(regno, u);
jit_stxi_f(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, regno);
jit_stxi_f(arg_offset(v->u.w), JIT_FP, regno);
jit_unget_reg(regno);
}
else {
@ -675,7 +675,7 @@ _jit_getarg_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
jit_ldxi_d(u, JIT_FP, v->u.w);
}
else if (jit_swf_p())
jit_ldxi_d(u, JIT_FP, v->u.w < 4 ? v->u.w << 2 : v->u.w);
jit_ldxi_d(u, JIT_FP, arg_offset(v->u.w));
else {
if (jit_arg_reg_p(v->u.w))
jit_movr_ww_d(u, JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1));
@ -695,7 +695,7 @@ _jit_putargr_d(jit_state_t *_jit, jit_int32_t u, jit_node_t *v)
jit_stxi_d(v->u.w, JIT_FP, u);
}
else if (jit_swf_p())
jit_stxi_d(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, u);
jit_stxi_d(arg_offset(v->u.w), JIT_FP, u);
else {
if (jit_arg_reg_p(v->u.w))
jit_movr_d_ww(JIT_RA0 - v->u.w, JIT_RA0 - (v->u.w + 1), u);
@ -722,7 +722,7 @@ _jit_putargi_d(jit_state_t *_jit, jit_float64_t u, jit_node_t *v)
else if (jit_swf_p()) {
regno = jit_get_reg(jit_class_fpr);
jit_movi_d(regno, u);
jit_stxi_d(v->u.w < 4 ? v->u.w << 2 : v->u.w, JIT_FP, regno);
jit_stxi_d(arg_offset(v->u.w), JIT_FP, regno);
jit_unget_reg(regno);
}
else {

View file

@ -3654,6 +3654,10 @@ _epilog(jit_state_t *_jit, jit_node_t *node)
static void
_vastart(jit_state_t *_jit, jit_int32_t r0)
{
#if __X32 || __CYGWIN__
assert(_jitc->function->self.call & jit_call_varargs);
addi(r0, _RBP_REGNO, _jitc->function->self.size);
#else
jit_int32_t reg;
assert(_jitc->function->self.call & jit_call_varargs);
@ -3662,7 +3666,6 @@ _vastart(jit_state_t *_jit, jit_int32_t r0)
addi(r0, _RBP_REGNO, _jitc->function->vaoff);
reg = jit_get_reg(jit_class_gpr);
#if __X64 && !__CYGWIN__
/* Initialize gp offset in the save area. */
movi(rn(reg), _jitc->function->vagp);
stxi_i(offsetof(jit_va_list_t, gpoff), r0, rn(reg));
@ -3670,35 +3673,35 @@ _vastart(jit_state_t *_jit, jit_int32_t r0)
/* Initialize fp offset in the save area. */
movi(rn(reg), _jitc->function->vafp);
stxi_i(offsetof(jit_va_list_t, fpoff), r0, rn(reg));
#endif
/* Initialize overflow pointer to the first stack argument. */
addi(rn(reg), _RBP_REGNO, _jitc->function->self.size);
stxi(offsetof(jit_va_list_t, over), r0, rn(reg));
#if __X64 && !__CYGWIN__
/* Initialize register save area pointer. */
addi(rn(reg), r0, first_gp_offset);
stxi(offsetof(jit_va_list_t, save), r0, rn(reg));
#endif
jit_unget_reg(reg);
#endif
}
static void
_vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
{
#if __X32 || __CYGWIN__
assert(_jitc->function->self.call & jit_call_varargs);
ldr(r0, r1);
addi(r1, r1, va_gp_increment);
#else
jit_int32_t rg0;
#if __X64 && !__CYGWIN__
jit_int32_t rg1;
jit_word_t ge_code;
jit_word_t lt_code;
#endif
assert(_jitc->function->self.call & jit_call_varargs);
rg0 = jit_get_reg(jit_class_gpr);
#if __X64 && !__CYGWIN__
rg1 = jit_get_reg(jit_class_gpr);
/* Load the gp offset in save area in the first temporary. */
@ -3728,7 +3731,6 @@ _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
/* Where to land if argument is in overflow area. */
patch_rel_char(ge_code, _jit->pc.w);
#endif
/* Load overflow pointer. */
ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));
@ -3740,12 +3742,11 @@ _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
addi(rn(rg0), rn(rg0), va_gp_increment);
stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
#if __X64 && !__CYGWIN__
/* Where to land if argument is in save area. */
patch_rel_char(lt_code, _jit->pc.w);
#endif
jit_unget_reg(rg0);
#endif
}
/* The x87 boolean argument tells if will put the result in a x87
@ -3753,17 +3754,22 @@ _vaarg(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1)
static void
_vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_bool_t x87)
{
#if __X32 || __CYGWIN__
assert(_jitc->function->self.call & jit_call_varargs);
if (x87)
x87_ldr_d(r0, r1);
else
sse_ldr_d(r0, r1);
addi(r1, r1, 8);
#else
jit_int32_t rg0;
#if __X64 && !__CYGWIN__
jit_int32_t rg1;
jit_word_t ge_code;
jit_word_t lt_code;
#endif
assert(_jitc->function->self.call & jit_call_varargs);
rg0 = jit_get_reg(jit_class_gpr);
#if __X64 && !__CYGWIN__
rg1 = jit_get_reg(jit_class_gpr);
/* Load the fp offset in save area in the first temporary. */
@ -3796,7 +3802,6 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_bool_t x87)
/* Where to land if argument is in overflow area. */
patch_rel_char(ge_code, _jit->pc.w);
#endif
/* Load overflow pointer. */
ldxi(rn(rg0), r1, offsetof(jit_va_list_t, over));
@ -3811,12 +3816,11 @@ _vaarg_d(jit_state_t *_jit, jit_int32_t r0, jit_int32_t r1, jit_bool_t x87)
addi(rn(rg0), rn(rg0), 8);
stxi(offsetof(jit_va_list_t, over), r1, rn(rg0));
#if __X64 && !__CYGWIN__
/* Where to land if argument is in save area. */
patch_rel_char(lt_code, _jit->pc.w);
#endif
jit_unget_reg(rg0);
#endif
}
static void

View file

@ -9,7 +9,7 @@
0, /* #name */
0, /* #note */
3, /* label */
26, /* prolog */
34, /* prolog */
0, /* arg */
3, /* addr */
6, /* addi */
@ -23,7 +23,7 @@
6, /* subci */
6, /* subxr */
5, /* subxi */
10, /* rsbi */
8, /* rsbi */
5, /* mulr */
7, /* muli */
20, /* qmulr */
@ -84,7 +84,7 @@
3, /* extr_us */
0, /* extr_i */
0, /* extr_ui */
4, /* htonr_us */
7, /* htonr_us */
4, /* htonr_ui */
0, /* htonr_ul */
3, /* ldr_c */
@ -102,13 +102,13 @@
0, /* ldr_l */
0, /* ldi_l */
4, /* ldxr_c */
4, /* ldxi_c */
7, /* ldxi_c */
4, /* ldxr_uc */
4, /* ldxi_uc */
7, /* ldxi_uc */
4, /* ldxr_s */
4, /* ldxi_s */
7, /* ldxi_s */
4, /* ldxr_us */
4, /* ldxi_us */
7, /* ldxi_us */
3, /* ldxr_i */
6, /* ldxi_i */
0, /* ldxr_ui */
@ -126,7 +126,7 @@
11, /* stxr_c */
11, /* stxi_c */
4, /* stxr_s */
4, /* stxi_s */
7, /* stxi_s */
3, /* stxr_i */
6, /* stxi_i */
0, /* stxr_l */
@ -173,15 +173,15 @@
9, /* bxsubi_u */
2, /* jmpr */
5, /* jmpi */
4, /* callr */
7, /* calli */
2, /* callr */
5, /* calli */
24, /* epilog */
0, /* arg_f */
8, /* addr_f */
19, /* addi_f */
12, /* subr_f */
19, /* subi_f */
19, /* rsbi_f */
21, /* rsbi_f */
8, /* mulr_f */
19, /* muli_f */
12, /* divr_f */
@ -226,11 +226,11 @@
4, /* ldr_f */
8, /* ldi_f */
5, /* ldxr_f */
5, /* ldxi_f */
8, /* ldxi_f */
6, /* str_f */
10, /* sti_f */
7, /* stxr_f */
7, /* stxi_f */
8, /* stxi_f */
10, /* bltr_f */
23, /* blti_f */
10, /* bler_f */
@ -264,7 +264,7 @@
26, /* addi_d */
12, /* subr_d */
26, /* subi_d */
26, /* rsbi_d */
30, /* rsbi_d */
8, /* mulr_d */
26, /* muli_d */
12, /* divr_d */
@ -313,7 +313,7 @@
6, /* str_d */
10, /* sti_d */
7, /* stxr_d */
7, /* stxi_d */
8, /* stxi_d */
10, /* bltr_d */
28, /* blti_d */
10, /* bler_d */
@ -353,9 +353,9 @@
0, /* movi_d_w */
10, /* x86_retval_f */
10, /* x86_retval_d */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
3, /* va_start */
5, /* va_arg */
7, /* va_arg_d */
0, /* va_end */
#endif /* __X32 */
@ -721,7 +721,7 @@
#else
# if __X64_32
#define JIT_INSTR_MAX 44
#define JIT_INSTR_MAX 108
0, /* data */
0, /* live */
3, /* align */
@ -730,7 +730,7 @@
0, /* #name */
0, /* #note */
3, /* label */
39, /* prolog */
108, /* prolog */
0, /* arg */
5, /* addr */
7, /* addi */
@ -822,15 +822,15 @@
0, /* ldi_ui */
0, /* ldr_l */
0, /* ldi_l */
6, /* ldxr_c */
9, /* ldxr_c */
7, /* ldxi_c */
6, /* ldxr_uc */
9, /* ldxr_uc */
7, /* ldxi_uc */
6, /* ldxr_s */
9, /* ldxr_s */
7, /* ldxi_s */
6, /* ldxr_us */
9, /* ldxr_us */
7, /* ldxi_us */
5, /* ldxr_i */
8, /* ldxr_i */
7, /* ldxi_i */
0, /* ldxr_ui */
0, /* ldxi_ui */
@ -844,11 +844,11 @@
8, /* sti_i */
0, /* str_l */
0, /* sti_l */
8, /* stxr_c */
12, /* stxr_c */
7, /* stxi_c */
6, /* stxr_s */
10, /* stxr_s */
7, /* stxi_s */
5, /* stxr_i */
9, /* stxr_i */
6, /* stxi_i */
0, /* stxr_l */
0, /* stxi_l */
@ -896,7 +896,7 @@
5, /* jmpi */
3, /* callr */
9, /* calli */
34, /* epilog */
35, /* epilog */
0, /* arg_f */
10, /* addr_f */
21, /* addi_f */
@ -946,11 +946,11 @@
11, /* movi_f */
6, /* ldr_f */
10, /* ldi_f */
7, /* ldxr_f */
11, /* ldxr_f */
9, /* ldxi_f */
6, /* str_f */
10, /* sti_f */
7, /* stxr_f */
11, /* stxr_f */
9, /* stxi_f */
10, /* bltr_f */
21, /* blti_f */
@ -1029,11 +1029,11 @@
23, /* movi_d */
6, /* ldr_d */
10, /* ldi_d */
7, /* ldxr_d */
11, /* ldxr_d */
9, /* ldxi_d */
6, /* str_d */
10, /* sti_d */
7, /* stxr_d */
11, /* stxr_d */
9, /* stxi_d */
11, /* bltr_d */
34, /* blti_d */
@ -1074,22 +1074,22 @@
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
41, /* va_start */
45, /* va_arg */
54, /* va_arg_d */
0, /* va_end */
# else
#define JIT_INSTR_MAX 43
#define JIT_INSTR_MAX 115
0, /* data */
0, /* live */
7, /* align */
6, /* align */
0, /* save */
0, /* load */
0, /* #name */
0, /* #note */
7, /* label */
43, /* prolog */
115, /* prolog */
0, /* arg */
5, /* addr */
13, /* addi */
@ -1103,7 +1103,7 @@
13, /* subci */
9, /* subxr */
7, /* subxi */
19, /* rsbi */
16, /* rsbi */
7, /* mulr */
14, /* muli */
20, /* qmulr */
@ -1182,17 +1182,17 @@
4, /* ldr_l */
8, /* ldi_l */
6, /* ldxr_c */
5, /* ldxi_c */
8, /* ldxi_c */
6, /* ldxr_uc */
5, /* ldxi_uc */
8, /* ldxi_uc */
6, /* ldxr_s */
5, /* ldxi_s */
8, /* ldxi_s */
6, /* ldxr_us */
5, /* ldxi_us */
8, /* ldxi_us */
5, /* ldxr_i */
7, /* ldxi_i */
5, /* ldxr_ui */
4, /* ldxi_ui */
6, /* ldxi_ui */
5, /* ldxr_l */
7, /* ldxi_l */
4, /* str_c */
@ -1204,9 +1204,9 @@
4, /* str_l */
8, /* sti_l */
5, /* stxr_c */
4, /* stxi_c */
6, /* stxi_c */
6, /* stxr_s */
5, /* stxi_s */
7, /* stxi_s */
5, /* stxr_i */
6, /* stxi_i */
5, /* stxr_l */
@ -1251,22 +1251,22 @@
10, /* bxsubi */
9, /* bxsubr_u */
10, /* bxsubi_u */
0, /* jmpr */
3, /* jmpr */
5, /* jmpi */
3, /* callr */
13, /* calli */
37, /* epilog */
38, /* epilog */
0, /* arg_f */
10, /* addr_f */
20, /* addi_f */
21, /* addi_f */
15, /* subr_f */
20, /* subi_f */
20, /* rsbi_f */
21, /* subi_f */
30, /* rsbi_f */
10, /* mulr_f */
20, /* muli_f */
21, /* muli_f */
15, /* divr_f */
20, /* divi_f */
14, /* negr_f */
21, /* divi_f */
15, /* negr_f */
15, /* absr_f */
5, /* sqrtr_f */
11, /* ltr_f */
@ -1306,13 +1306,13 @@
6, /* ldr_f */
10, /* ldi_f */
7, /* ldxr_f */
6, /* ldxi_f */
9, /* ldxi_f */
6, /* str_f */
10, /* sti_f */
7, /* stxr_f */
7, /* stxi_f */
9, /* stxi_f */
10, /* bltr_f */
20, /* blti_f */
21, /* blti_f */
10, /* bler_f */
25, /* blei_f */
12, /* beqr_f */
@ -1344,12 +1344,12 @@
25, /* addi_d */
15, /* subr_d */
25, /* subi_d */
25, /* rsbi_d */
30, /* rsbi_d */
10, /* mulr_d */
25, /* muli_d */
15, /* divr_d */
25, /* divi_d */
21, /* negr_d */
22, /* negr_d */
16, /* absr_d */
5, /* sqrtr_d */
12, /* ltr_d */
@ -1389,11 +1389,11 @@
6, /* ldr_d */
10, /* ldi_d */
7, /* ldxr_d */
6, /* ldxi_d */
9, /* ldxi_d */
6, /* str_d */
10, /* sti_d */
7, /* stxr_d */
7, /* stxi_d */
9, /* stxi_d */
11, /* bltr_d */
26, /* blti_d */
11, /* bler_d */
@ -1433,9 +1433,9 @@
0, /* movi_d_w */
0, /* x86_retval_f */
0, /* x86_retval_d */
0, /* va_start */
0, /* va_arg */
0, /* va_arg_d */
42, /* va_start */
41, /* va_arg */
50, /* va_arg_d */
0, /* va_end */
#endif /* __CYGWIN__ */
# endif /* __X64_32 */

View file

@ -61,13 +61,16 @@
# define REAL_WORDSIZE 8
#endif
/*
* Types
*/
#if __X32 || __CYGWIN__
typedef jit_pointer_t jit_va_list_t;
#else
typedef struct jit_va_list {
#if __X64 && !__CYGWIN__
jit_int32_t gpoff;
jit_int32_t fpoff;
#endif
jit_pointer_t over;
#if __X64 && !__CYGWIN__
jit_pointer_t save;
/* Declared explicitly as int64 for the x32 abi */
jit_int64_t rdi;
@ -92,8 +95,8 @@ typedef struct jit_va_list {
jit_float64_t _up6;
jit_float64_t xmm7;
jit_float64_t _up7;
#endif
} jit_va_list_t;
#endif
/*
* Prototypes
@ -564,12 +567,12 @@ _jit_ellipsis(jit_state_t *_jit)
assert(!(_jitc->function->self.call & jit_call_varargs));
_jitc->function->self.call |= jit_call_varargs;
#if __X64 && !__CYGWIN__
/* Allocate va_list like object in the stack.
* If applicable, with enough space to save all argument
* registers, and use fixed offsets for them. */
_jitc->function->vaoff = jit_allocai(sizeof(jit_va_list_t));
#if __X64 && !__CYGWIN__
/* Initialize gp offset in save area. */
if (jit_arg_reg_p(_jitc->function->self.argi))
_jitc->function->vagp = _jitc->function->self.argi * 8;