1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-06-11 22:31:12 +02:00

Add support to test different/alternate code generation setups.

* check/lightning.c: Remove the ".cpu name value" syntax,
	as it was not able to do proper changes before the jit
	internal data structure was initialized. Now it supports
	several getopt options to force using different jit
	generation options, effectively replacing the previous
	syntax.

	* check/run-test: Add simple extra logic to handle differently
	named test scripts, used to test things like x87 coprocessor
	in ix86, and arm instruction set or software float in armv7l.

	* configure.ac: Add some AC_RUN_IFELSE calls to figure at
	compile time if can test different code generation options,
	and update Makefile generation accordingly.

	* check/Makefile.am, lib/jit_arm.c, lib/jit_x86.c: Update to
	properly work with the test tool updating the jit_cpu global
	information.

	* check/check.arm.sh, check/check.swf.sh, check/check.x87.sh:
	New wrapper files passing -mthumb=0, mvfp=0 and -mx87=1 to
	the test tool, if applicable, so that it can validate alternate
	code generation options on test hosts that support them.
This commit is contained in:
pcpa 2012-12-14 22:40:08 -02:00
parent 0e83b52d49
commit d05538bff6
10 changed files with 322 additions and 75 deletions

View file

@ -1,3 +1,29 @@
2012-12-14 Paulo Andrade <pcpa@gnu.org>
* check/lightning.c: Remove the ".cpu name value" syntax,
as it was not able to do proper changes before the jit
internal data structure was initialized. Now it supports
several getopt options to force using different jit
generation options, effectively replacing the previous
syntax.
* check/run-test: Add simple extra logic to handle differently
named test scripts, used to test things like x87 coprocessor
in ix86, and arm instruction set or software float in armv7l.
* configure.ac: Add some AC_RUN_IFELSE calls to figure at
compile time if can test different code generation options,
and update Makefile generation accordingly.
* check/Makefile.am, lib/jit_arm.c, lib/jit_x86.c: Update to
properly work with the test tool updating the jit_cpu global
information.
* check/check.arm.sh, check/check.swf.sh, check/check.x87.sh:
New wrapper files passing -mthumb=0, mvfp=0 and -mx87=1 to
the test tool, if applicable, so that it can validate alternate
code generation options on test hosts that support them.
2012-12-14 Paulo Andrade <pcpa@gnu.org>
* lib/jit_x86-x87.c, lib/jit_x86.c: Correct test cases in ix86

View file

@ -58,10 +58,13 @@ EXTRA_DIST = \
alu_com.tst alu_com.ok \
alu_neg.tst alu_neg.ok \
varargs.tst varargs.ok \
check.sh run-test \
all.tst
check.sh \
check.x87.sh \
check.arm.sh check.swf.sh \
run-test all.tst
TESTS = 3to2 add allocai \
base_TESTS = \
3to2 add allocai \
bp divi fib rpn \
ldstr ldsti \
ldstxr ldstxi \
@ -75,12 +78,79 @@ TESTS = 3to2 add allocai \
alu_com alu_neg \
varargs
CLEANFILES = $(TESTS)
# Not so pretty but good for a prototype
$(TESTS): check.sh
$(base_TESTS): check.sh
$(LN_S) $(srcdir)/check.sh $@
TESTS = $(base_TESTS)
if test_x86_x87
x87_TESTS = \
3to2.x87 add.x87 allocai.x87 \
bp.x87 divi.x87 fib.x87 rpn.x87 \
ldstr.x87 ldsti.x87 \
ldstxr.x87 ldstxi.x87 \
ldstr-c.x87 ldstxr-c.x87 ldstxi-c.x87 \
cvt.x87 branch.x87 \
alu_add.x87 alux_add.x87 \
alu_sub.x87 alux_sub.x87 \
alu_mul.x87 alu_div.x87 alu_rem.x87 \
alu_and.x87 alu_or.x87 alu_xor.x87 \
alu_lsh.x87 alu_rsh.x87 \
alu_com.x87 alu_neg.x87 \
varargs.x87
$(x87_TESTS): check.x87.sh
$(LN_S) $(srcdir)/check.x87.sh $@
TESTS += $(x87_TESTS)
endif
if test_arm_arm
arm_TESTS = \
3to2.arm add.arm allocai.arm \
bp.arm divi.arm fib.arm rpn.arm \
ldstr.arm ldsti.arm \
ldstxr.arm ldstxi.arm \
ldstr-c.arm ldstxr-c.arm ldstxi-c.arm \
cvt.arm branch.arm \
alu_add.arm alux_add.arm \
alu_sub.arm alux_sub.arm \
alu_mul.arm alu_div.arm alu_rem.arm \
alu_and.arm alu_or.arm alu_xor.arm \
alu_lsh.arm alu_rsh.arm \
alu_com.arm alu_neg.arm \
varargs.arm
$(arm_TESTS): check.arm.sh
$(LN_S) $(srcdir)/check.arm.sh $@
TESTS += $(arm_TESTS)
endif
if test_arm_swf
swf_TESTS = \
3to2.swf add.swf allocai.swf \
bp.swf divi.swf fib.swf rpn.swf \
ldstr.swf ldsti.swf \
ldstxr.swf ldstxi.swf \
ldstr-c.swf ldstxr-c.swf ldstxi-c.swf \
cvt.swf branch.swf \
alu_add.swf alux_add.swf \
alu_sub.swf alux_sub.swf \
alu_mul.swf alu_div.swf alu_rem.swf \
alu_and.swf alu_or.swf alu_xor.swf \
alu_lsh.swf alu_rsh.swf \
alu_com.swf alu_neg.swf \
varargs.swf
$(swf_TESTS): check.swf.sh
$(LN_S) $(srcdir)/check.swf.sh $@
TESTS += $(swf_TESTS)
endif
CLEANFILES = $(TESTS)
TESTS_ENVIRONMENT=$(srcdir)/run-test
debug: $(check_PROGRAMS)

2
check/check.arm.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
./lightning -mthumb=0 $srcdir/`basename $0 | sed -e 's|\.arm$||'`.tst

2
check/check.swf.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
./lightning -mvfp=0 $srcdir/`basename $0 | sed -e 's|\.swf$||'`.tst

2
check/check.x87.sh Executable file
View file

@ -0,0 +1,2 @@
#!/bin/sh
./lightning -mx87=1 $srcdir/`basename $0 | sed -e 's|\.x87$||'`.tst

View file

@ -2061,46 +2061,6 @@ dot(void)
check_data(length);
data_offset += length;
}
else if (strcmp(parser.string, "cpu") == 0) {
if (primary(skip_ws) != tok_symbol)
error("expecting cpu flag");
ch = get_int(skip_ws);
if (strcmp(parser.string, "sse2") == 0)
#if defined(__i386__)
/* only meaningful for i386 as there is no x87 path for x86_64
* and should only use just after jit_prolog and not mix with
* code that uses xmm registers */
jit_cpu.sse2 = !!ch
#endif
;
else if (strcmp(parser.string, "sse4_1") == 0)
#if defined(__i386__) || defined(__x86_64__)
jit_cpu.sse4_1 = !!ch
#endif
;
else if (strcmp(parser.string, "version") == 0)
#if defined(__arm__)
jit_cpu.version = ch
#endif
;
else if (strcmp(parser.string, "thumb") == 0)
#if defined(__arm__)
jit_cpu.thumb = ch
#endif
;
else if (strcmp(parser.string, "vfp") == 0)
#if defined(__arm__)
jit_cpu.vfp = ch
#endif
;
else if (strcmp(parser.string, "neon") == 0)
#if defined(__arm__)
jit_cpu.neon = !!ch
#endif
;
else
warn("ignoring \".cpu %s %d\"", parser.string, ch);
}
else if (strcmp(parser.string, "disasm") == 0)
flag_disasm = 1;
else
@ -3776,21 +3736,46 @@ static void
usage(void)
{
fprintf(stderr, "\
Usage: %s [jit-assembler-options] file [jit-program-options]\n\
Options:\n\
Usage: %s [jit assembler options] file [jit program options]\n\
Jit assembler options:\n\
-help Display this information\n\
-v[0-3] Verbose output level\n\
-D<macro>[=<val>] Preprocessor options\n"
#if defined(__i386__) && __WORDSIZE == 32
" -mx87=1 Force using x87 when sse2 available\n"
#endif
#if defined(__i386__) || defined(__x86_64__)
" -msse4_1=0 Do not use sse4_1 instructions when available\n"
#endif
#if defined(__arm__)
" -mcpu=<val> Force cpu version (4, 5, 6 or 7)\n\
-mthumb[=0|1] Enable or disable thumb\n\
-mvfp=<val> Set vpf version (0 to disable)\n\
-mneon[=0|1] Enable or disable neon\n"
#endif
, progname);
finish_jit();
exit(1);
}
int
main(int argc, char *argv[])
{
static const char *short_options = "v::";
static const char *short_options = "v:";
static struct option long_options[] = {
{ "help", 0, 0, 'h' },
#if defined(__i386__) && __WORDSIZE == 32
{ "mx87", 1, 0, '7' },
#endif
#if defined(__i386__) || defined(__x86_64__)
{ "msse4_1", 1, 0, '4' },
#endif
#if defined(__arm__)
{ "mcpu", 1, 0, 'c' },
{ "mthumb", 1, 0, 't' },
{ "mvfp", 1, 0, 'f' },
{ "mneon", 1, 0, 'n' },
#endif
{ 0, 0, 0, 0 }
};
int offset;
@ -3799,6 +3784,8 @@ main(int argc, char *argv[])
int opt_short;
char cmdline[8192];
init_jit();
progname = argv[0];
for (;;) {
if ((opt_short = getopt_long_only(argc, argv, short_options,
@ -3818,6 +3805,67 @@ main(int argc, char *argv[])
else
flag_verbose = 1;
break;
#if defined(__i386__) && __WORDSIZE == 32
case '7':
if (optarg) {
if (strcmp(optarg, "") == 0 || strcmp(optarg, "1") == 0)
jit_cpu.sse2 = 0;
else if (strcmp(optarg, "0"))
usage();
}
else
jit_cpu.sse2 = 0;
break;
#endif
#if defined(__i386__) || defined(__x86_64__)
case '4':
if (optarg) {
if (strcmp(optarg, "0") == 0)
jit_cpu.sse4_2 = 0;
else if (strcmp(optarg, "1"))
usage();
}
break;
#endif
#if defined(__arm__)
case 'c':
if (optarg) {
offset = strtol(optarg, &endptr, 10);
if (*endptr || offset < 0)
usage();
if (offset < jit_cpu.version)
jit_cpu.version = offset;
}
break;
case 't':
if (optarg) {
if (strcmp(optarg, "0") == 0)
jit_cpu.thumb = 0;
else if (strcmp(optarg, "1") && strcmp(optarg, "2"))
usage();
}
break;
case 'f':
# if !defined(__ARM_PCS_VFP)
/* Do not allow overrinding hard float abi */
if (optarg) {
offset = strtol(optarg, &endptr, 10);
if (*endptr || offset < 0)
usage();
if (offset < jit_cpu.vfp)
jit_cpu.vfp = offset;
}
# endif
break;
case 'n':
if (optarg) {
if (strcmp(optarg, "0") == 0)
jit_cpu.neon = 0;
else if (strcmp(optarg, "1"))
usage();
}
break;
#endif
}
}
@ -3899,7 +3947,6 @@ main(int argc, char *argv[])
}
#endif
init_jit();
_jit = jit_new_state();
instrs = new_hash();

View file

@ -1,9 +1,10 @@
#! /bin/sh
ok=`echo $1 | sed -e 's@\.\(x87\|arm\|swf\)@@'`
$1 | tr -d \\r > $1.log
if cmp -s $srcdir/$1.ok $1.log; then
if cmp -s $srcdir/$ok.ok $1.log; then
rm $1.log
else
diff $srcdir/$1.ok $1.log
diff $srcdir/$ok.ok $1.log
exit 1
fi

View file

@ -67,16 +67,104 @@ case "$target_cpu" in
*powerpc*) cpu=ppc ;;
*) ;;
esac
if test x$cpu = x; then
AC_MSG_ERROR([cpu $target_cpu not supported])
fi
AM_CONDITIONAL(cpu_arm, [test cpu-$cpu = cpu-arm])
AM_CONDITIONAL(cpu_mips, [test cpu-$cpu = cpu-mips])
AM_CONDITIONAL(cpu_ppc, [test cpu-$cpu = cpu-ppc])
AM_CONDITIONAL(cpu_x86, [test cpu-$cpu = cpu-x86])
if test $cpu = arm; then
AC_CHECK_LIB(m, sqrtf, ,
[AC_MSG_ERROR([sqrtf required but not available])])
# Test x87 if both, x87 and sse2 available
ac_cv_test_x86_x87=
# Test arm instruction set if thumb instruction set available
ac_cv_test_arm_arm=
# Test sofware float if vfp available and not using hard float abi
ac_cv_test_arm_swf=
save_CFLAGS=$CFLAGS
CFLAGS="-I$PWD/include -D_GNU_SOURCE"
if test x$cpu = x; then
AC_MSG_ERROR([cpu $target_cpu not supported])
elif test $cpu = x86; then
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <lightning.h>
int main(void) {
int ac, flags;
unsigned int eax, ebx, ecx, edx;
if (__WORDSIZE == 64)
return 1;
__asm__ volatile ("pushfl;\n\t"
"popl %0;\n\t"
"movl \$0x240000, %1;\n\t"
"xorl %0, %1;\n\t"
"pushl %1;\n\t"
"popfl;\n\t"
"pushfl;\n\t"
"popl %1;\n\t"
"xorl %0, %1;\n\t"
"pushl %0;\n\t"
"popfl"
: "=r" (flags), "=r" (ac));
if ((ac & (1 << 21)) == 0)
return 1;
__asm__ volatile ("xchgl %%ebx, %1; cpuid; xchgl %%ebx, %1"
: "=a" (eax), "=r" (ebx),
"=c" (ecx), "=d" (edx)
: "0" (1));
return (edx & 1 << 26) ? 0 : 1;
}
]])],[ac_cv_test_x86_x87=yes],[][])
elif test $cpu = arm; then
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
int main(void) {
#if defined(__linux__)
FILE *fp;
char buf[128];
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
return 1;
while (fgets(buf, sizeof(buf), fp)) {
if (strncmp(buf, "Features\t:", 10) == 0 &&
strstr(buf + 10, "thumb")) {
fclose(fp);
return 0;
}
}
fclose(fp);
#endif
return 1;
}
]])],[ac_cv_test_arm_arm=yes],[][])
AC_RUN_IFELSE([AC_LANG_SOURCE([[
#include <stdio.h>
int main(void) {
#if defined(__linux__)
FILE *fp;
char buf[128];
# if !defined(__ARM_PCS_VFP)
if ((fp = fopen("/proc/cpuinfo", "r")) == NULL)
return 1;
while (fgets(buf, sizeof(buf), fp)) {
if (strncmp(buf, "Features\t:", 10) == 0 &&
strstr(buf + 10, "vfp")) {
fclose(fp);
return 0;
}
}
fclose(fp);
# endif
#endif
return 1;
}
]])],[ac_cv_test_arm_swf=yes],[][])
fi
CFLAGS=$save_CFLAGS
AM_CONDITIONAL(test_x86_x87, [test x$ac_cv_test_x86_x87 = xyes])
AM_CONDITIONAL(test_arm_arm, [test x$ac_cv_test_arm_arm = xyes])
AM_CONDITIONAL(test_arm_swf, [test x$ac_cv_test_arm_swf = xyes])
if test $cpu=arm; then
AC_CHECK_LIB(m, sqrtf, ,
[AC_MSG_ERROR([sqrtf required but not available])])
fi
AC_SUBST([LIGHTNING_CFLAGS])

View file

@ -185,17 +185,22 @@ void
_jit_init(jit_state_t *_jit)
{
jit_int32_t regno;
static jit_bool_t first = 1;
_jit->reglen = jit_size(_rvs) - 1;
/* jit_get_cpu() should have been already called, and only once */
if (!jit_cpu.vfp) {
/* cause register to never be allocated, because simple
* software float only allocates stack space for 8 slots */
for (regno = _D8; regno < _D7; regno++)
_rvs[regno].spec = 0;
}
if (!jit_cpu.abi) {
for (regno = _S15; regno <= _D0; regno++)
_rvs[regno].spec &= ~rc(arg);
if (first) {
/* jit_get_cpu() should have been already called, and only once */
if (!jit_cpu.vfp) {
/* cause register to never be allocated, because simple
* software float only allocates stack space for 8 slots */
for (regno = _D8; regno < _D7; regno++)
_rvs[regno].spec = 0;
}
if (!jit_cpu.abi) {
for (regno = _S15; regno <= _D0; regno++)
_rvs[regno].spec &= ~rc(arg);
}
first = 0;
}
}

View file

@ -268,15 +268,19 @@ jit_get_cpu(void)
void
_jit_init(jit_state_t *_jit)
{
jit_int32_t regno;
static jit_bool_t first = 1;
_jit->reglen = jit_size(_rvs) - 1;
#if __WORDSIZE == 32
if (!jit_cpu.sse2) {
jit_int32_t regno;
for (regno = _jit->reglen; regno >= 0; regno--) {
if (_rvs[regno].spec & jit_class_xpr)
_rvs[regno].spec = 0;
if (first) {
if (!jit_cpu.sse2) {
for (regno = _jit->reglen; regno >= 0; regno--) {
if (_rvs[regno].spec & jit_class_xpr)
_rvs[regno].spec = 0;
}
}
first = 0;
}
#endif
}