1 | // [Blend2D] |
2 | // 2D Vector Graphics Powered by a JIT Compiler. |
3 | // |
4 | // [License] |
5 | // Zlib - See LICENSE.md file in the package. |
6 | |
7 | #include "./blapi-build_p.h" |
8 | #include "./blsupport_p.h" |
9 | |
10 | // ============================================================================ |
11 | // [BLScopedAllocator] |
12 | // ============================================================================ |
13 | |
14 | void* BLScopedAllocator::alloc(size_t size, size_t alignment) noexcept { |
15 | // First try to allocate from the local memory pool. |
16 | uint8_t* p = blAlignUp(poolPtr, alignment); |
17 | size_t remain = size_t(blUSubSaturate((uintptr_t)poolEnd, (uintptr_t)p)); |
18 | |
19 | if (remain >= size) { |
20 | poolPtr = p + size; |
21 | return p; |
22 | } |
23 | |
24 | // Bail to malloc of local pool was either not provided or didn't have the |
25 | // required capacity. |
26 | size_t sizeWithOverhead = size + sizeof(Link) + (alignment - 1); |
27 | p = static_cast<uint8_t*>(malloc(sizeWithOverhead)); |
28 | |
29 | if (p == nullptr) |
30 | return nullptr; |
31 | |
32 | reinterpret_cast<Link*>(p)->next = links; |
33 | links = reinterpret_cast<Link*>(p); |
34 | |
35 | return blAlignUp(p + sizeof(Link), alignment); |
36 | } |
37 | |
38 | void BLScopedAllocator::reset() noexcept { |
39 | Link* link = links; |
40 | while (link) { |
41 | Link* next = link->next; |
42 | free(link); |
43 | link = next; |
44 | } |
45 | |
46 | links = nullptr; |
47 | poolPtr = poolMem; |
48 | } |
49 | |
50 | // ============================================================================ |
51 | // [BLSupport - Unit Tests] |
52 | // ============================================================================ |
53 | |
54 | #ifdef BL_TEST |
55 | template<typename T> |
56 | BL_INLINE bool testIsConsecutiveBitMask(T x) { |
57 | if (x == 0) |
58 | return false; |
59 | |
60 | T m = x; |
61 | while ((m & 0x1) == 0) |
62 | m >>= 1; |
63 | return ((m + 1) & m) == 0; |
64 | } |
65 | |
66 | static void testAlignment() noexcept { |
67 | INFO("blIsAligned()" ); |
68 | EXPECT(blIsAligned<size_t>(0xFFFF, 4) == false); |
69 | EXPECT(blIsAligned<size_t>(0xFFF4, 4) == true); |
70 | EXPECT(blIsAligned<size_t>(0xFFF8, 8) == true); |
71 | EXPECT(blIsAligned<size_t>(0xFFF0, 16) == true); |
72 | |
73 | INFO("blAlignUp()" ); |
74 | EXPECT(blAlignUp<size_t>(0xFFFF, 4) == 0x10000); |
75 | EXPECT(blAlignUp<size_t>(0xFFF4, 4) == 0x0FFF4); |
76 | EXPECT(blAlignUp<size_t>(0xFFF8, 8) == 0x0FFF8); |
77 | EXPECT(blAlignUp<size_t>(0xFFF0, 16) == 0x0FFF0); |
78 | EXPECT(blAlignUp<size_t>(0xFFF0, 32) == 0x10000); |
79 | |
80 | INFO("blAlignUpDiff()" ); |
81 | EXPECT(blAlignUpDiff<size_t>(0xFFFF, 4) == 1); |
82 | EXPECT(blAlignUpDiff<size_t>(0xFFF4, 4) == 0); |
83 | EXPECT(blAlignUpDiff<size_t>(0xFFF8, 8) == 0); |
84 | EXPECT(blAlignUpDiff<size_t>(0xFFF0, 16) == 0); |
85 | EXPECT(blAlignUpDiff<size_t>(0xFFF0, 32) == 16); |
86 | |
87 | INFO("blAlignUpPowerOf2()" ); |
88 | EXPECT(blAlignUpPowerOf2<size_t>(0x0000) == 0x00000); |
89 | EXPECT(blAlignUpPowerOf2<size_t>(0xFFFF) == 0x10000); |
90 | EXPECT(blAlignUpPowerOf2<size_t>(0xF123) == 0x10000); |
91 | EXPECT(blAlignUpPowerOf2<size_t>(0x0F00) == 0x01000); |
92 | EXPECT(blAlignUpPowerOf2<size_t>(0x0100) == 0x00100); |
93 | EXPECT(blAlignUpPowerOf2<size_t>(0x1001) == 0x02000); |
94 | } |
95 | |
96 | static void testBitUtils() noexcept { |
97 | uint32_t i; |
98 | |
99 | INFO("blBitShl() / blBitShr()" ); |
100 | EXPECT(blBitShl<int32_t >(0x00001111 , 16) == 0x11110000 ); |
101 | EXPECT(blBitShl<uint32_t>(0x00001111 , 16) == 0x11110000 ); |
102 | EXPECT(blBitShr<int32_t >(0x11110000u, 16) == 0x00001111u); |
103 | EXPECT(blBitShr<uint32_t>(0x11110000u, 16) == 0x00001111u); |
104 | EXPECT(blBitSar<uint32_t>(0xFFFF0000u, 16) == 0xFFFFFFFFu); |
105 | |
106 | INFO("blBitRol() / blBitRor()" ); |
107 | EXPECT(blBitRol<int32_t >(0x00100000 , 16) == 0x00000010 ); |
108 | EXPECT(blBitRol<uint32_t>(0x00100000u, 16) == 0x00000010u); |
109 | EXPECT(blBitRor<int32_t >(0x00001000 , 16) == 0x10000000 ); |
110 | EXPECT(blBitRor<uint32_t>(0x00001000u, 16) == 0x10000000u); |
111 | |
112 | INFO("blBitCtz()" ); |
113 | EXPECT(blBitCtz(1u) == 0); |
114 | EXPECT(blBitCtz(2u) == 1); |
115 | EXPECT(blBitCtz(3u) == 0); |
116 | EXPECT(blBitCtz(0x80000000u) == 31); |
117 | EXPECT(blBitCtzStatic(1u) == 0); |
118 | EXPECT(blBitCtzStatic(2u) == 1); |
119 | EXPECT(blBitCtzStatic(3u) == 0); |
120 | EXPECT(blBitCtzStatic(0x80000000u) == 31); |
121 | |
122 | INFO("blIsPowerOf2()" ); |
123 | for (i = 0; i < 64; i++) { |
124 | EXPECT(blIsPowerOf2(uint64_t(1) << i) == true); |
125 | EXPECT(blIsPowerOf2((uint64_t(1) << i) ^ 0x001101) == false); |
126 | } |
127 | |
128 | INFO("blIsBitMaskConsecutive()" ); |
129 | i = 0; |
130 | for (;;) { |
131 | bool result = blIsBitMaskConsecutive(i); |
132 | bool expect = testIsConsecutiveBitMask(i); |
133 | EXPECT(result == expect); |
134 | |
135 | if (i == 0xFFFFu) |
136 | break; |
137 | i++; |
138 | } |
139 | } |
140 | |
141 | static void testIntUtils() noexcept { |
142 | uint32_t i; |
143 | |
144 | INFO("blByteSwap()" ); |
145 | EXPECT(blByteSwap16(int16_t(0x0102)) == int16_t(0x0201)); |
146 | EXPECT(blByteSwap16(uint16_t(0x0102)) == uint16_t(0x0201)); |
147 | EXPECT(blByteSwap24(int32_t(0x00010203)) == int32_t(0x00030201)); |
148 | EXPECT(blByteSwap24(uint32_t(0x00010203)) == uint32_t(0x00030201)); |
149 | EXPECT(blByteSwap32(int32_t(0x01020304)) == int32_t(0x04030201)); |
150 | EXPECT(blByteSwap32(uint32_t(0x01020304)) == uint32_t(0x04030201)); |
151 | EXPECT(blByteSwap64(uint64_t(0x0102030405060708)) == uint64_t(0x0807060504030201)); |
152 | |
153 | INFO("blClamp()" ); |
154 | EXPECT(blClamp<int>(-1, 100, 1000) == 100); |
155 | EXPECT(blClamp<int>(99, 100, 1000) == 100); |
156 | EXPECT(blClamp<int>(1044, 100, 1000) == 1000); |
157 | EXPECT(blClamp<double>(-1.0, 100.0, 1000.0) == 100.0); |
158 | EXPECT(blClamp<double>(99.0, 100.0, 1000.0) == 100.0); |
159 | EXPECT(blClamp<double>(1044.0, 100.0, 1000.0) == 1000.0); |
160 | |
161 | INFO("blClampToByte()" ); |
162 | EXPECT(blClampToByte(-1) == 0); |
163 | EXPECT(blClampToByte(42) == 42); |
164 | EXPECT(blClampToByte(255) == 0xFF); |
165 | EXPECT(blClampToByte(256) == 0xFF); |
166 | EXPECT(blClampToByte(0x7FFFFFFF) == 0xFF); |
167 | EXPECT(blClampToByte(0x7FFFFFFFu) == 0xFF); |
168 | EXPECT(blClampToByte(0xFFFFFFFFu) == 0xFF); |
169 | |
170 | INFO("blClampToWord()" ); |
171 | EXPECT(blClampToWord(-1) == 0); |
172 | EXPECT(blClampToWord(42) == 42); |
173 | EXPECT(blClampToWord(0xFFFF) == 0xFFFF); |
174 | EXPECT(blClampToWord(0x10000) == 0xFFFF); |
175 | EXPECT(blClampToWord(0x10000u) == 0xFFFF); |
176 | EXPECT(blClampToWord(0x7FFFFFFF) == 0xFFFF); |
177 | EXPECT(blClampToWord(0x7FFFFFFFu) == 0xFFFF); |
178 | EXPECT(blClampToWord(0xFFFFFFFFu) == 0xFFFF); |
179 | |
180 | INFO("blUdiv255()" ); |
181 | for (i = 0; i < 255 * 255; i++) { |
182 | uint32_t result = blUdiv255(i); |
183 | uint32_t j = i + 128; |
184 | |
185 | // This version doesn't overflow 16 bits. |
186 | uint32_t expected = (j + (j >> 8)) >> 8; |
187 | |
188 | EXPECT(result == expected, "blUdiv255(%u) -> %u (Expected %u)" , i, result, expected); |
189 | } |
190 | } |
191 | |
192 | static void testSafeArith() noexcept { |
193 | INFO("blAddOverflow()" ); |
194 | BLOverflowFlag of = 0; |
195 | |
196 | EXPECT(blAddOverflow<int32_t>(0, 0, &of) == 0 && !of); |
197 | EXPECT(blAddOverflow<int32_t>(0, 1, &of) == 1 && !of); |
198 | EXPECT(blAddOverflow<int32_t>(1, 0, &of) == 1 && !of); |
199 | |
200 | EXPECT(blAddOverflow<int32_t>(2147483647, 0, &of) == 2147483647 && !of); |
201 | EXPECT(blAddOverflow<int32_t>(0, 2147483647, &of) == 2147483647 && !of); |
202 | EXPECT(blAddOverflow<int32_t>(2147483647, -1, &of) == 2147483646 && !of); |
203 | EXPECT(blAddOverflow<int32_t>(-1, 2147483647, &of) == 2147483646 && !of); |
204 | |
205 | EXPECT(blAddOverflow<int32_t>(-2147483647, 0, &of) == -2147483647 && !of); |
206 | EXPECT(blAddOverflow<int32_t>(0, -2147483647, &of) == -2147483647 && !of); |
207 | EXPECT(blAddOverflow<int32_t>(-2147483647, -1, &of) == -2147483647 - 1 && !of); |
208 | EXPECT(blAddOverflow<int32_t>(-1, -2147483647, &of) == -2147483647 - 1 && !of); |
209 | |
210 | blAddOverflow<int32_t>(2147483647, 1, &of); EXPECT(of); of = 0; |
211 | blAddOverflow<int32_t>(1, 2147483647, &of); EXPECT(of); of = 0; |
212 | blAddOverflow<int32_t>(-2147483647, -2, &of); EXPECT(of); of = 0; |
213 | blAddOverflow<int32_t>(-2, -2147483647, &of); EXPECT(of); of = 0; |
214 | |
215 | EXPECT(blAddOverflow<uint32_t>(0u, 0u, &of) == 0 && !of); |
216 | EXPECT(blAddOverflow<uint32_t>(0u, 1u, &of) == 1 && !of); |
217 | EXPECT(blAddOverflow<uint32_t>(1u, 0u, &of) == 1 && !of); |
218 | |
219 | EXPECT(blAddOverflow<uint32_t>(2147483647u, 1u, &of) == 2147483648u && !of); |
220 | EXPECT(blAddOverflow<uint32_t>(1u, 2147483647u, &of) == 2147483648u && !of); |
221 | EXPECT(blAddOverflow<uint32_t>(0xFFFFFFFFu, 0u, &of) == 0xFFFFFFFFu && !of); |
222 | EXPECT(blAddOverflow<uint32_t>(0u, 0xFFFFFFFFu, &of) == 0xFFFFFFFFu && !of); |
223 | |
224 | blAddOverflow<uint32_t>(0xFFFFFFFFu, 1u, &of); EXPECT(of); of = 0; |
225 | blAddOverflow<uint32_t>(1u, 0xFFFFFFFFu, &of); EXPECT(of); of = 0; |
226 | |
227 | blAddOverflow<uint32_t>(0x80000000u, 0xFFFFFFFFu, &of); EXPECT(of); of = 0; |
228 | blAddOverflow<uint32_t>(0xFFFFFFFFu, 0x80000000u, &of); EXPECT(of); of = 0; |
229 | blAddOverflow<uint32_t>(0xFFFFFFFFu, 0xFFFFFFFFu, &of); EXPECT(of); of = 0; |
230 | |
231 | INFO("blSubOverflow()" ); |
232 | EXPECT(blSubOverflow<int32_t>(0, 0, &of) == 0 && !of); |
233 | EXPECT(blSubOverflow<int32_t>(0, 1, &of) == -1 && !of); |
234 | EXPECT(blSubOverflow<int32_t>(1, 0, &of) == 1 && !of); |
235 | EXPECT(blSubOverflow<int32_t>(0, -1, &of) == 1 && !of); |
236 | EXPECT(blSubOverflow<int32_t>(-1, 0, &of) == -1 && !of); |
237 | |
238 | EXPECT(blSubOverflow<int32_t>(2147483647, 1, &of) == 2147483646 && !of); |
239 | EXPECT(blSubOverflow<int32_t>(2147483647, 2147483647, &of) == 0 && !of); |
240 | EXPECT(blSubOverflow<int32_t>(-2147483647, 1, &of) == -2147483647 - 1 && !of); |
241 | EXPECT(blSubOverflow<int32_t>(-2147483647, -1, &of) == -2147483646 && !of); |
242 | EXPECT(blSubOverflow<int32_t>(-2147483647 - 0, -2147483647 - 0, &of) == 0 && !of); |
243 | EXPECT(blSubOverflow<int32_t>(-2147483647 - 1, -2147483647 - 1, &of) == 0 && !of); |
244 | |
245 | blSubOverflow<int32_t>(-2, 2147483647, &of); EXPECT(of); of = 0; |
246 | blSubOverflow<int32_t>(-2147483647, 2, &of); EXPECT(of); of = 0; |
247 | |
248 | blSubOverflow<int32_t>(-2147483647 , 2147483647, &of); EXPECT(of); of = 0; |
249 | blSubOverflow<int32_t>(-2147483647 - 1, 2147483647, &of); EXPECT(of); of = 0; |
250 | |
251 | blSubOverflow<int32_t>(2147483647, -2147483647 - 0, &of); EXPECT(of); of = 0; |
252 | blSubOverflow<int32_t>(2147483647, -2147483647 - 1, &of); EXPECT(of); of = 0; |
253 | |
254 | EXPECT(blSubOverflow<uint32_t>(0, 0, &of) == 0 && !of); |
255 | EXPECT(blSubOverflow<uint32_t>(1, 0, &of) == 1 && !of); |
256 | |
257 | EXPECT(blSubOverflow<uint32_t>(0xFFFFFFFFu, 0u, &of) == 0xFFFFFFFFu && !of); |
258 | EXPECT(blSubOverflow<uint32_t>(0xFFFFFFFFu, 0xFFFFFFFFu, &of) == 0u && !of); |
259 | |
260 | blSubOverflow<uint32_t>(0u, 1u, &of); EXPECT(of); of = 0; |
261 | blSubOverflow<uint32_t>(1u, 2u, &of); EXPECT(of); of = 0; |
262 | |
263 | blSubOverflow<uint32_t>(0u, 0xFFFFFFFFu, &of); EXPECT(of); of = 0; |
264 | blSubOverflow<uint32_t>(1u, 0xFFFFFFFFu, &of); EXPECT(of); of = 0; |
265 | |
266 | blSubOverflow<uint32_t>(0u, 0x7FFFFFFFu, &of); EXPECT(of); of = 0; |
267 | blSubOverflow<uint32_t>(1u, 0x7FFFFFFFu, &of); EXPECT(of); of = 0; |
268 | |
269 | blSubOverflow<uint32_t>(0x7FFFFFFEu, 0x7FFFFFFFu, &of); EXPECT(of); of = 0; |
270 | blSubOverflow<uint32_t>(0xFFFFFFFEu, 0xFFFFFFFFu, &of); EXPECT(of); of = 0; |
271 | |
272 | INFO("blMulOverflow()" ); |
273 | EXPECT(blMulOverflow<int32_t>(0, 0, &of) == 0 && !of); |
274 | EXPECT(blMulOverflow<int32_t>(0, 1, &of) == 0 && !of); |
275 | EXPECT(blMulOverflow<int32_t>(1, 0, &of) == 0 && !of); |
276 | |
277 | EXPECT(blMulOverflow<int32_t>( 1, 1, &of) == 1 && !of); |
278 | EXPECT(blMulOverflow<int32_t>( 1, -1, &of) == -1 && !of); |
279 | EXPECT(blMulOverflow<int32_t>(-1, 1, &of) == -1 && !of); |
280 | EXPECT(blMulOverflow<int32_t>(-1, -1, &of) == 1 && !of); |
281 | |
282 | EXPECT(blMulOverflow<int32_t>( 32768, 65535, &of) == 2147450880 && !of); |
283 | EXPECT(blMulOverflow<int32_t>( 32768, -65535, &of) == -2147450880 && !of); |
284 | EXPECT(blMulOverflow<int32_t>(-32768, 65535, &of) == -2147450880 && !of); |
285 | EXPECT(blMulOverflow<int32_t>(-32768, -65535, &of) == 2147450880 && !of); |
286 | |
287 | EXPECT(blMulOverflow<int32_t>(2147483647, 1, &of) == 2147483647 && !of); |
288 | EXPECT(blMulOverflow<int32_t>(1, 2147483647, &of) == 2147483647 && !of); |
289 | |
290 | EXPECT(blMulOverflow<int32_t>(-2147483647 - 1, 1, &of) == -2147483647 - 1 && !of); |
291 | EXPECT(blMulOverflow<int32_t>(1, -2147483647 - 1, &of) == -2147483647 - 1 && !of); |
292 | |
293 | blMulOverflow<int32_t>( 65535, 65535, &of); EXPECT(of); of = 0; |
294 | blMulOverflow<int32_t>( 65535, -65535, &of); EXPECT(of); of = 0; |
295 | blMulOverflow<int32_t>(-65535, 65535, &of); EXPECT(of); of = 0; |
296 | blMulOverflow<int32_t>(-65535, -65535, &of); EXPECT(of); of = 0; |
297 | |
298 | blMulOverflow<int32_t>( 2147483647 , 2147483647 , &of); EXPECT(of); of = 0; |
299 | blMulOverflow<int32_t>( 2147483647 , -2147483647 - 1, &of); EXPECT(of); of = 0; |
300 | blMulOverflow<int32_t>(-2147483647 - 1, 2147483647 , &of); EXPECT(of); of = 0; |
301 | blMulOverflow<int32_t>(-2147483647 - 1, -2147483647 - 1, &of); EXPECT(of); of = 0; |
302 | |
303 | EXPECT(blMulOverflow<uint32_t>(0, 0, &of) == 0 && !of); |
304 | EXPECT(blMulOverflow<uint32_t>(0, 1, &of) == 0 && !of); |
305 | EXPECT(blMulOverflow<uint32_t>(1, 0, &of) == 0 && !of); |
306 | EXPECT(blMulOverflow<uint32_t>(1, 1, &of) == 1 && !of); |
307 | |
308 | EXPECT(blMulOverflow<uint32_t>(0x10000000u, 15, &of) == 0xF0000000u && !of); |
309 | EXPECT(blMulOverflow<uint32_t>(15, 0x10000000u, &of) == 0xF0000000u && !of); |
310 | |
311 | EXPECT(blMulOverflow<uint32_t>(0xFFFFFFFFu, 1, &of) == 0xFFFFFFFFu && !of); |
312 | EXPECT(blMulOverflow<uint32_t>(1, 0xFFFFFFFFu, &of) == 0xFFFFFFFFu && !of); |
313 | |
314 | blMulOverflow<uint32_t>(0xFFFFFFFFu, 2, &of); EXPECT(of); of = 0; |
315 | blMulOverflow<uint32_t>(2, 0xFFFFFFFFu, &of); EXPECT(of); of = 0; |
316 | |
317 | blMulOverflow<uint32_t>(0x80000000u, 2, &of); EXPECT(of); of = 0; |
318 | blMulOverflow<uint32_t>(2, 0x80000000u, &of); EXPECT(of); of = 0; |
319 | |
320 | EXPECT(blMulOverflow<int64_t>(0, 0, &of) == 0 && !of); |
321 | EXPECT(blMulOverflow<int64_t>(0, 1, &of) == 0 && !of); |
322 | EXPECT(blMulOverflow<int64_t>(1, 0, &of) == 0 && !of); |
323 | |
324 | EXPECT(blMulOverflow<int64_t>( 1, 1, &of) == 1 && !of); |
325 | EXPECT(blMulOverflow<int64_t>( 1, -1, &of) == -1 && !of); |
326 | EXPECT(blMulOverflow<int64_t>(-1, 1, &of) == -1 && !of); |
327 | EXPECT(blMulOverflow<int64_t>(-1, -1, &of) == 1 && !of); |
328 | |
329 | EXPECT(blMulOverflow<int64_t>( 32768, 65535, &of) == 2147450880 && !of); |
330 | EXPECT(blMulOverflow<int64_t>( 32768, -65535, &of) == -2147450880 && !of); |
331 | EXPECT(blMulOverflow<int64_t>(-32768, 65535, &of) == -2147450880 && !of); |
332 | EXPECT(blMulOverflow<int64_t>(-32768, -65535, &of) == 2147450880 && !of); |
333 | |
334 | EXPECT(blMulOverflow<int64_t>(2147483647, 1, &of) == 2147483647 && !of); |
335 | EXPECT(blMulOverflow<int64_t>(1, 2147483647, &of) == 2147483647 && !of); |
336 | |
337 | EXPECT(blMulOverflow<int64_t>(-2147483647 - 1, 1, &of) == -2147483647 - 1 && !of); |
338 | EXPECT(blMulOverflow<int64_t>(1, -2147483647 - 1, &of) == -2147483647 - 1 && !of); |
339 | |
340 | EXPECT(blMulOverflow<int64_t>( 65535, 65535, &of) == int64_t(4294836225) && !of); |
341 | EXPECT(blMulOverflow<int64_t>( 65535, -65535, &of) == -int64_t(4294836225) && !of); |
342 | EXPECT(blMulOverflow<int64_t>(-65535, 65535, &of) == -int64_t(4294836225) && !of); |
343 | EXPECT(blMulOverflow<int64_t>(-65535, -65535, &of) == int64_t(4294836225) && !of); |
344 | |
345 | EXPECT(blMulOverflow<int64_t>( 2147483647 , 2147483647 , &of) == int64_t(4611686014132420609) && !of); |
346 | EXPECT(blMulOverflow<int64_t>( 2147483647 , -2147483647 - 1, &of) == -int64_t(4611686016279904256) && !of); |
347 | EXPECT(blMulOverflow<int64_t>(-2147483647 - 1, 2147483647 , &of) == -int64_t(4611686016279904256) && !of); |
348 | EXPECT(blMulOverflow<int64_t>(-2147483647 - 1, -2147483647 - 1, &of) == int64_t(4611686018427387904) && !of); |
349 | |
350 | EXPECT(blMulOverflow<int64_t>(int64_t(0x7FFFFFFFFFFFFFFF), int64_t(1), &of) == int64_t(0x7FFFFFFFFFFFFFFF) && !of); |
351 | EXPECT(blMulOverflow<int64_t>(int64_t(1), int64_t(0x7FFFFFFFFFFFFFFF), &of) == int64_t(0x7FFFFFFFFFFFFFFF) && !of); |
352 | |
353 | blMulOverflow<int64_t>(int64_t(0x7FFFFFFFFFFFFFFF), int64_t(2), &of); EXPECT(of); of = 0; |
354 | blMulOverflow<int64_t>(int64_t(2), int64_t(0x7FFFFFFFFFFFFFFF), &of); EXPECT(of); of = 0; |
355 | |
356 | blMulOverflow<int64_t>(int64_t( 0x7FFFFFFFFFFFFFFF), int64_t( 0x7FFFFFFFFFFFFFFF), &of); EXPECT(of); of = 0; |
357 | blMulOverflow<int64_t>(int64_t( 0x7FFFFFFFFFFFFFFF), int64_t(-0x7FFFFFFFFFFFFFFF), &of); EXPECT(of); of = 0; |
358 | blMulOverflow<int64_t>(int64_t(-0x7FFFFFFFFFFFFFFF), int64_t( 0x7FFFFFFFFFFFFFFF), &of); EXPECT(of); of = 0; |
359 | blMulOverflow<int64_t>(int64_t(-0x7FFFFFFFFFFFFFFF), int64_t(-0x7FFFFFFFFFFFFFFF), &of); EXPECT(of); of = 0; |
360 | |
361 | EXPECT(blMulOverflow<uint64_t>(0, 0, &of) == 0 && !of); |
362 | EXPECT(blMulOverflow<uint64_t>(0, 1, &of) == 0 && !of); |
363 | EXPECT(blMulOverflow<uint64_t>(1, 0, &of) == 0 && !of); |
364 | EXPECT(blMulOverflow<uint64_t>(1, 1, &of) == 1 && !of); |
365 | |
366 | EXPECT(blMulOverflow<uint64_t>(0x1000000000000000u, 15, &of) == 0xF000000000000000u && !of); |
367 | EXPECT(blMulOverflow<uint64_t>(15, 0x1000000000000000u, &of) == 0xF000000000000000u && !of); |
368 | |
369 | EXPECT(blMulOverflow<uint64_t>(0xFFFFFFFFFFFFFFFFu, 1, &of) == 0xFFFFFFFFFFFFFFFFu && !of); |
370 | EXPECT(blMulOverflow<uint64_t>(1, 0xFFFFFFFFFFFFFFFFu, &of) == 0xFFFFFFFFFFFFFFFFu && !of); |
371 | |
372 | blMulOverflow<uint64_t>(0xFFFFFFFFFFFFFFFFu, 2, &of); EXPECT(of); of = 0; |
373 | blMulOverflow<uint64_t>(2, 0xFFFFFFFFFFFFFFFFu, &of); EXPECT(of); of = 0; |
374 | |
375 | blMulOverflow<uint64_t>(0x8000000000000000u, 2, &of); EXPECT(of); of = 0; |
376 | blMulOverflow<uint64_t>(2, 0x8000000000000000u, &of); EXPECT(of); of = 0; |
377 | } |
378 | |
379 | static void testReadWrite() noexcept { |
380 | INFO("blMemRead() / blMemWrite()" ); |
381 | { |
382 | uint8_t arr[32] = { 0 }; |
383 | |
384 | blMemWriteU16uBE(arr + 1, 0x0102u); |
385 | blMemWriteU16uBE(arr + 3, 0x0304u); |
386 | EXPECT(blMemReadU32uBE(arr + 1) == 0x01020304u); |
387 | EXPECT(blMemReadU32uLE(arr + 1) == 0x04030201u); |
388 | EXPECT(blMemReadU32uBE(arr + 2) == 0x02030400u); |
389 | EXPECT(blMemReadU32uLE(arr + 2) == 0x00040302u); |
390 | |
391 | blMemWriteU32uLE(arr + 5, 0x05060708u); |
392 | EXPECT(blMemReadU64uBE(arr + 1) == 0x0102030408070605u); |
393 | EXPECT(blMemReadU64uLE(arr + 1) == 0x0506070804030201u); |
394 | |
395 | blMemWriteU64uLE(arr + 7, 0x1122334455667788u); |
396 | EXPECT(blMemReadU32uBE(arr + 8) == 0x77665544u); |
397 | } |
398 | } |
399 | |
400 | UNIT(blend2d_support) { |
401 | testAlignment(); |
402 | testBitUtils(); |
403 | testIntUtils(); |
404 | testSafeArith(); |
405 | testReadWrite(); |
406 | } |
407 | #endif |
408 | |