main
1#define NOTLIBC_NOMAIN
2#include "notlibc.c"
3
4#define N 12
5
6void PRESERVE_WITH_LTO entry(void) {
7
8 assert( (-1^1) == -2 ); /* All safemath code assumes 2's complement. Assert it here, too. */
9
10 Status s = S_SUCCESS;
11
12 /* Validate correct basic addition and subtraction behaviour */
13 assert( u64_add( &s, 3, 2 ) == 5 ); assert(S_OK(s));
14 assert( u32_add( &s, 3, 2 ) == 5 ); assert(S_OK(s));
15 assert( u16_add( &s, 3, 2 ) == 5 ); assert(S_OK(s));
16 assert( u8_add( &s, 3, 2 ) == 5 ); assert(S_OK(s));
17
18 assert( u64_sub( &s, 3, 2 ) == 1 ); assert(S_OK(s));
19 assert( u32_sub( &s, 3, 2 ) == 1 ); assert(S_OK(s));
20 assert( u16_sub( &s, 3, 2 ) == 1 ); assert(S_OK(s));
21 assert( u8_sub( &s, 3, 2 ) == 1 ); assert(S_OK(s));
22
23 assert( s64_add( &s, 3, 2 ) == 5 ); assert(S_OK(s));
24 assert( s32_add( &s, 3, 2 ) == 5 ); assert(S_OK(s));
25 assert( s16_add( &s, 3, 2 ) == 5 ); assert(S_OK(s));
26 assert( s8_add( &s, 3, 2 ) == 5 ); assert(S_OK(s));
27
28 assert( s64_sub( &s, 3, 2 ) == 1 ); assert(S_OK(s));
29 assert( s32_sub( &s, 3, 2 ) == 1 ); assert(S_OK(s));
30 assert( s16_sub( &s, 3, 2 ) == 1 ); assert(S_OK(s));
31 assert( s8_sub( &s, 3, 2 ) == 1 ); assert(S_OK(s));
32
33 /* Catch potential off-by-one implementation errors */
34 /* Unsigned */
35 assert( u64_add( &s, u64_MAX - 1, 1 ) == u64_MAX ); assert(S_OK(s));
36 assert( u32_add( &s, u32_MAX - 1, 1 ) == u32_MAX ); assert(S_OK(s));
37 assert( u16_add( &s, u16_MAX - 1, 1 ) == u16_MAX ); assert(S_OK(s));
38 assert( u8_add( &s, u8_MAX - 1, 1 ) == u8_MAX ); assert(S_OK(s));
39
40 assert( u64_sub( &s, u64_MIN + 1, 1 ) == u64_MIN ); assert(S_OK(s));
41 assert( u32_sub( &s, u32_MIN + 1, 1 ) == u32_MIN ); assert(S_OK(s));
42 assert( u16_sub( &s, u16_MIN + 1, 1 ) == u16_MIN ); assert(S_OK(s));
43 assert( u8_sub( &s, u8_MIN + 1, 1 ) == u8_MIN ); assert(S_OK(s));
44
45 /* Signed */
46 assert( s64_add( &s, s64_MAX - 1, 1 ) == s64_MAX ); assert(S_OK(s));
47 assert( s32_add( &s, s32_MAX - 1, 1 ) == s32_MAX ); assert(S_OK(s));
48 assert( s16_add( &s, s16_MAX - 1, 1 ) == s16_MAX ); assert(S_OK(s));
49 assert( s8_add( &s, s8_MAX - 1, 1 ) == s8_MAX ); assert(S_OK(s));
50
51 assert( s64_sub( &s, s64_MAX - 1, -1 ) == s64_MAX ); assert(S_OK(s));
52 assert( s32_sub( &s, s32_MAX - 1, -1 ) == s32_MAX ); assert(S_OK(s));
53 assert( s16_sub( &s, s16_MAX - 1, -1 ) == s16_MAX ); assert(S_OK(s));
54 assert( s8_sub( &s, s8_MAX - 1, -1 ) == s8_MAX ); assert(S_OK(s));
55
56 assert( s64_sub( &s, s64_MIN + 1, 1 ) == s64_MIN ); assert(S_OK(s));
57 assert( s32_sub( &s, s32_MIN + 1, 1 ) == s32_MIN ); assert(S_OK(s));
58 assert( s16_sub( &s, s16_MIN + 1, 1 ) == s16_MIN ); assert(S_OK(s));
59 assert( s8_sub( &s, s8_MIN + 1, 1 ) == s8_MIN ); assert(S_OK(s));
60
61 assert( s64_add( &s, s64_MIN + 1, -1 ) == s64_MIN ); assert(S_OK(s));
62 assert( s32_add( &s, s32_MIN + 1, -1 ) == s32_MIN ); assert(S_OK(s));
63 assert( s16_add( &s, s16_MIN + 1, -1 ) == s16_MIN ); assert(S_OK(s));
64 assert( s8_add( &s, s8_MIN + 1, -1 ) == s8_MIN ); assert(S_OK(s));
65
66 /* Overflow */
67 /* Unsigned */
68 s = S_SUCCESS; (void)u64_add( &s, u64_MAX, N ); assert( S_NOK(s) );
69 s = S_SUCCESS; (void)u32_add( &s, u32_MAX, N ); assert( S_NOK(s) );
70 s = S_SUCCESS; (void)u16_add( &s, u16_MAX, N ); assert( S_NOK(s) );
71 s = S_SUCCESS; (void) u8_add( &s, u8_MAX, N ); assert( S_NOK(s) );
72
73 s = S_SUCCESS; (void)u64_add( &s, u64_MAX, 1 ); assert( S_NOK(s) );
74 s = S_SUCCESS; (void)u32_add( &s, u32_MAX, 1 ); assert( S_NOK(s) );
75 s = S_SUCCESS; (void)u16_add( &s, u16_MAX, 1 ); assert( S_NOK(s) );
76 s = S_SUCCESS; (void) u8_add( &s, u8_MAX, 1 ); assert( S_NOK(s) );
77
78 /* Signed */
79 s = S_SUCCESS; (void)s64_add( &s, s64_MAX, N ); assert( S_NOK(s) );
80 s = S_SUCCESS; (void)s32_add( &s, s32_MAX, N ); assert( S_NOK(s) );
81 s = S_SUCCESS; (void)s16_add( &s, s16_MAX, N ); assert( S_NOK(s) );
82 s = S_SUCCESS; (void) s8_add( &s, s8_MAX, N ); assert( S_NOK(s) );
83 s = S_SUCCESS; (void)s64_sub( &s, s64_MAX, -N ); assert( S_NOK(s) );
84 s = S_SUCCESS; (void)s32_sub( &s, s32_MAX, -N ); assert( S_NOK(s) );
85 s = S_SUCCESS; (void)s16_sub( &s, s16_MAX, -N ); assert( S_NOK(s) );
86 s = S_SUCCESS; (void) s8_sub( &s, s8_MAX, -N ); assert( S_NOK(s) );
87
88 s = S_SUCCESS; (void)s64_add( &s, s64_MAX, 1 ); assert( S_NOK(s) );
89 s = S_SUCCESS; (void)s32_add( &s, s32_MAX, 1 ); assert( S_NOK(s) );
90 s = S_SUCCESS; (void)s16_add( &s, s16_MAX, 1 ); assert( S_NOK(s) );
91 s = S_SUCCESS; (void) s8_add( &s, s8_MAX, 1 ); assert( S_NOK(s) );
92 s = S_SUCCESS; (void)s64_sub( &s, s64_MAX, -1 ); assert( S_NOK(s) );
93 s = S_SUCCESS; (void)s32_sub( &s, s32_MAX, -1 ); assert( S_NOK(s) );
94 s = S_SUCCESS; (void)s16_sub( &s, s16_MAX, -1 ); assert( S_NOK(s) );
95 s = S_SUCCESS; (void) s8_sub( &s, s8_MAX, -1 ); assert( S_NOK(s) );
96
97 /* Underflow */
98
99 /* Unsigned */
100 s = S_SUCCESS; (void)u64_sub( &s, u64_MIN, N ); assert( S_NOK(s) );
101 s = S_SUCCESS; (void)u32_sub( &s, u32_MIN, N ); assert( S_NOK(s) );
102 s = S_SUCCESS; (void)u16_sub( &s, u16_MIN, N ); assert( S_NOK(s) );
103 s = S_SUCCESS; (void) u8_sub( &s, u8_MIN, N ); assert( S_NOK(s) );
104
105 s = S_SUCCESS; (void)u64_sub( &s, u64_MIN, 1 ); assert( S_NOK(s) );
106 s = S_SUCCESS; (void)u32_sub( &s, u32_MIN, 1 ); assert( S_NOK(s) );
107 s = S_SUCCESS; (void)u16_sub( &s, u16_MIN, 1 ); assert( S_NOK(s) );
108 s = S_SUCCESS; (void) u8_sub( &s, u8_MIN, 1 ); assert( S_NOK(s) );
109
110 /* Signed */
111 s = S_SUCCESS; (void)s64_sub( &s, s64_MIN, N ); assert( S_NOK(s) );
112 s = S_SUCCESS; (void)s32_sub( &s, s32_MIN, N ); assert( S_NOK(s) );
113 s = S_SUCCESS; (void)s16_sub( &s, s16_MIN, N ); assert( S_NOK(s) );
114 s = S_SUCCESS; (void) s8_sub( &s, s8_MIN, N ); assert( S_NOK(s) );
115 s = S_SUCCESS; (void)s64_sub( &s, s64_MIN, 1 ); assert( S_NOK(s) );
116 s = S_SUCCESS; (void)s32_sub( &s, s32_MIN, 1 ); assert( S_NOK(s) );
117 s = S_SUCCESS; (void)s16_sub( &s, s16_MIN, 1 ); assert( S_NOK(s) );
118 s = S_SUCCESS; (void) s8_sub( &s, s8_MIN, 1 ); assert( S_NOK(s) );
119
120 s = S_SUCCESS; (void)s64_add( &s, s64_MIN, -N ); assert( S_NOK(s) );
121 s = S_SUCCESS; (void)s32_add( &s, s32_MIN, -N ); assert( S_NOK(s) );
122 s = S_SUCCESS; (void)s16_add( &s, s16_MIN, -N ); assert( S_NOK(s) );
123 s = S_SUCCESS; (void) s8_add( &s, s8_MIN, -N ); assert( S_NOK(s) );
124 s = S_SUCCESS; (void)s64_add( &s, s64_MIN, -1 ); assert( S_NOK(s) );
125 s = S_SUCCESS; (void)s32_add( &s, s32_MIN, -1 ); assert( S_NOK(s) );
126 s = S_SUCCESS; (void)s16_add( &s, s16_MIN, -1 ); assert( S_NOK(s) );
127 s = S_SUCCESS; (void) s8_add( &s, s8_MIN, -1 ); assert( S_NOK(s) );
128 s = S_SUCCESS;
129
130 /* Basic multiplication */
131 assert( u64_mul( &s, 3, 2 ) == 6 ); assert(S_OK(s));
132 assert( u32_mul( &s, 3, 2 ) == 6 ); assert(S_OK(s));
133 assert( u16_mul( &s, 3, 2 ) == 6 ); assert(S_OK(s));
134 assert( u8_mul( &s, 3, 2 ) == 6 ); assert(S_OK(s));
135
136 assert( s64_mul( &s, 3, 2 ) == 6 ); assert(S_OK(s));
137 assert( s32_mul( &s, 3, 2 ) == 6 ); assert(S_OK(s));
138 assert( s16_mul( &s, 3, 2 ) == 6 ); assert(S_OK(s));
139 assert( s8_mul( &s, 3, 2 ) == 6 ); assert(S_OK(s));
140
141 assert( s64_mul( &s, -3, 2 ) == -6 ); assert(S_OK(s));
142 assert( s32_mul( &s, -3, 2 ) == -6 ); assert(S_OK(s));
143 assert( s16_mul( &s, -3, 2 ) == -6 ); assert(S_OK(s));
144 assert( s8_mul( &s, -3, 2 ) == -6 ); assert(S_OK(s));
145
146 /* Zero */
147 assert( u64_mul( &s, u64_MAX, 0 ) == 0 ); assert(S_OK(s));
148 assert( u32_mul( &s, u32_MAX, 0 ) == 0 ); assert(S_OK(s));
149 assert( u16_mul( &s, u16_MAX, 0 ) == 0 ); assert(S_OK(s));
150 assert( u8_mul( &s, u8_MAX, 0 ) == 0 ); assert(S_OK(s));
151
152 assert( s64_mul( &s, s64_MAX, 0 ) == 0 ); assert(S_OK(s));
153 assert( s32_mul( &s, s32_MAX, 0 ) == 0 ); assert(S_OK(s));
154 assert( s16_mul( &s, s16_MAX, 0 ) == 0 ); assert(S_OK(s));
155 assert( s8_mul( &s, s8_MAX, 0 ) == 0 ); assert(S_OK(s));
156
157 assert( u64_mul( &s, 0, u64_MAX ) == 0 ); assert(S_OK(s));
158 assert( u32_mul( &s, 0, u32_MAX ) == 0 ); assert(S_OK(s));
159 assert( u16_mul( &s, 0, u16_MAX ) == 0 ); assert(S_OK(s));
160 assert( u8_mul( &s, 0, u8_MAX ) == 0 ); assert(S_OK(s));
161
162 assert( s64_mul( &s, 0, s64_MIN ) == 0 ); assert(S_OK(s));
163 assert( s32_mul( &s, 0, s32_MIN ) == 0 ); assert(S_OK(s));
164 assert( s16_mul( &s, 0, s16_MIN ) == 0 ); assert(S_OK(s));
165 assert( s8_mul( &s, 0, s8_MIN ) == 0 ); assert(S_OK(s));
166
167 /* Overflow */
168 s = S_SUCCESS; (void)u64_mul( &s, u64_MAX, 2 ); assert( S_NOK(s) );
169 s = S_SUCCESS; (void)u32_mul( &s, u32_MAX, 2 ); assert( S_NOK(s) );
170 s = S_SUCCESS; (void)u16_mul( &s, u16_MAX, 2 ); assert( S_NOK(s) );
171 s = S_SUCCESS; (void) u8_mul( &s, u8_MAX, 2 ); assert( S_NOK(s) );
172
173 s = S_SUCCESS; (void)s64_mul( &s, s64_MIN, 2 ); assert( S_NOK(s) );
174 s = S_SUCCESS; (void)s32_mul( &s, s32_MIN, 2 ); assert( S_NOK(s) );
175 s = S_SUCCESS; (void)s16_mul( &s, s16_MIN, 2 ); assert( S_NOK(s) );
176 s = S_SUCCESS; (void) s8_mul( &s, s8_MIN, 2 ); assert( S_NOK(s) );
177
178 s = S_SUCCESS; (void)s64_mul( &s, s64_MAX, 2 ); assert( S_NOK(s) );
179 s = S_SUCCESS; (void)s32_mul( &s, s32_MAX, 2 ); assert( S_NOK(s) );
180 s = S_SUCCESS; (void)s16_mul( &s, s16_MAX, 2 ); assert( S_NOK(s) );
181 s = S_SUCCESS; (void) s8_mul( &s, s8_MAX, 2 ); assert( S_NOK(s) );
182
183 s = S_SUCCESS; (void)s64_mul( &s, s64_MIN, -1 ); assert( S_NOK(s) );
184 s = S_SUCCESS; (void)s32_mul( &s, s32_MIN, -1 ); assert( S_NOK(s) );
185 s = S_SUCCESS; (void)s16_mul( &s, s16_MIN, -1 ); assert( S_NOK(s) );
186 s = S_SUCCESS; (void) s8_mul( &s, s8_MIN, -1 ); assert( S_NOK(s) );
187
188 s = S_SUCCESS; (void)s64_mul( &s, s64_MIN/2, -2 ); assert( S_NOK(s) );
189 s = S_SUCCESS; (void)s32_mul( &s, s32_MIN/2, -2 ); assert( S_NOK(s) );
190 s = S_SUCCESS; (void)s16_mul( &s, s16_MIN/2, -2 ); assert( S_NOK(s) );
191 s = S_SUCCESS; (void) s8_mul( &s, s8_MIN/2, -2 ); assert( S_NOK(s) );
192 s = S_SUCCESS;
193
194 /* Signed-specific */
195 s64_mul( &s, s64_MAX, -1 );
196 s32_mul( &s, s32_MAX, -1 );
197 s16_mul( &s, s16_MAX, -1 );
198 s8_mul( &s, s8_MAX, -1);
199
200 assert( s64_mul( &s, s64_MIN + 1, -1 ) == s64_MAX ); assert(S_OK(s));
201 assert( s32_mul( &s, s32_MIN + 1, -1 ) == s32_MAX ); assert(S_OK(s));
202 assert( s16_mul( &s, s16_MIN + 1, -1 ) == s16_MAX ); assert(S_OK(s));
203 assert( s8_mul( &s, s8_MIN + 1, -1 ) == s8_MAX ); assert(S_OK(s));
204
205 assert( s64_mul( &s, s64_MIN / -2, -2 ) == s64_MIN ); assert(S_OK(s));
206 assert( s32_mul( &s, s32_MIN / -2, -2 ) == s32_MIN ); assert(S_OK(s));
207 assert( s16_mul( &s, s16_MIN / -2, -2 ) == s16_MIN ); assert(S_OK(s));
208 assert( s8_mul( &s, s8_MIN / -2, -2 ) == s8_MIN ); assert(S_OK(s));
209
210 assert( s64_mul( &s, s64_MIN / 2 + 1, -2 ) == s64_MAX - 1 ); assert(S_OK(s));
211 assert( s32_mul( &s, s32_MIN / 2 + 1, -2 ) == s32_MAX - 1 ); assert(S_OK(s));
212 assert( s16_mul( &s, s16_MIN / 2 + 1, -2 ) == s16_MAX - 1 ); assert(S_OK(s));
213 assert( s8_mul( &s, s8_MIN / 2 + 1, -2 ) == s8_MAX - 1 ); assert(S_OK(s));
214
215 /* Catch potential off-by-one errors */
216 assert( u64_mul( &s, u64_MAX/2, 2 ) == u64_MAX - 1 ); assert(S_OK(s));
217 assert( u32_mul( &s, u32_MAX/2, 2 ) == u32_MAX - 1 ); assert(S_OK(s));
218 assert( u16_mul( &s, u16_MAX/2, 2 ) == u16_MAX - 1 ); assert(S_OK(s));
219 assert( u8_mul( &s, u8_MAX/2, 2 ) == u8_MAX - 1 ); assert(S_OK(s));
220
221 s = S_SUCCESS; (void)u64_mul( &s, u64_MAX / 2 + 1, 2 ); assert( S_NOK(s) );
222 s = S_SUCCESS; (void)u32_mul( &s, u32_MAX / 2 + 1, 2 ); assert( S_NOK(s) );
223 s = S_SUCCESS; (void)u16_mul( &s, u16_MAX / 2 + 1, 2 ); assert( S_NOK(s) );
224 s = S_SUCCESS; (void) u8_mul( &s, u8_MAX / 2 + 1, 2 ); assert( S_NOK(s) );
225 s = S_SUCCESS;
226
227 assert( s64_mul( &s, s64_MAX/2, 2 ) == s64_MAX - 1 ); assert(S_OK(s));
228 assert( s32_mul( &s, s32_MAX/2, 2 ) == s32_MAX - 1 ); assert(S_OK(s));
229 assert( s16_mul( &s, s16_MAX/2, 2 ) == s16_MAX - 1 ); assert(S_OK(s));
230 assert( s8_mul( &s, s8_MAX/2, 2 ) == s8_MAX - 1 ); assert(S_OK(s));
231
232 assert( s64_mul( &s, s64_MIN/2, 2 ) == s64_MIN ); assert(S_OK(s));
233 assert( s32_mul( &s, s32_MIN/2, 2 ) == s32_MIN ); assert(S_OK(s));
234 assert( s16_mul( &s, s16_MIN/2, 2 ) == s16_MIN ); assert(S_OK(s));
235 assert( s8_mul( &s, s8_MIN/2, 2 ) == s8_MIN ); assert(S_OK(s));
236
237 s = S_SUCCESS; (void)s64_mul( &s, s64_MAX/2 + 1, 2 ); assert( S_NOK(s) );
238 s = S_SUCCESS; (void)s32_mul( &s, s32_MAX/2 + 1, 2 ); assert( S_NOK(s) );
239 s = S_SUCCESS; (void)s16_mul( &s, s16_MAX/2 + 1, 2 ); assert( S_NOK(s) );
240 s = S_SUCCESS; (void) s8_mul( &s, s8_MAX/2 + 1, 2 ); assert( S_NOK(s) );
241
242 s = S_SUCCESS; (void)s64_mul( &s, s64_MIN/2 - 1, 2 ); assert( S_NOK(s) );
243 s = S_SUCCESS; (void)s32_mul( &s, s32_MIN/2 - 1, 2 ); assert( S_NOK(s) );
244 s = S_SUCCESS; (void)s16_mul( &s, s16_MIN/2 - 1, 2 ); assert( S_NOK(s) );
245 s = S_SUCCESS; (void) s8_mul( &s, s8_MIN/2 - 1, 2 ); assert( S_NOK(s) );
246
247 terminate(0);
248}