summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--tools/regression/ia64/unaligned/test.c154
-rw-r--r--tools/regression/ia64/unaligned/unaligned.t64
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");
OpenPOWER on IntegriCloud