Mercurial > octave
comparison liboctave/util/oct-inttypes.h @ 21302:8376de2eaf00
define OCTAVE_HAVE_FAST_INT_OPS in octave-config.h
* acinclude.m4 (OCTAVE_FAST_INT_OPS): Define OCTAVE_HAVE_FAST_INT_OPS
instead of HAVE_FAST_INT_OPS.
* oct-inttypes.cc, oct-inttypes.h: Use new macro name.
* mk-octave-config-h.sh: Emit definition of OCTAVE_HAVE_FAST_INT_OPS.
* build-env-features.sh: Also include symbols beginning with
"OCTAVE_HAVE_".
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Thu, 18 Feb 2016 16:42:42 -0500 |
parents | 933083fee7ae |
children | c53bfd6d8e08 |
comparison
equal
deleted
inserted
replaced
21301:40de9f8f23a6 | 21302:8376de2eaf00 |
---|---|
497 OCTAVE_API uint64_t | 497 OCTAVE_API uint64_t |
498 octave_int_arith_base<uint64_t, false>::mul_internal (uint64_t, uint64_t); | 498 octave_int_arith_base<uint64_t, false>::mul_internal (uint64_t, uint64_t); |
499 | 499 |
500 #endif | 500 #endif |
501 | 501 |
502 // Signed integer arithmetics. | 502 // Signed integer arithmetic. |
503 // Rationale: If HAVE_FAST_INT_OPS is defined, the following conditions | 503 // |
504 // should hold: | 504 // Rationale: If OCTAVE_HAVE_FAST_INT_OPS is defined, the following |
505 // 1. Signed numbers are represented by twos complement | 505 // conditions should hold: |
506 // (see <http://en.wikipedia.org/wiki/Two%27s_complement>) | 506 // |
507 // 2. static_cast to unsigned int counterpart works like interpreting | 507 // 1. Signed numbers are represented by twos complement (see |
508 // the signed bit pattern as unsigned (and is thus zero-cost). | 508 // <http://en.wikipedia.org/wiki/Two%27s_complement>) |
509 // 3. Signed addition and subtraction yield the same bit results as unsigned. | 509 // |
510 // (We use casts to prevent optimization interference, so there is no | 510 // 2. static_cast to unsigned int counterpart works like |
511 // need for things like -ftrapv). | 511 // interpreting the signed bit pattern as unsigned (and is thus |
512 // 4. Bit operations on signed integers work like on unsigned integers, | 512 // zero-cost). |
513 // except for the shifts. Shifts are arithmetic. | 513 // |
514 // 3. Signed addition and subtraction yield the same bit results as | |
515 // unsigned. (We use casts to prevent optimization interference, | |
516 // so there is no need for things like -ftrapv). | |
517 // | |
518 // 4. Bit operations on signed integers work like on unsigned | |
519 // integers, except for the shifts. Shifts are arithmetic. | |
514 // | 520 // |
515 // The above conditions are satisfied by most modern platforms. If | 521 // The above conditions are satisfied by most modern platforms. If |
516 // HAVE_FAST_INT_OPS is defined, bit tricks and wraparound arithmetics are used | 522 // OCTAVE_HAVE_FAST_INT_OPS is defined, bit tricks and wraparound |
517 // to avoid conditional jumps as much as possible, thus being friendly to | 523 // arithmetics are used to avoid conditional jumps as much as |
518 // modern pipeline processor architectures. | 524 // possible, thus being friendly to modern pipeline processor |
519 // Otherwise, we fall back to a bullet-proof code that only uses assumptions | 525 // architectures. Otherwise, we fall back to a bullet-proof code that |
520 // guaranteed by the standard. | 526 // only uses assumptions guaranteed by the standard. |
521 | 527 |
522 template <typename T> | 528 template <typename T> |
523 class octave_int_arith_base<T, true> : octave_int_base<T> | 529 class octave_int_arith_base<T, true> : octave_int_base<T> |
524 { | 530 { |
525 // The corresponding unsigned type. | 531 // The corresponding unsigned type. |
528 | 534 |
529 // Returns 1 for negative number, 0 otherwise. | 535 // Returns 1 for negative number, 0 otherwise. |
530 static T | 536 static T |
531 __signbit (T x) | 537 __signbit (T x) |
532 { | 538 { |
533 #ifdef HAVE_FAST_INT_OPS | 539 #if defined (OCTAVE_HAVE_FAST_INT_OPS) |
534 return static_cast<UT> (x) >> std::numeric_limits<T>::digits; | 540 return static_cast<UT> (x) >> std::numeric_limits<T>::digits; |
535 #else | 541 #else |
536 return (x < 0) ? 1 : 0; | 542 return (x < 0) ? 1 : 0; |
537 #endif | 543 #endif |
538 } | 544 } |
539 | 545 |
540 static T | 546 static T |
541 abs (T x) | 547 abs (T x) |
542 { | 548 { |
543 #ifdef HAVE_FAST_INT_OPS | 549 #if defined (OCTAVE_HAVE_FAST_INT_OPS) |
544 // This is close to how GCC does std::abs, but we can't just use std::abs, | 550 // This is close to how GCC does std::abs, but we can't just use std::abs, |
545 // because its behaviour for INT_MIN is undefined and the compiler could | 551 // because its behaviour for INT_MIN is undefined and the compiler could |
546 // discard the following test. | 552 // discard the following test. |
547 T m = x >> std::numeric_limits<T>::digits; | 553 T m = x >> std::numeric_limits<T>::digits; |
548 T y = (x ^ m) - m; | 554 T y = (x ^ m) - m; |
587 | 593 |
588 // Minus has problems similar to abs. | 594 // Minus has problems similar to abs. |
589 static T | 595 static T |
590 minus (T x) | 596 minus (T x) |
591 { | 597 { |
592 #ifdef HAVE_FAST_INT_OPS | 598 #if defined (OCTAVE_HAVE_FAST_INT_OPS) |
593 T y = -x; | 599 T y = -x; |
594 if (y == octave_int_base<T>::min_val ()) | 600 if (y == octave_int_base<T>::min_val ()) |
595 { | 601 { |
596 --y; | 602 --y; |
597 } | 603 } |
610 } | 616 } |
611 | 617 |
612 static T | 618 static T |
613 add (T x, T y) | 619 add (T x, T y) |
614 { | 620 { |
615 #ifdef HAVE_FAST_INT_OPS | 621 #if defined (OCTAVE_HAVE_FAST_INT_OPS) |
616 // The typecasts do nothing, but they are here to prevent an optimizing | 622 // The typecasts do nothing, but they are here to prevent an optimizing |
617 // compiler from interfering. Also, the signed operations on small types | 623 // compiler from interfering. Also, the signed operations on small types |
618 // actually return int. | 624 // actually return int. |
619 T u = static_cast<UT> (x) + static_cast<UT> (y); | 625 T u = static_cast<UT> (x) + static_cast<UT> (y); |
620 T ux = u ^ x; | 626 T ux = u ^ x; |
652 | 658 |
653 // This is very similar to addition. | 659 // This is very similar to addition. |
654 static T | 660 static T |
655 sub (T x, T y) | 661 sub (T x, T y) |
656 { | 662 { |
657 #ifdef HAVE_FAST_INT_OPS | 663 #if defined (OCTAVE_HAVE_FAST_INT_OPS) |
658 // The typecasts do nothing, but they are here to prevent an optimizing | 664 // The typecasts do nothing, but they are here to prevent an optimizing |
659 // compiler from interfering. Also, the signed operations on small types | 665 // compiler from interfering. Also, the signed operations on small types |
660 // actually return int. | 666 // actually return int. |
661 T u = static_cast<UT> (x) - static_cast<UT> (y); | 667 T u = static_cast<UT> (x) - static_cast<UT> (y); |
662 T ux = u ^ x; | 668 T ux = u ^ x; |
787 { | 793 { |
788 int64_t retval; | 794 int64_t retval; |
789 | 795 |
790 long double p = static_cast<long double> (x) * static_cast<long double> (y); | 796 long double p = static_cast<long double> (x) * static_cast<long double> (y); |
791 | 797 |
792 // NOTE: We could maybe do it with a single branch if HAVE_FAST_INT_OPS, | 798 // NOTE: We could maybe do it with a single branch if |
793 // but it would require one more runtime conversion, so the question is | 799 // OCTAVE_HAVE_FAST_INT_OPS, but it would require one more runtime |
794 // whether it would really be faster. | 800 // conversion, so the question is whether it would really be faster. |
795 if (p > static_cast<long double> (octave_int_base<int64_t>::max_val ())) | 801 if (p > static_cast<long double> (octave_int_base<int64_t>::max_val ())) |
796 retval = octave_int_base<int64_t>::max_val (); | 802 retval = octave_int_base<int64_t>::max_val (); |
797 else if (p < static_cast<long double> (octave_int_base<int64_t>::min_val ())) | 803 else if (p < static_cast<long double> (octave_int_base<int64_t>::min_val ())) |
798 retval = octave_int_base<int64_t>::min_val (); | 804 retval = octave_int_base<int64_t>::min_val (); |
799 else | 805 else |