home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / h / vd2 / system / int128.h < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  8.4 KB  |  362 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    System library component
  3. //    Copyright (C) 1998-2004 Avery Lee, All Rights Reserved.
  4. //
  5. //    Beginning with 1.6.0, the VirtualDub system library is licensed
  6. //    differently than the remainder of VirtualDub.  This particular file is
  7. //    thus licensed as follows (the "zlib" license):
  8. //
  9. //    This software is provided 'as-is', without any express or implied
  10. //    warranty.  In no event will the authors be held liable for any
  11. //    damages arising from the use of this software.
  12. //
  13. //    Permission is granted to anyone to use this software for any purpose,
  14. //    including commercial applications, and to alter it and redistribute it
  15. //    freely, subject to the following restrictions:
  16. //
  17. //    1.    The origin of this software must not be misrepresented; you must
  18. //        not claim that you wrote the original software. If you use this
  19. //        software in a product, an acknowledgment in the product
  20. //        documentation would be appreciated but is not required.
  21. //    2.    Altered source versions must be plainly marked as such, and must
  22. //        not be misrepresented as being the original software.
  23. //    3.    This notice may not be removed or altered from any source
  24. //        distribution.
  25.  
  26. #ifndef f_VD2_SYSTEM_INT128_H
  27. #define f_VD2_SYSTEM_INT128_H
  28.  
  29. #include <vd2/system/vdtypes.h>
  30.  
  31. struct vdint128;
  32. struct vduint128;
  33.  
  34. #ifdef _M_AMD64
  35.     extern "C" __int64 _mul128(__int64 x, __int64 y, __int64 *hiresult);
  36.     extern "C" unsigned __int64 _umul128(unsigned __int64 x, unsigned __int64 y, unsigned __int64 *hiresult);
  37.     extern "C" unsigned __int64 __shiftleft128(unsigned __int64 low, unsigned __int64 high, unsigned char shift);
  38.     extern "C" unsigned __int64 __shiftright128(unsigned __int64 low, unsigned __int64 high, unsigned char shift);
  39.  
  40.     #pragma intrinsic(_mul128)
  41.     #pragma intrinsic(_umul128)
  42.     #pragma intrinsic(__shiftleft128)
  43.     #pragma intrinsic(__shiftright128)
  44.  
  45.     extern "C" {
  46.         void vdasm_uint128_add(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  47.         void vdasm_uint128_sub(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  48.         void vdasm_uint128_mul(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  49.     }
  50. #else
  51.     extern "C" {
  52.         void __cdecl vdasm_uint128_add(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  53.         void __cdecl vdasm_uint128_sub(uint64 dst[2], const uint64 x[2], const uint64 y[2]);
  54.     }
  55. #endif
  56.  
  57. struct vdint128 {
  58. public:
  59.     union {
  60.         sint32 d[4];
  61.         sint64 q[2];
  62.     };
  63.  
  64.     vdint128() {}
  65.  
  66.     vdint128(sint64 x) {
  67.         q[0] = x;
  68.         q[1] = x>>63;
  69.     }
  70.  
  71.     vdint128(uint64 x) {
  72.         q[0] = (sint64)x;
  73.         q[1] = 0;
  74.     }
  75.  
  76.     vdint128(int x) {
  77.         q[0] = x;
  78.         q[1] = (sint64)x >> 63;
  79.     }
  80.  
  81.     vdint128(unsigned int x) {
  82.         q[0] = x;
  83.         q[1] = 0;
  84.     }
  85.  
  86.     vdint128(unsigned long x) {
  87.         q[0] = x;
  88.         q[1] = 0;
  89.     }
  90.  
  91.     vdint128(sint64 hi, uint64 lo) {
  92.         q[0] = lo;
  93.         q[1] = hi;
  94.     }
  95.  
  96.     sint64 getHi() const { return q[1]; }
  97.     uint64 getLo() const { return q[0]; }
  98.  
  99.     operator double() const;
  100.     operator sint64() const {
  101.         return (sint64)q[0];
  102.     }
  103.     operator uint64() const {
  104.         return (uint64)q[0];
  105.     }
  106.  
  107.     bool operator==(const vdint128& x) const {
  108.         return q[1] == x.q[1] && q[0] == x.q[0];
  109.     }
  110.  
  111.     bool operator!=(const vdint128& x) const {
  112.         return q[1] != x.q[1] || q[0] != x.q[0];
  113.     }
  114.  
  115.     bool operator<(const vdint128& x) const {
  116.         return q[1] < x.q[1] || (q[1] == x.q[1] && (uint64)q[0] < (uint64)x.q[0]);
  117.     }
  118.  
  119.     bool operator<=(const vdint128& x) const {
  120.         return q[1] < x.q[1] || (q[1] == x.q[1] && (uint64)q[0] <= (uint64)x.q[0]);
  121.     }
  122.  
  123.     bool operator>(const vdint128& x) const {
  124.         return q[1] > x.q[1] || (q[1] == x.q[1] && (uint64)q[0] > (uint64)x.q[0]);
  125.     }
  126.  
  127.     bool operator>=(const vdint128& x) const {
  128.         return q[1] > x.q[1] || (q[1] == x.q[1] && (uint64)q[0] >= (uint64)x.q[0]);
  129.     }
  130.  
  131.     const vdint128 operator+(const vdint128& x) const {
  132.         vdint128 t;
  133.         vdasm_uint128_add((uint64 *)t.q, (const uint64 *)q, (const uint64 *)x.q);
  134.         return t;
  135.     }
  136.  
  137.     const vdint128 operator-(const vdint128& x) const {
  138.         vdint128 t;
  139.         vdasm_uint128_sub((uint64 *)t.q, (const uint64 *)q, (const uint64 *)x.q);
  140.         return t;
  141.     }
  142.  
  143.     const vdint128& operator+=(const vdint128& x) {
  144.         vdasm_uint128_add((uint64 *)q, (const uint64 *)q, (const uint64 *)x.q);
  145.         return *this;
  146.     }
  147.  
  148.     const vdint128& operator-=(const vdint128& x) {
  149.         vdasm_uint128_sub((uint64 *)q, (const uint64 *)q, (const uint64 *)x.q);
  150.         return *this;
  151.     }
  152.  
  153.     const vdint128 operator*(const vdint128& x) const;
  154.  
  155.     const vdint128 operator/(int x) const;
  156.  
  157.     const vdint128 operator-() const {
  158.         vdint128 t(0);
  159.         vdasm_uint128_sub((uint64 *)t.q, (const uint64 *)t.q, (const uint64 *)q);
  160.         return t;
  161.     }
  162.  
  163.     const vdint128 abs() const {
  164.         return q[1] < 0 ? -*this : *this;
  165.     }
  166.  
  167. #ifdef _M_AMD64
  168.     void setSquare(sint64 v) {
  169.         const vdint128 v128(v);
  170.         operator=(v128*v128);
  171.     }
  172.  
  173.     const vdint128 operator<<(int count) const {
  174.         vdint128 t;
  175.  
  176.         if (count >= 64) {
  177.             t.q[0] = 0;
  178.             t.q[1] = q[0] << (count-64);
  179.         } else {
  180.             t.q[0] = q[0] << count;
  181.             t.q[1] = __shiftleft128(q[0], q[1], count);
  182.         }
  183.  
  184.         return t;
  185.     }
  186.  
  187.     const vdint128 operator>>(int count) const {
  188.         vdint128 t;
  189.  
  190.         if (count >= 64) {
  191.             t.q[0] = q[1] >> (count-64);
  192.             t.q[1] = q[1] >> 63;
  193.         } else {
  194.             t.q[0] = __shiftright128(q[0], q[1], count);
  195.             t.q[1] = q[1] >> count;
  196.         }
  197.  
  198.         return t;
  199.     }
  200. #else
  201.     void setSquare(sint64 v);
  202.  
  203.     const vdint128 operator<<(int v) const;
  204.     const vdint128 operator>>(int v) const;
  205. #endif
  206. };
  207.  
  208. struct vduint128 {
  209. public:
  210.     union {
  211.         uint32 d[4];
  212.         uint64 q[2];
  213.     };
  214.  
  215.     vduint128() {}
  216.  
  217.     vduint128(sint64 x) {
  218.         q[0] = (sint64)x;
  219.         q[1] = 0;
  220.     }
  221.  
  222.     vduint128(uint64 x) {
  223.         q[0] = x;
  224.         q[1] = 0;
  225.     }
  226.  
  227.     vduint128(int x) {
  228.         q[0] = (uint64)x;
  229.         q[1] = 0;
  230.     }
  231.  
  232.     vduint128(unsigned x) {
  233.         q[0] = x;
  234.         q[1] = 0;
  235.     }
  236.  
  237.     vduint128(uint64 hi, uint64 lo) {
  238.         q[0] = lo;
  239.         q[1] = hi;
  240.     }
  241.  
  242.     uint64 getHi() const { return q[1]; }
  243.     uint64 getLo() const { return q[0]; }
  244.  
  245.     operator sint64() const {
  246.         return (sint64)q[0];
  247.     }
  248.  
  249.     operator uint64() const {
  250.         return (uint64)q[0];
  251.     }
  252.  
  253.     bool operator==(const vduint128& x) const {
  254.         return q[1] == x.q[1] && q[0] == x.q[0];
  255.     }
  256.  
  257.     bool operator!=(const vduint128& x) const {
  258.         return q[1] != x.q[1] || q[0] != x.q[0];
  259.     }
  260.  
  261.     bool operator<(const vduint128& x) const {
  262.         return q[1] < x.q[1] || (q[1] == x.q[1] && q[0] < x.q[0]);
  263.     }
  264.  
  265.     bool operator<=(const vduint128& x) const {
  266.         return q[1] < x.q[1] || (q[1] == x.q[1] && q[0] <= x.q[0]);
  267.     }
  268.  
  269.     bool operator>(const vduint128& x) const {
  270.         return q[1] > x.q[1] || (q[1] == x.q[1] && q[0] > x.q[0]);
  271.     }
  272.  
  273.     bool operator>=(const vduint128& x) const {
  274.         return q[1] > x.q[1] || (q[1] == x.q[1] && q[0] >= x.q[0]);
  275.     }
  276.  
  277.     const vduint128 operator+(const vduint128& x) const {
  278.         vduint128 t;
  279.         vdasm_uint128_add(t.q, q, x.q);
  280.         return t;
  281.     }
  282.  
  283.     const vduint128 operator-(const vduint128& x) const {
  284.         vduint128 t;
  285.         vdasm_uint128_sub(t.q, q, x.q);
  286.         return t;
  287.     }
  288.  
  289.     const vduint128& operator+=(const vduint128& x) {
  290.         vdasm_uint128_add(q, q, x.q);
  291.         return *this;
  292.     }
  293.  
  294.     const vduint128& operator-=(const vduint128& x) {
  295.         vdasm_uint128_sub(q, q, x.q);
  296.         return *this;
  297.     }
  298.  
  299.     const vduint128 operator*(const vduint128& x) const;
  300.  
  301.     const vduint128 operator-() const {
  302.         vduint128 t(0U);
  303.         vdasm_uint128_sub((uint64 *)t.q, (const uint64 *)t.q, (const uint64 *)q);
  304.         return t;
  305.     }
  306.  
  307.     vduint128& operator<<=(int count) {
  308.         return operator=(operator<<(count));
  309.     }
  310.  
  311.     vduint128& operator>>=(int count) {
  312.         return operator=(operator>>(count));
  313.     }
  314.  
  315. #ifdef _M_AMD64
  316.     const vduint128 operator<<(int count) const {
  317.         vduint128 t;
  318.  
  319.         if (count >= 64) {
  320.             t.q[0] = 0;
  321.             t.q[1] = q[0] << (count-64);
  322.         } else {
  323.             t.q[0] = q[0] << count;
  324.             t.q[1] = __shiftleft128(q[0], q[1], count);
  325.         }
  326.  
  327.         return t;
  328.     }
  329.  
  330.     const vduint128 operator>>(int count) const {
  331.         vduint128 t;
  332.  
  333.         if (count >= 64) {
  334.             t.q[0] = q[1] >> (count-64);
  335.             t.q[1] = 0;
  336.         } else {
  337.             t.q[0] = __shiftright128(q[0], q[1], count);
  338.             t.q[1] = q[1] >> count;
  339.         }
  340.  
  341.         return t;
  342.     }
  343. #else
  344.     const vduint128 operator<<(int v) const;
  345.     const vduint128 operator>>(int v) const;
  346. #endif
  347. };
  348.  
  349. #ifdef _M_AMD64
  350.     inline vduint128 VDUMul64x64To128(uint64 x, uint64 y) {
  351.         vduint128 result;
  352.         result.q[0] = _umul128(x, y, &result.q[1]);
  353.         return result;
  354.     }
  355.     uint64 VDUDiv128x64To64(const vduint128& dividend, uint64 divisor, uint64& remainder);
  356. #else
  357.     vduint128 VDUMul64x64To128(uint64 x, uint64 y);
  358.     uint64 VDUDiv128x64To64(const vduint128& dividend, uint64 divisor, uint64& remainder);
  359. #endif
  360.  
  361. #endif
  362.