VirtualBox

Changeset 59527 in vbox


Ignore:
Timestamp:
Jan 31, 2016 11:54:20 AM (9 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
105318
Message:

iprt/asm.h: Experimented with alternative serializating instructions (ASMSerializeInstruction), cpuid(0) is very reasonable compared to iret (rdtscp would be preferable).

Location:
trunk
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/asm-watcom-x86-16.h

    r59480 r59527  
    150150/* ASMAtomicCmpXchgExU64: External assembly implementation, too few registers for parameters.  */
    151151
    152 #undef      ASMSerializeInstruction
    153 #if 1
    154 # pragma aux ASMSerializeInstruction = \
     152#undef      ASMSerializeInstructionCpuId
     153#pragma aux ASMSerializeInstructionCpuId = \
     154    ".586" \
     155    "xor eax, eax" \
     156    "cpuid" \
     157    parm [] \
     158    modify exact [ax bx cx dx];
     159
     160#undef ASMSerializeInstructionIRet
     161#pragma aux ASMSerializeInstructionIRet = \
    155162    "pushf" \
    156163    "push cs" \
     
    158165    "jmp  done" \
    159166    "foo:" \
    160     "iret" /* serializing */ \
     167    "iret" \
    161168    "done:" \
    162169    parm [] \
    163     modify exact [ax];
    164 #else
    165 # pragma aux ASMSerializeInstruction = \
    166     ".586" \
    167     "xor eax, eax" \
    168     "cpuid" \
     170    modify exact [];
     171
     172#undef      ASMSerializeInstructionRdTscp
     173#pragma aux ASMSerializeInstructionRdTscp = \
     174    0x0f 0x01 0xf9 \
    169175    parm [] \
    170     modify exact [ax bx cx dx];
    171 #endif
     176    modify exact [ax dx cx];
    172177
    173178#undef      ASMAtomicReadU64
  • trunk/include/iprt/asm-watcom-x86-32.h

    r58788 r59527  
    151151    modify exact [eax edx];
    152152
    153 #undef      ASMSerializeInstruction
    154 #pragma aux ASMSerializeInstruction = \
     153#undef      ASMSerializeInstructionCpuId
     154#pragma aux ASMSerializeInstructionCpuId = \
    155155    ".586" \
    156156    "xor eax, eax" \
     
    158158    parm [] \
    159159    modify exact [eax ebx ecx edx];
     160
     161#undef ASMSerializeInstructionIRet
     162#pragma aux ASMSerializeInstructionIRet = \
     163    "pushf" \
     164    "push cs" \
     165    "call foo" /* 'push offset done' doesn't work */ \
     166    "jmp  done" \
     167    "foo:" \
     168    "iret" \
     169    "done:" \
     170    parm [] \
     171    modify exact [];
     172
     173#undef      ASMSerializeInstructionRdTscp
     174#pragma aux ASMSerializeInstructionRdTscp = \
     175    0x0f 0x01 0xf9 \
     176    parm [] \
     177    modify exact [eax edx ecx];
    160178
    161179#undef      ASMAtomicReadU64
  • trunk/include/iprt/asm.h

    r59480 r59527  
    13731373
    13741374/**
    1375  * Serialize Instruction.
     1375 * Virtualization unfriendly serializing instruction, always exits.
    13761376 */
    13771377#if RT_INLINE_ASM_EXTERNAL && !RT_INLINE_ASM_USES_INTRIN
    1378 DECLASM(void) ASMSerializeInstruction(void);
    1379 #else
    1380 DECLINLINE(void) ASMSerializeInstruction(void)
     1378DECLASM(void) ASMSerializeInstructionCpuId(void);
     1379#else
     1380DECLINLINE(void) ASMSerializeInstructionCpuId(void)
    13811381{
    13821382# if RT_INLINE_ASM_GNU_STYLE
    13831383    RTCCUINTREG xAX = 0;
    13841384#  ifdef RT_ARCH_AMD64
    1385     __asm__ ("cpuid"
    1386              : "=a" (xAX)
    1387              : "0" (xAX)
    1388              : "rbx", "rcx", "rdx");
     1385    __asm__ __volatile__ ("cpuid"
     1386                          : "=a" (xAX)
     1387                          : "0" (xAX)
     1388                          : "rbx", "rcx", "rdx");
    13891389#  elif (defined(PIC) || defined(__PIC__)) && defined(__i386__)
    1390     __asm__ ("push  %%ebx\n\t"
    1391              "cpuid\n\t"
    1392              "pop   %%ebx\n\t"
    1393              : "=a" (xAX)
    1394              : "0" (xAX)
    1395              : "ecx", "edx");
    1396 #  else
    1397     __asm__ ("cpuid"
    1398              : "=a" (xAX)
    1399              : "0" (xAX)
    1400              : "ebx", "ecx", "edx");
     1390    __asm__ __volatile__ ("push  %%ebx\n\t"
     1391                          "cpuid\n\t"
     1392                          "pop   %%ebx\n\t"
     1393                          : "=a" (xAX)
     1394                          : "0" (xAX)
     1395                          : "ecx", "edx");
     1396#  else
     1397    __asm__ __volatile__ ("cpuid"
     1398                          : "=a" (xAX)
     1399                          : "0" (xAX)
     1400                          : "ebx", "ecx", "edx");
    14011401#  endif
    14021402
     
    14151415# endif
    14161416}
     1417#endif
     1418
     1419/**
     1420 * Virtualization friendly serializing instruction, though more expensive.
     1421 */
     1422#if RT_INLINE_ASM_EXTERNAL
     1423DECLASM(void) ASMSerializeInstructionIRet(void);
     1424#else
     1425DECLINLINE(void) ASMSerializeInstructionIRet(void)
     1426{
     1427# if RT_INLINE_ASM_GNU_STYLE
     1428#  ifdef RT_ARCH_AMD64
     1429    __asm__ __volatile__ ("movq  %%rsp,%%r10\n\t"
     1430                          "subq  $128, %%rsp\n\t" /*redzone*/
     1431                          "mov   %%ss, %%eax\n\t"
     1432                          "pushq %%rax\n\t"
     1433                          "pushq %%r10\n\t"
     1434                          "pushfq\n\t"
     1435                          "movl  %%cs, %%eax\n\t"
     1436                          "pushq %%rax\n\t"
     1437                          "leaq  1f(%%rip), %%rax\n\t"
     1438                          "pushq %%rax\n\t"
     1439                          "iretq\n\t"
     1440                          "1:\n\t"
     1441                          ::: "rax", "r10");
     1442#  else
     1443    __asm__ __volatile__ ("pushfl\n\t"
     1444                          "pushl %%cs\n\t"
     1445                          "pushl $1f\n\t"
     1446                          "iretl\n\t"
     1447                          "1:\n\t"
     1448                          :::);
     1449#  endif
     1450
     1451# else
     1452    __asm
     1453    {
     1454        pushfd
     1455        push    cs
     1456        push    la_ret
     1457        retd
     1458    la_ret:
     1459    }
     1460# endif
     1461}
     1462#endif
     1463
     1464/**
     1465 * Virtualization friendlier serializing instruction, may still cause exits.
     1466 */
     1467#if RT_INLINE_ASM_EXTERNAL && RT_INLINE_ASM_USES_INTRIN < 15
     1468DECLASM(void) ASMSerializeInstructionRdTscp(void);
     1469#else
     1470DECLINLINE(void) ASMSerializeInstructionRdTscp(void)
     1471{
     1472# if RT_INLINE_ASM_GNU_STYLE
     1473    /* rdtscp is not supported by ancient linux build VM of course :-( */
     1474#  ifdef RT_ARCH_AMD64
     1475    /*__asm__ __volatile__("rdtscp\n\t" ::: "rax", "rdx, "rcx"); */
     1476    __asm__ __volatile__(".byte 0x0f,0x01,0xf9\n\t" ::: "rax", "rdx", "rcx");
     1477#  else
     1478    /*__asm__ __volatile__("rdtscp\n\t" ::: "eax", "edx, "ecx"); */
     1479    __asm__ __volatile__(".byte 0x0f,0x01,0xf9\n\t" ::: "eax", "edx", "ecx");
     1480#  endif
     1481# else
     1482#  if RT_INLINE_ASM_USES_INTRIN >= 15
     1483    uint32_t uIgnore;
     1484    (void)__rdtscp(&uIgnore);
     1485    (void)uIgnore;
     1486#  else
     1487    __asm
     1488    {
     1489        rdtscp
     1490    }
     1491#  endif
     1492# endif
     1493}
     1494#endif
     1495
     1496
     1497/**
     1498 * Serialize Instruction.
     1499 */
     1500#if (defined(RT_ARCH_X86) && ARCH_BITS == 16) || defined(IN_GUEST)
     1501# define ASMSerializeInstruction() ASMSerializeInstructionIRet()
     1502#else
     1503# define ASMSerializeInstruction() ASMSerializeInstructionCpuId()
    14171504#endif
    14181505
  • trunk/src/VBox/Runtime/Makefile.kmk

    r59511 r59527  
    55
    66#
    7 # Copyright (C) 2006-2015 Oracle Corporation
     7# Copyright (C) 2006-2016 Oracle Corporation
    88#
    99# This file is part of VirtualBox Open Source Edition (OSE), as
     
    675675        common/asm/ASMXSave.asm \
    676676        common/asm/ASMXRstor.asm \
     677        common/asm/ASMSerializeInstruction-cpuid.asm \
     678        common/asm/ASMSerializeInstruction-iret.asm \
     679        common/asm/ASMSerializeInstruction-rdtscp.asm \
    677680        common/math/bignum-amd64-x86.asm
    678681RuntimeR3_SOURCES.amd64 += \
     
    690693        common/asm/ASMXSave.asm \
    691694        common/asm/ASMXRstor.asm \
     695        common/asm/ASMSerializeInstruction-cpuid.asm \
     696        common/asm/ASMSerializeInstruction-iret.asm \
     697        common/asm/ASMSerializeInstruction-rdtscp.asm \
    692698        common/math/bignum-amd64-x86.asm \
    693699        common/math/RTUInt128MulByU64.asm
  • trunk/src/VBox/Runtime/testcase/tstRTInlineAsm.cpp

    r57358 r59527  
    15961596    static int64_t  volatile s_i64;
    15971597    register unsigned i;
    1598     const unsigned cRounds = _2M;
     1598    const unsigned cRounds = _2M;       /* Must be multiple of 8 */
    15991599    register uint64_t u64Elapsed;
    16001600
     
    16161616        RTThreadYield(); \
    16171617        u64Elapsed = RTTimeNanoTS(); \
    1618         for (i = cRounds; i > 0; i--) \
     1618        for (i = cRounds / 8; i > 0; i--) \
     1619        { \
    16191620            op; \
     1621            op; \
     1622            op; \
     1623            op; \
     1624            op; \
     1625            op; \
     1626            op; \
     1627            op; \
     1628        } \
    16201629        u64Elapsed = RTTimeNanoTS() - u64Elapsed; \
    16211630        RTTestValue(g_hTest, str, u64Elapsed / cRounds, RTTESTUNIT_NS_PER_CALL); \
    16221631    } while (0)
     1632#endif
     1633#if (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86)) && !defined(GCC44_32BIT_PIC)
     1634# define BENCH_TSC(op, str) \
     1635    do { \
     1636        RTThreadYield(); \
     1637        u64Elapsed = ASMReadTSC(); \
     1638        for (i = cRounds / 8; i > 0; i--) \
     1639        { \
     1640            op; \
     1641            op; \
     1642            op; \
     1643            op; \
     1644            op; \
     1645            op; \
     1646            op; \
     1647            op; \
     1648        } \
     1649        u64Elapsed = ASMReadTSC() - u64Elapsed; \
     1650        RTTestValue(g_hTest, str, u64Elapsed / cRounds, /*RTTESTUNIT_TICKS_PER_CALL*/ RTTESTUNIT_NONE); \
     1651    } while (0)
     1652#else
     1653# define BENCH_TSC(op, str) BENCH(op, str)
    16231654#endif
    16241655
     
    16821713    BENCH(ASMAtomicUoAndU32(&s_u32, 0xffffffff), "ASMAtomicUoAndU32");
    16831714    BENCH(ASMAtomicUoOrU32(&s_u32, 0xffffffff),  "ASMAtomicUoOrU32");
     1715    BENCH_TSC(ASMSerializeInstructionCpuId(),    "ASMSerializeInstructionCpuId");
     1716    BENCH_TSC(ASMSerializeInstructionIRet(),     "ASMSerializeInstructionIRet");
    16841717
    16851718    /* The Darwin gcc does not like this ... */
     
    16881721#endif
    16891722#if !defined(GCC44_32BIT_PIC) && (defined(RT_ARCH_AMD64) || defined(RT_ARCH_X86))
    1690     BENCH(s_u64 = ASMReadTSC(),                 "ASMReadTSC");
    16911723    uint32_t uAux;
    16921724    if (   ASMHasCpuId()
    16931725        && ASMIsValidExtRange(ASMCpuId_EAX(0x80000000))
    16941726        && (ASMCpuId_EDX(0x80000001) & X86_CPUID_EXT_FEATURE_EDX_RDTSCP) )
     1727    {
     1728        BENCH_TSC(ASMSerializeInstructionRdTscp(), "ASMSerializeInstructionRdTscp");
    16951729        BENCH(s_u64 = ASMReadTscWithAux(&uAux),  "ASMReadTscWithAux");
     1730    }
     1731    BENCH(s_u64 = ASMReadTSC(),                 "ASMReadTSC");
    16961732    union
    16971733    {
  • trunk/src/VBox/ValidationKit/bootsectors/bs3kit/Makefile.kmk

    r59482 r59527  
    119119       ../../../Runtime/common/asm/ASMBitLastSetU32.asm \
    120120       ../../../Runtime/common/asm/ASMBitLastSetU64.asm \
     121       ../../../Runtime/common/asm/ASMSerializeInstruction-cpuid.asm \
     122       ../../../Runtime/common/asm/ASMSerializeInstruction-iret.asm \
     123       ../../../Runtime/common/asm/ASMSerializeInstruction-rdtscp.asm \
    121124
    122125# The 16-bit BS3Kit library.
Note: See TracChangeset for help on using the changeset viewer.

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