source: grub-pc/trunk/fuentes/grub-core/tests/div_test.c @ 22

Last change on this file since 22 was 22, checked in by mabarracus, 4 years ago

updated version and apply net.ifnames=0 into debian/rules

File size: 4.2 KB
Line 
1/*
2 *  GRUB  --  GRand Unified Bootloader
3 *  Copyright (C) 2013 Free Software Foundation, Inc.
4 *
5 *  GRUB is free software: you can redistribute it and/or modify
6 *  it under the terms of the GNU General Public License as published by
7 *  the Free Software Foundation, either version 3 of the License, or
8 *  (at your option) any later version.
9 *
10 *  GRUB is distributed in the hope that it will be useful,
11 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 *  GNU General Public License for more details.
14 *
15 *  You should have received a copy of the GNU General Public License
16 *  along with GRUB.  If not, see <http://www.gnu.org/licenses/>.
17 */
18
19#include <grub/test.h>
20#include <grub/dl.h>
21#include <grub/misc.h>
22
23GRUB_MOD_LICENSE ("GPLv3+");
24
25static grub_uint64_t vectors[][2] = {
26  { 0xffffffffffffffffULL, 1},
27  { 1, 0xffffffffffffffffULL},
28  { 0xffffffffffffffffULL, 0xffffffffffffffffULL},
29  { 1, 1 },
30  { 2, 1 }
31};
32
33static void
34test32 (grub_uint32_t a, grub_uint32_t b)
35{
36  grub_uint64_t q, r;
37  q = grub_divmod64 (a, b, &r);
38  grub_test_assert (r < b, "remainder is larger than dividend: 0x%llx %% 0x%llx = 0x%llx",
39                    (long long) a, (long long) b, (long long) r);
40  grub_test_assert (q * b + r == a, "division doesn't satisfy base property: 0x%llx * 0x%llx + 0x%llx != 0x%llx", (long long) q, (long long) b, (long long) r,
41                    (long long) a);
42  /* Overflow check.  */
43  grub_test_assert ((q >> 32) == 0,
44                    "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b);
45  grub_test_assert ((r >> 32) == 0,
46                    "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b);
47  /* q * b + r is at most:
48     0xffffffff * 0xffffffff + 0xffffffff = 0xffffffff00000000
49     so no overflow
50   */
51  grub_test_assert (q == (a / b),
52                    "C compiler division failure in 0x%llx, 0x%llx", (long long) a, (long long) b);
53  grub_test_assert (r == (a % b),
54                    "C compiler modulo failure in 0x%llx, 0x%llx", (long long) a, (long long) b);
55}
56
57static void
58test64 (grub_uint64_t a, grub_uint64_t b)
59{
60  grub_uint64_t q, r;
61  grub_uint64_t x1, x2;
62  q = grub_divmod64 (a, b, &r);
63  grub_test_assert (r < b, "remainder is larger than dividend: 0x%llx %% 0x%llx = 0x%llx",
64                    (long long) a, (long long) b, (long long) r);
65  grub_test_assert (q * b + r == a, "division doesn't satisfy base property: 0x%llx * 0x%llx + 0x%llx != 0x%llx", (long long) q, (long long) b, (long long) r,
66                    (long long) a);
67  /* Overflow checks.  */
68  grub_test_assert ((q >> 32) * (b >> 32) == 0,
69                    "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b);
70  x1 = (q >> 32) * (b & 0xffffffff);
71  grub_test_assert (x1 < (1LL << 32),
72                    "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b);
73  x1 <<= 32;
74  x2 = (b >> 32) * (q & 0xffffffff);
75  grub_test_assert (x2 < (1LL << 32),
76                    "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b);
77  x2 <<= 32;
78  grub_test_assert (x1 <= ~x2,
79                    "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b);
80  x1 += x2;
81  x2 = (q & 0xffffffff) * (b & 0xffffffff);
82  grub_test_assert (x1 <= ~x2,
83                    "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b);
84  x1 += x2;
85  grub_test_assert (x1 <= ~r,
86                    "division overflow in 0x%llx, 0x%llx", (long long) a, (long long) b);
87  x1 += r;
88  grub_test_assert (a == x1,
89                    "division overflow test failure in 0x%llx, 0x%llx", (long long) a, (long long) b);
90#if GRUB_TARGET_SIZEOF_VOID_P == 8
91  grub_test_assert (q == (a / b),
92                    "C compiler division failure in 0x%llx, 0x%llx", (long long) a, (long long) b);
93  grub_test_assert (r == (a % b),
94                    "C compiler modulo failure in 0x%llx, 0x%llx", (long long) a, (long long) b);
95#endif
96}
97
98static void
99div_test (void)
100{
101  grub_uint64_t a = 404, b = 7;
102  grub_size_t i;
103
104  for (i = 0; i < ARRAY_SIZE (vectors); i++)
105    {
106      test64 (vectors[i][0], vectors[i][1]);
107      test32 (vectors[i][0], vectors[i][1]);
108    }
109  for (i = 0; i < 40000; i++)
110    {
111      a = 17 * a + 13 * b;
112      b = 23 * a + 29 * b;
113      if (b == 0)
114        b = 1;
115      if (a == 0)
116        a = 1;
117      test64 (a, b);
118      test32 (a, b);
119
120    }
121}
122
123/* Register example_test method as a functional test.  */
124GRUB_FUNCTIONAL_TEST (div_test, div_test);
Note: See TracBrowser for help on using the repository browser.