diff options
-rw-r--r-- | tools/regression/ia64/unaligned/test.c | 154 | ||||
-rw-r--r-- | tools/regression/ia64/unaligned/unaligned.t | 64 |
2 files changed, 181 insertions, 37 deletions
diff --git a/tools/regression/ia64/unaligned/test.c b/tools/regression/ia64/unaligned/test.c index 2d8e4e4..936f355 100644 --- a/tools/regression/ia64/unaligned/test.c +++ b/tools/regression/ia64/unaligned/test.c @@ -26,9 +26,72 @@ * $FreeBSD$ */ +#include <machine/float.h> #include <string.h> -struct { +/* Memory accesses. */ +#define Load 0x01 +#define Store 0x02 + +/* Data type. */ +#define Integer 0x11 +#define FloatingPoint 0x12 + +/* Data size. */ +#define Small 0x21 +#define Medium 0x22 +#define Large 0x23 + +/* Post increment. */ +#define NoPostInc 0x31 +#define MinConstPostInc 0x32 +#define PlusConstPostInc 0x33 +#define ScratchRegPostInc 0x34 +#define PreservedRegPostInc 0x35 + +#if ACCESS == 0 || TYPE == 0 || SIZE == 0 || POSTINC == 0 +#error define ACCESS, TYPE, SIZE and/or POSTINC +#endif + +#if TYPE == Integer +# define REG "r8" +# if SIZE == Small +# define DATA_TYPE short +# define DATA_VALUE 0x1234 +# define LD "ld2" +# define ST "st2" +# elif SIZE == Medium +# define DATA_TYPE int +# define DATA_VALUE 0x12345678 +# define LD "ld4" +# define ST "st4" +# elif SIZE == Large +# define DATA_TYPE long +# define DATA_VALUE 0x1234567890ABCDEF +# define LD "ld8" +# define ST "st8" +# endif +#elif TYPE == FloatingPoint +# define REG "f6" +# if SIZE == Small +# define DATA_TYPE float +# define DATA_VALUE FLT_MIN +# define LD "ldfs" +# define ST "stfs" +# elif SIZE == Medium +# define DATA_TYPE double +# define DATA_VALUE DBL_MIN +# define LD "ldfd" +# define ST "stfd" +# elif SIZE == Large +# define DATA_TYPE long double +# define DATA_VALUE LDBL_MIN +# define LD "ldfe" +# define ST "stfe" +# endif +#endif + +static struct { DATA_TYPE aligned; char _; char misaligned[sizeof(DATA_TYPE)]; @@ -44,17 +107,90 @@ main() /* Set PSR.ac. */ asm volatile("sum 8"); -#if defined(TEST_STORE) - /* Misaligned store. */ - *misaligned = value; - memcpy(aligned, misaligned, sizeof(DATA_TYPE)); -#elif defined(TEST_LOAD) +#if ACCESS == Load + /* + * LOAD + */ memcpy(misaligned, &value, sizeof(DATA_TYPE)); + +# if POSTINC == NoPostInc /* Misaligned load. */ *aligned = *misaligned; -#else -#error Define TEST_LOAD or TEST_STORE +# elif POSTINC == MinConstPostInc + asm volatile( + "ld8 r2=%0;;" + LD " " REG "=[r2],%2;;" + "st8 %0=r2;" ST " %1=" REG ";;" + : "=m"(misaligned), "=m"(*aligned) + : "i"(-sizeof(DATA_TYPE)) + : REG, "r2", "memory"); +# elif POSTINC == PlusConstPostInc + asm volatile( + "ld8 r2=%0;;" + LD " " REG "=[r2],%2;;" + "st8 %0=r2;" ST " %1=" REG ";;" + : "=m"(misaligned), "=m"(*aligned) + : "i"(sizeof(DATA_TYPE)) + : REG, "r2", "memory"); +# elif POSTINC == ScratchRegPostInc + asm volatile( + "ld8 r2=%0; mov r3=%2;;" + LD " " REG "=[r2],r3;;" + "st8 %0=r2;" ST " %1=" REG ";;" + : "=m"(misaligned), "=m"(*aligned) + : "i"(sizeof(DATA_TYPE)) + : REG, "r2", "r3", "memory"); +# elif POSTINC == PreservedRegPostInc + asm volatile( + "ld8 r2=%0; mov r4=%2;;" + LD " " REG "=[r2],r4;;" + "st8 %0=r2;" ST " %1=" REG ";;" + : "=m"(misaligned), "=m"(*aligned) + : "i"(sizeof(DATA_TYPE)) + : REG, "r2", "r4", "memory"); +# endif + +#elif ACCESS == Store + /* + * STORE + */ + +# if POSTINC == NoPostInc + /* Misaligned store. */ + *misaligned = value; +# elif POSTINC == MinConstPostInc + asm volatile( + "ld8 r2=%0;" LD " " REG "=%1;;" + ST " [r2]=" REG ",%2;;" + "st8 %0=r2;;" + : "=m"(misaligned) + : "m"(value), "i"(-sizeof(DATA_TYPE)) + : REG, "r2", "memory"); +# elif POSTINC == PlusConstPostInc + asm volatile( + "ld8 r2=%0;" LD " " REG "=%1;;" + ST " [r2]=" REG ",%2;;" + "st8 %0=r2;;" + : "=m"(misaligned) + : "m"(value), "i"(sizeof(DATA_TYPE)) + : REG, "r2", "memory"); +# elif POSTINC == ScratchRegPostInc || POSTINC == PreservedRegPostInc + return (1); +# endif + + memcpy(aligned, misaligned, sizeof(DATA_TYPE)); #endif - return (*aligned == value) ? 0 : 1; + if (*aligned != value) + return (2); + +#if POSTINC == NoPostInc + return (0); +#elif POSTINC == MinConstPostInc + return (((char *)misaligned == data.misaligned - sizeof(DATA_TYPE)) + ? 0 : 4); +#else + return (((char *)misaligned == data.misaligned + sizeof(DATA_TYPE)) + ? 0 : 4); +#endif } diff --git a/tools/regression/ia64/unaligned/unaligned.t b/tools/regression/ia64/unaligned/unaligned.t index 57a31cd..47bdd34 100644 --- a/tools/regression/ia64/unaligned/unaligned.t +++ b/tools/regression/ia64/unaligned/unaligned.t @@ -29,38 +29,42 @@ my $srcdir = `dirname $0`; chomp $srcdir; -my $tmpfile = "/tmp/unaligned." . $$; +my @accesses = ("Load", "Store"); +my @types = ("Integer", "FloatingPoint"); +my @sizes = ("Small", "Medium", "Large"); +my @postincs = ("NoPostInc", "MinConstPostInc", "PlusConstPostInc", + "ScratchRegPostInc", "PreservedRegPostInc"); -my @types = ("short", "int", "long", "float", "double", "long double"); -my %values = ( "short" => "0x1234", - "int" => "0x12345678", - "long" => "0x123456789abcdef0", - "float" => "1.04716", - "double" => "3.1415", - "long double" => "0.33312112048384" - ); -my @tests = ("TEST_LOAD", "TEST_STORE"); +sub run ($$$$$) { + local ($nr, $access, $type, $size, $postinc) = @_; + local $test = "${access}_${type}_${size}_${postinc}"; + local $tmpfile = "/tmp/" . $$ . "_$test"; + local $st; -sub run ($$$) { - local ($nr, $type, $test) = @_; - local $value = $values{$type}; - local $st; - $st = system("cc -o $tmpfile -DDATA_TYPE='$type' -DDATA_VALUE=$value -D$test -Wall $srcdir/test.c"); - if ($st != 0) { - print "not ok $nr ($type,$test) # compiling $tmpfile\n"; - return; - } + $st = system("cc -o $tmpfile -DACCESS=$access -DTYPE=$type -DSIZE=$size -DPOSTINC=$postinc -Wall -O -g $srcdir/test.c"); + if ($st != 0) { + print "not ok $nr $test # compiling $test\n"; + } + else { $st = system($tmpfile); if ($st == 0) { - print "ok $nr ($type,$test)\n"; + print "ok $nr $test\n"; + } + elsif ($st == 256) { + print "ok $nr $test # SKIP nonexistent combination\n"; + } + elsif ($st == 512) { + print "not ok $nr $test # value mismatch\n"; } - elsif ($st == 1) { - print "not ok $nr ($type,$test) # value mismatch\n"; + elsif ($st == 1024) { + print "not ok $nr $test # post increment mismatch\n"; } else { - print "not ok $nr ($type,$test) # signalled\n"; + print "not ok $nr $test # signalled (exit status $st)\n"; + return; # Preserve the executable } - unlink $tmpfile; + } + unlink $tmpfile; } system("sysctl debug.unaligned_test=1"); @@ -69,14 +73,18 @@ if (`sysctl -n debug.unaligned_test` != "1") { exit 0; } -my $count = @types * @tests; +my $count = @accesses * @types * @sizes * @postincs; print "1..$count\n"; my $nr=0; -foreach $type (@types) { - foreach $test (@tests) { - run ++$nr, $type, $test; +foreach $access (@accesses) { + foreach $type (@types) { + foreach $size (@sizes) { + foreach $postinc (@postincs) { + run ++$nr, $access, $type, $size, $postinc; + } } + } } system("sysctl debug.unaligned_test=0"); |