ab79f21206cdb9783b9bba512ea31826cd854ee3
[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 #if HAVE_INT128
69 case PSI_T_INT128:
70 i1.u64 = v1->i128;
71 break;
72
73 #endif
74
75 #if HAVE_UINT128
76 case PSI_T_UINT128:
77 i1.u64 = v1->u128;
78 break;
79
80 #endif
81
82 case PSI_T_FLOAT:
83 i1.u64 = v1->fval;
84 break;
85
86 case PSI_T_DOUBLE:
87 i1.u64 = v1->dval;
88 break;
89
90 #if HAVE_LONG_DOUBLE
91 case PSI_T_LONG_DOUBLE:
92 i1.u64 = v1->ldval;
93 break;
94
95 #endif
96
97 default:
98 assert(0);
99 break;
100 }
101
102 switch (t2) {
103 case PSI_T_INT8:
104 i2.u64 = v2->i8;
105 break;
106 case PSI_T_UINT8:
107 i2.u64 = v2->u8;
108 break;
109 case PSI_T_INT16:
110 i2.u64 = v2->i16;
111 break;
112 case PSI_T_UINT16:
113 i2.u64 = v2->u16;
114 break;
115 case PSI_T_INT32:
116 i2.u64 = v2->i32;
117 break;
118 case PSI_T_UINT32:
119 i2.u64 = v2->u32;
120 break;
121 case PSI_T_INT64:
122 i2.u64 = v2->i64;
123 break;
124 case PSI_T_UINT64:
125 i2.u64 = v2->u64;
126 break;
127 #if HAVE_INT128
128 case PSI_T_INT128:
129 i2.u64 = v2->i128;
130 break;
131 #endif
132
133 #if HAVE_UINT128
134 case PSI_T_UINT128:
135 i2.u64 = v2->u128;
136 break;
137 #endif
138
139 case PSI_T_FLOAT:
140 i2.u64 = v2->fval;
141 break;
142 case PSI_T_DOUBLE:
143 i2.u64 = v2->dval;
144 break;
145 #if HAVE_LONG_DOUBLE
146 case PSI_T_LONG_DOUBLE:
147 i2.u64 = v2->ldval;
148 break;
149 #endif
150
151 default:
152 assert(0);
153 break;
154 }
155
156 res->u64 = i1.u64 << i2.u64;
157 return PSI_T_UINT64;
158 }
159
160 static inline token_t psi_calc_bin_rshift(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
161 {
162 impl_val i1, i2;
163
164 switch (t1) {
165 case PSI_T_INT8:
166 i1.u64 = v1->i8;
167 break;
168
169 case PSI_T_UINT8:
170 i1.u64 = v1->u8;
171 break;
172
173 case PSI_T_INT16:
174 i1.u64 = v1->i16;
175 break;
176
177 case PSI_T_UINT16:
178 i1.u64 = v1->u16;
179 break;
180
181 case PSI_T_INT32:
182 i1.u64 = v1->i32;
183 break;
184
185 case PSI_T_UINT32:
186 i1.u64 = v1->u32;
187 break;
188
189 case PSI_T_INT64:
190 i1.u64 = v1->i64;
191 break;
192
193 case PSI_T_UINT64:
194 i1.u64 = v1->u64;
195 break;
196
197 #if HAVE_INT128
198 case PSI_T_INT128:
199 i1.u64 = v1->i128;
200 break;
201
202 #endif
203
204 #if HAVE_UINT128
205 case PSI_T_UINT128:
206 i1.u64 = v1->u128;
207 break;
208
209 #endif
210
211 case PSI_T_FLOAT:
212 i1.u64 = v1->fval;
213 break;
214
215 case PSI_T_DOUBLE:
216 i1.u64 = v1->dval;
217 break;
218
219 #if HAVE_LONG_DOUBLE
220 case PSI_T_LONG_DOUBLE:
221 i1.u64 = v1->ldval;
222 break;
223
224 #endif
225
226 default:
227 assert(0);
228 break;
229 }
230
231 switch (t2) {
232 case PSI_T_INT8:
233 i2.u64 = v2->i8;
234 break;
235 case PSI_T_UINT8:
236 i2.u64 = v2->u8;
237 break;
238 case PSI_T_INT16:
239 i2.u64 = v2->i16;
240 break;
241 case PSI_T_UINT16:
242 i2.u64 = v2->u16;
243 break;
244 case PSI_T_INT32:
245 i2.u64 = v2->i32;
246 break;
247 case PSI_T_UINT32:
248 i2.u64 = v2->u32;
249 break;
250 case PSI_T_INT64:
251 i2.u64 = v2->i64;
252 break;
253 case PSI_T_UINT64:
254 i2.u64 = v2->u64;
255 break;
256 #if HAVE_INT128
257 case PSI_T_INT128:
258 i2.u64 = v2->i128;
259 break;
260 #endif
261
262 #if HAVE_UINT128
263 case PSI_T_UINT128:
264 i2.u64 = v2->u128;
265 break;
266 #endif
267
268 case PSI_T_FLOAT:
269 i2.u64 = v2->fval;
270 break;
271 case PSI_T_DOUBLE:
272 i2.u64 = v2->dval;
273 break;
274 #if HAVE_LONG_DOUBLE
275 case PSI_T_LONG_DOUBLE:
276 i2.u64 = v2->ldval;
277 break;
278 #endif
279
280 default:
281 assert(0);
282 break;
283 }
284
285 res->u64 = i1.u64 >> i2.u64;
286 return PSI_T_UINT64;
287 }
288
289 static inline token_t psi_calc_bin_and(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
290 {
291 impl_val i1, i2;
292
293 switch (t1) {
294 case PSI_T_INT8:
295 i1.u64 = v1->i8;
296 break;
297
298 case PSI_T_UINT8:
299 i1.u64 = v1->u8;
300 break;
301
302 case PSI_T_INT16:
303 i1.u64 = v1->i16;
304 break;
305
306 case PSI_T_UINT16:
307 i1.u64 = v1->u16;
308 break;
309
310 case PSI_T_INT32:
311 i1.u64 = v1->i32;
312 break;
313
314 case PSI_T_UINT32:
315 i1.u64 = v1->u32;
316 break;
317
318 case PSI_T_INT64:
319 i1.u64 = v1->i64;
320 break;
321
322 case PSI_T_UINT64:
323 i1.u64 = v1->u64;
324 break;
325
326 #if HAVE_INT128
327 case PSI_T_INT128:
328 i1.u64 = v1->i128;
329 break;
330
331 #endif
332
333 #if HAVE_UINT128
334 case PSI_T_UINT128:
335 i1.u64 = v1->u128;
336 break;
337
338 #endif
339
340 case PSI_T_FLOAT:
341 i1.u64 = v1->fval;
342 break;
343
344 case PSI_T_DOUBLE:
345 i1.u64 = v1->dval;
346 break;
347
348 #if HAVE_LONG_DOUBLE
349 case PSI_T_LONG_DOUBLE:
350 i1.u64 = v1->ldval;
351 break;
352
353 #endif
354
355 default:
356 assert(0);
357 break;
358 }
359
360 switch (t2) {
361 case PSI_T_INT8:
362 i2.u64 = v2->i8;
363 break;
364 case PSI_T_UINT8:
365 i2.u64 = v2->u8;
366 break;
367 case PSI_T_INT16:
368 i2.u64 = v2->i16;
369 break;
370 case PSI_T_UINT16:
371 i2.u64 = v2->u16;
372 break;
373 case PSI_T_INT32:
374 i2.u64 = v2->i32;
375 break;
376 case PSI_T_UINT32:
377 i2.u64 = v2->u32;
378 break;
379 case PSI_T_INT64:
380 i2.u64 = v2->i64;
381 break;
382 case PSI_T_UINT64:
383 i2.u64 = v2->u64;
384 break;
385 #if HAVE_INT128
386 case PSI_T_INT128:
387 i2.u64 = v2->i128;
388 break;
389 #endif
390
391 #if HAVE_UINT128
392 case PSI_T_UINT128:
393 i2.u64 = v2->u128;
394 break;
395 #endif
396
397 case PSI_T_FLOAT:
398 i2.u64 = v2->fval;
399 break;
400 case PSI_T_DOUBLE:
401 i2.u64 = v2->dval;
402 break;
403 #if HAVE_LONG_DOUBLE
404 case PSI_T_LONG_DOUBLE:
405 i2.u64 = v2->ldval;
406 break;
407 #endif
408
409 default:
410 assert(0);
411 break;
412 }
413
414 res->u64 = i1.u64 & i2.u64;
415 return PSI_T_UINT64;
416 }
417
418 static inline token_t psi_calc_bin_xor(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
419 {
420 impl_val i1, i2;
421
422 switch (t1) {
423 case PSI_T_INT8:
424 i1.u64 = v1->i8;
425 break;
426
427 case PSI_T_UINT8:
428 i1.u64 = v1->u8;
429 break;
430
431 case PSI_T_INT16:
432 i1.u64 = v1->i16;
433 break;
434
435 case PSI_T_UINT16:
436 i1.u64 = v1->u16;
437 break;
438
439 case PSI_T_INT32:
440 i1.u64 = v1->i32;
441 break;
442
443 case PSI_T_UINT32:
444 i1.u64 = v1->u32;
445 break;
446
447 case PSI_T_INT64:
448 i1.u64 = v1->i64;
449 break;
450
451 case PSI_T_UINT64:
452 i1.u64 = v1->u64;
453 break;
454
455 #if HAVE_INT128
456 case PSI_T_INT128:
457 i1.u64 = v1->i128;
458 break;
459
460 #endif
461
462 #if HAVE_UINT128
463 case PSI_T_UINT128:
464 i1.u64 = v1->u128;
465 break;
466
467 #endif
468
469 case PSI_T_FLOAT:
470 i1.u64 = v1->fval;
471 break;
472
473 case PSI_T_DOUBLE:
474 i1.u64 = v1->dval;
475 break;
476
477 #if HAVE_LONG_DOUBLE
478 case PSI_T_LONG_DOUBLE:
479 i1.u64 = v1->ldval;
480 break;
481
482 #endif
483
484 default:
485 assert(0);
486 break;
487 }
488
489 switch (t2) {
490 case PSI_T_INT8:
491 i2.u64 = v2->i8;
492 break;
493 case PSI_T_UINT8:
494 i2.u64 = v2->u8;
495 break;
496 case PSI_T_INT16:
497 i2.u64 = v2->i16;
498 break;
499 case PSI_T_UINT16:
500 i2.u64 = v2->u16;
501 break;
502 case PSI_T_INT32:
503 i2.u64 = v2->i32;
504 break;
505 case PSI_T_UINT32:
506 i2.u64 = v2->u32;
507 break;
508 case PSI_T_INT64:
509 i2.u64 = v2->i64;
510 break;
511 case PSI_T_UINT64:
512 i2.u64 = v2->u64;
513 break;
514 #if HAVE_INT128
515 case PSI_T_INT128:
516 i2.u64 = v2->i128;
517 break;
518 #endif
519
520 #if HAVE_UINT128
521 case PSI_T_UINT128:
522 i2.u64 = v2->u128;
523 break;
524 #endif
525
526 case PSI_T_FLOAT:
527 i2.u64 = v2->fval;
528 break;
529 case PSI_T_DOUBLE:
530 i2.u64 = v2->dval;
531 break;
532 #if HAVE_LONG_DOUBLE
533 case PSI_T_LONG_DOUBLE:
534 i2.u64 = v2->ldval;
535 break;
536 #endif
537
538 default:
539 assert(0);
540 break;
541 }
542
543 res->u64 = i1.u64 ^ i2.u64;
544 return PSI_T_UINT64;
545 }
546
547 static inline token_t psi_calc_bin_or(token_t t1, impl_val *v1, token_t t2, impl_val *v2, impl_val *res)
548 {
549 impl_val i1, i2;
550
551 switch (t1) {
552 case PSI_T_INT8:
553 i1.u64 = v1->i8;
554 break;
555
556 case PSI_T_UINT8:
557 i1.u64 = v1->u8;
558 break;
559
560 case PSI_T_INT16:
561 i1.u64 = v1->i16;
562 break;
563
564 case PSI_T_UINT16:
565 i1.u64 = v1->u16;
566 break;
567
568 case PSI_T_INT32:
569 i1.u64 = v1->i32;
570 break;
571
572 case PSI_T_UINT32:
573 i1.u64 = v1->u32;
574 break;
575
576 case PSI_T_INT64:
577 i1.u64 = v1->i64;
578 break;
579
580 case PSI_T_UINT64:
581 i1.u64 = v1->u64;
582 break;
583
584 #if HAVE_INT128
585 case PSI_T_INT128:
586 i1.u64 = v1->i128;
587 break;
588
589 #endif
590
591 #if HAVE_UINT128
592 case PSI_T_UINT128:
593 i1.u64 = v1->u128;
594 break;
595
596 #endif
597
598 case PSI_T_FLOAT:
599 i1.u64 = v1->fval;
600 break;
601
602 case PSI_T_DOUBLE:
603 i1.u64 = v1->dval;
604 break;
605
606 #if HAVE_LONG_DOUBLE
607 case PSI_T_LONG_DOUBLE:
608 i1.u64 = v1->ldval;
609 break;
610
611 #endif
612
613 default:
614 assert(0);
615 break;
616 }
617
618 switch (t2) {
619 case PSI_T_INT8:
620 i2.u64 = v2->i8;
621 break;
622 case PSI_T_UINT8:
623 i2.u64 = v2->u8;
624 break;
625 case PSI_T_INT16:
626 i2.u64 = v2->i16;
627 break;
628 case PSI_T_UINT16:
629 i2.u64 = v2->u16;
630 break;
631 case PSI_T_INT32:
632 i2.u64 = v2->i32;
633 break;
634 case PSI_T_UINT32:
635 i2.u64 = v2->u32;
636 break;
637 case PSI_T_INT64:
638 i2.u64 = v2->i64;
639 break;
640 case PSI_T_UINT64:
641 i2.u64 = v2->u64;
642 break;
643 #if HAVE_INT128
644 case PSI_T_INT128:
645 i2.u64 = v2->i128;
646 break;
647 #endif
648
649 #if HAVE_UINT128
650 case PSI_T_UINT128:
651 i2.u64 = v2->u128;
652 break;
653 #endif
654
655 case PSI_T_FLOAT:
656 i2.u64 = v2->fval;
657 break;
658 case PSI_T_DOUBLE:
659 i2.u64 = v2->dval;
660 break;
661 #if HAVE_LONG_DOUBLE
662 case PSI_T_LONG_DOUBLE:
663 i2.u64 = v2->ldval;
664 break;
665 #endif
666
667 default:
668 assert(0);
669 break;
670 }
671
672 res->u64 = i1.u64 | i2.u64;
673 return PSI_T_UINT64;
674 }