Merge branch 'slimconfigure'
[m6w6/ext-psi] / src / calc / bin.h
1 /*******************************************************************************
2 Copyright (c) 2016, Michael Wallner <mike@php.net>.
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice,
9 this list of conditions and the following disclaimer.
10 * Redistributions in binary form must reproduce the above copyright
11 notice, this list of conditions and the following disclaimer in the
12 documentation and/or other materials provided with the distribution.
13
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
15 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
18 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
20 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
21 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
22 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 *******************************************************************************/
25
26 #include "php_psi_stdinc.h"
27 #include <assert.h>
28
29 #include "token.h"
30
31 static inline token_t psi_calc_bin_lshift(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
32 {
33 impl_val i1, i2;
34
35 switch (t1) {
36 case PSI_T_INT8:
37 i1.u64 = v1->i8;
38 break;
39
40 case PSI_T_UINT8:
41 i1.u64 = v1->u8;
42 break;
43
44 case PSI_T_INT16:
45 i1.u64 = v1->i16;
46 break;
47
48 case PSI_T_UINT16:
49 i1.u64 = v1->u16;
50 break;
51
52 case PSI_T_INT32:
53 i1.u64 = v1->i32;
54 break;
55
56 case PSI_T_UINT32:
57 i1.u64 = v1->u32;
58 break;
59
60 case PSI_T_INT64:
61 i1.u64 = v1->i64;
62 break;
63
64 case PSI_T_UINT64:
65 i1.u64 = v1->u64;
66 break;
67
68 case PSI_T_INT128:
69 i1.u64 = v1->i128;
70 break;
71
72 case PSI_T_UINT128:
73 i1.u64 = v1->u128;
74 break;
75
76 case PSI_T_FLOAT:
77 i1.u64 = v1->fval;
78 break;
79
80 case PSI_T_DOUBLE:
81 i1.u64 = v1->dval;
82 break;
83
84 #if HAVE_LONG_DOUBLE
85 case PSI_T_LONG_DOUBLE:
86 i1.u64 = v1->ldval;
87 break;
88
89 #endif
90
91 default:
92 assert(0);
93 break;
94 }
95
96 switch (t2) {
97 case PSI_T_INT8:
98 i2.u64 = v2->i8;
99 break;
100 case PSI_T_UINT8:
101 i2.u64 = v2->u8;
102 break;
103 case PSI_T_INT16:
104 i2.u64 = v2->i16;
105 break;
106 case PSI_T_UINT16:
107 i2.u64 = v2->u16;
108 break;
109 case PSI_T_INT32:
110 i2.u64 = v2->i32;
111 break;
112 case PSI_T_UINT32:
113 i2.u64 = v2->u32;
114 break;
115 case PSI_T_INT64:
116 i2.u64 = v2->i64;
117 break;
118 case PSI_T_UINT64:
119 i2.u64 = v2->u64;
120 break;
121 case PSI_T_INT128:
122 i2.u64 = v2->i128;
123 break;
124 case PSI_T_UINT128:
125 i2.u64 = v2->u128;
126 break;
127 case PSI_T_FLOAT:
128 i2.u64 = v2->fval;
129 break;
130 case PSI_T_DOUBLE:
131 i2.u64 = v2->dval;
132 break;
133 #if HAVE_LONG_DOUBLE
134 case PSI_T_LONG_DOUBLE:
135 i2.u64 = v2->ldval;
136 break;
137 #endif
138
139 default:
140 assert(0);
141 break;
142 }
143
144 res->u64 = i1.u64 << i2.u64;
145 return PSI_T_UINT64;
146 }
147
148 static inline token_t psi_calc_bin_rshift(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
149 {
150 impl_val i1, i2;
151
152 switch (t1) {
153 case PSI_T_INT8:
154 i1.u64 = v1->i8;
155 break;
156
157 case PSI_T_UINT8:
158 i1.u64 = v1->u8;
159 break;
160
161 case PSI_T_INT16:
162 i1.u64 = v1->i16;
163 break;
164
165 case PSI_T_UINT16:
166 i1.u64 = v1->u16;
167 break;
168
169 case PSI_T_INT32:
170 i1.u64 = v1->i32;
171 break;
172
173 case PSI_T_UINT32:
174 i1.u64 = v1->u32;
175 break;
176
177 case PSI_T_INT64:
178 i1.u64 = v1->i64;
179 break;
180
181 case PSI_T_UINT64:
182 i1.u64 = v1->u64;
183 break;
184
185 case PSI_T_INT128:
186 i1.u64 = v1->i128;
187 break;
188
189 case PSI_T_UINT128:
190 i1.u64 = v1->u128;
191 break;
192
193 case PSI_T_FLOAT:
194 i1.u64 = v1->fval;
195 break;
196
197 case PSI_T_DOUBLE:
198 i1.u64 = v1->dval;
199 break;
200
201 #if HAVE_LONG_DOUBLE
202 case PSI_T_LONG_DOUBLE:
203 i1.u64 = v1->ldval;
204 break;
205
206 #endif
207
208 default:
209 assert(0);
210 break;
211 }
212
213 switch (t2) {
214 case PSI_T_INT8:
215 i2.u64 = v2->i8;
216 break;
217 case PSI_T_UINT8:
218 i2.u64 = v2->u8;
219 break;
220 case PSI_T_INT16:
221 i2.u64 = v2->i16;
222 break;
223 case PSI_T_UINT16:
224 i2.u64 = v2->u16;
225 break;
226 case PSI_T_INT32:
227 i2.u64 = v2->i32;
228 break;
229 case PSI_T_UINT32:
230 i2.u64 = v2->u32;
231 break;
232 case PSI_T_INT64:
233 i2.u64 = v2->i64;
234 break;
235 case PSI_T_UINT64:
236 i2.u64 = v2->u64;
237 break;
238 case PSI_T_INT128:
239 i2.u64 = v2->i128;
240 break;
241 case PSI_T_UINT128:
242 i2.u64 = v2->u128;
243 break;
244 case PSI_T_FLOAT:
245 i2.u64 = v2->fval;
246 break;
247 case PSI_T_DOUBLE:
248 i2.u64 = v2->dval;
249 break;
250 #if HAVE_LONG_DOUBLE
251 case PSI_T_LONG_DOUBLE:
252 i2.u64 = v2->ldval;
253 break;
254 #endif
255
256 default:
257 assert(0);
258 break;
259 }
260
261 res->u64 = i1.u64 >> i2.u64;
262 return PSI_T_UINT64;
263 }
264
265 static inline token_t psi_calc_bin_and(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
266 {
267 impl_val i1, i2;
268
269 switch (t1) {
270 case PSI_T_INT8:
271 i1.u64 = v1->i8;
272 break;
273
274 case PSI_T_UINT8:
275 i1.u64 = v1->u8;
276 break;
277
278 case PSI_T_INT16:
279 i1.u64 = v1->i16;
280 break;
281
282 case PSI_T_UINT16:
283 i1.u64 = v1->u16;
284 break;
285
286 case PSI_T_INT32:
287 i1.u64 = v1->i32;
288 break;
289
290 case PSI_T_UINT32:
291 i1.u64 = v1->u32;
292 break;
293
294 case PSI_T_INT64:
295 i1.u64 = v1->i64;
296 break;
297
298 case PSI_T_UINT64:
299 i1.u64 = v1->u64;
300 break;
301
302 case PSI_T_INT128:
303 i1.u64 = v1->i128;
304 break;
305
306 case PSI_T_UINT128:
307 i1.u64 = v1->u128;
308 break;
309
310 case PSI_T_FLOAT:
311 i1.u64 = v1->fval;
312 break;
313
314 case PSI_T_DOUBLE:
315 i1.u64 = v1->dval;
316 break;
317
318 #if HAVE_LONG_DOUBLE
319 case PSI_T_LONG_DOUBLE:
320 i1.u64 = v1->ldval;
321 break;
322
323 #endif
324
325 default:
326 assert(0);
327 break;
328 }
329
330 switch (t2) {
331 case PSI_T_INT8:
332 i2.u64 = v2->i8;
333 break;
334 case PSI_T_UINT8:
335 i2.u64 = v2->u8;
336 break;
337 case PSI_T_INT16:
338 i2.u64 = v2->i16;
339 break;
340 case PSI_T_UINT16:
341 i2.u64 = v2->u16;
342 break;
343 case PSI_T_INT32:
344 i2.u64 = v2->i32;
345 break;
346 case PSI_T_UINT32:
347 i2.u64 = v2->u32;
348 break;
349 case PSI_T_INT64:
350 i2.u64 = v2->i64;
351 break;
352 case PSI_T_UINT64:
353 i2.u64 = v2->u64;
354 break;
355 case PSI_T_INT128:
356 i2.u64 = v2->i128;
357 break;
358 case PSI_T_UINT128:
359 i2.u64 = v2->u128;
360 break;
361 case PSI_T_FLOAT:
362 i2.u64 = v2->fval;
363 break;
364 case PSI_T_DOUBLE:
365 i2.u64 = v2->dval;
366 break;
367 #if HAVE_LONG_DOUBLE
368 case PSI_T_LONG_DOUBLE:
369 i2.u64 = v2->ldval;
370 break;
371 #endif
372
373 default:
374 assert(0);
375 break;
376 }
377
378 res->u64 = i1.u64 & i2.u64;
379 return PSI_T_UINT64;
380 }
381
382 static inline token_t psi_calc_bin_xor(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
383 {
384 impl_val i1, i2;
385
386 switch (t1) {
387 case PSI_T_INT8:
388 i1.u64 = v1->i8;
389 break;
390
391 case PSI_T_UINT8:
392 i1.u64 = v1->u8;
393 break;
394
395 case PSI_T_INT16:
396 i1.u64 = v1->i16;
397 break;
398
399 case PSI_T_UINT16:
400 i1.u64 = v1->u16;
401 break;
402
403 case PSI_T_INT32:
404 i1.u64 = v1->i32;
405 break;
406
407 case PSI_T_UINT32:
408 i1.u64 = v1->u32;
409 break;
410
411 case PSI_T_INT64:
412 i1.u64 = v1->i64;
413 break;
414
415 case PSI_T_UINT64:
416 i1.u64 = v1->u64;
417 break;
418
419 case PSI_T_INT128:
420 i1.u64 = v1->i128;
421 break;
422
423 case PSI_T_UINT128:
424 i1.u64 = v1->u128;
425 break;
426
427 case PSI_T_FLOAT:
428 i1.u64 = v1->fval;
429 break;
430
431 case PSI_T_DOUBLE:
432 i1.u64 = v1->dval;
433 break;
434
435 #if HAVE_LONG_DOUBLE
436 case PSI_T_LONG_DOUBLE:
437 i1.u64 = v1->ldval;
438 break;
439
440 #endif
441
442 default:
443 assert(0);
444 break;
445 }
446
447 switch (t2) {
448 case PSI_T_INT8:
449 i2.u64 = v2->i8;
450 break;
451 case PSI_T_UINT8:
452 i2.u64 = v2->u8;
453 break;
454 case PSI_T_INT16:
455 i2.u64 = v2->i16;
456 break;
457 case PSI_T_UINT16:
458 i2.u64 = v2->u16;
459 break;
460 case PSI_T_INT32:
461 i2.u64 = v2->i32;
462 break;
463 case PSI_T_UINT32:
464 i2.u64 = v2->u32;
465 break;
466 case PSI_T_INT64:
467 i2.u64 = v2->i64;
468 break;
469 case PSI_T_UINT64:
470 i2.u64 = v2->u64;
471 break;
472 case PSI_T_INT128:
473 i2.u64 = v2->i128;
474 break;
475 case PSI_T_UINT128:
476 i2.u64 = v2->u128;
477 break;
478 case PSI_T_FLOAT:
479 i2.u64 = v2->fval;
480 break;
481 case PSI_T_DOUBLE:
482 i2.u64 = v2->dval;
483 break;
484 #if HAVE_LONG_DOUBLE
485 case PSI_T_LONG_DOUBLE:
486 i2.u64 = v2->ldval;
487 break;
488 #endif
489
490 default:
491 assert(0);
492 break;
493 }
494
495 res->u64 = i1.u64 ^ i2.u64;
496 return PSI_T_UINT64;
497 }
498
499 static inline token_t psi_calc_bin_or(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
500 {
501 impl_val i1, i2;
502
503 switch (t1) {
504 case PSI_T_INT8:
505 i1.u64 = v1->i8;
506 break;
507
508 case PSI_T_UINT8:
509 i1.u64 = v1->u8;
510 break;
511
512 case PSI_T_INT16:
513 i1.u64 = v1->i16;
514 break;
515
516 case PSI_T_UINT16:
517 i1.u64 = v1->u16;
518 break;
519
520 case PSI_T_INT32:
521 i1.u64 = v1->i32;
522 break;
523
524 case PSI_T_UINT32:
525 i1.u64 = v1->u32;
526 break;
527
528 case PSI_T_INT64:
529 i1.u64 = v1->i64;
530 break;
531
532 case PSI_T_UINT64:
533 i1.u64 = v1->u64;
534 break;
535
536 case PSI_T_INT128:
537 i1.u64 = v1->i128;
538 break;
539
540 case PSI_T_UINT128:
541 i1.u64 = v1->u128;
542 break;
543
544 case PSI_T_FLOAT:
545 i1.u64 = v1->fval;
546 break;
547
548 case PSI_T_DOUBLE:
549 i1.u64 = v1->dval;
550 break;
551
552 #if HAVE_LONG_DOUBLE
553 case PSI_T_LONG_DOUBLE:
554 i1.u64 = v1->ldval;
555 break;
556
557 #endif
558
559 default:
560 assert(0);
561 break;
562 }
563
564 switch (t2) {
565 case PSI_T_INT8:
566 i2.u64 = v2->i8;
567 break;
568 case PSI_T_UINT8:
569 i2.u64 = v2->u8;
570 break;
571 case PSI_T_INT16:
572 i2.u64 = v2->i16;
573 break;
574 case PSI_T_UINT16:
575 i2.u64 = v2->u16;
576 break;
577 case PSI_T_INT32:
578 i2.u64 = v2->i32;
579 break;
580 case PSI_T_UINT32:
581 i2.u64 = v2->u32;
582 break;
583 case PSI_T_INT64:
584 i2.u64 = v2->i64;
585 break;
586 case PSI_T_UINT64:
587 i2.u64 = v2->u64;
588 break;
589 case PSI_T_INT128:
590 i2.u64 = v2->i128;
591 break;
592 case PSI_T_UINT128:
593 i2.u64 = v2->u128;
594 break;
595 case PSI_T_FLOAT:
596 i2.u64 = v2->fval;
597 break;
598 case PSI_T_DOUBLE:
599 i2.u64 = v2->dval;
600 break;
601 #if HAVE_LONG_DOUBLE
602 case PSI_T_LONG_DOUBLE:
603 i2.u64 = v2->ldval;
604 break;
605 #endif
606
607 default:
608 assert(0);
609 break;
610 }
611
612 res->u64 = i1.u64 | i2.u64;
613 return PSI_T_UINT64;
614 }