|
From: Tom H. <th...@cy...> - 2004-03-27 18:02:42
|
CVS commit by thughes:
Extended instruction test system to handle x87 floating point instructions
and started working on adding tests for the x87 instruction set.
A addrcheck/tests/insn_fpu.stderr.exp 1.1
A addrcheck/tests/insn_fpu.stdout.exp 1.1
A addrcheck/tests/insn_fpu.vgtest 1.1
A cachegrind/tests/insn_fpu.stderr.exp 1.1
A cachegrind/tests/insn_fpu.stdout.exp 1.1
A cachegrind/tests/insn_fpu.vgtest 1.1
A helgrind/tests/insn_fpu.stderr.exp 1.1
A helgrind/tests/insn_fpu.stdout.exp 1.1
A helgrind/tests/insn_fpu.vgtest 1.1
A memcheck/tests/insn_fpu.stderr.exp 1.1
A memcheck/tests/insn_fpu.stdout.exp 1.1
A memcheck/tests/insn_fpu.vgtest 1.1
A none/tests/insn_fpu.def 1.1
A none/tests/insn_fpu.stderr.exp 1.1
A none/tests/insn_fpu.stdout.exp 1.1
A none/tests/insn_fpu.vgtest 1.1
M +1 -1 addrcheck/tests/Makefile.am 1.7
M +1 -1 cachegrind/tests/Makefile.am 1.12
M +1 -1 helgrind/tests/Makefile.am 1.7
M +1 -1 memcheck/tests/Makefile.am 1.34
M +3 -1 none/tests/Makefile.am 1.35
M +224 -12 none/tests/gen_insn_test.pl 1.5
M +4 -1 tests/cputest.c 1.3
--- valgrind/addrcheck/tests/Makefile.am #1.6:1.7
@@ -1,5 +1,5 @@
noinst_SCRIPTS = filter_stderr
-INSN_TESTS=insn_basic insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
+INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
EXTRA_DIST = $(noinst_SCRIPTS) \
--- valgrind/cachegrind/tests/Makefile.am #1.11:1.12
@@ -1,5 +1,5 @@
noinst_SCRIPTS = filter_stderr filter_cachesim_discards
-INSN_TESTS=insn_basic insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
+INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
EXTRA_DIST = $(noinst_SCRIPTS) \
--- valgrind/helgrind/tests/Makefile.am #1.6:1.7
@@ -1,5 +1,5 @@
noinst_SCRIPTS = filter_stderr
-INSN_TESTS=insn_basic insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
+INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
EXTRA_DIST = $(noinst_SCRIPTS) \
--- valgrind/memcheck/tests/Makefile.am #1.33:1.34
@@ -8,5 +8,5 @@
filter_tronical
-INSN_TESTS=insn_basic insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
+INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
EXTRA_DIST = $(noinst_SCRIPTS) \
--- valgrind/none/tests/Makefile.am #1.34:1.35
@@ -2,5 +2,5 @@
CLEANFILES = $(addsuffix .c,$(INSN_TESTS))
-INSN_TESTS=insn_basic insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
+INSN_TESTS=insn_basic insn_fpu insn_cmov insn_mmx insn_mmxext insn_sse insn_sse2
EXTRA_DIST = $(noinst_SCRIPTS) \
@@ -90,4 +90,6 @@
insn_basic_SOURCES = insn_basic.def
insn_basic_LDADD = -lm
+insn_fpu_SOURCES = insn_fpu.def
+insn_fpu_LDADD = -lm
insn_cmov_SOURCES = insn_cmov.def
insn_cmov_LDADD = -lm
--- valgrind/none/tests/gen_insn_test.pl #1.4:1.5
@@ -8,12 +8,14 @@
r16 => "reg16_t",
r32 => "reg32_t",
- mm => "mm_reg_t",
- xmm => "xmm_reg_t",
+ mm => "reg64_t",
+ xmm => "reg128_t",
m8 => "reg8_t",
m16 => "reg16_t",
m32 => "reg32_t",
- m64 => "mm_reg_t",
- m128 => "xmm_reg_t",
- eflags => "reg32_t"
+ m64 => "reg64_t",
+ m128 => "reg128_t",
+ eflags => "reg32_t",
+ st => "reg64_t",
+ fpusw => "reg16_t"
);
@@ -52,5 +54,7 @@
bh => 5,
ch => 6,
- dh => 7
+ dh => 7,
+ st0 => 0, st1 => 1, st2 => 2, st3 => 3,
+ st4 => 4, st5 => 5, st6 => 6, st7 => 7
);
@@ -113,5 +117,5 @@
float ps[2];
double pd[1];
-} mm_reg_t __attribute__ ((aligned (8)));
+} reg64_t __attribute__ ((aligned (8)));
typedef union {
@@ -126,5 +130,5 @@
float ps[4];
double pd[2];
-} xmm_reg_t __attribute__ ((aligned (16)));
+} reg128_t __attribute__ ((aligned (16)));
static sigjmp_buf catchpoint;
@@ -185,4 +189,5 @@
my @mmregs = map { "mm$_" } (0 .. 7);
my @xmmregs = map { "xmm$_" } (0 .. 7);
+ my @fpregs = map { "st$_" } (0 .. 7);
my @presets;
@@ -190,5 +195,7 @@
my $eflagsmask;
my $eflagsset;
-
+ my $fpuswmask;
+ my $fpuswset;
+
foreach my $preset (split(/\s+/, $presets))
{
@@ -230,4 +237,41 @@
$presetc++;
}
+ elsif ($preset =~ /^st([0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
+ {
+ my $name = "preset$presetc";
+ my $type = "st";
+ my $regnum = $1;
+ my $register = $fpregs[$regnum];
+ my $subtype = $2;
+ my @values = split(/,/, $3);
+
+ die "Register st$1 already used" unless defined($register);
+
+ my $preset = {
+ name => $name,
+ type => $type,
+ subtype => $subtype,
+ register => $register
+ };
+
+ delete($fpregs[$regnum]);
+
+ push @presets, $preset;
+
+ print qq| $ArgTypes{$type} $name = \{ .$subtype = \{|;
+
+ my $valuec = 0;
+
+ foreach my $value (@values)
+ {
+ print qq|,| if $valuec > 0;
+ print qq| $value$SubTypeSuffixes{$subtype}|;
+ $valuec++;
+ }
+
+ print qq| \} \};\n|;
+
+ $presetc++;
+ }
elsif ($preset =~ /^(eflags)\[([^\]]+)\]$/)
{
@@ -241,4 +285,15 @@
$eflagsset = sprintf "0x%x", $values[1];
}
+ elsif ($preset =~ /^(fpusw)\[([^\]]+)\]$/)
+ {
+ my $type = $1;
+ my @values = split(/,/, $2);
+
+ $values[0] = oct($values[0]) if $values[0] =~ /^0/;
+ $values[1] = oct($values[1]) if $values[1] =~ /^0/;
+
+ $fpuswmask = sprintf "0x%x", ~$values[0];
+ $fpuswset = sprintf "0x%x", $values[1];
+ }
else
{
@@ -291,4 +346,41 @@
print qq| \} \};\n|;
}
+ elsif ($arg =~ /^st([0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
+ {
+ my $type = "st";
+ my $regnum = $1;
+ my $register = $fpregs[$regnum] if defined($regnum);
+ my $subtype = $2;
+ my @values = split(/,/, $3);
+
+ die "Register st$1 already used" if defined($regnum) && !defined($register);
+
+ my $arg = {
+ name => $name,
+ type => $type,
+ subtype => $subtype
+ };
+
+ if (defined($register))
+ {
+ $arg->{register} = $register;
+ delete($fpregs[$regnum]);
+ }
+
+ push @args, $arg;
+
+ print qq| $ArgTypes{$type} $name = \{ .$subtype = \{|;
+
+ my $valuec = 0;
+
+ foreach my $value (@values)
+ {
+ print qq|,| if $valuec > 0;
+ print qq| $value$SubTypeSuffixes{$subtype}|;
+ $valuec++;
+ }
+
+ print qq| \} \};\n|;
+ }
elsif ($arg =~ /^(imm8|imm16|imm32)\[([^\]]+)\]$/)
{
@@ -330,4 +422,11 @@
$arg->{register} = shift @xmmregs;
}
+ elsif ($arg->{type} =~ /^st$/)
+ {
+ while (!exists($arg->{register}) || !defined($arg->{register}))
+ {
+ $arg->{register} = shift @fpregs;
+ }
+ }
}
@@ -384,4 +483,23 @@
print qq| $ArgTypes{$type} $name;\n|;
}
+ elsif ($result =~ /^(st[0-9]+)\.(ps|pd)\[([^\]]+)\]$/)
+ {
+ my $register = $1;
+ my $type = "st";
+ my $subtype = $2;
+ my @values = split(/,/, $3);
+
+ my $result = {
+ name => $name,
+ type => $type,
+ subtype => $subtype,
+ register => $register,
+ values => [ @values ]
+ };
+
+ push @results, $result;
+
+ print qq| $ArgTypes{$type} $name;\n|;
+ }
elsif ($result =~ /^eflags\[([^\]]+)\]$/)
{
@@ -408,4 +526,28 @@
}
}
+ elsif ($result =~ /^fpusw\[([^\]]+)\]$/)
+ {
+ my @values = split(/,/, $1);
+
+ $values[0] = oct($values[0]) if $values[0] =~ /^0/;
+ $values[1] = oct($values[1]) if $values[1] =~ /^0/;
+
+ my $result = {
+ name => $name,
+ type => "fpusw",
+ subtype => "ud",
+ values => [ map { sprintf "0x%x", $_ } @values ]
+ };
+
+ push @results, $result;
+
+ print qq| $ArgTypes{fpusw} $name;\n|;
+
+ if (!defined($fpuswmask) && !defined($fpuswset))
+ {
+ $fpuswmask = sprintf "0x%x", ~$values[0];
+ $fpuswset = sprintf "0x%x", $values[0] & ~$values[1];
+ }
+ }
else
{
@@ -420,5 +562,5 @@
foreach my $result (@results)
{
- if ($result->{type} =~ /^(m(8|16|32|64|128)|eflags)$/)
+ if ($result->{type} =~ /^(m(8|16|32|64|128)|st|flags|fpusw)$/)
{
$result->{argnum} = $argnum++;
@@ -451,4 +593,6 @@
print qq| \"fsave %$stateargnum\\n\"\n|;
+ my @fpargs;
+
foreach my $arg (@presets, @args)
{
@@ -474,6 +618,29 @@
print qq| \"movhps 8%$arg->{argnum}, %%$arg->{register}\\n\"\n|;
}
+ elsif ($arg->{type} eq "st")
+ {
+ $fpargs[$RegNums{$arg->{register}}] = $arg;
+ }
}
+ foreach my $arg (reverse @fpargs)
+ {
+ if (defined($arg))
+ {
+ if ($arg->{subtype} eq "ps")
+ {
+ print qq| \"flds %$arg->{argnum}\\n\"\n|;
+ }
+ elsif ($arg->{subtype} eq "pd")
+ {
+ print qq| \"fldl %$arg->{argnum}\\n\"\n|;
+ }
+ }
+ else
+ {
+ print qq| \"fldz\\n\"\n|;
+ }
+ }
+
if (defined($eflagsmask) || defined($eflagsset))
{
@@ -496,4 +663,12 @@
print qq|$prefix%%$arg->{register}|;
}
+ elsif ($arg->{type} =~ /^st$/)
+ {
+ my $register = $arg->{register};
+
+ $register =~ s/st(\d+)/st\($1\)/;
+
+ print qq|$prefix%%$register|;
+ }
elsif ($arg->{type} =~ /^(m(8|16|32|64|128))$/)
{
@@ -517,4 +692,6 @@
print qq|\\n\"\n|;
+ my @fpresults;
+
foreach my $result (@results)
{
@@ -540,4 +717,8 @@
print qq| \"movhps %%$result->{register}, 8%$result->{argnum}\\n\"\n|;
}
+ elsif ($result->{type} eq "st")
+ {
+ $fpresults[$RegNums{$result->{register}}] = $result;
+ }
elsif ($result->{type} eq "eflags")
{
@@ -545,4 +726,27 @@
print qq| \"popl %$result->{argnum}\\n\"\n|;
}
+ elsif ($result->{type} eq "fpusw")
+ {
+ print qq| \"fstsw %$result->{argnum}\\n\"\n|;
+ }
+ }
+
+ foreach my $result (@fpresults)
+ {
+ if (defined($result))
+ {
+ if ($result->{subtype} eq "ps")
+ {
+ print qq| \"fstps %$result->{argnum}\\n\"\n|;
+ }
+ elsif ($result->{subtype} eq "pd")
+ {
+ print qq| \"fstpl %$result->{argnum}\\n\"\n|;
+ }
+ }
+ else
+ {
+ print qq| \"fincstp\\n\"\n|;
+ }
}
@@ -555,5 +759,5 @@
foreach my $result (@results)
{
- if ($result->{type} =~ /^(m(8|16|32|64|128)|eflags)$/)
+ if ($result->{type} =~ /^(m(8|16|32|64|128)|st|eflags|fpusw)$/)
{
print qq|$prefix\"=m\" \($result->{name}\)|;
@@ -590,5 +794,5 @@
foreach my $arg (@presets, @args)
{
- if ($arg->{register})
+ if ($arg->{register} && $arg->{type} ne "st")
{
print qq|$prefix\"$arg->{register}\"|;
@@ -617,4 +821,8 @@
print qq|${prefix}\($result->{name}.ud[0] & $values[0]UL\) == $values[1]UL|;
}
+ elsif ($type eq "fpusw")
+ {
+ print qq|${prefix}\($result->{name}.uw[0] & $values[0]\) == $values[1]|;
+ }
else
{
@@ -660,4 +868,8 @@
print qq| printf(" eflags & 0x%lx = 0x%lx (expected 0x%lx)\\n", $values[0]UL, $result->{name}.ud\[0\] & $values[0]UL, $values[1]UL);\n|;
}
+ elsif ($type eq "fpusw")
+ {
+ print qq| printf(" fpusw & 0x%x = 0x%x (expected 0x%x)\\n", $values[0], $result->{name}.uw\[0\] & $values[0], $values[1]);\n|;
+ }
else
{
--- valgrind/tests/cputest.c #1.2:1.3
@@ -24,5 +24,8 @@ int main(int argc, char **argv)
if ( argc == 2 ) {
- if ( strcmp( argv[1], "cmov" ) == 0 ) {
+ if ( strcmp( argv[1], "fpu" ) == 0 ) {
+ level = 1;
+ mask = 1 << 0;
+ } else if ( strcmp( argv[1], "cmov" ) == 0 ) {
level = 1;
mask = 1 << 15;
|