1 /*
2  * PROJECT:         ReactOS API tests
3  * LICENSE:         GPL-2.0-or-later (https://spdx.org/licenses/GPL-2.0-or-later)
4  * PURPOSE:         Tests for statically linked __rt_sdiv/udiv/sdiv64/udiv64 on ARM
5  * COPYRIGHT:       Copyright 2021 Stanislav Motylkov <x86corez@gmail.com>
6  */
7 
8 #include <apitest.h>
9 
10 typedef struct _SDIV_TEST_DATA
11 {
12     LONG dividend;
13     LONG divisor;
14     LONG expected_div;
15     LONG expected_mod;
16 } SDIV_TEST_DATA;
17 
18 typedef struct _UDIV_TEST_DATA
19 {
20     ULONG dividend;
21     ULONG divisor;
22     ULONG expected_div;
23     ULONG expected_mod;
24 } UDIV_TEST_DATA;
25 
26 typedef struct _SDIV64_TEST_DATA
27 {
28     LONGLONG dividend;
29     LONGLONG divisor;
30     LONGLONG expected_div;
31     LONGLONG expected_mod;
32 } SDIV64_TEST_DATA;
33 
34 typedef struct _UDIV64_TEST_DATA
35 {
36     ULONGLONG dividend;
37     ULONGLONG divisor;
38     ULONGLONG expected_div;
39     ULONGLONG expected_mod;
40 } UDIV64_TEST_DATA;
41 
42 START_TEST(__rt_div)
43 {
44     SDIV_TEST_DATA sdiv[] =
45     {
46         /* Dividend is larger than divisor */
47         { 3425, 400, 8, 225 },
48         { -3425, 400, -8, -225 },
49         { 3425, -400, -8, 225 },
50         { -3425, -400, 8, -225 },
51         /* Divisor is larger than dividend */
52         { 12, 42, 0, 12 },
53         { -12, 42, 0, -12 },
54         { 12, -42, 0, 12 },
55         { -12, -42, 0, -12 },
56         /* Division without remainder */
57         { 16777216, 65536, 256, 0 },
58         { -16777216, 65536, -256, 0 },
59         { 16777216, -65536, -256, 0 },
60         { -16777216, -65536, 256, 0 },
61     };
62     UDIV_TEST_DATA udiv[] =
63     {
64         /* Dividend is larger than divisor */
65         { 3425, 400, 8, 225 },
66         /* Divisor is larger than dividend */
67         { 12, 42, 0, 12 },
68         /* Division without remainder */
69         { 16777216, 65536, 256, 0 },
70     };
71     SDIV64_TEST_DATA sdiv64[] =
72     {
73         /* Dividend is larger than divisor */
74         { 34918215, 7, 4988316, 3 },
75         { -34918215, 7, -4988316, -3 },
76         { 34918215, -7, -4988316, 3 },
77         { -34918215, -7, 4988316, -3 },
78         /* Divisor is larger than dividend */
79         { 12, 42, 0, 12 },
80         { -12, 42, 0, -12 },
81         { 12, -42, 0, 12 },
82         { -12, -42, 0, -12 },
83         /* Division without remainder */
84         { 16777216, 65536, 256, 0 },
85         { -16777216, 65536, -256, 0 },
86         { 16777216, -65536, -256, 0 },
87         { -16777216, -65536, 256, 0 },
88 
89         /* Big 64-bit numbers */
90 
91         /* Dividend is larger than divisor */
92         { 0x2AFFFFFFFLL * 100, 400, 2885681151LL, 300 },
93         { -0x2AFFFFFFFLL * 100, 400, -2885681151LL, -300 },
94         { 0x2AFFFFFFFLL * 100, -400, -2885681151LL, 300 },
95         { -0x2AFFFFFFFLL * 100, -400, 2885681151LL, -300 },
96         /* Divisor is larger than dividend */
97         { 0x2AFFFFFFFLL * 50, 0x2AFFFFFFFLL * 100, 0, 0x2AFFFFFFFLL * 50 },
98         { -0x2AFFFFFFFLL * 50, 0x2AFFFFFFFLL * 100, 0, -0x2AFFFFFFFLL * 50 },
99         { 0x2AFFFFFFFLL * 50, -0x2AFFFFFFFLL * 100, 0, 0x2AFFFFFFFLL * 50 },
100         { -0x2AFFFFFFFLL * 50, -0x2AFFFFFFFLL * 100, 0, -0x2AFFFFFFFLL * 50 },
101         /* Division without remainder */
102         { 0x2AFFFFFFFLL * 100, 100, 0x2AFFFFFFFLL, 0 },
103         { -0x2AFFFFFFFLL * 100, 100, -0x2AFFFFFFFLL, 0 },
104         { 0x2AFFFFFFFLL * 100, -100, -0x2AFFFFFFFLL, 0 },
105         { -0x2AFFFFFFFLL * 100, -100, 0x2AFFFFFFFLL, 0 },
106     };
107     UDIV64_TEST_DATA udiv64[] =
108     {
109         /* Dividend is larger than divisor */
110         { 34918215, 7, 4988316, 3 },
111         /* Divisor is larger than dividend */
112         { 12, 42, 0, 12 },
113         /* Division without remainder */
114         { 16777216, 65536, 256, 0 },
115 
116         /* Big 64-bit numbers */
117 
118         /* Dividend is larger than divisor */
119         { 0x2AFFFFFFFULL * 100, 400, 2885681151ULL, 300 },
120         /* Divisor is larger than dividend */
121         { 0x2AFFFFFFFULL * 50, 0x2AFFFFFFFULL * 100, 0, 0x2AFFFFFFFULL * 50 },
122         /* Division without remainder */
123         { 0x2AFFFFFFFULL * 100, 100, 0x2AFFFFFFFULL, 0 },
124     };
125     INT i;
126 
127     for (i = 0; i < _countof(sdiv); i++)
128     {
129         LONG test_div, test_mod;
130 
131         test_div = sdiv[i].dividend / sdiv[i].divisor;
132         test_mod = sdiv[i].dividend % sdiv[i].divisor;
133         ok(test_div == sdiv[i].expected_div, "(sdiv) %d: Expected %ld, got %ld / %ld = %ld\n",
134            i, sdiv[i].expected_div, sdiv[i].dividend, sdiv[i].divisor, test_div);
135         ok(test_mod == sdiv[i].expected_mod, "(sdiv) %d: Expected %ld, got %ld %% %ld = %ld\n",
136            i, sdiv[i].expected_mod, sdiv[i].dividend, sdiv[i].divisor, test_mod);
137     }
138 
139     for (i = 0; i < _countof(udiv); i++)
140     {
141         ULONG test_div, test_mod;
142 
143         test_div = udiv[i].dividend / udiv[i].divisor;
144         test_mod = udiv[i].dividend % udiv[i].divisor;
145         ok(test_div == udiv[i].expected_div, "(udiv) %d: Expected %lu, got %lu / %lu = %lu\n",
146            i, udiv[i].expected_div, udiv[i].dividend, udiv[i].divisor, test_div);
147         ok(test_mod == udiv[i].expected_mod, "(udiv) %d: Expected %lu, got %lu %% %lu = %lu\n",
148            i, udiv[i].expected_mod, udiv[i].dividend, udiv[i].divisor, test_mod);
149     }
150 
151     for (i = 0; i < _countof(sdiv64); i++)
152     {
153         LONGLONG test_div, test_mod;
154 
155         test_div = sdiv64[i].dividend / sdiv64[i].divisor;
156         test_mod = sdiv64[i].dividend % sdiv64[i].divisor;
157         ok(test_div == sdiv64[i].expected_div, "(sdiv64) %d: Expected %lld, got %lld / %lld = %lld\n",
158            i, sdiv64[i].expected_div, sdiv64[i].dividend, sdiv64[i].divisor, test_div);
159         ok(test_mod == sdiv64[i].expected_mod, "(sdiv64) %d: Expected %lld, got %lld %% %lld = %lld\n",
160            i, sdiv64[i].expected_mod, sdiv64[i].dividend, sdiv64[i].divisor, test_mod);
161     }
162 
163     for (i = 0; i < _countof(udiv64); i++)
164     {
165         ULONGLONG test_div, test_mod;
166 
167         test_div = udiv64[i].dividend / udiv64[i].divisor;
168         test_mod = udiv64[i].dividend % udiv64[i].divisor;
169         ok(test_div == udiv64[i].expected_div, "(udiv64) %d: Expected %llu, got %llu / %llu = %llu\n",
170            i, udiv64[i].expected_div, udiv64[i].dividend, udiv64[i].divisor, test_div);
171         ok(test_mod == udiv64[i].expected_mod, "(udiv64) %d: Expected %llu, got %llu %% %llu = %llu\n",
172            i, udiv64[i].expected_mod, udiv64[i].dividend, udiv64[i].divisor, test_mod);
173     }
174 }
175 
176