xref: /linux-6.15/lib/math/test_div64.c (revision 1dc82675)
15086ea4bSMaciej W. Rozycki // SPDX-License-Identifier: GPL-2.0
25086ea4bSMaciej W. Rozycki /*
35086ea4bSMaciej W. Rozycki  * Copyright (C) 2021  Maciej W. Rozycki
45086ea4bSMaciej W. Rozycki  */
55086ea4bSMaciej W. Rozycki 
65086ea4bSMaciej W. Rozycki #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
75086ea4bSMaciej W. Rozycki 
85086ea4bSMaciej W. Rozycki #include <linux/init.h>
95086ea4bSMaciej W. Rozycki #include <linux/ktime.h>
105086ea4bSMaciej W. Rozycki #include <linux/module.h>
115086ea4bSMaciej W. Rozycki #include <linux/printk.h>
125086ea4bSMaciej W. Rozycki #include <linux/time64.h>
135086ea4bSMaciej W. Rozycki #include <linux/types.h>
145086ea4bSMaciej W. Rozycki 
155086ea4bSMaciej W. Rozycki #include <asm/div64.h>
165086ea4bSMaciej W. Rozycki 
175086ea4bSMaciej W. Rozycki #define TEST_DIV64_N_ITER 1024
185086ea4bSMaciej W. Rozycki 
19517b322cSMaciej W. Rozycki static const u64 test_div64_dividends[] = {
205086ea4bSMaciej W. Rozycki 	0x00000000ab275080,
215086ea4bSMaciej W. Rozycki 	0x0000000fe73c1959,
225086ea4bSMaciej W. Rozycki 	0x000000e54c0a74b1,
235086ea4bSMaciej W. Rozycki 	0x00000d4398ff1ef9,
245086ea4bSMaciej W. Rozycki 	0x0000a18c2ee1c097,
255086ea4bSMaciej W. Rozycki 	0x00079fb80b072e4a,
265086ea4bSMaciej W. Rozycki 	0x0072db27380dd689,
275086ea4bSMaciej W. Rozycki 	0x0842f488162e2284,
285086ea4bSMaciej W. Rozycki 	0xf66745411d8ab063,
29*1dc82675SNicolas Pitre 	0xfffffffffffffffb,
30*1dc82675SNicolas Pitre 	0xfffffffffffffffc,
31*1dc82675SNicolas Pitre 	0xffffffffffffffff,
325086ea4bSMaciej W. Rozycki };
33517b322cSMaciej W. Rozycki #define SIZE_DIV64_DIVIDENDS ARRAY_SIZE(test_div64_dividends)
345086ea4bSMaciej W. Rozycki 
355086ea4bSMaciej W. Rozycki #define TEST_DIV64_DIVISOR_0 0x00000009
365086ea4bSMaciej W. Rozycki #define TEST_DIV64_DIVISOR_1 0x0000007c
375086ea4bSMaciej W. Rozycki #define TEST_DIV64_DIVISOR_2 0x00000204
385086ea4bSMaciej W. Rozycki #define TEST_DIV64_DIVISOR_3 0x0000cb5b
395086ea4bSMaciej W. Rozycki #define TEST_DIV64_DIVISOR_4 0x00010000
405086ea4bSMaciej W. Rozycki #define TEST_DIV64_DIVISOR_5 0x0008a880
415086ea4bSMaciej W. Rozycki #define TEST_DIV64_DIVISOR_6 0x003fd3ae
425086ea4bSMaciej W. Rozycki #define TEST_DIV64_DIVISOR_7 0x0b658fac
43*1dc82675SNicolas Pitre #define TEST_DIV64_DIVISOR_8 0x80000001
44*1dc82675SNicolas Pitre #define TEST_DIV64_DIVISOR_9 0xdc08b349
45*1dc82675SNicolas Pitre #define TEST_DIV64_DIVISOR_A 0xfffffffe
46*1dc82675SNicolas Pitre #define TEST_DIV64_DIVISOR_B 0xffffffff
475086ea4bSMaciej W. Rozycki 
485086ea4bSMaciej W. Rozycki static const u32 test_div64_divisors[] = {
495086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_0,
505086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_1,
515086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_2,
525086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_3,
535086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_4,
545086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_5,
555086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_6,
565086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_7,
575086ea4bSMaciej W. Rozycki 	TEST_DIV64_DIVISOR_8,
58*1dc82675SNicolas Pitre 	TEST_DIV64_DIVISOR_9,
59*1dc82675SNicolas Pitre 	TEST_DIV64_DIVISOR_A,
60*1dc82675SNicolas Pitre 	TEST_DIV64_DIVISOR_B,
615086ea4bSMaciej W. Rozycki };
625086ea4bSMaciej W. Rozycki #define SIZE_DIV64_DIVISORS ARRAY_SIZE(test_div64_divisors)
635086ea4bSMaciej W. Rozycki 
645086ea4bSMaciej W. Rozycki static const struct {
655086ea4bSMaciej W. Rozycki 	u64 quotient;
665086ea4bSMaciej W. Rozycki 	u32 remainder;
67*1dc82675SNicolas Pitre } test_div64_results[SIZE_DIV64_DIVIDENDS][SIZE_DIV64_DIVISORS] = {
685086ea4bSMaciej W. Rozycki 	{
695086ea4bSMaciej W. Rozycki 		{ 0x0000000013045e47, 0x00000001 },
705086ea4bSMaciej W. Rozycki 		{ 0x000000000161596c, 0x00000030 },
715086ea4bSMaciej W. Rozycki 		{ 0x000000000054e9d4, 0x00000130 },
725086ea4bSMaciej W. Rozycki 		{ 0x000000000000d776, 0x0000278e },
735086ea4bSMaciej W. Rozycki 		{ 0x000000000000ab27, 0x00005080 },
745086ea4bSMaciej W. Rozycki 		{ 0x00000000000013c4, 0x0004ce80 },
755086ea4bSMaciej W. Rozycki 		{ 0x00000000000002ae, 0x001e143c },
765086ea4bSMaciej W. Rozycki 		{ 0x000000000000000f, 0x0033e56c },
77*1dc82675SNicolas Pitre 		{ 0x0000000000000001, 0x2b27507f },
78*1dc82675SNicolas Pitre 		{ 0x0000000000000000, 0xab275080 },
79*1dc82675SNicolas Pitre 		{ 0x0000000000000000, 0xab275080 },
805086ea4bSMaciej W. Rozycki 		{ 0x0000000000000000, 0xab275080 },
815086ea4bSMaciej W. Rozycki 	}, {
825086ea4bSMaciej W. Rozycki 		{ 0x00000001c45c02d1, 0x00000000 },
835086ea4bSMaciej W. Rozycki 		{ 0x0000000020d5213c, 0x00000049 },
845086ea4bSMaciej W. Rozycki 		{ 0x0000000007e3d65f, 0x000001dd },
855086ea4bSMaciej W. Rozycki 		{ 0x0000000000140531, 0x000065ee },
865086ea4bSMaciej W. Rozycki 		{ 0x00000000000fe73c, 0x00001959 },
875086ea4bSMaciej W. Rozycki 		{ 0x000000000001d637, 0x0004e5d9 },
885086ea4bSMaciej W. Rozycki 		{ 0x0000000000003fc9, 0x000713bb },
895086ea4bSMaciej W. Rozycki 		{ 0x0000000000000165, 0x029abe7d },
90*1dc82675SNicolas Pitre 		{ 0x000000000000001f, 0x673c193a },
915086ea4bSMaciej W. Rozycki 		{ 0x0000000000000012, 0x6e9f7e37 },
92*1dc82675SNicolas Pitre 		{ 0x000000000000000f, 0xe73c1977 },
93*1dc82675SNicolas Pitre 		{ 0x000000000000000f, 0xe73c1968 },
945086ea4bSMaciej W. Rozycki 	}, {
955086ea4bSMaciej W. Rozycki 		{ 0x000000197a3a0cf7, 0x00000002 },
965086ea4bSMaciej W. Rozycki 		{ 0x00000001d9632e5c, 0x00000021 },
975086ea4bSMaciej W. Rozycki 		{ 0x0000000071c28039, 0x000001cd },
985086ea4bSMaciej W. Rozycki 		{ 0x000000000120a844, 0x0000b885 },
995086ea4bSMaciej W. Rozycki 		{ 0x0000000000e54c0a, 0x000074b1 },
1005086ea4bSMaciej W. Rozycki 		{ 0x00000000001a7bb3, 0x00072331 },
1015086ea4bSMaciej W. Rozycki 		{ 0x00000000000397ad, 0x0002c61b },
1025086ea4bSMaciej W. Rozycki 		{ 0x000000000000141e, 0x06ea2e89 },
103*1dc82675SNicolas Pitre 		{ 0x00000000000001ca, 0x4c0a72e7 },
1045086ea4bSMaciej W. Rozycki 		{ 0x000000000000010a, 0xab002ad7 },
105*1dc82675SNicolas Pitre 		{ 0x00000000000000e5, 0x4c0a767b },
106*1dc82675SNicolas Pitre 		{ 0x00000000000000e5, 0x4c0a7596 },
1075086ea4bSMaciej W. Rozycki 	}, {
1085086ea4bSMaciej W. Rozycki 		{ 0x0000017949e37538, 0x00000001 },
1095086ea4bSMaciej W. Rozycki 		{ 0x0000001b62441f37, 0x00000055 },
1105086ea4bSMaciej W. Rozycki 		{ 0x0000000694a3391d, 0x00000085 },
1115086ea4bSMaciej W. Rozycki 		{ 0x0000000010b2a5d2, 0x0000a753 },
1125086ea4bSMaciej W. Rozycki 		{ 0x000000000d4398ff, 0x00001ef9 },
1135086ea4bSMaciej W. Rozycki 		{ 0x0000000001882ec6, 0x0005cbf9 },
1145086ea4bSMaciej W. Rozycki 		{ 0x000000000035333b, 0x0017abdf },
1155086ea4bSMaciej W. Rozycki 		{ 0x00000000000129f1, 0x0ab4520d },
116*1dc82675SNicolas Pitre 		{ 0x0000000000001a87, 0x18ff0472 },
1175086ea4bSMaciej W. Rozycki 		{ 0x0000000000000f6e, 0x8ac0ce9b },
118*1dc82675SNicolas Pitre 		{ 0x0000000000000d43, 0x98ff397f },
119*1dc82675SNicolas Pitre 		{ 0x0000000000000d43, 0x98ff2c3c },
1205086ea4bSMaciej W. Rozycki 	}, {
1215086ea4bSMaciej W. Rozycki 		{ 0x000011f321a74e49, 0x00000006 },
1225086ea4bSMaciej W. Rozycki 		{ 0x0000014d8481d211, 0x0000005b },
1235086ea4bSMaciej W. Rozycki 		{ 0x0000005025cbd92d, 0x000001e3 },
1245086ea4bSMaciej W. Rozycki 		{ 0x00000000cb5e71e3, 0x000043e6 },
1255086ea4bSMaciej W. Rozycki 		{ 0x00000000a18c2ee1, 0x0000c097 },
1265086ea4bSMaciej W. Rozycki 		{ 0x0000000012a88828, 0x00036c97 },
1275086ea4bSMaciej W. Rozycki 		{ 0x000000000287f16f, 0x002c2a25 },
1285086ea4bSMaciej W. Rozycki 		{ 0x00000000000e2cc7, 0x02d581e3 },
129*1dc82675SNicolas Pitre 		{ 0x0000000000014318, 0x2ee07d7f },
1305086ea4bSMaciej W. Rozycki 		{ 0x000000000000bbf4, 0x1ba08c03 },
131*1dc82675SNicolas Pitre 		{ 0x000000000000a18c, 0x2ee303af },
132*1dc82675SNicolas Pitre 		{ 0x000000000000a18c, 0x2ee26223 },
1335086ea4bSMaciej W. Rozycki 	}, {
1345086ea4bSMaciej W. Rozycki 		{ 0x0000d8db8f72935d, 0x00000005 },
1355086ea4bSMaciej W. Rozycki 		{ 0x00000fbd5aed7a2e, 0x00000002 },
1365086ea4bSMaciej W. Rozycki 		{ 0x000003c84b6ea64a, 0x00000122 },
1375086ea4bSMaciej W. Rozycki 		{ 0x0000000998fa8829, 0x000044b7 },
1385086ea4bSMaciej W. Rozycki 		{ 0x000000079fb80b07, 0x00002e4a },
1395086ea4bSMaciej W. Rozycki 		{ 0x00000000e16b20fa, 0x0002a14a },
1405086ea4bSMaciej W. Rozycki 		{ 0x000000001e940d22, 0x00353b2e },
1415086ea4bSMaciej W. Rozycki 		{ 0x0000000000ab40ac, 0x06fba6ba },
142*1dc82675SNicolas Pitre 		{ 0x00000000000f3f70, 0x0af7eeda },
1435086ea4bSMaciej W. Rozycki 		{ 0x000000000008debd, 0x72d98365 },
144*1dc82675SNicolas Pitre 		{ 0x0000000000079fb8, 0x0b166dba },
145*1dc82675SNicolas Pitre 		{ 0x0000000000079fb8, 0x0b0ece02 },
1465086ea4bSMaciej W. Rozycki 	}, {
1475086ea4bSMaciej W. Rozycki 		{ 0x000cc3045b8fc281, 0x00000000 },
1485086ea4bSMaciej W. Rozycki 		{ 0x0000ed1f48b5c9fc, 0x00000079 },
1495086ea4bSMaciej W. Rozycki 		{ 0x000038fb9c63406a, 0x000000e1 },
1505086ea4bSMaciej W. Rozycki 		{ 0x000000909705b825, 0x00000a62 },
1515086ea4bSMaciej W. Rozycki 		{ 0x00000072db27380d, 0x0000d689 },
1525086ea4bSMaciej W. Rozycki 		{ 0x0000000d43fce827, 0x00082b09 },
1535086ea4bSMaciej W. Rozycki 		{ 0x00000001ccaba11a, 0x0037e8dd },
1545086ea4bSMaciej W. Rozycki 		{ 0x000000000a13f729, 0x0566dffd },
155*1dc82675SNicolas Pitre 		{ 0x0000000000e5b64e, 0x3728203b },
1565086ea4bSMaciej W. Rozycki 		{ 0x000000000085a14b, 0x23d36726 },
157*1dc82675SNicolas Pitre 		{ 0x000000000072db27, 0x38f38cd7 },
158*1dc82675SNicolas Pitre 		{ 0x000000000072db27, 0x3880b1b0 },
1595086ea4bSMaciej W. Rozycki 	}, {
1605086ea4bSMaciej W. Rozycki 		{ 0x00eafeb9c993592b, 0x00000001 },
1615086ea4bSMaciej W. Rozycki 		{ 0x00110e5befa9a991, 0x00000048 },
1625086ea4bSMaciej W. Rozycki 		{ 0x00041947b4a1d36a, 0x000000dc },
1635086ea4bSMaciej W. Rozycki 		{ 0x00000a6679327311, 0x0000c079 },
1645086ea4bSMaciej W. Rozycki 		{ 0x00000842f488162e, 0x00002284 },
1655086ea4bSMaciej W. Rozycki 		{ 0x000000f4459740fc, 0x00084484 },
1665086ea4bSMaciej W. Rozycki 		{ 0x0000002122c47bf9, 0x002ca446 },
1675086ea4bSMaciej W. Rozycki 		{ 0x00000000b9936290, 0x004979c4 },
168*1dc82675SNicolas Pitre 		{ 0x000000001085e910, 0x05a83974 },
1695086ea4bSMaciej W. Rozycki 		{ 0x00000000099ca89d, 0x9db446bf },
170*1dc82675SNicolas Pitre 		{ 0x000000000842f488, 0x26b40b94 },
171*1dc82675SNicolas Pitre 		{ 0x000000000842f488, 0x1e71170c },
1725086ea4bSMaciej W. Rozycki 	}, {
1735086ea4bSMaciej W. Rozycki 		{ 0x1b60cece589da1d2, 0x00000001 },
1745086ea4bSMaciej W. Rozycki 		{ 0x01fcb42be1453f5b, 0x0000004f },
1755086ea4bSMaciej W. Rozycki 		{ 0x007a3f2457df0749, 0x0000013f },
1765086ea4bSMaciej W. Rozycki 		{ 0x0001363130e3ec7b, 0x000017aa },
1775086ea4bSMaciej W. Rozycki 		{ 0x0000f66745411d8a, 0x0000b063 },
1785086ea4bSMaciej W. Rozycki 		{ 0x00001c757dfab350, 0x00048863 },
1795086ea4bSMaciej W. Rozycki 		{ 0x000003dc4979c652, 0x00224ea7 },
1805086ea4bSMaciej W. Rozycki 		{ 0x000000159edc3144, 0x06409ab3 },
181*1dc82675SNicolas Pitre 		{ 0x00000001ecce8a7e, 0x30bc25e5 },
1825086ea4bSMaciej W. Rozycki 		{ 0x000000011eadfee3, 0xa99c48a8 },
183*1dc82675SNicolas Pitre 		{ 0x00000000f6674543, 0x0a593ae9 },
184*1dc82675SNicolas Pitre 		{ 0x00000000f6674542, 0x13f1f5a5 },
185*1dc82675SNicolas Pitre 	}, {
186*1dc82675SNicolas Pitre 		{ 0x1c71c71c71c71c71, 0x00000002 },
187*1dc82675SNicolas Pitre 		{ 0x0210842108421084, 0x0000000b },
188*1dc82675SNicolas Pitre 		{ 0x007f01fc07f01fc0, 0x000000fb },
189*1dc82675SNicolas Pitre 		{ 0x00014245eabf1f9a, 0x0000a63d },
190*1dc82675SNicolas Pitre 		{ 0x0000ffffffffffff, 0x0000fffb },
191*1dc82675SNicolas Pitre 		{ 0x00001d913cecc509, 0x0007937b },
192*1dc82675SNicolas Pitre 		{ 0x00000402c70c678f, 0x0005bfc9 },
193*1dc82675SNicolas Pitre 		{ 0x00000016766cb70b, 0x045edf97 },
194*1dc82675SNicolas Pitre 		{ 0x00000001fffffffb, 0x80000000 },
195*1dc82675SNicolas Pitre 		{ 0x0000000129d84b3a, 0xa2e8fe71 },
196*1dc82675SNicolas Pitre 		{ 0x0000000100000001, 0xfffffffd },
197*1dc82675SNicolas Pitre 		{ 0x0000000100000000, 0xfffffffb },
198*1dc82675SNicolas Pitre 	}, {
199*1dc82675SNicolas Pitre 		{ 0x1c71c71c71c71c71, 0x00000003 },
200*1dc82675SNicolas Pitre 		{ 0x0210842108421084, 0x0000000c },
201*1dc82675SNicolas Pitre 		{ 0x007f01fc07f01fc0, 0x000000fc },
202*1dc82675SNicolas Pitre 		{ 0x00014245eabf1f9a, 0x0000a63e },
203*1dc82675SNicolas Pitre 		{ 0x0000ffffffffffff, 0x0000fffc },
204*1dc82675SNicolas Pitre 		{ 0x00001d913cecc509, 0x0007937c },
205*1dc82675SNicolas Pitre 		{ 0x00000402c70c678f, 0x0005bfca },
206*1dc82675SNicolas Pitre 		{ 0x00000016766cb70b, 0x045edf98 },
207*1dc82675SNicolas Pitre 		{ 0x00000001fffffffc, 0x00000000 },
208*1dc82675SNicolas Pitre 		{ 0x0000000129d84b3a, 0xa2e8fe72 },
209*1dc82675SNicolas Pitre 		{ 0x0000000100000002, 0x00000000 },
210*1dc82675SNicolas Pitre 		{ 0x0000000100000000, 0xfffffffc },
211*1dc82675SNicolas Pitre 	}, {
212*1dc82675SNicolas Pitre 		{ 0x1c71c71c71c71c71, 0x00000006 },
213*1dc82675SNicolas Pitre 		{ 0x0210842108421084, 0x0000000f },
214*1dc82675SNicolas Pitre 		{ 0x007f01fc07f01fc0, 0x000000ff },
215*1dc82675SNicolas Pitre 		{ 0x00014245eabf1f9a, 0x0000a641 },
216*1dc82675SNicolas Pitre 		{ 0x0000ffffffffffff, 0x0000ffff },
217*1dc82675SNicolas Pitre 		{ 0x00001d913cecc509, 0x0007937f },
218*1dc82675SNicolas Pitre 		{ 0x00000402c70c678f, 0x0005bfcd },
219*1dc82675SNicolas Pitre 		{ 0x00000016766cb70b, 0x045edf9b },
220*1dc82675SNicolas Pitre 		{ 0x00000001fffffffc, 0x00000003 },
221*1dc82675SNicolas Pitre 		{ 0x0000000129d84b3a, 0xa2e8fe75 },
222*1dc82675SNicolas Pitre 		{ 0x0000000100000002, 0x00000003 },
223*1dc82675SNicolas Pitre 		{ 0x0000000100000001, 0x00000000 },
2245086ea4bSMaciej W. Rozycki 	},
2255086ea4bSMaciej W. Rozycki };
2265086ea4bSMaciej W. Rozycki 
test_div64_verify(u64 quotient,u32 remainder,int i,int j)2275086ea4bSMaciej W. Rozycki static inline bool test_div64_verify(u64 quotient, u32 remainder, int i, int j)
2285086ea4bSMaciej W. Rozycki {
2295086ea4bSMaciej W. Rozycki 	return (quotient == test_div64_results[i][j].quotient &&
2305086ea4bSMaciej W. Rozycki 		remainder == test_div64_results[i][j].remainder);
2315086ea4bSMaciej W. Rozycki }
2325086ea4bSMaciej W. Rozycki 
2335086ea4bSMaciej W. Rozycki /*
2345086ea4bSMaciej W. Rozycki  * This needs to be a macro, because we don't want to rely on the compiler
2355086ea4bSMaciej W. Rozycki  * to do constant propagation, and `do_div' may take a different path for
2365086ea4bSMaciej W. Rozycki  * constants, so we do want to verify that as well.
2375086ea4bSMaciej W. Rozycki  */
238517b322cSMaciej W. Rozycki #define test_div64_one(dividend, divisor, i, j) ({			\
2395086ea4bSMaciej W. Rozycki 	bool result = true;						\
2405086ea4bSMaciej W. Rozycki 	u64 quotient;							\
2415086ea4bSMaciej W. Rozycki 	u32 remainder;							\
2425086ea4bSMaciej W. Rozycki 									\
243517b322cSMaciej W. Rozycki 	quotient = dividend;						\
2445086ea4bSMaciej W. Rozycki 	remainder = do_div(quotient, divisor);				\
2455086ea4bSMaciej W. Rozycki 	if (!test_div64_verify(quotient, remainder, i, j)) {		\
2465086ea4bSMaciej W. Rozycki 		pr_err("ERROR: %016llx / %08x => %016llx,%08x\n",	\
247517b322cSMaciej W. Rozycki 		       dividend, divisor, quotient, remainder);		\
2485086ea4bSMaciej W. Rozycki 		pr_err("ERROR: expected value              => %016llx,%08x\n",\
2495086ea4bSMaciej W. Rozycki 		       test_div64_results[i][j].quotient,		\
2505086ea4bSMaciej W. Rozycki 		       test_div64_results[i][j].remainder);		\
2515086ea4bSMaciej W. Rozycki 		result = false;						\
2525086ea4bSMaciej W. Rozycki 	}								\
2535086ea4bSMaciej W. Rozycki 	result;								\
2545086ea4bSMaciej W. Rozycki })
2555086ea4bSMaciej W. Rozycki 
2565086ea4bSMaciej W. Rozycki /*
2575086ea4bSMaciej W. Rozycki  * Run calculation for the same divisor value expressed as a constant
2585086ea4bSMaciej W. Rozycki  * and as a variable, so as to verify the implementation for both cases
2595086ea4bSMaciej W. Rozycki  * should they be handled by different code execution paths.
2605086ea4bSMaciej W. Rozycki  */
test_div64(void)2615086ea4bSMaciej W. Rozycki static bool __init test_div64(void)
2625086ea4bSMaciej W. Rozycki {
263517b322cSMaciej W. Rozycki 	u64 dividend;
2645086ea4bSMaciej W. Rozycki 	int i, j;
2655086ea4bSMaciej W. Rozycki 
266517b322cSMaciej W. Rozycki 	for (i = 0; i < SIZE_DIV64_DIVIDENDS; i++) {
267517b322cSMaciej W. Rozycki 		dividend = test_div64_dividends[i];
268517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_0, i, 0))
2695086ea4bSMaciej W. Rozycki 			return false;
270517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_1, i, 1))
2715086ea4bSMaciej W. Rozycki 			return false;
272517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_2, i, 2))
2735086ea4bSMaciej W. Rozycki 			return false;
274517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_3, i, 3))
2755086ea4bSMaciej W. Rozycki 			return false;
276517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_4, i, 4))
2775086ea4bSMaciej W. Rozycki 			return false;
278517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_5, i, 5))
2795086ea4bSMaciej W. Rozycki 			return false;
280517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_6, i, 6))
2815086ea4bSMaciej W. Rozycki 			return false;
282517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_7, i, 7))
2835086ea4bSMaciej W. Rozycki 			return false;
284517b322cSMaciej W. Rozycki 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_8, i, 8))
2855086ea4bSMaciej W. Rozycki 			return false;
286*1dc82675SNicolas Pitre 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_9, i, 9))
287*1dc82675SNicolas Pitre 			return false;
288*1dc82675SNicolas Pitre 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_A, i, 10))
289*1dc82675SNicolas Pitre 			return false;
290*1dc82675SNicolas Pitre 		if (!test_div64_one(dividend, TEST_DIV64_DIVISOR_B, i, 11))
291*1dc82675SNicolas Pitre 			return false;
2925086ea4bSMaciej W. Rozycki 		for (j = 0; j < SIZE_DIV64_DIVISORS; j++) {
293517b322cSMaciej W. Rozycki 			if (!test_div64_one(dividend, test_div64_divisors[j],
2945086ea4bSMaciej W. Rozycki 					    i, j))
2955086ea4bSMaciej W. Rozycki 				return false;
2965086ea4bSMaciej W. Rozycki 		}
2975086ea4bSMaciej W. Rozycki 	}
2985086ea4bSMaciej W. Rozycki 	return true;
2995086ea4bSMaciej W. Rozycki }
3005086ea4bSMaciej W. Rozycki 
test_div64_init(void)3015086ea4bSMaciej W. Rozycki static int __init test_div64_init(void)
3025086ea4bSMaciej W. Rozycki {
3035086ea4bSMaciej W. Rozycki 	struct timespec64 ts, ts0, ts1;
3045086ea4bSMaciej W. Rozycki 	int i;
3055086ea4bSMaciej W. Rozycki 
3065086ea4bSMaciej W. Rozycki 	pr_info("Starting 64bit/32bit division and modulo test\n");
3075086ea4bSMaciej W. Rozycki 	ktime_get_ts64(&ts0);
3085086ea4bSMaciej W. Rozycki 
3095086ea4bSMaciej W. Rozycki 	for (i = 0; i < TEST_DIV64_N_ITER; i++)
3105086ea4bSMaciej W. Rozycki 		if (!test_div64())
3115086ea4bSMaciej W. Rozycki 			break;
3125086ea4bSMaciej W. Rozycki 
3135086ea4bSMaciej W. Rozycki 	ktime_get_ts64(&ts1);
3145086ea4bSMaciej W. Rozycki 	ts = timespec64_sub(ts1, ts0);
3155086ea4bSMaciej W. Rozycki 	pr_info("Completed 64bit/32bit division and modulo test, "
3165086ea4bSMaciej W. Rozycki 		"%llu.%09lus elapsed\n", ts.tv_sec, ts.tv_nsec);
3175086ea4bSMaciej W. Rozycki 
3185086ea4bSMaciej W. Rozycki 	return 0;
3195086ea4bSMaciej W. Rozycki }
3205086ea4bSMaciej W. Rozycki 
test_div64_exit(void)3215086ea4bSMaciej W. Rozycki static void __exit test_div64_exit(void)
3225086ea4bSMaciej W. Rozycki {
3235086ea4bSMaciej W. Rozycki }
3245086ea4bSMaciej W. Rozycki 
3255086ea4bSMaciej W. Rozycki module_init(test_div64_init);
3265086ea4bSMaciej W. Rozycki module_exit(test_div64_exit);
3275086ea4bSMaciej W. Rozycki 
3285086ea4bSMaciej W. Rozycki MODULE_AUTHOR("Maciej W. Rozycki <[email protected]>");
3295086ea4bSMaciej W. Rozycki MODULE_LICENSE("GPL");
3305086ea4bSMaciej W. Rozycki MODULE_DESCRIPTION("64bit/32bit division and modulo test module");
331