Ignore:
Timestamp:
Oct 15, 2013, 3:16:39 PM (12 years ago)
Author:
[email protected]
Message:

[iOS] Upstream JavaScriptCore support for ARM64
https://bugs.webkit.org/show_bug.cgi?id=122762

Source/JavaScriptCore:

Reviewed by Oliver Hunt and Filip Pizlo.

  • Configurations/Base.xcconfig:
  • Configurations/DebugRelease.xcconfig:
  • Configurations/JavaScriptCore.xcconfig:
  • Configurations/ToolExecutable.xcconfig:
  • JavaScriptCore.xcodeproj/project.pbxproj:
  • assembler/ARM64Assembler.h: Added.
  • assembler/AbstractMacroAssembler.h:

(JSC::isARM64):
(JSC::AbstractMacroAssembler::Label::Label):
(JSC::AbstractMacroAssembler::Jump::Jump):
(JSC::AbstractMacroAssembler::Jump::link):
(JSC::AbstractMacroAssembler::Jump::linkTo):
(JSC::AbstractMacroAssembler::CachedTempRegister::CachedTempRegister):
(JSC::AbstractMacroAssembler::CachedTempRegister::registerIDInvalidate):
(JSC::AbstractMacroAssembler::CachedTempRegister::registerIDNoInvalidate):
(JSC::AbstractMacroAssembler::CachedTempRegister::value):
(JSC::AbstractMacroAssembler::CachedTempRegister::setValue):
(JSC::AbstractMacroAssembler::CachedTempRegister::invalidate):
(JSC::AbstractMacroAssembler::invalidateAllTempRegisters):
(JSC::AbstractMacroAssembler::isTempRegisterValid):
(JSC::AbstractMacroAssembler::clearTempRegisterValid):
(JSC::AbstractMacroAssembler::setTempRegisterValid):

  • assembler/LinkBuffer.cpp:

(JSC::LinkBuffer::copyCompactAndLinkCode):
(JSC::LinkBuffer::linkCode):

  • assembler/LinkBuffer.h:
  • assembler/MacroAssembler.h:

(JSC::MacroAssembler::isPtrAlignedAddressOffset):
(JSC::MacroAssembler::pushToSave):
(JSC::MacroAssembler::popToRestore):
(JSC::MacroAssembler::patchableBranchTest32):

  • assembler/MacroAssemblerARM64.h: Added.
  • assembler/MacroAssemblerARMv7.h:
  • dfg/DFGFixupPhase.cpp:

(JSC::DFG::FixupPhase::fixupNode):

  • dfg/DFGOSRExitCompiler32_64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGOSRExitCompiler64.cpp:

(JSC::DFG::OSRExitCompiler::compileExit):

  • dfg/DFGSpeculativeJIT.cpp:

(JSC::DFG::SpeculativeJIT::compileArithDiv):
(JSC::DFG::SpeculativeJIT::compileArithMod):

  • disassembler/ARM64/A64DOpcode.cpp: Added.
  • disassembler/ARM64/A64DOpcode.h: Added.
  • disassembler/ARM64Disassembler.cpp: Added.
  • heap/MachineStackMarker.cpp:

(JSC::getPlatformThreadRegisters):
(JSC::otherThreadStackPointer):

  • heap/Region.h:
  • jit/AssemblyHelpers.h:

(JSC::AssemblyHelpers::debugCall):

  • jit/CCallHelpers.h:
  • jit/ExecutableAllocator.h:
  • jit/FPRInfo.h:

(JSC::FPRInfo::toRegister):
(JSC::FPRInfo::toIndex):
(JSC::FPRInfo::debugName):

  • jit/GPRInfo.h:

(JSC::GPRInfo::toRegister):
(JSC::GPRInfo::toIndex):
(JSC::GPRInfo::debugName):

  • jit/JITInlines.h:

(JSC::JIT::restoreArgumentReferenceForTrampoline):

  • jit/JITOperationWrappers.h:
  • jit/JITOperations.cpp:
  • jit/JITStubs.cpp:

(JSC::performPlatformSpecificJITAssertions):
(JSC::tryCachePutByID):

  • jit/JITStubs.h:

(JSC::JITStackFrame::returnAddressSlot):

  • jit/JITStubsARM64.h: Added.
  • jit/JSInterfaceJIT.h:
  • jit/Repatch.cpp:

(JSC::emitRestoreScratch):
(JSC::generateProtoChainAccessStub):
(JSC::tryCacheGetByID):
(JSC::emitPutReplaceStub):
(JSC::tryCachePutByID):
(JSC::tryRepatchIn):

  • jit/ScratchRegisterAllocator.h:

(JSC::ScratchRegisterAllocator::preserveReusedRegistersByPushing):
(JSC::ScratchRegisterAllocator::restoreReusedRegistersByPopping):

  • jit/ThunkGenerators.cpp:

(JSC::nativeForGenerator):
(JSC::floorThunkGenerator):
(JSC::ceilThunkGenerator):

  • jsc.cpp:

(main):

  • llint/LLIntOfflineAsmConfig.h:
  • llint/LLIntSlowPaths.cpp:

(JSC::LLInt::handleHostCall):

  • llint/LowLevelInterpreter.asm:
  • llint/LowLevelInterpreter64.asm:
  • offlineasm/arm.rb:
  • offlineasm/arm64.rb: Added.
  • offlineasm/backends.rb:
  • offlineasm/instructions.rb:
  • offlineasm/risc.rb:
  • offlineasm/transform.rb:
  • yarr/YarrJIT.cpp:

(JSC::Yarr::YarrGenerator::alignCallFrameSizeInBytes):
(JSC::Yarr::YarrGenerator::initCallFrame):
(JSC::Yarr::YarrGenerator::removeCallFrame):
(JSC::Yarr::YarrGenerator::generateEnter):

  • yarr/YarrJIT.h:

Source/WTF:

Reviewed by Oliver Hunt.

  • Configurations/Base.xcconfig:
  • wtf/Atomics.h:

(WTF::weakCompareAndSwap):
(WTF::armV7_dmb):

  • wtf/FastMalloc.cpp:
  • wtf/Platform.h:
  • wtf/dtoa.cpp:
  • wtf/dtoa/utils.h:
  • wtf/text/ASCIIFastPath.h:

(WTF::copyLCharsFromUCharSource):

  • wtf/text/StringImpl.h:
Location:
trunk/Source/JavaScriptCore/offlineasm
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/JavaScriptCore/offlineasm/arm.rb

    r148705 r157474  
    218218        }
    219219        result = riscLowerMalformedAddressesDouble(result)
    220         result = riscLowerMisplacedImmediates(result, ["storeb", "storei", "storep"])
     220        result = riscLowerMisplacedImmediates(result, ["storeb", "storei", "storep", "storeq"])
    221221        result = riscLowerMalformedImmediates(result, 0..0xff)
    222222        result = riscLowerMisplacedAddresses(result)
  • trunk/Source/JavaScriptCore/offlineasm/backends.rb

    r148474 r157474  
    2424require "config"
    2525require "arm"
     26require "arm64"
    2627require "ast"
    2728require "x86"
     
    3738     "ARMv7",
    3839     "ARMv7_TRADITIONAL",
     40     "ARM64",
    3941     "MIPS",
    4042     "SH4",
     
    5456     "ARMv7",
    5557     "ARMv7_TRADITIONAL",
     58     "ARM64",
    5659     "MIPS",
    5760     "SH4",
  • trunk/Source/JavaScriptCore/offlineasm/instructions.rb

    r157452 r157474  
    258258    ]
    259259
    260 ARM_INSTRUCTIONS =
    261     [
    262      "smulli",
    263      "addis",
    264      "subis",
    265      "oris"
     260RISC_INSTRUCTIONS =
     261    [
     262     "smulli",  # Multiply two 32-bit words and produce a 64-bit word
     263     "addis",   # Add integers and set a flag.
     264     "subis",   # Same, but for subtraction.
     265     "oris",    # Same, but for bitwise or.
     266     "addps"    # addis but for pointers.
    266267    ]
    267268
     
    305306    ]
    306307
    307 INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + ARM_INSTRUCTIONS + MIPS_INSTRUCTIONS + SH4_INSTRUCTIONS + CXX_INSTRUCTIONS
     308INSTRUCTIONS = MACRO_INSTRUCTIONS + X86_INSTRUCTIONS + RISC_INSTRUCTIONS + MIPS_INSTRUCTIONS + SH4_INSTRUCTIONS + CXX_INSTRUCTIONS
    308309
    309310INSTRUCTION_PATTERN = Regexp.new('\\A((' + INSTRUCTIONS.join(')|(') + '))\\Z')
  • trunk/Source/JavaScriptCore/offlineasm/risc.rb

    r148474 r157474  
    372372            when "move"
    373373                newList << node
    374             when "addi", "addp", "addis", "subi", "subp", "subis"
     374            when "addi", "addp", "addq", "addis", "subi", "subp", "subq", "subis"
    375375                if node.operands[0].is_a? Immediate and
    376376                        (not validImmediates.include? node.operands[0].value) and
     
    388388                    newList << node.riscLowerMalformedImmediatesRecurse(newList, validImmediates)
    389389                end
    390             when "muli", "mulp"
     390            when "muli", "mulp", "mulq"
    391391                if node.operands[0].is_a? Immediate
    392392                    tmp = Tmp.new(codeOrigin, :gpr)
     
    466466                                           node.opcode,
    467467                                           riscAsRegisters(newList, postInstructions, node.operands, "p"),
     468                                           annotation)
     469            when "addq", "andq", "lshiftq", "mulq", "negq", "orq", "rshiftq", "urshiftq",
     470                "subq", "xorq", /^bq/, /^btq/, /^cq/
     471                newList << Instruction.new(node.codeOrigin,
     472                                           node.opcode,
     473                                           riscAsRegisters(newList, postInstructions, node.operands, "q"),
    468474                                           annotation)
    469475            when "bbeq", "bbneq", "bba", "bbaeq", "bbb", "bbbeq", "btbz", "btbnz", "tbz", "tbnz",
     
    553559end
    554560
     561#
     562# Lowering of the not instruction. The following:
     563#
     564# noti t0
     565#
     566# becomes:
     567#
     568# xori -1, t0
     569#
     570
     571def riscLowerNot(list)
     572    newList = []
     573    list.each {
     574        | node |
     575        if node.is_a? Instruction
     576            case node.opcode
     577            when "noti", "notp"
     578                raise "Wrong nubmer of operands at #{node.codeOriginString}" unless node.operands.size == 1
     579                suffix = node.opcode[-1..-1]
     580                newList << Instruction.new(node.codeOrigin, "xor" + suffix,
     581                                           [Immediate.new(node.codeOrigin, -1), node.operands[0]])
     582            else
     583                newList << node
     584            end
     585        else
     586            newList << node
     587        end
     588    }
     589    return newList
     590end
     591
     592#
     593# Lowing of complex branch ops on 64-bit. For example:
     594#
     595# bmulio foo, bar, baz
     596#
     597# becomes:
     598#
     599# smulli foo, bar, bar
     600# rshiftp bar, 32, tmp1
     601# rshifti bar, 31, tmp2
     602# zxi2p bar, bar
     603# bineq tmp1, tmp2, baz
     604#
     605
     606def riscLowerHardBranchOps64(list)
     607    newList = []
     608    list.each {
     609        | node |
     610        if node.is_a? Instruction and node.opcode == "bmulio"
     611            tmp1 = Tmp.new(node.codeOrigin, :gpr)
     612            tmp2 = Tmp.new(node.codeOrigin, :gpr)
     613            newList << Instruction.new(node.codeOrigin, "smulli", [node.operands[0], node.operands[1], node.operands[1]])
     614            newList << Instruction.new(node.codeOrigin, "rshiftp", [node.operands[1], Immediate.new(node.codeOrigin, 32), tmp1])
     615            newList << Instruction.new(node.codeOrigin, "rshifti", [node.operands[1], Immediate.new(node.codeOrigin, 31), tmp2])
     616            newList << Instruction.new(node.codeOrigin, "zxi2p", [node.operands[1], node.operands[1]])
     617            newList << Instruction.new(node.codeOrigin, "bineq", [tmp1, tmp2, node.operands[2]])
     618        else
     619            newList << node
     620        end
     621    }
     622    newList
     623end
     624
     625#
     626# Lowering of test instructions. For example:
     627#
     628# btiz t0, t1, .foo
     629#
     630# becomes:
     631#
     632# andi t0, t1, tmp
     633# bieq tmp, 0, .foo
     634#
     635# and another example:
     636#
     637# tiz t0, t1, t2
     638#
     639# becomes:
     640#
     641# andi t0, t1, tmp
     642# cieq tmp, 0, t2
     643#
     644
     645def riscLowerTest(list)
     646    def emit(newList, andOpcode, branchOpcode, node)
     647        if node.operands.size == 2
     648            newList << Instruction.new(node.codeOrigin, branchOpcode, [node.operands[0], Immediate.new(node.codeOrigin, 0), node.operands[1]])
     649            return
     650        end
     651
     652        raise "Incorrect number of operands at #{codeOriginString}" unless node.operands.size == 3
     653
     654        if node.operands[0].immediate? and node.operands[0].value == -1
     655            newList << Instruction.new(node.codeOrigin, branchOpcode, [node.operands[1], Immediate.new(node.codeOrigin, 0), node.operands[2]])
     656            return
     657        end
     658
     659        if node.operands[1].immediate? and node.operands[1].value == -1
     660            newList << Instruction.new(node.codeOrigin, branchOpcode, [node.operands[0], Immediate.new(node.codeOrigin, 0), node.operands[2]])
     661            return
     662        end
     663       
     664        tmp = Tmp.new(node.codeOrigin, :gpr)
     665        newList << Instruction.new(node.codeOrigin, andOpcode, [node.operands[0], node.operands[1], tmp])
     666        newList << Instruction.new(node.codeOrigin, branchOpcode, [tmp, Immediate.new(node.codeOrigin, 0), node.operands[2]])
     667    end
     668
     669    newList = []
     670    list.each {
     671        | node |
     672        if node.is_a? Instruction
     673            case node.opcode
     674            when "btis"
     675                emit(newList, "andi", "bilt", node)
     676            when "btiz"
     677                emit(newList, "andi", "bieq", node)
     678            when "btinz"
     679                emit(newList, "andi", "bineq", node)
     680            when "btps"
     681                emit(newList, "andp", "bplt", node)
     682            when "btpz"
     683                emit(newList, "andp", "bpeq", node)
     684            when "btpnz"
     685                emit(newList, "andp", "bpneq", node)
     686            when "btqs"
     687                emit(newList, "andq", "bqlt", node)
     688            when "btqz"
     689                emit(newList, "andq", "bqeq", node)
     690            when "btqnz"
     691                emit(newList, "andq", "bqneq", node)
     692            when "btbs"
     693                emit(newList, "andi", "bblt", node)
     694            when "btbz"
     695                emit(newList, "andi", "bbeq", node)
     696            when "btbnz"
     697                emit(newList, "andi", "bbneq", node)
     698            when "tis"
     699                emit(newList, "andi", "cilt", node)
     700            when "tiz"
     701                emit(newList, "andi", "cieq", node)
     702            when "tinz"
     703                emit(newList, "andi", "cineq", node)
     704            when "tps"
     705                emit(newList, "andp", "cplt", node)
     706            when "tpz"
     707                emit(newList, "andp", "cpeq", node)
     708            when "tpnz"
     709                emit(newList, "andp", "cpneq", node)
     710            when "tqs"
     711                emit(newList, "andq", "cqlt", node)
     712            when "tqz"
     713                emit(newList, "andq", "cqeq", node)
     714            when "tqnz"
     715                emit(newList, "andq", "cqneq", node)
     716            when "tbs"
     717                emit(newList, "andi", "cblt", node)
     718            when "tbz"
     719                emit(newList, "andi", "cbeq", node)
     720            when "tbnz"
     721                emit(newList, "andi", "cbneq", node)
     722            else
     723                newList << node
     724            end
     725        else
     726            newList << node
     727        end
     728    }
     729    return newList
     730end
  • trunk/Source/JavaScriptCore/offlineasm/transform.rb

    r123147 r157474  
    405405    def validate
    406406        validateChildren
     407       
     408        # Further verify that this list contains only instructions, labels, and skips.
     409        @list.each {
     410            | node |
     411            unless node.is_a? Instruction or
     412                    node.is_a? Label or
     413                    node.is_a? LocalLabel or
     414                    node.is_a? Skip
     415                raise "Unexpected #{node.inspect} at #{node.codeOrigin}"
     416            end
     417        }
    407418    end
    408419end
Note: See TracChangeset for help on using the changeset viewer.