|
6 | 6 | //
|
7 | 7 | //===----------------------------------------------------------------------===//
|
8 | 8 |
|
| 9 | +#include "terminator.h" |
9 | 10 | #include "flang/Runtime/numeric.h"
|
10 | 11 | #include "flang/Common/long-double.h"
|
11 | 12 | #include <climits>
|
@@ -62,14 +63,24 @@ template <typename T> inline T Fraction(T x) {
|
62 | 63 | }
|
63 | 64 |
|
64 | 65 | // MOD & MODULO (16.9.135, .136)
|
65 |
| -template <bool IS_MODULO, typename T> inline T IntMod(T x, T p) { |
| 66 | +template <bool IS_MODULO, typename T> |
| 67 | +inline T IntMod(T x, T p, const char *sourceFile, int sourceLine) { |
| 68 | + if (p == 0) { |
| 69 | + Terminator{sourceFile, sourceLine}.Crash( |
| 70 | + IS_MODULO ? "MODULO with P==0" : "MOD with P==0"); |
| 71 | + } |
66 | 72 | auto mod{x - (x / p) * p};
|
67 | 73 | if (IS_MODULO && (x > 0) != (p > 0)) {
|
68 | 74 | mod += p;
|
69 | 75 | }
|
70 | 76 | return mod;
|
71 | 77 | }
|
72 |
| -template <bool IS_MODULO, typename T> inline T RealMod(T x, T p) { |
| 78 | +template <bool IS_MODULO, typename T> |
| 79 | +inline T RealMod(T x, T p, const char *sourceFile, int sourceLine) { |
| 80 | + if (p == 0) { |
| 81 | + Terminator{sourceFile, sourceLine}.Crash( |
| 82 | + IS_MODULO ? "MODULO with P==0" : "MOD with P==0"); |
| 83 | + } |
73 | 84 | if constexpr (IS_MODULO) {
|
74 | 85 | return x - std::floor(x / p) * p;
|
75 | 86 | } else {
|
@@ -542,99 +553,113 @@ bool RTNAME(IsNaN16)(CppTypeFor<TypeCategory::Real, 16> x) {
|
542 | 553 |
|
543 | 554 | CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModInteger1)(
|
544 | 555 | CppTypeFor<TypeCategory::Integer, 1> x,
|
545 |
| - CppTypeFor<TypeCategory::Integer, 1> p) { |
546 |
| - return IntMod<false>(x, p); |
| 556 | + CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile, |
| 557 | + int sourceLine) { |
| 558 | + return IntMod<false>(x, p, sourceFile, sourceLine); |
547 | 559 | }
|
548 | 560 | CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModInteger2)(
|
549 | 561 | CppTypeFor<TypeCategory::Integer, 2> x,
|
550 |
| - CppTypeFor<TypeCategory::Integer, 2> p) { |
551 |
| - return IntMod<false>(x, p); |
| 562 | + CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile, |
| 563 | + int sourceLine) { |
| 564 | + return IntMod<false>(x, p, sourceFile, sourceLine); |
552 | 565 | }
|
553 | 566 | CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModInteger4)(
|
554 | 567 | CppTypeFor<TypeCategory::Integer, 4> x,
|
555 |
| - CppTypeFor<TypeCategory::Integer, 4> p) { |
556 |
| - return IntMod<false>(x, p); |
| 568 | + CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile, |
| 569 | + int sourceLine) { |
| 570 | + return IntMod<false>(x, p, sourceFile, sourceLine); |
557 | 571 | }
|
558 | 572 | CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModInteger8)(
|
559 | 573 | CppTypeFor<TypeCategory::Integer, 8> x,
|
560 |
| - CppTypeFor<TypeCategory::Integer, 8> p) { |
561 |
| - return IntMod<false>(x, p); |
| 574 | + CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile, |
| 575 | + int sourceLine) { |
| 576 | + return IntMod<false>(x, p, sourceFile, sourceLine); |
562 | 577 | }
|
563 | 578 | #ifdef __SIZEOF_INT128__
|
564 | 579 | CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModInteger16)(
|
565 | 580 | CppTypeFor<TypeCategory::Integer, 16> x,
|
566 |
| - CppTypeFor<TypeCategory::Integer, 16> p) { |
567 |
| - return IntMod<false>(x, p); |
| 581 | + CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile, |
| 582 | + int sourceLine) { |
| 583 | + return IntMod<false>(x, p, sourceFile, sourceLine); |
568 | 584 | }
|
569 | 585 | #endif
|
570 | 586 | CppTypeFor<TypeCategory::Real, 4> RTNAME(ModReal4)(
|
571 |
| - CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) { |
572 |
| - return RealMod<false>(x, p); |
| 587 | + CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p, |
| 588 | + const char *sourceFile, int sourceLine) { |
| 589 | + return RealMod<false>(x, p, sourceFile, sourceLine); |
573 | 590 | }
|
574 | 591 | CppTypeFor<TypeCategory::Real, 8> RTNAME(ModReal8)(
|
575 |
| - CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) { |
576 |
| - return RealMod<false>(x, p); |
| 592 | + CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p, |
| 593 | + const char *sourceFile, int sourceLine) { |
| 594 | + return RealMod<false>(x, p, sourceFile, sourceLine); |
577 | 595 | }
|
578 | 596 | #if LONG_DOUBLE == 80
|
579 | 597 | CppTypeFor<TypeCategory::Real, 10> RTNAME(ModReal10)(
|
580 |
| - CppTypeFor<TypeCategory::Real, 10> x, |
581 |
| - CppTypeFor<TypeCategory::Real, 10> p) { |
582 |
| - return RealMod<false>(x, p); |
| 598 | + CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p, |
| 599 | + const char *sourceFile, int sourceLine) { |
| 600 | + return RealMod<false>(x, p, sourceFile, sourceLine); |
583 | 601 | }
|
584 | 602 | #elif LONG_DOUBLE == 128
|
585 | 603 | CppTypeFor<TypeCategory::Real, 16> RTNAME(ModReal16)(
|
586 |
| - CppTypeFor<TypeCategory::Real, 16> x, |
587 |
| - CppTypeFor<TypeCategory::Real, 16> p) { |
588 |
| - return RealMod<false>(x, p); |
| 604 | + CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p, |
| 605 | + const char *sourceFile, int sourceLine) { |
| 606 | + return RealMod<false>(x, p, sourceFile, sourceLine); |
589 | 607 | }
|
590 | 608 | #endif
|
591 | 609 |
|
592 | 610 | CppTypeFor<TypeCategory::Integer, 1> RTNAME(ModuloInteger1)(
|
593 | 611 | CppTypeFor<TypeCategory::Integer, 1> x,
|
594 |
| - CppTypeFor<TypeCategory::Integer, 1> p) { |
595 |
| - return IntMod<true>(x, p); |
| 612 | + CppTypeFor<TypeCategory::Integer, 1> p, const char *sourceFile, |
| 613 | + int sourceLine) { |
| 614 | + return IntMod<true>(x, p, sourceFile, sourceLine); |
596 | 615 | }
|
597 | 616 | CppTypeFor<TypeCategory::Integer, 2> RTNAME(ModuloInteger2)(
|
598 | 617 | CppTypeFor<TypeCategory::Integer, 2> x,
|
599 |
| - CppTypeFor<TypeCategory::Integer, 2> p) { |
600 |
| - return IntMod<true>(x, p); |
| 618 | + CppTypeFor<TypeCategory::Integer, 2> p, const char *sourceFile, |
| 619 | + int sourceLine) { |
| 620 | + return IntMod<true>(x, p, sourceFile, sourceLine); |
601 | 621 | }
|
602 | 622 | CppTypeFor<TypeCategory::Integer, 4> RTNAME(ModuloInteger4)(
|
603 | 623 | CppTypeFor<TypeCategory::Integer, 4> x,
|
604 |
| - CppTypeFor<TypeCategory::Integer, 4> p) { |
605 |
| - return IntMod<true>(x, p); |
| 624 | + CppTypeFor<TypeCategory::Integer, 4> p, const char *sourceFile, |
| 625 | + int sourceLine) { |
| 626 | + return IntMod<true>(x, p, sourceFile, sourceLine); |
606 | 627 | }
|
607 | 628 | CppTypeFor<TypeCategory::Integer, 8> RTNAME(ModuloInteger8)(
|
608 | 629 | CppTypeFor<TypeCategory::Integer, 8> x,
|
609 |
| - CppTypeFor<TypeCategory::Integer, 8> p) { |
610 |
| - return IntMod<true>(x, p); |
| 630 | + CppTypeFor<TypeCategory::Integer, 8> p, const char *sourceFile, |
| 631 | + int sourceLine) { |
| 632 | + return IntMod<true>(x, p, sourceFile, sourceLine); |
611 | 633 | }
|
612 | 634 | #ifdef __SIZEOF_INT128__
|
613 | 635 | CppTypeFor<TypeCategory::Integer, 16> RTNAME(ModuloInteger16)(
|
614 | 636 | CppTypeFor<TypeCategory::Integer, 16> x,
|
615 |
| - CppTypeFor<TypeCategory::Integer, 16> p) { |
616 |
| - return IntMod<true>(x, p); |
| 637 | + CppTypeFor<TypeCategory::Integer, 16> p, const char *sourceFile, |
| 638 | + int sourceLine) { |
| 639 | + return IntMod<true>(x, p, sourceFile, sourceLine); |
617 | 640 | }
|
618 | 641 | #endif
|
619 | 642 | CppTypeFor<TypeCategory::Real, 4> RTNAME(ModuloReal4)(
|
620 |
| - CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p) { |
621 |
| - return RealMod<true>(x, p); |
| 643 | + CppTypeFor<TypeCategory::Real, 4> x, CppTypeFor<TypeCategory::Real, 4> p, |
| 644 | + const char *sourceFile, int sourceLine) { |
| 645 | + return RealMod<true>(x, p, sourceFile, sourceLine); |
622 | 646 | }
|
623 | 647 | CppTypeFor<TypeCategory::Real, 8> RTNAME(ModuloReal8)(
|
624 |
| - CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p) { |
625 |
| - return RealMod<true>(x, p); |
| 648 | + CppTypeFor<TypeCategory::Real, 8> x, CppTypeFor<TypeCategory::Real, 8> p, |
| 649 | + const char *sourceFile, int sourceLine) { |
| 650 | + return RealMod<true>(x, p, sourceFile, sourceLine); |
626 | 651 | }
|
627 | 652 | #if LONG_DOUBLE == 80
|
628 | 653 | CppTypeFor<TypeCategory::Real, 10> RTNAME(ModuloReal10)(
|
629 |
| - CppTypeFor<TypeCategory::Real, 10> x, |
630 |
| - CppTypeFor<TypeCategory::Real, 10> p) { |
631 |
| - return RealMod<true>(x, p); |
| 654 | + CppTypeFor<TypeCategory::Real, 10> x, CppTypeFor<TypeCategory::Real, 10> p, |
| 655 | + const char *sourceFile, int sourceLine) { |
| 656 | + return RealMod<true>(x, p, sourceFile, sourceLine); |
632 | 657 | }
|
633 | 658 | #elif LONG_DOUBLE == 128
|
634 | 659 | CppTypeFor<TypeCategory::Real, 16> RTNAME(ModuloReal16)(
|
635 |
| - CppTypeFor<TypeCategory::Real, 16> x, |
636 |
| - CppTypeFor<TypeCategory::Real, 16> p) { |
637 |
| - return RealMod<true>(x, p); |
| 660 | + CppTypeFor<TypeCategory::Real, 16> x, CppTypeFor<TypeCategory::Real, 16> p, |
| 661 | + const char *sourceFile, int sourceLine) { |
| 662 | + return RealMod<true>(x, p, sourceFile, sourceLine); |
638 | 663 | }
|
639 | 664 | #endif
|
640 | 665 |
|
|
0 commit comments