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