From 255cee09b71255051c2b40eae0c88bffce1f6f32 Mon Sep 17 00:00:00 2001 From: xleroy Date: Sat, 20 Apr 2013 07:54:52 +0000 Subject: Big merge of the newregalloc-int64 branch. Lots of changes in two directions: 1- new register allocator (+ live range splitting, spilling&reloading, etc) based on a posteriori validation using the Rideau-Leroy algorithm 2- support for 64-bit integer arithmetic (type "long long"). git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2200 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- runtime/test/test_int64.c | 238 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 238 insertions(+) create mode 100644 runtime/test/test_int64.c (limited to 'runtime/test') diff --git a/runtime/test/test_int64.c b/runtime/test/test_int64.c new file mode 100644 index 00000000..11adce32 --- /dev/null +++ b/runtime/test/test_int64.c @@ -0,0 +1,238 @@ +/* ************************************************************************** */ +/* */ +/* The Compcert verified compiler */ +/* */ +/* Xavier Leroy, INRIA Paris-Rocquencourt */ +/* */ +/* Copyright (c) 2013 Institut National de Recherche en Informatique et */ +/* en Automatique. */ +/* */ +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions are met:*/ +/* * Redistributions of source code must retain the above copyright */ +/* notice, this list of conditions and the following disclaimer. */ +/* * Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ +/* * Neither the name of the nor the */ +/* names of its contributors may be used to endorse or promote products */ +/* derived from this software without specific prior written permission.*/ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS */ +/* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ +/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR */ +/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */ +/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, */ +/* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR */ +/* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF */ +/* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING */ +/* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS */ +/* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/* ************************************************************************** */ + +/* Differential testing of 64-bit integer operations */ +/* This file is to be compiled by a C compiler other than CompCert C */ + +#include +#include + +typedef unsigned long long u64; +typedef signed long long s64; + +extern s64 __i64_neg(s64 x); +extern s64 __i64_add(s64 x, s64 y); +extern s64 __i64_sub(s64 x, s64 y); +extern s64 __i64_mul(s64 x, s64 y); +extern u64 __i64_udiv(u64 x, u64 y); +extern u64 __i64_umod(u64 x, u64 y); +extern s64 __i64_sdiv(s64 x, s64 y); +extern s64 __i64_smod(s64 x, s64 y); + +extern u64 __i64_shl(u64 x, unsigned amount); +extern u64 __i64_shr(u64 x, unsigned amount); +extern s64 __i64_sar(s64 x, unsigned amount); + +extern int __i64_ucmp(u64 x, u64 y); +extern int __i64_scmp(s64 x, s64 y); + +extern double __i64_utod(u64 x); +extern double __i64_stod(s64 x); +extern u64 __i64_dtou(double d); +extern s64 __i64_dtos(double d); + +static u64 rnd64(void) +{ + static u64 seed = 0; + seed = seed * 6364136223846793005ULL + 1442695040888963407ULL; + return seed; +} + +static int error = 0; + +static void test1(u64 x, u64 y) +{ + u64 z, uy; + s64 t, sy; + int i; + double f, g; + + z = __i64_neg(x); + if (z != -x) + error++, printf("- %016llx = %016llx, expected %016llx\n", x, z, -x); + z = __i64_add(x, y); + if (z != x + y) + error++, printf("%016llx + %016llx = %016llx, expected %016llx\n", x, y, z, x + y); + + z = __i64_sub(x, y); + if (z != x - y) + error++, printf("%016llx - %016llx = %016llx, expected %016llx\n", x, y, z, x - y); + + z = __i64_mul(x, y); + if (z != x * y) + error++, printf("%016llx * %016llx = %016llx, expected %016llx\n", x, y, z, x * y); + + if (y != 0) { + + z = __i64_udiv(x, y); + if (z != x / y) + error++, printf("%llu /u %llu = %llu, expected %llu\n", x, y, z, x / y); + + z = __i64_umod(x, y); + if (z != x % y) + error++, printf("%llu %%u %llu = %llu, expected %llu\n", x, y, z, x % y); + + } + + if (y != 0 && !(x == 0x800000000000LLU && y == -1)) { + + t = __i64_sdiv(x, y); + if (t != (s64) x / (s64) y) + error++, printf("%lld /s %lld = %lld, expected %lld\n", x, y, t, (s64) x / (s64) y); + + t = __i64_smod(x, y); + if (t != (s64) x % (s64) y) + error++, printf("%lld %%s %lld = %lld, expected %lld\n", x, y, t, (s64) x % (s64) y); + + } + + /* Test division with small (32-bit) divisors */ + uy = y >> 32; + sy = (s64)y >> 32; + + if (uy != 0) { + + z = __i64_udiv(x, uy); + if (z != x / uy) + error++, printf("%llu /u %llu = %llu, expected %llu\n", x, uy, z, x / uy); + + z = __i64_umod(x, uy); + if (z != x % uy) + error++, printf("%llu %%u %llu = %llu, expected %llu\n", x, uy, z, x % uy); + + } + + if (sy != 0 && !(x == 0x800000000000LLU && sy == -1)) { + + t = __i64_sdiv(x, sy); + if (t != (s64) x / sy) + error++, printf("%lld /s %lld = %lld, expected %lld\n", x, sy, t, (s64) x / sy); + + t = __i64_smod(x, sy); + if (t != (s64) x % sy) + error++, printf("%lld %%s %lld = %lld, expected %lld\n", x, sy, t, (s64) x % sy); + + } + + i = y & 63; + + z = __i64_shl(x, i); + if (z != x << i) + error++, printf("%016llx << %d = %016llx, expected %016llx\n", x, i, z, x << i); + + z = __i64_shr(x, i); + if (z != x >> i) + error++, printf("%016llx >>u %d = %016llx, expected %016llx\n", x, i, z, x >> i); + + t = __i64_sar(x, i); + if (t != (s64) x >> i) + error++, printf("%016llx >>s %d = %016llx, expected %016llx\n", x, i, t, (s64) x >> i); + + i = __i64_ucmp(x, y); + if (x == y) { + if (! (i == 0)) + error++, printf("ucmp(%016llx, %016llx) = %d, expected 0\n", x, y, i); + } + else if (x < y) { + if (! (i < 0)) + error++, printf("ucmp(%016llx, %016llx) = %d, expected < 0\n", x, y, i); + } else { + if (! (i > 0)) + error++, printf("ucmp(%016llx, %016llx) = %d, expected > 0\n", x, y, i); + } + + i = __i64_scmp(x, y); + if (x == y) { + if (! (i == 0)) + error++, printf("scmp(%016llx, %016llx) = %d, expected 0\n", x, y, i); + } + else if ((s64)x < (s64)y) { + if (! (i < 0)) + error++, printf("scmp(%016llx, %016llx) = %d, expected < 0\n", x, y, i); + } else { + if (! (i > 0)) + error++, printf("scmp(%016llx, %016llx) = %d, expected > 0\n", x, y, i); + } + + f = __i64_utod(x); + g = (double) x; + if (f != g) + error++, printf("(double) %llu (u) = %a, expected %a\n", x, f, g); + + f = __i64_stod(x); + g = (double) (s64) x; + if (f != g) + error++, printf("(double) %lld (s) = %a, expected %a\n", x, f, g); + + f = ((double) x) * 0.0001; + z = __i64_dtou(f); + if (z != (u64) f) + error++, printf("(u64) %a = %llu, expected %llu\n", f, z, (u64) f); + + f = ((double) (s64) x) * 0.0001; + t = __i64_dtos(f); + if (t != (s64) f) + error++, printf("(s64) %a = %lld, expected %lld\n", f, z, (s64) f); +} + +#define NSPECIFIC 8 + +unsigned long long specific[NSPECIFIC] = { + 0, 1, -1, 0x7FFFFFFFULL, 0x80000000ULL, 0xFFFFFFFFULL, + 0x7FFFFFFFFFFFULL, 0x8000000000000000ULL +}; + +int main() +{ + int i, j; + + /* Some specific values */ + for (i = 0; i < NSPECIFIC; i++) + for (j = 0; j < NSPECIFIC; j++) + test1(specific[i], specific[j]); + + /* Random testing */ + for (i = 0; i < 50; i++) { + for (j = 0; j < 1000000; j++) + test1(rnd64(), rnd64()); + printf("."); fflush(stdout); + } + printf("\n"); + if (error == 0) + printf ("Test passed\n"); + else + printf ("TEST FAILED, %d error(s) detected\n", error); + return 0; +} + -- cgit