VirtualBox

Changeset 52443 in vbox


Ignore:
Timestamp:
Aug 21, 2014 4:16:19 PM (10 years ago)
Author:
vboxsync
Message:

Runtime: added ASMMultU32ByU32DivByU32() and fixed early clobber operands in ASMMultU64ByU32DivByU32

Location:
trunk
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/asm-math.h

    r52294 r52443  
    322322
    323323/**
     324 * Multiple a 32-bit by a 32-bit integer and divide the result by a 32-bit integer
     325 * using a 64 bit intermediate result.
     326 * @note    Don't use 64-bit C arithmetic here since some gcc compilers generate references to
     327 *          __udivdi3 and __umoddi3 even if this inline function is not used.
     328 *
     329 * @returns (u32A * u32B) / u32C.
     330 * @param   u32A    The 32-bit value (A).
     331 * @param   u32B    The 32-bit value to multiple by A.
     332 * @param   u32C    The 32-bit value to divide A*B by.
     333 *
     334 * @remarks Architecture specific.
     335 */
     336#if RT_INLINE_ASM_EXTERNAL || !defined(__GNUC__) || (!defined(RT_ARCH_AMD64) && !defined(RT_ARCH_X86))
     337DECLASM(uint32_t) ASMMultU32ByU32DivByU32(uint32_t u32A, uint32_t u32B, uint32_t u32C);
     338#else
     339DECLINLINE(uint32_t) ASMMultU32ByU32DivByU32(uint32_t u32A, uint32_t u32B, uint32_t u32C)
     340{
     341# if RT_INLINE_ASM_GNU_STYLE
     342    uint32_t u32Result, u32Spill;
     343    __asm__ __volatile__("mul %2\n\t"
     344                         "div %3\n\t"
     345                         : "=&a" (u32Result),
     346                           "=&d" (u32Spill)
     347                         : "r" (u32B),
     348                           "r" (u32C),
     349                           "0" (u32A),
     350                           "1" (0));
     351    return u32Result;
     352# else
     353    return (uint32_t)(((uint64_t)u32A * u32B) / u32C);
     354# endif
     355}
     356#endif
     357
     358
     359/**
    324360 * Multiple a 64-bit by a 32-bit integer and divide the result by a 32-bit integer
    325361 * using a 96 bit intermediate result.
     
    344380    __asm__ __volatile__("mulq %2\n\t"
    345381                         "divq %3\n\t"
    346                          : "=a" (u64Result),
    347                            "=d" (u64Spill)
     382                         : "=&a" (u64Result),
     383                           "=&d" (u64Spill)
    348384                         : "r" ((uint64_t)u32B),
    349385                           "r" ((uint64_t)u32C),
  • trunk/src/VBox/Runtime/Makefile.kmk

    r52345 r52443  
    181181        win/amd64/ASMGetDR7.asm \
    182182        common/asm/ASMAtomicCmpXchgU8.asm \
     183        common/asm/ASMMultU32ByU32DivByU32.asm \
    183184        common/asm/ASMMultU64ByU32DivByU32.asm \
    184185        common/asm/ASMCpuId_Idx_ECX.asm \
     
    197198RuntimeWin32ASM_SOURCES = \
    198199        common/asm/ASMAtomicCmpXchgU8.asm \
     200        common/asm/ASMMultU32ByU32DivByU32.asm \
    199201        common/asm/ASMMultU64ByU32DivByU32.asm \
    200202        common/asm/ASMCpuId_Idx_ECX.asm \
  • trunk/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp

    r52345 r52443  
    14341434    uint32_t u32 = ASMDivU64ByU32RetU32(UINT64_C(0x0800000000000000), UINT32_C(0x10000000));
    14351435    CHECKVAL(u32, UINT32_C(0x80000000), "%#010RX32");
     1436
     1437#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
     1438    u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x00000001), UINT32_C(0x00000001), UINT32_C(0x00000001));
     1439    CHECKVAL(u32, UINT32_C(0x00000001), "%#018RX32");
     1440    u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x10000000), UINT32_C(0x80000000), UINT32_C(0x20000000));
     1441    CHECKVAL(u32, UINT32_C(0x40000000), "%#018RX32");
     1442    u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x76543210), UINT32_C(0xffffffff), UINT32_C(0xffffffff));
     1443    CHECKVAL(u32, UINT32_C(0x76543210), "%#018RX32");
     1444    u32 = ASMMultU32ByU32DivByU32(UINT32_C(0xffffffff), UINT32_C(0xffffffff), UINT32_C(0xffffffff));
     1445    CHECKVAL(u32, UINT32_C(0xffffffff), "%#018RX32");
     1446    u32 = ASMMultU32ByU32DivByU32(UINT32_C(0xffffffff), UINT32_C(0xfffffff0), UINT32_C(0xffffffff));
     1447    CHECKVAL(u32, UINT32_C(0xfffffff0), "%#018RX32");
     1448    u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x10359583), UINT32_C(0x58734981), UINT32_C(0xf8694045));
     1449    CHECKVAL(u32, UINT32_C(0x05c584ce), "%#018RX32");
     1450    u32 = ASMMultU32ByU32DivByU32(UINT32_C(0x10359583), UINT32_C(0xf8694045), UINT32_C(0x58734981));
     1451    CHECKVAL(u32, UINT32_C(0x2d860795), "%#018RX32");
     1452#endif
    14361453
    14371454#if defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette