Changeset 237136 in webkit


Ignore:
Timestamp:
Oct 15, 2018 12:47:09 PM (6 years ago)
Author:
sbarati@apple.com
Message:

Emit fjcvtzs on ARM64E on Darwin
https://bugs.webkit.org/show_bug.cgi?id=184023

Reviewed by Yusuke Suzuki and Filip Pizlo.

JSTests:

  • stress/double-to-int32-NaN.js: Added.

(assert):
(foo):

Source/JavaScriptCore:

ARMv8.3 introduced the fjcvtzs instruction which does double->int32
conversion using the semantics defined by JavaScript:
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0801g/hko1477562192868.html
This patch teaches JSC to use that instruction when possible.

  • assembler/ARM64Assembler.h:

(JSC::ARM64Assembler::fjcvtzs):
(JSC::ARM64Assembler::fjcvtzsInsn):

  • assembler/MacroAssemblerARM64.cpp:

(JSC::MacroAssemblerARM64::collectCPUFeatures):

  • assembler/MacroAssemblerARM64.h:

(JSC::MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics):
(JSC::MacroAssemblerARM64::convertDoubleToInt32UsingJavaScriptSemantics):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileValueToInt32):

  • disassembler/ARM64/A64DOpcode.cpp:
  • disassembler/ARM64/A64DOpcode.h:

(JSC::ARM64Disassembler::A64DOpcode::appendInstructionName):

  • ftl/FTLLowerDFGToB3.cpp:

(JSC::FTL::DFG::LowerDFGToB3::doubleToInt32):

  • jit/JITRightShiftGenerator.cpp:

(JSC::JITRightShiftGenerator::generateFastPath):

  • runtime/MathCommon.h:

(JSC::toInt32):

Source/WTF:

  • wtf/Platform.h:
Location:
trunk
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/JSTests/ChangeLog

    r237129 r237136  
     12018-10-15  Saam barati  <sbarati@apple.com>
     2
     3        Emit fjcvtzs on ARM64E on Darwin
     4        https://bugs.webkit.org/show_bug.cgi?id=184023
     5
     6        Reviewed by Yusuke Suzuki and Filip Pizlo.
     7
     8        * stress/double-to-int32-NaN.js: Added.
     9        (assert):
     10        (foo):
     11
    1122018-10-15  Saam Barati  <sbarati@apple.com>
    213
  • trunk/Source/JavaScriptCore/ChangeLog

    r237129 r237136  
     12018-10-15  Saam barati  <sbarati@apple.com>
     2
     3        Emit fjcvtzs on ARM64E on Darwin
     4        https://bugs.webkit.org/show_bug.cgi?id=184023
     5
     6        Reviewed by Yusuke Suzuki and Filip Pizlo.
     7
     8        ARMv8.3 introduced the fjcvtzs instruction which does double->int32
     9        conversion using the semantics defined by JavaScript:
     10        http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0801g/hko1477562192868.html
     11        This patch teaches JSC to use that instruction when possible.
     12
     13        * assembler/ARM64Assembler.h:
     14        (JSC::ARM64Assembler::fjcvtzs):
     15        (JSC::ARM64Assembler::fjcvtzsInsn):
     16        * assembler/MacroAssemblerARM64.cpp:
     17        (JSC::MacroAssemblerARM64::collectCPUFeatures):
     18        * assembler/MacroAssemblerARM64.h:
     19        (JSC::MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics):
     20        (JSC::MacroAssemblerARM64::convertDoubleToInt32UsingJavaScriptSemantics):
     21        * dfg/DFGSpeculativeJIT.cpp:
     22        (JSC::DFG::SpeculativeJIT::compileValueToInt32):
     23        * disassembler/ARM64/A64DOpcode.cpp:
     24        * disassembler/ARM64/A64DOpcode.h:
     25        (JSC::ARM64Disassembler::A64DOpcode::appendInstructionName):
     26        * ftl/FTLLowerDFGToB3.cpp:
     27        (JSC::FTL::DFG::LowerDFGToB3::doubleToInt32):
     28        * jit/JITRightShiftGenerator.cpp:
     29        (JSC::JITRightShiftGenerator::generateFastPath):
     30        * runtime/MathCommon.h:
     31        (JSC::toInt32):
     32
    1332018-10-15  Saam Barati  <sbarati@apple.com>
    234
  • trunk/Source/JavaScriptCore/assembler/ARM64Assembler.h

    r236589 r237136  
    25342534    }
    25352535
     2536    ALWAYS_INLINE void fjcvtzs(RegisterID rd, FPRegisterID dn)
     2537    {
     2538        insn(fjcvtzsInsn(dn, rd));
     2539    }
     2540
    25362541    // Admin methods:
    25372542
     
    37453750        return 0x08007c00 | size << 30 | result << 16 | fence << 15 | dst << 5 | src;
    37463751    }
    3747    
     3752
     3753    static int fjcvtzsInsn(FPRegisterID dn, RegisterID rd)
     3754    {
     3755        return 0x1e7e0000 | (dn << 5) | rd;
     3756    }
     3757
    37483758    // Workaround for Cortex-A53 erratum (835769). Emit an extra nop if the
    37493759    // last instruction in the buffer is a load, store or prefetch. Needed
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.cpp

    r236450 r237136  
    534534void MacroAssemblerARM64::collectCPUFeatures()
    535535{
     536#if OS(LINUX)
    536537    static std::once_flag onceKey;
    537538    std::call_once(onceKey, [] {
    538 #if OS(LINUX)
    539539        // A register for describing ARM64 CPU features are only accessible in kernel mode.
    540540        // Thus, some kernel support is necessary to collect CPU features. In Linux, the
     
    552552
    553553        s_jscvtCheckState = (hwcaps & HWCAP_JSCVT) ? CPUIDCheckState::Set : CPUIDCheckState::Clear;
     554    });
     555#elif HAVE(FJCVTZS_INSTRUCTION)
     556    s_jscvtCheckState = CPUIDCheckState::Set;
    554557#else
    555         s_jscvtCheckState = CPUIDCheckState::Clear;
     558    s_jscvtCheckState = CPUIDCheckState::Clear;
    556559#endif
    557     });
    558560}
    559561
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h

    r236589 r237136  
    37593759        m_assembler.eor<64>(dest, src, src);
    37603760    }
     3761
     3762    ALWAYS_INLINE static bool supportsDoubleToInt32ConversionUsingJavaScriptSemantics()
     3763    {
     3764#if HAVE(FJCVTZS_INSTRUCTION)
     3765        return true;
     3766#else
     3767        if (s_jscvtCheckState == CPUIDCheckState::NotChecked)
     3768            collectCPUFeatures();
     3769
     3770        return s_jscvtCheckState == CPUIDCheckState::Set;
     3771#endif
     3772    }
     3773
     3774    void convertDoubleToInt32UsingJavaScriptSemantics(FPRegisterID src, RegisterID dest)
     3775    {
     3776        m_assembler.fjcvtzs(dest, src); // This zero extends.
     3777    }
    37613778   
    37623779#if ENABLE(FAST_TLS_JIT)
  • trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp

    r236901 r237136  
    23452345        FPRReg fpr = op1.fpr();
    23462346        GPRReg gpr = result.gpr();
    2347         JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
    2348        
    2349         addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this,
    2350             hasSensibleDoubleToInt() ? operationToInt32SensibleSlow : operationToInt32, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded, gpr, fpr));
    2351        
     2347#if CPU(ARM64)
     2348        if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics())
     2349            m_jit.convertDoubleToInt32UsingJavaScriptSemantics(fpr, gpr);
     2350        else
     2351#endif
     2352        {
     2353            JITCompiler::Jump notTruncatedToInteger = m_jit.branchTruncateDoubleToInt32(fpr, gpr, JITCompiler::BranchIfTruncateFailed);
     2354            addSlowPathGenerator(slowPathCall(notTruncatedToInteger, this,
     2355                hasSensibleDoubleToInt() ? operationToInt32SensibleSlow : operationToInt32, NeedToSpill, ExceptionCheckRequirement::CheckNotNeeded, gpr, fpr));
     2356        }
    23522357        int32Result(gpr, node);
    23532358        return;
     
    23962401            // First, if we get here we have a double encoded as a JSValue
    23972402            unboxDouble(gpr, resultGpr, fpr);
    2398 
    2399             silentSpillAllRegisters(resultGpr);
    2400             callOperation(operationToInt32, resultGpr, fpr);
    2401             silentFillAllRegisters();
     2403#if CPU(ARM64)
     2404            if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics())
     2405                m_jit.convertDoubleToInt32UsingJavaScriptSemantics(fpr, resultGpr);
     2406            else
     2407#endif
     2408            {
     2409                silentSpillAllRegisters(resultGpr);
     2410                callOperation(operationToInt32, resultGpr, fpr);
     2411                silentFillAllRegisters();
     2412            }
    24022413
    24032414            converted.append(m_jit.jump());
  • trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.cpp

    r214416 r237136  
    819819    "fcvtps", "fcvtpu", 0, 0, 0, 0, "fmov", "fmov",
    820820    "fcvtms", "fcvtmu", 0, 0, 0, 0, 0, 0,
    821     "fcvtzs", "fcvtzu", 0, 0, 0, 0, 0, 0
     821    "fcvtzs", "fcvtzu", 0, 0, 0, 0, "fjcvtzs", 0
    822822};
    823823
  • trunk/Source/JavaScriptCore/disassembler/ARM64/A64DOpcode.h

    r214416 r237136  
    116116    void appendInstructionName(const char* instructionName)
    117117    {
    118         bufferPrintf("   %-7.7s", instructionName);
     118        bufferPrintf("   %-8.8s", instructionName);
    119119    }
    120120
  • trunk/Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp

    r236901 r237136  
    1442814428    LValue doubleToInt32(LValue doubleValue)
    1442914429    {
     14430#if CPU(ARM64)
     14431        if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics()) {
     14432            PatchpointValue* patchpoint = m_out.patchpoint(Int32);
     14433            patchpoint->append(ConstrainedValue(doubleValue, B3::ValueRep::SomeRegister));
     14434            patchpoint->setGenerator([=] (CCallHelpers& jit, const StackmapGenerationParams& params) {
     14435                jit.convertDoubleToInt32UsingJavaScriptSemantics(params[1].fpr(), params[0].gpr());
     14436            });
     14437            patchpoint->effects = Effects::none();
     14438            return patchpoint;
     14439        }
     14440#endif
     14441
    1443014442        if (hasSensibleDoubleToInt())
    1443114443            return sensibleDoubleToInt32(doubleValue);
  • trunk/Source/JavaScriptCore/jit/JITRightShiftGenerator.cpp

    r226440 r237136  
    7171
    7272            jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
    73             m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
     73#if CPU(ARM64)
     74            if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics())
     75                jit.convertDoubleToInt32UsingJavaScriptSemantics(m_leftFPR, m_scratchGPR);
     76            else
     77#endif
     78            {
     79                m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
     80            }
    7481
    7582            if (shiftAmount) {
     
    123130            m_slowPathJumpList.append(jit.branchIfNotNumber(m_left, m_scratchGPR));
    124131            jit.unboxDoubleNonDestructive(m_left, m_leftFPR, m_scratchGPR, m_scratchFPR);
    125             m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
     132#if CPU(ARM64)
     133            if (MacroAssemblerARM64::supportsDoubleToInt32ConversionUsingJavaScriptSemantics())
     134                jit.convertDoubleToInt32UsingJavaScriptSemantics(m_leftFPR, m_scratchGPR);
     135            else
     136#endif
     137            {
     138                m_slowPathJumpList.append(jit.branchTruncateDoubleToInt32(m_leftFPR, m_scratchGPR));
     139            }
    126140
    127141            if (m_shiftType == SignedShift)
  • trunk/Source/JavaScriptCore/runtime/MathCommon.h

    r236240 r237136  
    140140ALWAYS_INLINE int32_t toInt32(double number)
    141141{
     142#if HAVE(FJCVTZS_INSTRUCTION)
     143    int32_t result = 0;
     144    __asm__ ("fjcvtzs %w0, %d1" : "=r" (result) : "w" (number) : "cc");
     145    return result;
     146#else
    142147    return toInt32Internal<ToInt32Mode::Generic>(number);
     148#endif
    143149}
    144150
  • trunk/Source/WTF/ChangeLog

    r237099 r237136  
     12018-10-15  Saam barati  <sbarati@apple.com>
     2
     3        Emit fjcvtzs on ARM64E on Darwin
     4        https://bugs.webkit.org/show_bug.cgi?id=184023
     5
     6        Reviewed by Yusuke Suzuki and Filip Pizlo.
     7
     8        * wtf/Platform.h:
     9
    1102018-10-15  Alex Christensen  <achristensen@webkit.org>
    211
  • trunk/Source/WTF/wtf/Platform.h

    r237099 r237136  
    10431043#endif
    10441044
     1045#if CPU(ARM64E) && OS(DARWIN)
     1046#define HAVE_FJCVTZS_INSTRUCTION 1
     1047#endif
     1048
    10451049#if PLATFORM(IOS_FAMILY)
    10461050#if !PLATFORM(WATCHOS) && !PLATFORM(APPLETV) && !PLATFORM(IOSMAC)
Note: See TracChangeset for help on using the changeset viewer.