Changeset 167557 in webkit


Ignore:
Timestamp:
Apr 19, 2014 6:22:06 PM (10 years ago)
Author:
benjamin@webkit.org
Message:

Make the CSS JIT compile for ARM64
https://bugs.webkit.org/show_bug.cgi?id=131834

Patch by Benjamin Poulain <bpoulain@apple.com> on 2014-04-19
Reviewed by Gavin Barraclough.

Source/JavaScriptCore:
Extend the ARM64 MacroAssembler to support the code generation required by
the CSS JIT.

  • assembler/MacroAssembler.h:
  • assembler/MacroAssemblerARM64.h:

(JSC::MacroAssemblerARM64::addPtrNoFlags):
(JSC::MacroAssemblerARM64::or32):
(JSC::MacroAssemblerARM64::branchPtr):
(JSC::MacroAssemblerARM64::test32):
(JSC::MacroAssemblerARM64::branch):

  • assembler/MacroAssemblerX86Common.h:

(JSC::MacroAssemblerX86Common::test32):

Source/WebCore:
Add the CPU specific code required to compile SelectorCompiler on ARM64.
The code is absolutely non-functional, it would crash immediately, but it compiles.

  • cssjit/FunctionCall.h:

(WebCore::FunctionCall::FunctionCall):
(WebCore::FunctionCall::callAndBranchOnCondition):

  • cssjit/RegisterAllocator.h:

What am I supposed to do with all those registers? There are so many of them :)
The array calleeSavedRegisters is defined for compatibility but it cannot be reached at the moment.

(WebCore::RegisterAllocator::isValidRegister):

  • cssjit/SelectorCompiler.cpp:

(WebCore::SelectorCompiler::SelectorCodeGenerator::modulo):
Implement modulo by doing dividend - (divisor * int(dividend/divisor)).

  • cssjit/StackAllocator.h:

StackAllocator will need a small redesign to handle the 16 bytes alligned stack of
ARM64.
The code has been modified to build but it is pretty useless.

(WebCore::StackAllocator::allocateUninitialized):
(WebCore::StackAllocator::push):
(WebCore::StackAllocator::pop):
(WebCore::StackAllocator::popAndDiscard):
(WebCore::StackAllocator::popAndDiscardUpTo):
(WebCore::StackAllocator::alignStackPreFunctionCall):
(WebCore::StackAllocator::unalignStackPostFunctionCall):

Location:
trunk/Source
Files:
9 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/ChangeLog

    r167550 r167557  
     12014-04-19  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        Make the CSS JIT compile for ARM64
     4        https://bugs.webkit.org/show_bug.cgi?id=131834
     5
     6        Reviewed by Gavin Barraclough.
     7
     8        Extend the ARM64 MacroAssembler to support the code generation required by
     9        the CSS JIT.
     10
     11        * assembler/MacroAssembler.h:
     12        * assembler/MacroAssemblerARM64.h:
     13        (JSC::MacroAssemblerARM64::addPtrNoFlags):
     14        (JSC::MacroAssemblerARM64::or32):
     15        (JSC::MacroAssemblerARM64::branchPtr):
     16        (JSC::MacroAssemblerARM64::test32):
     17        (JSC::MacroAssemblerARM64::branch):
     18        * assembler/MacroAssemblerX86Common.h:
     19        (JSC::MacroAssemblerX86Common::test32):
     20
    1212014-04-19  Andreas Kling  <akling@apple.com>
    222
  • trunk/Source/JavaScriptCore/assembler/MacroAssembler.h

    r165683 r167557  
    118118    using MacroAssemblerBase::branchAdd32;
    119119    using MacroAssemblerBase::branchMul32;
    120 #if CPU(X86_64)
     120#if CPU(ARM64) || CPU(X86_64)
    121121    using MacroAssemblerBase::branchPtr;
    122122#endif // CPU(X86_64)
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerARM64.h

    r167347 r167557  
    290290    }
    291291
     292    void addPtrNoFlags(TrustedImm32 imm, RegisterID srcDest)
     293    {
     294        add64(imm, srcDest);
     295    }
     296
    292297    void add64(Address src, RegisterID dest)
    293298    {
     
    471476        m_assembler.orr<32>(dataTempRegister, dataTempRegister, src);
    472477        store32(dataTempRegister, address.m_ptr);
     478    }
     479
     480    void or32(TrustedImm32 imm, Address address)
     481    {
     482        load32(address, getCachedDataTempRegisterIDAndInvalidate());
     483        or32(imm, dataTempRegister, dataTempRegister);
     484        store32(dataTempRegister, address);
    473485    }
    474486
     
    16521664    }
    16531665
     1666    Jump branchPtr(RelationalCondition cond, BaseIndex left, RegisterID right)
     1667    {
     1668        load64(left, getCachedMemoryTempRegisterIDAndInvalidate());
     1669        return branch64(cond, memoryTempRegister, right);
     1670    }
     1671
    16541672    Jump branch8(RelationalCondition cond, Address left, TrustedImm32 right)
    16551673    {
     
    16761694    {
    16771695        m_assembler.tst<32>(reg, mask);
     1696        return Jump(makeBranch(cond));
     1697    }
     1698
     1699    void test32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
     1700    {
     1701        if (mask.m_value == -1)
     1702            m_assembler.tst<32>(reg, reg);
     1703        else {
     1704            bool testedWithImmediate = false;
     1705            if ((cond == Zero) || (cond == NonZero)) {
     1706                LogicalImmediate logicalImm = LogicalImmediate::create32(mask.m_value);
     1707
     1708                if (logicalImm.isValid()) {
     1709                    m_assembler.tst<32>(reg, logicalImm);
     1710                    testedWithImmediate = true;
     1711                }
     1712            }
     1713            if (!testedWithImmediate) {
     1714                move(mask, getCachedDataTempRegisterIDAndInvalidate());
     1715                m_assembler.tst<32>(reg, dataTempRegister);
     1716            }
     1717        }
     1718    }
     1719
     1720    Jump branch(ResultCondition cond)
     1721    {
    16781722        return Jump(makeBranch(cond));
    16791723    }
  • trunk/Source/JavaScriptCore/assembler/MacroAssemblerX86Common.h

    r165009 r167557  
    11461146    }
    11471147
    1148     void test32(RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
     1148    void test32(ResultCondition, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
    11491149    {
    11501150        if (mask.m_value == -1)
     
    11661166    Jump branchTest32(ResultCondition cond, RegisterID reg, TrustedImm32 mask = TrustedImm32(-1))
    11671167    {
    1168         test32(reg, mask);
     1168        test32(cond, reg, mask);
    11691169        return branch(cond);
    11701170    }
  • trunk/Source/WebCore/ChangeLog

    r167553 r167557  
     12014-04-19  Benjamin Poulain  <bpoulain@apple.com>
     2
     3        Make the CSS JIT compile for ARM64
     4        https://bugs.webkit.org/show_bug.cgi?id=131834
     5
     6        Reviewed by Gavin Barraclough.
     7
     8        Add the CPU specific code required to compile SelectorCompiler on ARM64.
     9        The code is absolutely non-functional, it would crash immediately, but it compiles.
     10
     11        * cssjit/FunctionCall.h:
     12        (WebCore::FunctionCall::FunctionCall):
     13        (WebCore::FunctionCall::callAndBranchOnCondition):
     14        * cssjit/RegisterAllocator.h:
     15        What am I supposed to do with all those registers? There are so many of them :)
     16        The array calleeSavedRegisters is defined for compatibility but it cannot be reached at the moment.
     17
     18        (WebCore::RegisterAllocator::isValidRegister):
     19        * cssjit/SelectorCompiler.cpp:
     20        (WebCore::SelectorCompiler::SelectorCodeGenerator::modulo):
     21        Implement modulo by doing dividend - (divisor * int(dividend/divisor)).
     22
     23        * cssjit/StackAllocator.h:
     24        StackAllocator will need a small redesign to handle the 16 bytes alligned stack of
     25        ARM64.
     26        The code has been modified to build but it is pretty useless.
     27
     28        (WebCore::StackAllocator::allocateUninitialized):
     29        (WebCore::StackAllocator::push):
     30        (WebCore::StackAllocator::pop):
     31        (WebCore::StackAllocator::popAndDiscard):
     32        (WebCore::StackAllocator::popAndDiscardUpTo):
     33        (WebCore::StackAllocator::alignStackPreFunctionCall):
     34        (WebCore::StackAllocator::unalignStackPostFunctionCall):
     35
    1362014-04-19  Simon Fraser  <simon.fraser@apple.com>
    237
  • trunk/Source/WebCore/cssjit/FunctionCall.h

    r166666 r167557  
    3838class FunctionCall {
    3939public:
    40     FunctionCall(JSC::MacroAssembler& assembler, const RegisterAllocator& registerAllocator, StackAllocator& stackAllocator, Vector<std::pair<JSC::MacroAssembler::Call, JSC::FunctionPtr>>& callRegistry)
     40    FunctionCall(JSC::MacroAssembler& assembler, RegisterAllocator& registerAllocator, StackAllocator& stackAllocator, Vector<std::pair<JSC::MacroAssembler::Call, JSC::FunctionPtr>>& callRegistry)
    4141        : m_assembler(assembler)
    4242        , m_registerAllocator(registerAllocator)
     
    7676    {
    7777        prepareAndCall();
    78         m_assembler.test32(JSC::GPRInfo::returnValueGPR, JSC::MacroAssembler::TrustedImm32(0xff));
     78        m_assembler.test32(condition, JSC::GPRInfo::returnValueGPR, JSC::MacroAssembler::TrustedImm32(0xff));
    7979        cleanupPostCall();
    8080        return m_assembler.branch(condition);
     
    184184
    185185    JSC::MacroAssembler& m_assembler;
    186     const RegisterAllocator& m_registerAllocator;
     186    RegisterAllocator& m_registerAllocator;
    187187    StackAllocator& m_stackAllocator;
    188188    Vector<std::pair<JSC::MacroAssembler::Call, JSC::FunctionPtr>>& m_callRegistry;
  • trunk/Source/WebCore/cssjit/RegisterAllocator.h

    r167218 r167557  
    3636namespace WebCore {
    3737
    38 #if CPU(X86_64)
     38#if CPU(ARM64)
     39static const JSC::MacroAssembler::RegisterID callerSavedRegisters[] = {
     40    JSC::ARM64Registers::x0,
     41    JSC::ARM64Registers::x1,
     42    JSC::ARM64Registers::x2,
     43    JSC::ARM64Registers::x3,
     44    JSC::ARM64Registers::x4,
     45    JSC::ARM64Registers::x5,
     46    JSC::ARM64Registers::x6,
     47    JSC::ARM64Registers::x7,
     48    JSC::ARM64Registers::x8,
     49    JSC::ARM64Registers::x9,
     50    JSC::ARM64Registers::x10,
     51    JSC::ARM64Registers::x11,
     52    JSC::ARM64Registers::x12,
     53    JSC::ARM64Registers::x13,
     54    JSC::ARM64Registers::x14,
     55    JSC::ARM64Registers::x15,
     56};
     57static const JSC::MacroAssembler::RegisterID calleeSavedRegisters[] = {
     58    JSC::ARM64Registers::x19
     59};
     60#elif CPU(X86_64)
    3961static const JSC::MacroAssembler::RegisterID callerSavedRegisters[] = {
    4062    JSC::X86Registers::eax,
     
    5476    JSC::X86Registers::r15
    5577};
    56 static const unsigned registerCount = WTF_ARRAY_LENGTH(callerSavedRegisters) + WTF_ARRAY_LENGTH(calleeSavedRegisters);
    5778#else
    5879#error RegisterAllocator has no defined registers for the architecture.
    5980#endif
     81static const unsigned registerCount = WTF_ARRAY_LENGTH(callerSavedRegisters) + WTF_ARRAY_LENGTH(calleeSavedRegisters);
    6082
    6183class RegisterAllocator {
     
    117139    static bool isValidRegister(JSC::MacroAssembler::RegisterID registerID)
    118140    {
    119 #if CPU(X86_64)
     141#if CPU(ARM64)
     142        return registerID >= JSC::ARM64Registers::x0 && registerID <= JSC::ARM64Registers::x15;
     143#elif CPU(X86_64)
    120144        return registerID >= JSC::X86Registers::eax && registerID <= JSC::X86Registers::r15;
    121145#else
  • trunk/Source/WebCore/cssjit/SelectorCompiler.cpp

    r167218 r167557  
    145145
    146146private:
    147 #if CPU(X86_64)
    148     static const Assembler::RegisterID returnRegister = JSC::X86Registers::eax;
    149     static const Assembler::RegisterID elementAddressRegister = JSC::X86Registers::edi;
    150     static const Assembler::RegisterID checkingContextRegister = JSC::X86Registers::esi;
    151 #endif
     147    static const Assembler::RegisterID returnRegister = JSC::GPRInfo::returnValueGPR;
     148    static const Assembler::RegisterID elementAddressRegister = JSC::GPRInfo::argumentGPR0;
     149    static const Assembler::RegisterID checkingContextRegister = JSC::GPRInfo::argumentGPR1;
    152150
    153151    void computeBacktrackingInformation();
     
    929927{
    930928    RELEASE_ASSERT(divisor);
    931 #if CPU(X86_64)
     929#if CPU(ARM64)
     930    LocalRegister divisorRegister(m_registerAllocator);
     931    m_assembler.move(Assembler::TrustedImm32(divisor), divisorRegister);
     932
     933    LocalRegister resultRegister(m_registerAllocator);
     934    m_assembler.m_assembler.sdiv<32>(resultRegister, inputDividend, divisorRegister);
     935    m_assembler.mul32(divisorRegister, resultRegister);
     936    return m_assembler.branchSub32(condition, inputDividend, resultRegister, resultRegister);
     937#elif CPU(X86_64)
    932938    // idiv takes RAX + an arbitrary register, and return RAX + RDX. Most of this code is about doing
    933939    // an efficient allocation of those registers. If a register is already in use and is not the inputDividend,
     
    991997        m_assembler.move(Assembler::TrustedImm64(divisor), divisorRegister);
    992998        m_assembler.m_assembler.idivl_r(divisorRegister);
    993         m_assembler.test32(remainder);
     999        m_assembler.test32(condition, remainder);
    9941000    }
    9951001
  • trunk/Source/WebCore/cssjit/StackAllocator.h

    r166834 r167557  
    6464    {
    6565        RELEASE_ASSERT(!m_hasFunctionCallPadding);
    66         m_assembler.addPtrNoFlags(JSC::MacroAssembler::TrustedImm32(-8), JSC::MacroAssembler::stackPointerRegister);
    67         m_offsetFromTop += 8;
     66        m_assembler.addPtrNoFlags(JSC::MacroAssembler::TrustedImm32(-stackUnitInBytes), JSC::MacroAssembler::stackPointerRegister);
     67        m_offsetFromTop += stackUnitInBytes;
    6868        return StackReference(m_offsetFromTop);
    6969    }
    7070
     71    // FIXME: ARM64 needs an API take a list of register to push and pop to use strp and ldrp when possible.
    7172    StackReference push(JSC::MacroAssembler::RegisterID registerID)
    7273    {
    7374        RELEASE_ASSERT(!m_hasFunctionCallPadding);
     75#if CPU(ARM64)
     76        m_assembler.m_assembler.str<64>(registerID, JSC::ARM64Registers::sp, JSC::PreIndex(-16));
     77#else
    7478        m_assembler.push(registerID);
    75         m_offsetFromTop += 8;
     79#endif
     80        m_offsetFromTop += stackUnitInBytes;
    7681        return StackReference(m_offsetFromTop);
    7782    }
     
    8287        RELEASE_ASSERT(!m_hasFunctionCallPadding);
    8388        ASSERT(m_offsetFromTop > 0);
    84         m_offsetFromTop -= 8;
     89        m_offsetFromTop -= stackUnitInBytes;
     90#if CPU(ARM64)
     91        m_assembler.m_assembler.ldr<64>(registerID, JSC::ARM64Registers::sp, JSC::PostIndex(16));
     92#else
    8593        m_assembler.pop(registerID);
     94#endif
    8695    }
    8796
     
    8998    {
    9099        RELEASE_ASSERT(stackReference == m_offsetFromTop);
    91         m_assembler.addPtr(JSC::MacroAssembler::TrustedImm32(8), JSC::MacroAssembler::stackPointerRegister);
    92         m_offsetFromTop -= 8;
     100        m_assembler.addPtr(JSC::MacroAssembler::TrustedImm32(stackUnitInBytes), JSC::MacroAssembler::stackPointerRegister);
     101        m_offsetFromTop -= stackUnitInBytes;
    93102    }
    94103
    95104    void popAndDiscardUpTo(StackReference stackReference)
    96105    {
    97         unsigned positionBeforeStackReference = stackReference - 8;
     106        unsigned positionBeforeStackReference = stackReference - stackUnitInBytes;
    98107        RELEASE_ASSERT(positionBeforeStackReference < m_offsetFromTop);
    99108
     
    105114    void alignStackPreFunctionCall()
    106115    {
     116#if CPU(X86_64)
    107117        RELEASE_ASSERT(!m_hasFunctionCallPadding);
    108         unsigned topAlignment = 8;
     118        unsigned topAlignment = stackUnitInBytes;
    109119        if ((topAlignment + m_offsetFromTop) % 16) {
    110120            m_hasFunctionCallPadding = true;
    111             m_assembler.addPtrNoFlags(JSC::MacroAssembler::TrustedImm32(-8), JSC::MacroAssembler::stackPointerRegister);
     121            m_assembler.addPtrNoFlags(JSC::MacroAssembler::TrustedImm32(-stackUnitInBytes), JSC::MacroAssembler::stackPointerRegister);
    112122        }
     123#endif
    113124    }
    114125
    115126    void unalignStackPostFunctionCall()
    116127    {
     128#if CPU(X86_64)
    117129        if (m_hasFunctionCallPadding) {
    118             m_assembler.addPtrNoFlags(JSC::MacroAssembler::TrustedImm32(8), JSC::MacroAssembler::stackPointerRegister);
     130            m_assembler.addPtrNoFlags(JSC::MacroAssembler::TrustedImm32(stackUnitInBytes), JSC::MacroAssembler::stackPointerRegister);
    119131            m_hasFunctionCallPadding = false;
    120132        }
     133#endif
    121134    }
    122135
     
    160173
    161174private:
     175#if CPU(ARM64)
     176    static const unsigned stackUnitInBytes = 16;
     177#elif CPU(X86_64)
     178    static const unsigned stackUnitInBytes = 8;
     179#else
     180#error Stack Unit Size is undefined.
     181#endif
     182
    162183    void reset()
    163184    {
Note: See TracChangeset for help on using the changeset viewer.