1 : //=============================================================================
2 : // File <$/src/cpp/dev/idlc/arith_gmp.cpp>
3 : // This file is part of YaOrb : Yet Another Object Request Broker,
4 : // Copyright (c) 2006, Marc Alff.
5 : //
6 : // This program is free software; you can redistribute it and/or
7 : // modify it under the terms of the GNU General Public License
8 : // as published by the Free Software Foundation; either version 2
9 : // of the License, or (at your option) any later version.
10 : //
11 : // This program is distributed in the hope that it will be useful,
12 : // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 : // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 : // GNU General Public License for more details.
15 : //
16 : // You should have received a copy of the GNU General Public License
17 : // along with this program; if not, write to the Free Software
18 : // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19 : //
20 : //=============================================================================
21 :
22 : #include <yaorb/platform.h>
23 : #include <stdio.h>
24 : #include <gmp.h>
25 :
26 : #include "src/cpp/dev/idlc/arith.h"
27 :
28 : static const unsigned long MAX_U16 = 0xFFFF ;
29 : static const unsigned long MAX_U32 = 0xFFFFFFFF ;
30 :
31 : static const signed long MAX_S16 = 0x7FFF ;
32 : static const signed long MAX_S32 = 0x7FFFFFFF ;
33 :
34 : // Causes compile time warnings during GMP macro expansion with GCC
35 : // static const signed long MIN_S16 = - 0x8000 ;
36 : // static const signed long MIN_S32 = - 0x80000000 ;
37 :
38 : static const signed long MIN_S16 = - 0x7FFF -1 ;
39 : static const signed long MIN_S32 = - 0x7FFFFFFF -1 ;
40 :
41 : // #define to add debugging code (development only) :
42 : // #define DEBUG
43 :
44 : //=============================================================================
45 : // Debug helpers
46 : //=============================================================================
47 :
48 : #ifdef DEBUG
49 : void DEBUG_Dump(FILE *where, const char * msg, mpz_t value)
50 : {
51 : char buffer[80];
52 :
53 : mpz_get_str(buffer, 10, value) ;
54 : fprintf(where, "%s : %s\n", msg, buffer) ;
55 : }
56 : #endif
57 :
58 : #ifdef DEBUG
59 : void DEBUG_Operation(
60 : FILE * where,
61 : const char * name,
62 : mpz_t op1,
63 : mpz_t op2,
64 : mpz_t res,
65 : bool overflow)
66 : {
67 : char buffer[80];
68 :
69 : mpz_get_str(buffer, 10, op1) ;
70 : fprintf(where, "%s op1 : %s\n", name, buffer) ;
71 :
72 : mpz_get_str(buffer, 10, op2) ;
73 : fprintf(where, "%s op2 : %s\n", name, buffer) ;
74 :
75 : mpz_get_str(buffer, 10, res) ;
76 : fprintf(where, "%s res : %s\n", name, buffer) ;
77 :
78 : if (overflow)
79 : {
80 : fprintf(where, "%s returned overflow.\n", name) ;
81 : }
82 : else
83 : {
84 : fprintf(where, "%s returned ok.\n", name) ;
85 : }
86 : }
87 : #endif
88 :
89 : //=============================================================================
90 : // 64 bits manipulation helpers
91 : //=============================================================================
92 :
93 24 : void yaorb_mpz_set_u64(mpz_t value, uint64_t init)
94 : {
95 : // Note : mpz_set_ui works with "ui" = unsigned long int (32 bits).
96 : // There is no unsigned long long int version (64 bits).
97 :
98 : uint32_t hi ;
99 : uint32_t lo ;
100 :
101 : hi = (init >> 32) ;
102 : lo = init & 0xFFFFFFFF ;
103 :
104 : mpz_t hi_z ;
105 : mpz_t lo_z ;
106 : mpz_t twop32 ;
107 :
108 24 : mpz_init(hi_z);
109 24 : mpz_init(lo_z);
110 24 : mpz_init(twop32);
111 :
112 24 : mpz_set_ui(hi_z, hi) ;
113 24 : mpz_set_ui(lo_z, lo) ;
114 :
115 24 : mpz_ui_pow_ui(twop32, 2, 32) ;
116 24 : mpz_mul(value, hi_z, twop32) ;
117 24 : mpz_add(value, value, lo_z);
118 :
119 24 : mpz_clear(hi_z) ;
120 24 : mpz_clear(lo_z) ;
121 24 : mpz_clear(twop32) ;
122 : }
123 :
124 36 : void yaorb_mpz_set_s64(mpz_t value, int64_t init)
125 : {
126 : // Note : mpz_set_si works with "si" = signed long int (32 bits).
127 : // There is no signed long long int version (64 bits).
128 :
129 : int32_t hi ;
130 : uint32_t lo ; // yes, unsigned.
131 :
132 : hi = (init >> 32) ;
133 : lo = init & 0xFFFFFFFF ;
134 :
135 : mpz_t hi_z ;
136 : mpz_t lo_z ;
137 : mpz_t twop32 ;
138 :
139 36 : mpz_init(hi_z);
140 36 : mpz_init(lo_z);
141 36 : mpz_init(twop32);
142 :
143 36 : mpz_set_si(hi_z, hi) ;
144 36 : mpz_set_ui(lo_z, lo) ;
145 :
146 36 : mpz_ui_pow_ui(twop32, 2, 32) ;
147 36 : mpz_mul(value, hi_z, twop32) ;
148 36 : mpz_add(value, value, lo_z);
149 :
150 36 : mpz_clear(hi_z) ;
151 36 : mpz_clear(lo_z) ;
152 36 : mpz_clear(twop32) ;
153 : }
154 :
155 17 : uint64_t yaorb_mpz_get_u64(mpz_t value)
156 : {
157 : uint32_t hi ;
158 : uint32_t lo ;
159 : uint64_t result ;
160 :
161 : mpz_t hi_z ;
162 : mpz_t lo_z ;
163 : mpz_t twop32 ;
164 :
165 17 : mpz_init(hi_z) ;
166 17 : mpz_init(lo_z) ;
167 17 : mpz_init(twop32) ;
168 :
169 17 : mpz_ui_pow_ui(twop32, 2, 32) ;
170 17 : mpz_div(hi_z, value, twop32) ;
171 17 : mpz_mod(lo_z, value, twop32) ;
172 :
173 : hi = mpz_get_ui(hi_z) ;
174 : lo = mpz_get_ui(lo_z) ;
175 :
176 : #ifdef DEBUG
177 : {
178 : DEBUG_Dump(stderr, "get_u64 hi", hi_z) ;
179 : DEBUG_Dump(stderr, "get_u64 lo", lo_z) ;
180 : DEBUG_Dump(stderr, "get_u64 value", value) ;
181 : }
182 : #endif
183 :
184 17 : mpz_clear(hi_z) ;
185 17 : mpz_clear(lo_z) ;
186 17 : mpz_clear(twop32) ;
187 :
188 17 : result = hi ;
189 17 : result <<= 32 ;
190 : result += lo ;
191 :
192 : return result ;
193 : }
194 :
195 26 : int64_t yaorb_mpz_get_s64(mpz_t value)
196 : {
197 : int32_t hi ;
198 : uint32_t lo ; // yes, unsigned.
199 : int64_t result ;
200 :
201 : mpz_t hi_z ;
202 : mpz_t lo_z ;
203 : mpz_t twop32 ;
204 :
205 26 : mpz_init(hi_z) ;
206 26 : mpz_init(lo_z) ;
207 26 : mpz_init(twop32) ;
208 :
209 26 : mpz_ui_pow_ui(twop32, 2, 32) ;
210 26 : mpz_div(hi_z, value, twop32) ;
211 26 : mpz_mod(lo_z, value, twop32) ;
212 :
213 26 : hi = mpz_get_si(hi_z) ;
214 : lo = mpz_get_ui(lo_z) ;
215 :
216 : #ifdef DEBUG
217 : {
218 : DEBUG_Dump(stderr, "get_s64 hi", hi_z) ;
219 : DEBUG_Dump(stderr, "get_s64 lo", lo_z) ;
220 : DEBUG_Dump(stderr, "get_s64 value", value) ;
221 : }
222 : #endif
223 :
224 26 : mpz_clear(hi_z) ;
225 26 : mpz_clear(lo_z) ;
226 26 : mpz_clear(twop32) ;
227 :
228 26 : result = hi ;
229 26 : result <<= 32 ;
230 : result += lo ;
231 :
232 : return result ;
233 : }
234 :
235 : //=============================================================================
236 : // overflow helpers
237 : //=============================================================================
238 :
239 16 : bool check_u16(mpz_t value)
240 : {
241 : bool overflow = false ;
242 :
243 16 : if (mpz_cmp_ui(value, MAX_U16) > 0)
244 : {
245 : overflow = true;
246 : }
247 13 : else if (mpz_sgn(value) < 0)
248 : {
249 : overflow = true ;
250 : }
251 :
252 : return overflow ;
253 : }
254 :
255 16 : bool check_u32(mpz_t value)
256 : {
257 : bool overflow = false ;
258 :
259 16 : if (mpz_cmp_ui(value, MAX_U32) > 0)
260 : {
261 : overflow = true;
262 : }
263 13 : else if (mpz_sgn(value) < 0)
264 : {
265 : overflow = true ;
266 : }
267 :
268 : return overflow ;
269 : }
270 :
271 15 : bool check_u64(mpz_t value)
272 : {
273 : mpz_t max_u64 ;
274 : mpz_t one ;
275 : mpz_t twop64 ;
276 :
277 : // max_u64 = 2^64-1
278 15 : mpz_init(max_u64);
279 15 : mpz_init(twop64);
280 15 : mpz_init_set_ui(one, 1);
281 15 : mpz_ui_pow_ui(twop64, 2, 64) ;
282 15 : mpz_sub(max_u64, twop64, one);
283 :
284 : bool overflow = false ;
285 :
286 15 : if (mpz_cmp(value, max_u64) > 0)
287 : {
288 : overflow = true;
289 : }
290 13 : else if (mpz_sgn(value) < 0)
291 : {
292 : overflow = true ;
293 : }
294 :
295 : #ifdef DEBUG
296 : {
297 : DEBUG_Dump(stderr, "MAX_U64", max_u64) ;
298 : DEBUG_Dump(stderr, "CHECK_U64", value) ;
299 : }
300 : #endif
301 :
302 15 : mpz_clear(max_u64) ;
303 15 : mpz_clear(one) ;
304 15 : mpz_clear(twop64) ;
305 :
306 : return overflow ;
307 : }
308 :
309 24 : bool check_s16(mpz_t value)
310 : {
311 : bool overflow = false ;
312 :
313 24 : if (mpz_cmp_si(value, MAX_S16) > 0)
314 : {
315 : overflow = true;
316 : }
317 20 : else if (mpz_cmp_si(value, MIN_S16) < 0)
318 : {
319 : overflow = true;
320 : }
321 :
322 : return overflow ;
323 : }
324 :
325 24 : bool check_s32(mpz_t value)
326 : {
327 : bool overflow = false ;
328 :
329 24 : if (mpz_cmp_si(value, MAX_S32) > 0)
330 : {
331 : overflow = true;
332 : }
333 20 : else if (mpz_cmp_si(value, MIN_S32) < 0)
334 : {
335 : overflow = true;
336 : }
337 :
338 : return overflow ;
339 : }
340 :
341 23 : bool check_s64(mpz_t value)
342 : {
343 : mpz_t max_s64 ;
344 : mpz_t min_s64 ;
345 : mpz_t one ;
346 : mpz_t twop63 ;
347 :
348 23 : mpz_init(max_s64);
349 23 : mpz_init(min_s64) ;
350 23 : mpz_init(one);
351 23 : mpz_init(twop63);
352 :
353 : // max_s64 = 2^63-1
354 23 : mpz_init_set_ui(one, 1);
355 23 : mpz_ui_pow_ui(twop63, 2, 63) ;
356 23 : mpz_sub(max_s64, twop63, one);
357 :
358 : // min_s64 = - 2^63
359 23 : mpz_sub(min_s64, min_s64, twop63);
360 :
361 : bool overflow = false ;
362 :
363 23 : if (mpz_cmp(value, max_s64) > 0)
364 : {
365 : overflow = true;
366 : }
367 19 : else if (mpz_cmp(value, min_s64) < 0)
368 : {
369 : overflow = true;
370 : }
371 :
372 : #ifdef DEBUG
373 : {
374 : DEBUG_Dump(stderr, "MAX_S64", max_s64) ;
375 : DEBUG_Dump(stderr, "MIN_S64", min_s64) ;
376 : DEBUG_Dump(stderr, "CHECK_S64", value) ;
377 : }
378 : #endif
379 :
380 23 : mpz_clear(max_s64);
381 23 : mpz_clear(min_s64) ;
382 23 : mpz_clear(one);
383 23 : mpz_clear(twop63);
384 :
385 : return overflow ;
386 : }
387 :
388 : //=============================================================================
389 : // Implementation of all operations, with overflow checking.
390 : //=============================================================================
391 :
392 3 : bool add_u16(uint16_t operand_1, uint16_t operand_2, uint16_t * result)
393 : {
394 : mpz_t res ;
395 : mpz_t op1 ;
396 : mpz_t op2 ;
397 :
398 3 : mpz_init(res);
399 3 : mpz_init(op1);
400 3 : mpz_init(op2);
401 :
402 3 : mpz_set_ui(op1, operand_1);
403 3 : mpz_set_ui(op2, operand_2);
404 :
405 3 : mpz_add(res, op1, op2);
406 :
407 3 : * result = mpz_get_ui(res);
408 :
409 3 : bool overflow = check_u16(res) ;
410 :
411 : #ifdef DEBUG
412 : {
413 : DEBUG_Operation(stderr, "add_u16", op1, op2, res, overflow) ;
414 : }
415 : #endif
416 :
417 3 : mpz_clear(res);
418 3 : mpz_clear(op1);
419 3 : mpz_clear(op2);
420 :
421 : return overflow;
422 : }
423 :
424 5 : bool add_s16(int16_t operand_1, int16_t operand_2, int16_t * result)
425 : {
426 : mpz_t res ;
427 : mpz_t op1 ;
428 : mpz_t op2 ;
429 :
430 5 : mpz_init(res);
431 5 : mpz_init(op1);
432 5 : mpz_init(op2);
433 :
434 5 : mpz_set_si(op1, operand_1);
435 5 : mpz_set_si(op2, operand_2);
436 :
437 5 : mpz_add(res, op1, op2);
438 :
439 5 : * result = mpz_get_si(res);
440 :
441 5 : bool overflow = check_s16(res) ;
442 :
443 : #ifdef DEBUG
444 : {
445 : DEBUG_Operation(stderr, "add_s16", op1, op2, res, overflow) ;
446 : }
447 : #endif
448 :
449 5 : mpz_clear(res);
450 5 : mpz_clear(op1);
451 5 : mpz_clear(op2);
452 :
453 : return overflow;
454 : }
455 :
456 3 : bool add_u32(uint32_t operand_1, uint32_t operand_2, uint32_t * result)
457 : {
458 : mpz_t res ;
459 : mpz_t op1 ;
460 : mpz_t op2 ;
461 :
462 3 : mpz_init(res);
463 3 : mpz_init(op1);
464 3 : mpz_init(op2);
465 :
466 3 : mpz_set_ui(op1, operand_1);
467 3 : mpz_set_ui(op2, operand_2);
468 :
469 3 : mpz_add(res, op1, op2);
470 :
471 3 : * result = mpz_get_ui(res);
472 :
473 3 : bool overflow = check_u32(res) ;
474 :
475 : #ifdef DEBUG
476 : {
477 : DEBUG_Operation(stderr, "add_u32", op1, op2, res, overflow) ;
478 : }
479 : #endif
480 :
481 3 : mpz_clear(res);
482 3 : mpz_clear(op1);
483 3 : mpz_clear(op2);
484 :
485 : return overflow;
486 : }
487 :
488 5 : bool add_s32(int32_t operand_1, int32_t operand_2, int32_t * result)
489 : {
490 : mpz_t res ;
491 : mpz_t op1 ;
492 : mpz_t op2 ;
493 :
494 5 : mpz_init(res);
495 5 : mpz_init(op1);
496 5 : mpz_init(op2);
497 :
498 5 : mpz_set_si(op1, operand_1);
499 5 : mpz_set_si(op2, operand_2);
500 :
501 5 : mpz_add(res, op1, op2);
502 :
503 5 : * result = mpz_get_si(res);
504 :
505 5 : bool overflow = check_s32(res) ;
506 :
507 : #ifdef DEBUG
508 : {
509 : DEBUG_Operation(stderr, "add_s32", op1, op2, res, overflow) ;
510 : }
511 : #endif
512 :
513 5 : mpz_clear(res);
514 5 : mpz_clear(op1);
515 5 : mpz_clear(op2);
516 :
517 : return overflow;
518 : }
519 :
520 3 : bool add_u64(uint64_t operand_1, uint64_t operand_2, uint64_t * result)
521 : {
522 : mpz_t res ;
523 : mpz_t op1 ;
524 : mpz_t op2 ;
525 :
526 3 : mpz_init(res);
527 3 : mpz_init(op1);
528 3 : mpz_init(op2);
529 :
530 3 : yaorb_mpz_set_u64(op1, operand_1) ;
531 3 : yaorb_mpz_set_u64(op2, operand_2) ;
532 :
533 3 : mpz_add(res, op1, op2);
534 :
535 3 : * result = yaorb_mpz_get_u64(res);
536 :
537 3 : bool overflow = check_u64(res) ;
538 :
539 : #ifdef DEBUG
540 : {
541 : DEBUG_Operation(stderr, "add_u64", op1, op2, res, overflow) ;
542 : }
543 : #endif
544 :
545 3 : mpz_clear(res);
546 3 : mpz_clear(op1);
547 3 : mpz_clear(op2);
548 :
549 : return overflow;
550 : }
551 :
552 5 : bool add_s64(int64_t operand_1, int64_t operand_2, int64_t * result)
553 : {
554 : mpz_t res ;
555 : mpz_t op1 ;
556 : mpz_t op2 ;
557 :
558 5 : mpz_init(res);
559 5 : mpz_init(op1);
560 5 : mpz_init(op2);
561 :
562 5 : yaorb_mpz_set_s64(op1, operand_1) ;
563 5 : yaorb_mpz_set_s64(op2, operand_2) ;
564 :
565 5 : mpz_add(res, op1, op2);
566 :
567 5 : * result = yaorb_mpz_get_s64(res);
568 :
569 5 : bool overflow = check_s64(res) ;
570 :
571 : #ifdef DEBUG
572 : {
573 : DEBUG_Operation(stderr, "add_s64", op1, op2, res, overflow) ;
574 : }
575 : #endif
576 :
577 5 : mpz_clear(res);
578 5 : mpz_clear(op1);
579 5 : mpz_clear(op2);
580 :
581 : return overflow;
582 : }
583 :
584 1 : bool add_f32(float operand_1, float operand_2, float * result)
585 : {
586 1 : *result = operand_1 + operand_2 ;
587 :
588 : // FIXME : no overflow check
589 : return (false) ;
590 : }
591 :
592 1 : bool add_f64(double operand_1, double operand_2, double * result)
593 : {
594 1 : *result = operand_1 + operand_2 ;
595 :
596 : // FIXME : no overflow check
597 : return (false) ;
598 : }
599 :
600 1 : bool add_f96(long double operand_1, long double operand_2, long double * result)
601 : {
602 1 : *result = operand_1 + operand_2 ;
603 :
604 : // FIXME : no overflow check
605 : return (false) ;
606 : }
607 :
608 : // SUBSTRACTION
609 :
610 3 : bool sub_u16(uint16_t operand_1, uint16_t operand_2, uint16_t * result)
611 : {
612 : mpz_t res ;
613 : mpz_t op1 ;
614 : mpz_t op2 ;
615 :
616 3 : mpz_init(res);
617 3 : mpz_init(op1);
618 3 : mpz_init(op2);
619 :
620 3 : mpz_set_ui(op1, operand_1);
621 3 : mpz_set_ui(op2, operand_2);
622 :
623 3 : mpz_sub(res, op1, op2);
624 :
625 3 : * result = mpz_get_ui(res);
626 :
627 3 : bool overflow = check_u16(res) ;
628 :
629 : #ifdef DEBUG
630 : {
631 : DEBUG_Operation(stderr, "sub_u16", op1, op2, res, overflow) ;
632 : }
633 : #endif
634 :
635 3 : mpz_clear(res);
636 3 : mpz_clear(op1);
637 3 : mpz_clear(op2);
638 :
639 : return overflow;
640 : }
641 :
642 5 : bool sub_s16(int16_t operand_1, int16_t operand_2, int16_t * result)
643 : {
644 : mpz_t res ;
645 : mpz_t op1 ;
646 : mpz_t op2 ;
647 :
648 5 : mpz_init(res);
649 5 : mpz_init(op1);
650 5 : mpz_init(op2);
651 :
652 5 : mpz_set_si(op1, operand_1);
653 5 : mpz_set_si(op2, operand_2);
654 :
655 5 : mpz_sub(res, op1, op2);
656 :
657 5 : * result = mpz_get_si(res);
658 :
659 5 : bool overflow = check_s16(res) ;
660 :
661 : #ifdef DEBUG
662 : {
663 : DEBUG_Operation(stderr, "sub_s16", op1, op2, res, overflow) ;
664 : }
665 : #endif
666 :
667 5 : mpz_clear(res);
668 5 : mpz_clear(op1);
669 5 : mpz_clear(op2);
670 :
671 : return overflow;
672 : }
673 :
674 3 : bool sub_u32(uint32_t operand_1, uint32_t operand_2, uint32_t * result)
675 : {
676 : mpz_t res ;
677 : mpz_t op1 ;
678 : mpz_t op2 ;
679 :
680 3 : mpz_init(res);
681 3 : mpz_init(op1);
682 3 : mpz_init(op2);
683 :
684 3 : mpz_set_ui(op1, operand_1);
685 3 : mpz_set_ui(op2, operand_2);
686 :
687 3 : mpz_sub(res, op1, op2);
688 :
689 3 : * result = mpz_get_ui(res);
690 :
691 3 : bool overflow = check_u32(res) ;
692 :
693 : #ifdef DEBUG
694 : {
695 : DEBUG_Operation(stderr, "sub_u32", op1, op2, res, overflow) ;
696 : }
697 : #endif
698 :
699 3 : mpz_clear(res);
700 3 : mpz_clear(op1);
701 3 : mpz_clear(op2);
702 :
703 : return overflow;
704 : }
705 :
706 5 : bool sub_s32(int32_t operand_1, int32_t operand_2, int32_t * result)
707 : {
708 : mpz_t res ;
709 : mpz_t op1 ;
710 : mpz_t op2 ;
711 :
712 5 : mpz_init(res);
713 5 : mpz_init(op1);
714 5 : mpz_init(op2);
715 :
716 5 : mpz_set_si(op1, operand_1);
717 5 : mpz_set_si(op2, operand_2);
718 :
719 5 : mpz_sub(res, op1, op2);
720 :
721 5 : * result = mpz_get_si(res);
722 :
723 5 : bool overflow = check_s32(res) ;
724 :
725 : #ifdef DEBUG
726 : {
727 : DEBUG_Operation(stderr, "sub_s32", op1, op2, res, overflow) ;
728 : }
729 : #endif
730 :
731 5 : mpz_clear(res);
732 5 : mpz_clear(op1);
733 5 : mpz_clear(op2);
734 :
735 : return overflow;
736 : }
737 :
738 3 : bool sub_u64(uint64_t operand_1, uint64_t operand_2, uint64_t * result)
739 : {
740 : mpz_t res ;
741 : mpz_t op1 ;
742 : mpz_t op2 ;
743 :
744 3 : mpz_init(res);
745 3 : mpz_init(op1);
746 3 : mpz_init(op2);
747 :
748 3 : yaorb_mpz_set_u64(op1, operand_1) ;
749 3 : yaorb_mpz_set_u64(op2, operand_2) ;
750 :
751 3 : mpz_sub(res, op1, op2);
752 :
753 3 : * result = yaorb_mpz_get_u64(res);
754 :
755 3 : bool overflow = check_u64(res) ;
756 :
757 : #ifdef DEBUG
758 : {
759 : DEBUG_Operation(stderr, "sub_u64", op1, op2, res, overflow) ;
760 : }
761 : #endif
762 :
763 3 : mpz_clear(res);
764 3 : mpz_clear(op1);
765 3 : mpz_clear(op2);
766 :
767 : return overflow;
768 : }
769 :
770 5 : bool sub_s64(int64_t operand_1, int64_t operand_2, int64_t * result)
771 : {
772 : mpz_t res ;
773 : mpz_t op1 ;
774 : mpz_t op2 ;
775 :
776 5 : mpz_init(res);
777 5 : mpz_init(op1);
778 5 : mpz_init(op2);
779 :
780 5 : yaorb_mpz_set_s64(op1, operand_1) ;
781 5 : yaorb_mpz_set_s64(op2, operand_2) ;
782 :
783 5 : mpz_sub(res, op1, op2);
784 :
785 5 : * result = yaorb_mpz_get_s64(res);
786 :
787 5 : bool overflow = check_s64(res) ;
788 :
789 : #ifdef DEBUG
790 : {
791 : DEBUG_Operation(stderr, "sub_s64", op1, op2, res, overflow) ;
792 : }
793 : #endif
794 :
795 5 : mpz_clear(res);
796 5 : mpz_clear(op1);
797 5 : mpz_clear(op2);
798 :
799 : return overflow;
800 : }
801 :
802 1 : bool sub_f32(float operand_1, float operand_2, float * result)
803 : {
804 1 : *result = operand_1 - operand_2 ;
805 :
806 : // FIXME : no overflow check
807 : return (false) ;
808 : }
809 :
810 1 : bool sub_f64(double operand_1, double operand_2, double * result)
811 : {
812 1 : *result = operand_1 - operand_2 ;
813 :
814 : // FIXME : no overflow check
815 : return (false) ;
816 : }
817 :
818 1 : bool sub_f96(long double operand_1, long double operand_2, long double * result)
819 : {
820 1 : *result = operand_1 - operand_2 ;
821 :
822 : // FIXME : no overflow check
823 : return (false) ;
824 : }
825 :
826 : // MULTIPLICATION
827 :
828 1 : bool mul_u16(uint16_t operand_1, uint16_t operand_2, uint16_t * result)
829 : {
830 : mpz_t res ;
831 : mpz_t op1 ;
832 : mpz_t op2 ;
833 :
834 1 : mpz_init(res);
835 1 : mpz_init(op1);
836 1 : mpz_init(op2);
837 :
838 1 : mpz_set_ui(op1, operand_1);
839 1 : mpz_set_ui(op2, operand_2);
840 :
841 1 : mpz_mul(res, op1, op2);
842 :
843 1 : * result = mpz_get_ui(res);
844 :
845 1 : bool overflow = check_u16(res) ;
846 :
847 : #ifdef DEBUG
848 : {
849 : DEBUG_Operation(stderr, "mul_u16", op1, op2, res, overflow) ;
850 : }
851 : #endif
852 :
853 1 : mpz_clear(res);
854 1 : mpz_clear(op1);
855 1 : mpz_clear(op2);
856 :
857 : return overflow;
858 : }
859 :
860 1 : bool mul_s16(int16_t operand_1, int16_t operand_2, int16_t * result)
861 : {
862 : mpz_t res ;
863 : mpz_t op1 ;
864 : mpz_t op2 ;
865 :
866 1 : mpz_init(res);
867 1 : mpz_init(op1);
868 1 : mpz_init(op2);
869 :
870 1 : mpz_set_si(op1, operand_1);
871 1 : mpz_set_si(op2, operand_2);
872 :
873 1 : mpz_mul(res, op1, op2);
874 :
875 1 : * result = mpz_get_si(res);
876 :
877 1 : bool overflow = check_s16(res) ;
878 :
879 : #ifdef DEBUG
880 : {
881 : DEBUG_Operation(stderr, "mul_s16", op1, op2, res, overflow) ;
882 : }
883 : #endif
884 :
885 1 : mpz_clear(res);
886 1 : mpz_clear(op1);
887 1 : mpz_clear(op2);
888 :
889 : return overflow;
890 : }
891 :
892 1 : bool mul_u32(uint32_t operand_1, uint32_t operand_2, uint32_t * result)
893 : {
894 : mpz_t res ;
895 : mpz_t op1 ;
896 : mpz_t op2 ;
897 :
898 1 : mpz_init(res);
899 1 : mpz_init(op1);
900 1 : mpz_init(op2);
901 :
902 1 : mpz_set_ui(op1, operand_1);
903 1 : mpz_set_ui(op2, operand_2);
904 :
905 1 : mpz_mul(res, op1, op2);
906 :
907 1 : * result = mpz_get_ui(res);
908 :
909 1 : bool overflow = check_u32(res) ;
910 :
911 : #ifdef DEBUG
912 : {
913 : DEBUG_Operation(stderr, "mul_u32", op1, op2, res, overflow) ;
914 : }
915 : #endif
916 :
917 1 : mpz_clear(res);
918 1 : mpz_clear(op1);
919 1 : mpz_clear(op2);
920 :
921 : return overflow;
922 : }
923 :
924 1 : bool mul_s32(int32_t operand_1, int32_t operand_2, int32_t * result)
925 : {
926 : mpz_t res ;
927 : mpz_t op1 ;
928 : mpz_t op2 ;
929 :
930 1 : mpz_init(res);
931 1 : mpz_init(op1);
932 1 : mpz_init(op2);
933 :
934 1 : mpz_set_si(op1, operand_1);
935 1 : mpz_set_si(op2, operand_2);
936 :
937 1 : mpz_mul(res, op1, op2);
938 :
939 1 : * result = mpz_get_si(res);
940 :
941 1 : bool overflow = check_s32(res) ;
942 :
943 : #ifdef DEBUG
944 : {
945 : DEBUG_Operation(stderr, "mul_s32", op1, op2, res, overflow) ;
946 : }
947 : #endif
948 :
949 1 : mpz_clear(res);
950 1 : mpz_clear(op1);
951 1 : mpz_clear(op2);
952 :
953 : return overflow;
954 : }
955 :
956 1 : bool mul_u64(uint64_t operand_1, uint64_t operand_2, uint64_t * result)
957 : {
958 : mpz_t res ;
959 : mpz_t op1 ;
960 : mpz_t op2 ;
961 :
962 1 : mpz_init(res);
963 1 : mpz_init(op1);
964 1 : mpz_init(op2);
965 :
966 1 : yaorb_mpz_set_u64(op1, operand_1) ;
967 1 : yaorb_mpz_set_u64(op2, operand_2) ;
968 :
969 1 : mpz_mul(res, op1, op2);
970 :
971 1 : * result = yaorb_mpz_get_u64(res);
972 :
973 1 : bool overflow = check_u64(res) ;
974 :
975 : #ifdef DEBUG
976 : {
977 : DEBUG_Operation(stderr, "mul_u64", op1, op2, res, overflow) ;
978 : }
979 : #endif
980 :
981 1 : mpz_clear(res);
982 1 : mpz_clear(op1);
983 1 : mpz_clear(op2);
984 :
985 : return overflow;
986 : }
987 :
988 1 : bool mul_s64(int64_t operand_1, int64_t operand_2, int64_t * result)
989 : {
990 : mpz_t res ;
991 : mpz_t op1 ;
992 : mpz_t op2 ;
993 :
994 1 : mpz_init(res);
995 1 : mpz_init(op1);
996 1 : mpz_init(op2);
997 :
998 1 : yaorb_mpz_set_s64(op1, operand_1) ;
999 1 : yaorb_mpz_set_s64(op2, operand_2) ;
1000 :
1001 1 : mpz_mul(res, op1, op2);
1002 :
1003 1 : * result = yaorb_mpz_get_s64(res);
1004 :
1005 1 : bool overflow = check_s64(res) ;
1006 :
1007 : #ifdef DEBUG
1008 : {
1009 : DEBUG_Operation(stderr, "mul_s64", op1, op2, res, overflow) ;
1010 : }
1011 : #endif
1012 :
1013 1 : mpz_clear(res);
1014 1 : mpz_clear(op1);
1015 1 : mpz_clear(op2);
1016 :
1017 : return overflow;
1018 : }
1019 :
1020 1 : bool mul_f32(float operand_1, float operand_2, float * result)
1021 : {
1022 1 : *result = operand_1 * operand_2 ;
1023 :
1024 : // FIXME : no overflow check
1025 : return (false) ;
1026 : }
1027 :
1028 1 : bool mul_f64(double operand_1, double operand_2, double * result)
1029 : {
1030 1 : *result = operand_1 * operand_2 ;
1031 :
1032 : // FIXME : no overflow check
1033 : return (false) ;
1034 : }
1035 :
1036 1 : bool mul_f96(long double operand_1, long double operand_2, long double * result)
1037 : {
1038 1 : *result = operand_1 * operand_2 ;
1039 :
1040 : // FIXME : no overflow check
1041 : return (false) ;
1042 : }
1043 :
1044 : // DIVISION
1045 :
1046 1 : bool div_u16(uint16_t operand_1, uint16_t operand_2, uint16_t * result)
1047 : {
1048 : mpz_t res ;
1049 : mpz_t op1 ;
1050 : mpz_t op2 ;
1051 :
1052 1 : mpz_init(res);
1053 1 : mpz_init(op1);
1054 1 : mpz_init(op2);
1055 :
1056 1 : mpz_set_ui(op1, operand_1);
1057 1 : mpz_set_ui(op2, operand_2);
1058 :
1059 : bool overflow = false ;
1060 :
1061 1 : if (mpz_sgn(op2) == 0)
1062 : {
1063 : // divide by 0
1064 : overflow = true ;
1065 : }
1066 : else
1067 : {
1068 1 : mpz_tdiv_q(res, op1, op2);
1069 1 : overflow = check_u16(res) ;
1070 : }
1071 :
1072 1 : * result = mpz_get_ui(res);
1073 :
1074 : #ifdef DEBUG
1075 : {
1076 : DEBUG_Operation(stderr, "div_u16", op1, op2, res, overflow) ;
1077 : }
1078 : #endif
1079 :
1080 1 : mpz_clear(res);
1081 1 : mpz_clear(op1);
1082 1 : mpz_clear(op2);
1083 :
1084 : return overflow;
1085 : }
1086 :
1087 1 : bool div_s16(int16_t operand_1, int16_t operand_2, int16_t * result)
1088 : {
1089 : mpz_t res ;
1090 : mpz_t op1 ;
1091 : mpz_t op2 ;
1092 :
1093 1 : mpz_init(res);
1094 1 : mpz_init(op1);
1095 1 : mpz_init(op2);
1096 :
1097 1 : mpz_set_si(op1, operand_1);
1098 1 : mpz_set_si(op2, operand_2);
1099 :
1100 : bool overflow = false ;
1101 :
1102 1 : if (mpz_sgn(op2) == 0)
1103 : {
1104 : // divide by 0
1105 : overflow = true ;
1106 : }
1107 : else
1108 : {
1109 1 : mpz_tdiv_q(res, op1, op2);
1110 1 : overflow = check_s16(res) ;
1111 : }
1112 :
1113 1 : * result = mpz_get_si(res);
1114 :
1115 : #ifdef DEBUG
1116 : {
1117 : DEBUG_Operation(stderr, "div_s16", op1, op2, res, overflow) ;
1118 : }
1119 : #endif
1120 :
1121 1 : mpz_clear(res);
1122 1 : mpz_clear(op1);
1123 1 : mpz_clear(op2);
1124 :
1125 : return overflow;
1126 : }
1127 :
1128 1 : bool div_u32(uint32_t operand_1, uint32_t operand_2, uint32_t * result)
1129 : {
1130 : mpz_t res ;
1131 : mpz_t op1 ;
1132 : mpz_t op2 ;
1133 :
1134 1 : mpz_init(res);
1135 1 : mpz_init(op1);
1136 1 : mpz_init(op2);
1137 :
1138 1 : mpz_set_ui(op1, operand_1);
1139 1 : mpz_set_ui(op2, operand_2);
1140 :
1141 : bool overflow = false ;
1142 :
1143 1 : if (mpz_sgn(op2) == 0)
1144 : {
1145 : // divide by 0
1146 : overflow = true ;
1147 : }
1148 : else
1149 : {
1150 1 : mpz_tdiv_q(res, op1, op2);
1151 1 : overflow = check_u32(res) ;
1152 : }
1153 :
1154 1 : * result = mpz_get_ui(res);
1155 :
1156 : #ifdef DEBUG
1157 : {
1158 : DEBUG_Operation(stderr, "div_u32", op1, op2, res, overflow) ;
1159 : }
1160 : #endif
1161 :
1162 1 : mpz_clear(res);
1163 1 : mpz_clear(op1);
1164 1 : mpz_clear(op2);
1165 :
1166 : return overflow;
1167 : }
1168 :
1169 1 : bool div_s32(int32_t operand_1, int32_t operand_2, int32_t * result)
1170 : {
1171 : mpz_t res ;
1172 : mpz_t op1 ;
1173 : mpz_t op2 ;
1174 :
1175 1 : mpz_init(res);
1176 1 : mpz_init(op1);
1177 1 : mpz_init(op2);
1178 :
1179 1 : mpz_set_si(op1, operand_1);
1180 1 : mpz_set_si(op2, operand_2);
1181 :
1182 : bool overflow = false ;
1183 :
1184 1 : if (mpz_sgn(op2) == 0)
1185 : {
1186 : // divide by 0
1187 : overflow = true ;
1188 : }
1189 : else
1190 : {
1191 1 : mpz_tdiv_q(res, op1, op2);
1192 1 : overflow = check_s32(res) ;
1193 : }
1194 :
1195 1 : * result = mpz_get_si(res);
1196 :
1197 : #ifdef DEBUG
1198 : {
1199 : DEBUG_Operation(stderr, "div_s32", op1, op2, res, overflow) ;
1200 : }
1201 : #endif
1202 :
1203 1 : mpz_clear(res);
1204 1 : mpz_clear(op1);
1205 1 : mpz_clear(op2);
1206 :
1207 : return overflow;
1208 : }
1209 :
1210 1 : bool div_u64(uint64_t operand_1, uint64_t operand_2, uint64_t * result)
1211 : {
1212 : mpz_t res ;
1213 : mpz_t op1 ;
1214 : mpz_t op2 ;
1215 :
1216 1 : mpz_init(res);
1217 1 : mpz_init(op1);
1218 1 : mpz_init(op2);
1219 :
1220 1 : yaorb_mpz_set_u64(op1, operand_1) ;
1221 1 : yaorb_mpz_set_u64(op2, operand_2) ;
1222 :
1223 : bool overflow = false ;
1224 :
1225 1 : if (mpz_sgn(op2) == 0)
1226 : {
1227 : // divide by 0
1228 : overflow = true ;
1229 : }
1230 : else
1231 : {
1232 1 : mpz_tdiv_q(res, op1, op2);
1233 1 : overflow = check_u64(res) ;
1234 : }
1235 :
1236 1 : * result = yaorb_mpz_get_u64(res);
1237 :
1238 : #ifdef DEBUG
1239 : {
1240 : DEBUG_Operation(stderr, "div_u64", op1, op2, res, overflow) ;
1241 : }
1242 : #endif
1243 :
1244 1 : mpz_clear(res);
1245 1 : mpz_clear(op1);
1246 1 : mpz_clear(op2);
1247 :
1248 : return overflow;
1249 : }
1250 :
1251 1 : bool div_s64(int64_t operand_1, int64_t operand_2, int64_t * result)
1252 : {
1253 : mpz_t res ;
1254 : mpz_t op1 ;
1255 : mpz_t op2 ;
1256 :
1257 1 : mpz_init(res);
1258 1 : mpz_init(op1);
1259 1 : mpz_init(op2);
1260 :
1261 1 : yaorb_mpz_set_s64(op1, operand_1) ;
1262 1 : yaorb_mpz_set_s64(op2, operand_2) ;
1263 :
1264 : bool overflow = false ;
1265 :
1266 1 : if (mpz_sgn(op2) == 0)
1267 : {
1268 : // divide by 0
1269 : overflow = true ;
1270 : }
1271 : else
1272 : {
1273 1 : mpz_tdiv_q(res, op1, op2);
1274 1 : overflow = check_s64(res) ;
1275 : }
1276 :
1277 1 : * result = yaorb_mpz_get_s64(res);
1278 :
1279 : #ifdef DEBUG
1280 : {
1281 : DEBUG_Operation(stderr, "div_s64", op1, op2, res, overflow) ;
1282 : }
1283 : #endif
1284 :
1285 1 : mpz_clear(res);
1286 1 : mpz_clear(op1);
1287 1 : mpz_clear(op2);
1288 :
1289 : return overflow;
1290 : }
1291 :
1292 1 : bool div_f32(float operand_1, float operand_2, float * result)
1293 : {
1294 1 : *result = operand_1 / operand_2 ;
1295 :
1296 : // FIXME : no overflow check
1297 : return (false) ;
1298 : }
1299 :
1300 1 : bool div_f64(double operand_1, double operand_2, double * result)
1301 : {
1302 1 : *result = operand_1 / operand_2 ;
1303 :
1304 : // FIXME : no overflow check
1305 : return (false) ;
1306 : }
1307 :
1308 1 : bool div_f96(long double operand_1, long double operand_2, long double * result)
1309 : {
1310 1 : *result = operand_1 / operand_2 ;
1311 :
1312 : // FIXME : no overflow check
1313 : return (false) ;
1314 : }
1315 :
1316 : // SHIFT LEFT
1317 :
1318 7 : bool shl_u16(uint16_t operand_1, uint16_t operand_2, uint16_t * result)
1319 : {
1320 : mpz_t res ;
1321 : mpz_t op1 ;
1322 : mpz_t op2 ;
1323 :
1324 7 : mpz_init(res);
1325 7 : mpz_init(op1);
1326 7 : mpz_init(op2);
1327 :
1328 : bool overflow = false ;
1329 :
1330 : //==========================================================================
1331 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1332 : //==========================================================================
1333 :
1334 7 : if (operand_2 < 64)
1335 : {
1336 : uint8_t shift = (uint8_t) operand_2 ;
1337 :
1338 6 : mpz_set_ui(op1, operand_1);
1339 6 : mpz_ui_pow_ui(op2, 2, shift);
1340 6 : mpz_mul(res, op1, op2);
1341 :
1342 6 : overflow = check_u16(res) ;
1343 : }
1344 : else
1345 : {
1346 : overflow = true ;
1347 : }
1348 :
1349 7 : * result = mpz_get_ui(res);
1350 :
1351 : #ifdef DEBUG
1352 : {
1353 : DEBUG_Operation(stderr, "shl_u16", op1, op2, res, overflow) ;
1354 : }
1355 : #endif
1356 :
1357 7 : mpz_clear(res);
1358 7 : mpz_clear(op1);
1359 7 : mpz_clear(op2);
1360 :
1361 : return overflow;
1362 : }
1363 :
1364 12 : bool shl_s16(int16_t operand_1, int16_t operand_2, int16_t * result)
1365 : {
1366 : mpz_t res ;
1367 : mpz_t op1 ;
1368 : mpz_t op2 ;
1369 :
1370 12 : mpz_init(res);
1371 12 : mpz_init(op1);
1372 12 : mpz_init(op2);
1373 :
1374 : bool overflow = false ;
1375 :
1376 : //==========================================================================
1377 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1378 : //==========================================================================
1379 :
1380 12 : if ((0 <= operand_2) && (operand_2 < 64))
1381 : {
1382 : uint8_t shift = (uint8_t) operand_2 ;
1383 :
1384 10 : mpz_set_si(op1, operand_1);
1385 10 : mpz_ui_pow_ui(op2, 2, shift);
1386 10 : mpz_mul(res, op1, op2);
1387 :
1388 10 : overflow = check_s16(res) ;
1389 : }
1390 : else
1391 : {
1392 : overflow = true ;
1393 : }
1394 :
1395 12 : * result = mpz_get_si(res);
1396 :
1397 : #ifdef DEBUG
1398 : {
1399 : DEBUG_Operation(stderr, "shl_s16", op1, op2, res, overflow) ;
1400 : }
1401 : #endif
1402 :
1403 12 : mpz_clear(res);
1404 12 : mpz_clear(op1);
1405 12 : mpz_clear(op2);
1406 :
1407 : return overflow;
1408 : }
1409 :
1410 7 : bool shl_u32(uint32_t operand_1, uint32_t operand_2, uint32_t * result)
1411 : {
1412 : mpz_t res ;
1413 : mpz_t op1 ;
1414 : mpz_t op2 ;
1415 :
1416 7 : mpz_init(res);
1417 7 : mpz_init(op1);
1418 7 : mpz_init(op2);
1419 :
1420 : bool overflow = false ;
1421 :
1422 : //==========================================================================
1423 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1424 : //==========================================================================
1425 :
1426 7 : if (operand_2 < 64)
1427 : {
1428 : uint8_t shift = (uint8_t) operand_2 ;
1429 :
1430 6 : mpz_set_ui(op1, operand_1);
1431 6 : mpz_ui_pow_ui(op2, 2, shift);
1432 6 : mpz_mul(res, op1, op2);
1433 :
1434 6 : overflow = check_u32(res) ;
1435 : }
1436 : else
1437 : {
1438 : overflow = true ;
1439 : }
1440 :
1441 7 : * result = mpz_get_ui(res);
1442 :
1443 : #ifdef DEBUG
1444 : {
1445 : DEBUG_Operation(stderr, "shl_u32", op1, op2, res, overflow) ;
1446 : }
1447 : #endif
1448 :
1449 7 : mpz_clear(res);
1450 7 : mpz_clear(op1);
1451 7 : mpz_clear(op2);
1452 :
1453 : return overflow;
1454 : }
1455 :
1456 12 : bool shl_s32(int32_t operand_1, int32_t operand_2, int32_t * result)
1457 : {
1458 : mpz_t res ;
1459 : mpz_t op1 ;
1460 : mpz_t op2 ;
1461 :
1462 12 : mpz_init(res);
1463 12 : mpz_init(op1);
1464 12 : mpz_init(op2);
1465 :
1466 : bool overflow = false ;
1467 :
1468 : //==========================================================================
1469 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1470 : //==========================================================================
1471 :
1472 12 : if ((0 <= operand_2) && (operand_2 < 64))
1473 : {
1474 : uint8_t shift = (uint8_t) operand_2 ;
1475 :
1476 10 : mpz_set_si(op1, operand_1);
1477 10 : mpz_ui_pow_ui(op2, 2, shift);
1478 10 : mpz_mul(res, op1, op2);
1479 :
1480 10 : overflow = check_s32(res) ;
1481 : }
1482 : else
1483 : {
1484 : overflow = true ;
1485 : }
1486 :
1487 12 : * result = mpz_get_si(res);
1488 :
1489 : #ifdef DEBUG
1490 : {
1491 : DEBUG_Operation(stderr, "shl_s32", op1, op2, res, overflow) ;
1492 : }
1493 : #endif
1494 :
1495 12 : mpz_clear(res);
1496 12 : mpz_clear(op1);
1497 12 : mpz_clear(op2);
1498 :
1499 : return overflow;
1500 : }
1501 :
1502 7 : bool shl_u64(uint64_t operand_1, uint64_t operand_2, uint64_t * result)
1503 : {
1504 : mpz_t res ;
1505 : mpz_t op1 ;
1506 : mpz_t op2 ;
1507 :
1508 7 : mpz_init(res);
1509 7 : mpz_init(op1);
1510 7 : mpz_init(op2);
1511 :
1512 : bool overflow = false ;
1513 :
1514 : //==========================================================================
1515 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1516 : //==========================================================================
1517 :
1518 7 : if (operand_2 < 64)
1519 : {
1520 : uint8_t shift = (uint8_t) operand_2 ;
1521 :
1522 5 : yaorb_mpz_set_u64(op1, operand_1) ;
1523 :
1524 5 : mpz_ui_pow_ui(op2, 2, shift);
1525 5 : mpz_mul(res, op1, op2);
1526 :
1527 5 : overflow = check_u64(res) ;
1528 : }
1529 : else
1530 : {
1531 : overflow = true ;
1532 : }
1533 :
1534 7 : * result = yaorb_mpz_get_u64(res);
1535 :
1536 : #ifdef DEBUG
1537 : {
1538 : DEBUG_Operation(stderr, "shl_u64", op1, op2, res, overflow) ;
1539 : }
1540 : #endif
1541 :
1542 7 : mpz_clear(res);
1543 7 : mpz_clear(op1);
1544 7 : mpz_clear(op2);
1545 :
1546 : return overflow;
1547 : }
1548 :
1549 12 : bool shl_s64(int64_t operand_1, int64_t operand_2, int64_t * result)
1550 : {
1551 : mpz_t res ;
1552 : mpz_t op1 ;
1553 : mpz_t op2 ;
1554 :
1555 12 : mpz_init(res);
1556 12 : mpz_init(op1);
1557 12 : mpz_init(op2);
1558 :
1559 : bool overflow = false ;
1560 :
1561 : //==========================================================================
1562 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1563 : //==========================================================================
1564 :
1565 12 : if ((0 <= operand_2) && (operand_2 < 64))
1566 : {
1567 : uint8_t shift = (uint8_t) operand_2 ;
1568 :
1569 9 : yaorb_mpz_set_s64(op1, operand_1) ;
1570 :
1571 9 : mpz_ui_pow_ui(op2, 2, shift);
1572 9 : mpz_mul(res, op1, op2);
1573 :
1574 9 : overflow = check_s64(res) ;
1575 : }
1576 : else
1577 : {
1578 : overflow = true ;
1579 : }
1580 :
1581 12 : * result = yaorb_mpz_get_s64(res);
1582 :
1583 : #ifdef DEBUG
1584 : {
1585 : DEBUG_Operation(stderr, "shl_s64", op1, op2, res, overflow) ;
1586 : }
1587 : #endif
1588 :
1589 12 : mpz_clear(res);
1590 12 : mpz_clear(op1);
1591 12 : mpz_clear(op2);
1592 :
1593 : return overflow;
1594 : }
1595 :
1596 : // SHIFT RIGHT
1597 :
1598 1 : bool shr_u16(uint16_t operand_1, uint16_t operand_2, uint16_t * result)
1599 : {
1600 : mpz_t res ;
1601 : mpz_t op1 ;
1602 : mpz_t op2 ;
1603 :
1604 1 : mpz_init(res);
1605 1 : mpz_init(op1);
1606 1 : mpz_init(op2);
1607 :
1608 : bool overflow = false ;
1609 :
1610 : //==========================================================================
1611 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1612 : //==========================================================================
1613 :
1614 1 : if (operand_2 < 64)
1615 : {
1616 : uint8_t shift = (uint8_t) operand_2 ;
1617 :
1618 1 : mpz_set_ui(op1, operand_1);
1619 1 : mpz_ui_pow_ui(op2, 2, shift);
1620 1 : mpz_tdiv_q(res, op1, op2);
1621 :
1622 1 : overflow = check_u16(res) ;
1623 : }
1624 : else
1625 : {
1626 : overflow = true ;
1627 : }
1628 :
1629 1 : * result = mpz_get_ui(res);
1630 :
1631 : #ifdef DEBUG
1632 : {
1633 : DEBUG_Operation(stderr, "shr_u16", op1, op2, res, overflow) ;
1634 : }
1635 : #endif
1636 :
1637 1 : mpz_clear(res);
1638 1 : mpz_clear(op1);
1639 1 : mpz_clear(op2);
1640 :
1641 : return overflow;
1642 : }
1643 :
1644 1 : bool shr_s16(int16_t operand_1, int16_t operand_2, int16_t * result)
1645 : {
1646 : mpz_t res ;
1647 : mpz_t op1 ;
1648 : mpz_t op2 ;
1649 :
1650 1 : mpz_init(res);
1651 1 : mpz_init(op1);
1652 1 : mpz_init(op2);
1653 :
1654 : bool overflow = false ;
1655 :
1656 : //==========================================================================
1657 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1658 : //==========================================================================
1659 :
1660 1 : if ((0 <= operand_2) && (operand_2 < 64))
1661 : {
1662 : uint8_t shift = (uint8_t) operand_2 ;
1663 :
1664 1 : mpz_set_si(op1, operand_1);
1665 1 : mpz_ui_pow_ui(op2, 2, shift);
1666 1 : mpz_tdiv_q(res, op1, op2);
1667 :
1668 1 : overflow = check_s16(res) ;
1669 : }
1670 : else
1671 : {
1672 : overflow = true ;
1673 : }
1674 :
1675 1 : * result = mpz_get_si(res);
1676 :
1677 : #ifdef DEBUG
1678 : {
1679 : DEBUG_Operation(stderr, "shr_s16", op1, op2, res, overflow) ;
1680 : }
1681 : #endif
1682 :
1683 1 : mpz_clear(res);
1684 1 : mpz_clear(op1);
1685 1 : mpz_clear(op2);
1686 :
1687 : return overflow;
1688 : }
1689 :
1690 1 : bool shr_u32(uint32_t operand_1, uint32_t operand_2, uint32_t * result)
1691 : {
1692 : mpz_t res ;
1693 : mpz_t op1 ;
1694 : mpz_t op2 ;
1695 :
1696 1 : mpz_init(res);
1697 1 : mpz_init(op1);
1698 1 : mpz_init(op2);
1699 :
1700 : bool overflow = false ;
1701 :
1702 : //==========================================================================
1703 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1704 : //==========================================================================
1705 :
1706 1 : if (operand_2 < 64)
1707 : {
1708 : uint8_t shift = (uint8_t) operand_2 ;
1709 :
1710 1 : mpz_set_ui(op1, operand_1);
1711 1 : mpz_ui_pow_ui(op2, 2, shift);
1712 1 : mpz_tdiv_q(res, op1, op2);
1713 :
1714 1 : overflow = check_u32(res) ;
1715 : }
1716 : else
1717 : {
1718 : overflow = true ;
1719 : }
1720 :
1721 1 : * result = mpz_get_ui(res);
1722 :
1723 : #ifdef DEBUG
1724 : {
1725 : DEBUG_Operation(stderr, "shr_u32", op1, op2, res, overflow) ;
1726 : }
1727 : #endif
1728 :
1729 1 : mpz_clear(res);
1730 1 : mpz_clear(op1);
1731 1 : mpz_clear(op2);
1732 :
1733 : return overflow;
1734 : }
1735 :
1736 1 : bool shr_s32(int32_t operand_1, int32_t operand_2, int32_t * result)
1737 : {
1738 : mpz_t res ;
1739 : mpz_t op1 ;
1740 : mpz_t op2 ;
1741 :
1742 1 : mpz_init(res);
1743 1 : mpz_init(op1);
1744 1 : mpz_init(op2);
1745 :
1746 : bool overflow = false ;
1747 :
1748 : //==========================================================================
1749 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1750 : //==========================================================================
1751 :
1752 1 : if ((0 <= operand_2) && (operand_2 < 64))
1753 : {
1754 : uint8_t shift = (uint8_t) operand_2 ;
1755 :
1756 1 : mpz_set_si(op1, operand_1);
1757 1 : mpz_ui_pow_ui(op2, 2, shift);
1758 1 : mpz_tdiv_q(res, op1, op2);
1759 :
1760 1 : overflow = check_s32(res) ;
1761 : }
1762 : else
1763 : {
1764 : overflow = true ;
1765 : }
1766 :
1767 1 : * result = mpz_get_si(res);
1768 :
1769 : #ifdef DEBUG
1770 : {
1771 : DEBUG_Operation(stderr, "shr_s32", op1, op2, res, overflow) ;
1772 : }
1773 : #endif
1774 :
1775 1 : mpz_clear(res);
1776 1 : mpz_clear(op1);
1777 1 : mpz_clear(op2);
1778 :
1779 : return overflow;
1780 : }
1781 :
1782 1 : bool shr_u64(uint64_t operand_1, uint64_t operand_2, uint64_t * result)
1783 : {
1784 : mpz_t res ;
1785 : mpz_t op1 ;
1786 : mpz_t op2 ;
1787 :
1788 1 : mpz_init(res);
1789 1 : mpz_init(op1);
1790 1 : mpz_init(op2);
1791 :
1792 : bool overflow = false ;
1793 :
1794 : //==========================================================================
1795 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1796 : //==========================================================================
1797 :
1798 1 : if (operand_2 < 64)
1799 : {
1800 : uint8_t shift = (uint8_t) operand_2 ;
1801 :
1802 1 : yaorb_mpz_set_u64(op1, operand_1) ;
1803 :
1804 1 : mpz_ui_pow_ui(op2, 2, shift);
1805 1 : mpz_tdiv_q(res, op1, op2);
1806 :
1807 1 : overflow = check_u64(res) ;
1808 : }
1809 : else
1810 : {
1811 : overflow = true ;
1812 : }
1813 :
1814 1 : * result = yaorb_mpz_get_u64(res);
1815 :
1816 : #ifdef DEBUG
1817 : {
1818 : DEBUG_Operation(stderr, "shr_u64", op1, op2, res, overflow) ;
1819 : }
1820 : #endif
1821 :
1822 1 : mpz_clear(res);
1823 1 : mpz_clear(op1);
1824 1 : mpz_clear(op2);
1825 :
1826 : return overflow;
1827 : }
1828 :
1829 1 : bool shr_s64(int64_t operand_1, int64_t operand_2, int64_t * result)
1830 : {
1831 : mpz_t res ;
1832 : mpz_t op1 ;
1833 : mpz_t op2 ;
1834 :
1835 1 : mpz_init(res);
1836 1 : mpz_init(op1);
1837 1 : mpz_init(op2);
1838 :
1839 : bool overflow = false ;
1840 :
1841 : //==========================================================================
1842 : // REFERENCE : OMG 04-03-01, chap 3-10-2, page 3-35.
1843 : //==========================================================================
1844 :
1845 1 : if ((0 <= operand_2) && (operand_2 < 64))
1846 : {
1847 : uint8_t shift = (uint8_t) operand_2 ;
1848 :
1849 1 : yaorb_mpz_set_s64(op1, operand_1) ;
1850 :
1851 1 : mpz_ui_pow_ui(op2, 2, shift);
1852 1 : mpz_tdiv_q(res, op1, op2);
1853 :
1854 1 : overflow = check_s64(res) ;
1855 : }
1856 : else
1857 : {
1858 : overflow = true ;
1859 : }
1860 :
1861 1 : * result = yaorb_mpz_get_s64(res);
1862 :
1863 : #ifdef DEBUG
1864 : {
1865 : DEBUG_Operation(stderr, "shr_s64", op1, op2, res, overflow) ;
1866 : }
1867 : #endif
1868 :
1869 1 : mpz_clear(res);
1870 1 : mpz_clear(op1);
1871 1 : mpz_clear(op2);
1872 :
1873 : return overflow;
1874 : }
1875 :
1876 : // MODULO
1877 :
1878 1 : bool mod_u16(uint16_t operand_1, uint16_t operand_2, uint16_t * result)
1879 : {
1880 : mpz_t res ;
1881 : mpz_t op1 ;
1882 : mpz_t op2 ;
1883 :
1884 1 : mpz_init(res);
1885 1 : mpz_init(op1);
1886 1 : mpz_init(op2);
1887 :
1888 1 : mpz_set_ui(op1, operand_1);
1889 1 : mpz_set_ui(op2, operand_2);
1890 :
1891 : bool overflow = false ;
1892 :
1893 1 : if (mpz_sgn(op2) == 0)
1894 : {
1895 : // divide by 0
1896 : overflow = true ;
1897 : }
1898 : else
1899 : {
1900 1 : mpz_tdiv_r(res, op1, op2);
1901 1 : overflow = check_u16(res) ;
1902 : }
1903 :
1904 1 : * result = mpz_get_ui(res);
1905 :
1906 : #ifdef DEBUG
1907 : {
1908 : DEBUG_Operation(stderr, "mod_u16", op1, op2, res, overflow) ;
1909 : }
1910 : #endif
1911 :
1912 1 : mpz_clear(res);
1913 1 : mpz_clear(op1);
1914 1 : mpz_clear(op2);
1915 :
1916 : return overflow;
1917 : }
1918 :
1919 1 : bool mod_s16(int16_t operand_1, int16_t operand_2, int16_t * result)
1920 : {
1921 : mpz_t res ;
1922 : mpz_t op1 ;
1923 : mpz_t op2 ;
1924 :
1925 1 : mpz_init(res);
1926 1 : mpz_init(op1);
1927 1 : mpz_init(op2);
1928 :
1929 1 : mpz_set_si(op1, operand_1);
1930 1 : mpz_set_si(op2, operand_2);
1931 :
1932 : bool overflow = false ;
1933 :
1934 1 : if (mpz_sgn(op2) == 0)
1935 : {
1936 : // divide by 0
1937 : overflow = true ;
1938 : }
1939 : else
1940 : {
1941 1 : mpz_tdiv_r(res, op1, op2);
1942 1 : overflow = check_s16(res) ;
1943 : }
1944 :
1945 1 : * result = mpz_get_si(res);
1946 :
1947 : #ifdef DEBUG
1948 : {
1949 : DEBUG_Operation(stderr, "mod_s16", op1, op2, res, overflow) ;
1950 : }
1951 : #endif
1952 :
1953 1 : mpz_clear(res);
1954 1 : mpz_clear(op1);
1955 1 : mpz_clear(op2);
1956 :
1957 : return overflow;
1958 : }
1959 :
1960 1 : bool mod_u32(uint32_t operand_1, uint32_t operand_2, uint32_t * result)
1961 : {
1962 : mpz_t res ;
1963 : mpz_t op1 ;
1964 : mpz_t op2 ;
1965 :
1966 1 : mpz_init(res);
1967 1 : mpz_init(op1);
1968 1 : mpz_init(op2);
1969 :
1970 1 : mpz_set_ui(op1, operand_1);
1971 1 : mpz_set_ui(op2, operand_2);
1972 :
1973 : bool overflow = false ;
1974 :
1975 1 : if (mpz_sgn(op2) == 0)
1976 : {
1977 : // divide by 0
1978 : overflow = true ;
1979 : }
1980 : else
1981 : {
1982 1 : mpz_tdiv_r(res, op1, op2);
1983 1 : overflow = check_u32(res) ;
1984 : }
1985 :
1986 1 : * result = mpz_get_ui(res);
1987 :
1988 : #ifdef DEBUG
1989 : {
1990 : DEBUG_Operation(stderr, "mod_u32", op1, op2, res, overflow) ;
1991 : }
1992 : #endif
1993 :
1994 1 : mpz_clear(res);
1995 1 : mpz_clear(op1);
1996 1 : mpz_clear(op2);
1997 :
1998 : return overflow;
1999 : }
2000 :
2001 1 : bool mod_s32(int32_t operand_1, int32_t operand_2, int32_t * result)
2002 : {
2003 : mpz_t res ;
2004 : mpz_t op1 ;
2005 : mpz_t op2 ;
2006 :
2007 1 : mpz_init(res);
2008 1 : mpz_init(op1);
2009 1 : mpz_init(op2);
2010 :
2011 1 : mpz_set_si(op1, operand_1);
2012 1 : mpz_set_si(op2, operand_2);
2013 :
2014 : bool overflow = false ;
2015 :
2016 1 : if (mpz_sgn(op2) == 0)
2017 : {
2018 : // divide by 0
2019 : overflow = true ;
2020 : }
2021 : else
2022 : {
2023 1 : mpz_tdiv_r(res, op1, op2);
2024 1 : overflow = check_s32(res) ;
2025 : }
2026 :
2027 1 : * result = mpz_get_si(res);
2028 :
2029 : #ifdef DEBUG
2030 : {
2031 : DEBUG_Operation(stderr, "mod_s32", op1, op2, res, overflow) ;
2032 : }
2033 : #endif
2034 :
2035 1 : mpz_clear(res);
2036 1 : mpz_clear(op1);
2037 1 : mpz_clear(op2);
2038 :
2039 : return overflow;
2040 : }
2041 :
2042 1 : bool mod_u64(uint64_t operand_1, uint64_t operand_2, uint64_t * result)
2043 : {
2044 : mpz_t res ;
2045 : mpz_t op1 ;
2046 : mpz_t op2 ;
2047 :
2048 1 : mpz_init(res);
2049 1 : mpz_init(op1);
2050 1 : mpz_init(op2);
2051 :
2052 1 : yaorb_mpz_set_u64(op1, operand_1) ;
2053 1 : yaorb_mpz_set_u64(op2, operand_2) ;
2054 :
2055 : bool overflow = false ;
2056 :
2057 1 : if (mpz_sgn(op2) == 0)
2058 : {
2059 : // divide by 0
2060 : overflow = true ;
2061 : }
2062 : else
2063 : {
2064 1 : mpz_tdiv_r(res, op1, op2);
2065 1 : overflow = check_u64(res) ;
2066 : }
2067 :
2068 1 : * result = yaorb_mpz_get_u64(res);
2069 :
2070 : #ifdef DEBUG
2071 : {
2072 : DEBUG_Operation(stderr, "mod_u64", op1, op2, res, overflow) ;
2073 : }
2074 : #endif
2075 :
2076 1 : mpz_clear(res);
2077 1 : mpz_clear(op1);
2078 1 : mpz_clear(op2);
2079 :
2080 : return overflow;
2081 : }
2082 :
2083 1 : bool mod_s64(int64_t operand_1, int64_t operand_2, int64_t * result)
2084 : {
2085 : mpz_t res ;
2086 : mpz_t op1 ;
2087 : mpz_t op2 ;
2088 :
2089 1 : mpz_init(res);
2090 1 : mpz_init(op1);
2091 1 : mpz_init(op2);
2092 :
2093 1 : yaorb_mpz_set_s64(op1, operand_1) ;
2094 1 : yaorb_mpz_set_s64(op2, operand_2) ;
2095 :
2096 : bool overflow = false ;
2097 :
2098 1 : if (mpz_sgn(op2) == 0)
2099 : {
2100 : // divide by 0
2101 : overflow = true ;
2102 : }
2103 : else
2104 : {
2105 1 : mpz_tdiv_r(res, op1, op2);
2106 1 : overflow = check_s64(res) ;
2107 : }
2108 :
2109 1 : * result = yaorb_mpz_get_s64(res);
2110 :
2111 : #ifdef DEBUG
2112 : {
2113 : DEBUG_Operation(stderr, "mod_s64", op1, op2, res, overflow) ;
2114 : }
2115 : #endif
2116 :
2117 1 : mpz_clear(res);
2118 1 : mpz_clear(op1);
2119 1 : mpz_clear(op2);
2120 :
2121 : return overflow;
2122 : }
2123 :
|