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}