Ignore:
Timestamp:
Mar 26, 2018, 2:07:21 PM (7 years ago)
Author:
Yusuke Suzuki
Message:

We should have SSE4 detection in the X86 MacroAssembler.
https://bugs.webkit.org/show_bug.cgi?id=165363

Reviewed by JF Bastien.

Source/JavaScriptCore:

This patch adds popcnt support to WASM in x86_64 environment.
To use it, we refactor our CPUID feature detection in MacroAssemblerX86Common.
Our spec-tests already cover popcnt.

  • assembler/MacroAssemblerARM64.h:

(JSC::MacroAssemblerARM64::supportsCountPopulation):

  • assembler/MacroAssemblerX86Common.cpp:

(JSC::MacroAssemblerX86Common::getCPUID):
(JSC::MacroAssemblerX86Common::getCPUIDEx):
(JSC::MacroAssemblerX86Common::collectCPUFeatures):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::countPopulation32):
(JSC::MacroAssemblerX86Common::supportsFloatingPointRounding):
(JSC::MacroAssemblerX86Common::supportsCountPopulation):
(JSC::MacroAssemblerX86Common::supportsAVX):
(JSC::MacroAssemblerX86Common::supportsLZCNT):
(JSC::MacroAssemblerX86Common::supportsBMI1):
(JSC::MacroAssemblerX86Common::isSSE2Present):
(JSC::MacroAssemblerX86Common::updateEax1EcxFlags): Deleted.

  • assembler/MacroAssemblerX86_64.h:

(JSC::MacroAssemblerX86_64::countPopulation64):

  • assembler/X86Assembler.h:

(JSC::X86Assembler::popcnt_rr):
(JSC::X86Assembler::popcnt_mr):
(JSC::X86Assembler::popcntq_rr):
(JSC::X86Assembler::popcntq_mr):

  • wasm/WasmB3IRGenerator.cpp:

(JSC::Wasm::B3IRGenerator::addOp<OpType::I32Popcnt>):
(JSC::Wasm::B3IRGenerator::addOp<OpType::I64Popcnt>):

Source/WTF:

GCC 5 supports clobbering PIC registers in inline ASM [1,2].

[1]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=47602
[2]: https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=216154

  • wtf/Atomics.h:

(WTF::x86_cpuid):

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.cpp

    r229609 r229988  
    3131#include "ProbeContext.h"
    3232#include <wtf/InlineASM.h>
     33
     34#if COMPILER(MSVC)
     35#include <intrin.h>
     36#endif
    3337
    3438namespace JSC {
     
    758762#endif // ENABLE(MASM_PROBE)
    759763
    760 #if CPU(X86) && !OS(MAC_OS_X)
    761 MacroAssemblerX86Common::SSE2CheckState MacroAssemblerX86Common::s_sse2CheckState = NotCheckedSSE2;
     764MacroAssemblerX86Common::CPUID MacroAssemblerX86Common::getCPUID(unsigned level)
     765{
     766    return getCPUIDEx(level, 0);
     767}
     768
     769MacroAssemblerX86Common::CPUID MacroAssemblerX86Common::getCPUIDEx(unsigned level, unsigned count)
     770{
     771    CPUID result { };
     772#if COMPILER(MSVC)
     773    __cpuidex(bitwise_cast<int*>(result.data()), level, count);
     774#else
     775    __asm__ (
     776        "cpuid\n"
     777        : "=a"(result[0]), "=b"(result[1]), "=c"(result[2]), "=d"(result[3])
     778        : "0"(level), "2"(count)
     779    );
    762780#endif
    763 
     781    return result;
     782}
     783
     784void MacroAssemblerX86Common::collectCPUFeatures()
     785{
     786    static std::once_flag onceKey;
     787    std::call_once(onceKey, [] {
     788        {
     789            CPUID cpuid = getCPUID(0x1);
     790            s_sse2CheckState = (cpuid[3] & (1 << 26)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
     791            s_sse4_1CheckState = (cpuid[2] & (1 << 19)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
     792            s_sse4_2CheckState = (cpuid[2] & (1 << 20)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
     793            s_popcntCheckState = (cpuid[2] & (1 << 23)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
     794            s_avxCheckState = (cpuid[2] & (1 << 28)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
     795        }
     796        {
     797            CPUID cpuid = getCPUID(0x7);
     798            s_bmi1CheckState = (cpuid[2] & (1 << 3)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
     799        }
     800        {
     801            CPUID cpuid = getCPUID(0x80000001);
     802            s_lzcntCheckState = (cpuid[2] & (1 << 5)) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
     803        }
     804    });
     805}
     806
     807MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_sse2CheckState = CPUIDCheckState::NotChecked;
    764808MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_sse4_1CheckState = CPUIDCheckState::NotChecked;
     809MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_sse4_2CheckState = CPUIDCheckState::NotChecked;
    765810MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_avxCheckState = CPUIDCheckState::NotChecked;
    766811MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_lzcntCheckState = CPUIDCheckState::NotChecked;
    767812MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_bmi1CheckState = CPUIDCheckState::NotChecked;
     813MacroAssemblerX86Common::CPUIDCheckState MacroAssemblerX86Common::s_popcntCheckState = CPUIDCheckState::NotChecked;
    768814
    769815} // namespace JSC
Note: See TracChangeset for help on using the changeset viewer.