home *** CD-ROM | disk | FTP | other *** search
/ Tricks of the Windows Gam…ming Gurus (2nd Edition) / Disc2.iso / msdn_vcb / samples / vc98 / sdk / graphics / audio / acmapp / muldiv32.h < prev    next >
C/C++ Source or Header  |  1997-10-05  |  8KB  |  234 lines

  1. //==========================================================================;
  2. //
  3. //  THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  4. //  KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  5. //  IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  6. //  PURPOSE.
  7. //
  8. //  Copyright (C) 1992 - 1997 Microsoft Corporation.  All Rights Reserved.
  9. //
  10. //--------------------------------------------------------------------------;
  11. //
  12. //  muldiv32.h
  13. //
  14. //  Description:
  15. //      math routines for 32 bit signed and unsiged numbers.
  16. //
  17. //      MulDiv32(a,b,c) = (a * b) / c         (round down, signed)
  18. //
  19. //      MulDivRD(a,b,c) = (a * b) / c         (round down, unsigned)
  20. //      MulDivRN(a,b,c) = (a * b + c/2) / c   (round nearest, unsigned)
  21. //      MulDivRU(a,b,c) = (a * b + c-1) / c   (round up, unsigned)
  22. //
  23. //==========================================================================;
  24.  
  25. #ifndef _INC_MULDIV32
  26. #define _INC_MULDIV32
  27.  
  28.  
  29. #ifndef INLINE
  30. #define INLINE __inline
  31. #endif
  32.  
  33.  
  34. #ifdef WIN32
  35.  
  36.     //----------------------------------------------------------------------;
  37.     //
  38.     //  Win 32
  39.     //
  40.     //----------------------------------------------------------------------;
  41.  
  42.     #ifdef _X86_
  43.     
  44.         //
  45.         //  Use 32-bit x86 assembly.
  46.         //
  47.  
  48.         #pragma warning(disable:4035 4704)
  49.  
  50.         INLINE LONG MulDiv32(LONG a,LONG b,LONG c)
  51.         {
  52.             _asm     mov     eax,dword ptr a  //  mov  eax, a
  53.             _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  54.             _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  55.             _asm     imul    ebx              //  imul ebx
  56.             _asm     idiv    ecx              //  idiv ecx
  57.             _asm     shld     edx, eax, 16     //  shld edx, eax, 16
  58.  
  59.         } // MulDiv32()
  60.  
  61.         INLINE DWORD MulDivRN(DWORD a,DWORD b,DWORD c)
  62.         {
  63.             _asm     mov     eax,dword ptr a  //  mov  eax, a
  64.             _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  65.             _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  66.             _asm     mul     ebx              //  mul  ebx
  67.             _asm     mov     ebx,ecx          //  mov  ebx,ecx
  68.             _asm     shr     ebx,1            //  sar  ebx,1
  69.             _asm     add     eax,ebx          //  add  eax,ebx
  70.             _asm     adc     edx,0            //  adc  edx,0
  71.             _asm     div     ecx              //  div  ecx
  72.             _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  73.  
  74.         } // MulDiv32()
  75.  
  76.         INLINE DWORD MulDivRU(DWORD a,DWORD b,DWORD c)
  77.         {
  78.             _asm     mov     eax,dword ptr a  //  mov  eax, a
  79.             _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  80.             _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  81.             _asm     mul     ebx              //  mul  ebx
  82.             _asm     mov     ebx,ecx          //  mov  ebx,ecx
  83.             _asm     dec     ebx              //  dec  ebx
  84.             _asm     add     eax,ebx          //  add  eax,ebx
  85.             _asm     adc     edx,0            //  adc  edx,0
  86.             _asm     div     ecx              //  div  ecx
  87.             _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  88.  
  89.         } // MulDivRU32()
  90.  
  91.         INLINE DWORD MulDivRD(DWORD a,DWORD b,DWORD c)
  92.         {
  93.             _asm     mov     eax,dword ptr a  //  mov  eax, a
  94.             _asm     mov     ebx,dword ptr b  //  mov  ebx, b
  95.             _asm     mov     ecx,dword ptr c  //  mov  ecx, c
  96.             _asm     mul     ebx              //  mul  ebx
  97.             _asm     div     ecx              //  div  ecx
  98.             _asm     shld    edx, eax, 16     //  shld edx, eax, 16
  99.  
  100.         } // MulDivRD32()
  101.  
  102.         #pragma warning(default:4035 4704)
  103.  
  104.  
  105.     #else
  106.  
  107.         //
  108.         //  Use C9 __int64 support for Daytona RISC platforms.
  109.         //
  110.  
  111.         INLINE LONG MulDiv32( LONG a, LONG b, LONG c )
  112.         {
  113.             return (LONG)( Int32x32To64(a,b) / c );
  114.         }
  115.  
  116.  
  117.         INLINE DWORD MulDivRD( DWORD a, DWORD b, DWORD c )
  118.         {
  119.             return (DWORD)( UInt32x32To64(a,b) / c );
  120.         }
  121.  
  122.  
  123.         INLINE DWORD MulDivRN( DWORD a, DWORD b, DWORD c )
  124.         {
  125.             return (DWORD)( (UInt32x32To64(a,b)+c/2) / c );
  126.         }
  127.  
  128.  
  129.         INLINE DWORD MulDivRU( DWORD a, DWORD b, DWORD c )
  130.         {
  131.             return (DWORD)( (UInt32x32To64(a,b)+c-1) / c );
  132.         }
  133.  
  134.     #endif
  135.  
  136.  
  137. #else
  138.  
  139.     //----------------------------------------------------------------------;
  140.     //
  141.     //  Win 16
  142.     //
  143.     //----------------------------------------------------------------------;
  144.  
  145.     #pragma warning(disable:4035 4704)
  146.  
  147.     //
  148.     //  Compile for 16-bit - we can use x86 with proper opcode prefixes
  149.     //        to get 32-bit instructions.
  150.     //
  151.  
  152.     INLINE LONG MulDiv32(LONG a,LONG b,LONG c)
  153.     {
  154.         _asm _emit 0x66 _asm    mov     ax,word ptr a   //  mov  eax, a
  155.         _asm _emit 0x66 _asm    mov     bx,word ptr b   //  mov  ebx, b
  156.         _asm _emit 0x66 _asm    mov     cx,word ptr c   //  mov  ecx, c
  157.         _asm _emit 0x66 _asm    imul    bx              //  imul ebx
  158.         _asm _emit 0x66 _asm    idiv    cx              //  idiv ecx
  159.         _asm _emit 0x66                                 //  shld edx, eax, 16
  160.         _asm _emit 0x0F
  161.         _asm _emit 0xA4
  162.         _asm _emit 0xC2
  163.         _asm _emit 0x10
  164.  
  165.     } // MulDiv32()
  166.  
  167.     INLINE DWORD MulDivRN(DWORD a,DWORD b,DWORD c)
  168.     {
  169.         _asm _emit 0x66 _asm    mov     ax,word ptr a   //  mov  eax, a
  170.         _asm _emit 0x66 _asm    mov     bx,word ptr b   //  mov  ebx, b
  171.         _asm _emit 0x66 _asm    mov     cx,word ptr c   //  mov  ecx, c
  172.         _asm _emit 0x66 _asm    mul     bx              //  mul  ebx
  173.         _asm _emit 0x66 _asm    mov     bx,cx           //  mov  ebx,ecx
  174.         _asm _emit 0x66 _asm    shr     bx,1            //  sar  ebx,1
  175.         _asm _emit 0x66 _asm    add     ax,bx           //  add  eax,ebx
  176.         _asm _emit 0x66 _asm    adc     dx,0            //  adc  edx,0
  177.         _asm _emit 0x66 _asm    div     cx              //  div  ecx
  178.         _asm _emit 0x66                                 //  shld edx, eax, 16
  179.         _asm _emit 0x0F
  180.         _asm _emit 0xA4
  181.         _asm _emit 0xC2
  182.         _asm _emit 0x10
  183.  
  184.     } // MulDiv32()
  185.  
  186.     INLINE DWORD MulDivRU(DWORD a,DWORD b,DWORD c)
  187.     {
  188.         _asm _emit 0x66 _asm    mov     ax,word ptr a   //  mov  eax, a
  189.         _asm _emit 0x66 _asm    mov     bx,word ptr b   //  mov  ebx, b
  190.         _asm _emit 0x66 _asm    mov     cx,word ptr c   //  mov  ecx, c
  191.         _asm _emit 0x66 _asm    mul     bx              //  mul  ebx
  192.         _asm _emit 0x66 _asm    mov     bx,cx           //  mov  ebx,ecx
  193.         _asm _emit 0x66 _asm    dec     bx              //  dec  ebx
  194.         _asm _emit 0x66 _asm    add     ax,bx           //  add  eax,ebx
  195.         _asm _emit 0x66 _asm    adc     dx,0            //  adc  edx,0
  196.         _asm _emit 0x66 _asm    div     cx              //  div  ecx
  197.         _asm _emit 0x66                                 //  shld edx, eax, 16
  198.         _asm _emit 0x0F
  199.         _asm _emit 0xA4
  200.         _asm _emit 0xC2
  201.         _asm _emit 0x10
  202.  
  203.     } // MulDivRU32()
  204.  
  205.  
  206.     INLINE DWORD MulDivRD(DWORD a,DWORD b,DWORD c)
  207.     {
  208.         _asm _emit 0x66 _asm    mov     ax,word ptr a   //  mov  eax, a
  209.         _asm _emit 0x66 _asm    mov     bx,word ptr b   //  mov  ebx, b
  210.         _asm _emit 0x66 _asm    mov     cx,word ptr c   //  mov  ecx, c
  211.         _asm _emit 0x66 _asm    mul     bx              //  mul  ebx
  212.         _asm _emit 0x66 _asm    div     cx              //  div  ecx
  213.         _asm _emit 0x66                                 //  shld edx, eax, 16
  214.         _asm _emit 0x0F
  215.         _asm _emit 0xA4
  216.         _asm _emit 0xC2
  217.         _asm _emit 0x10
  218.  
  219.     } // MulDivRD32()
  220.  
  221.     #pragma warning(default:4035 4704)
  222.  
  223. #endif
  224.  
  225.  
  226. //
  227. //  some code references these by other names.
  228. //
  229. #define muldiv32    MulDivRN
  230. #define muldivrd32  MulDivRD
  231. #define muldivru32  MulDivRU
  232.  
  233. #endif  // _INC_MULDIV32
  234.