diff options
Diffstat (limited to 'JavaScriptCore/jit/JITOpcodes.cpp')
-rw-r--r-- | JavaScriptCore/jit/JITOpcodes.cpp | 109 |
1 files changed, 99 insertions, 10 deletions
diff --git a/JavaScriptCore/jit/JITOpcodes.cpp b/JavaScriptCore/jit/JITOpcodes.cpp index d9a32d9..c3f20f1 100644 --- a/JavaScriptCore/jit/JITOpcodes.cpp +++ b/JavaScriptCore/jit/JITOpcodes.cpp @@ -40,8 +40,12 @@ namespace JSC { #if USE(JSVALUE32_64) -void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) +void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines) { +#if ENABLE(JIT_OPTIMIZE_MOD) + Label softModBegin = align(); + softModulo(); +#endif #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) // (1) This function provides fast property access for string length Label stringLengthBegin = align(); @@ -365,18 +369,21 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable CodeRef finalCode = patchBuffer.finalizeCode(); *executablePool = finalCode.m_executablePool; - *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); - *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); + trampolines->ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); + trampolines->ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) - *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); + trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); #else UNUSED_PARAM(ctiStringLengthTrampoline); #endif #if ENABLE(JIT_OPTIMIZE_CALL) - *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); + trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); #else UNUSED_PARAM(ctiVirtualCallLink); #endif +#if ENABLE(JIT_OPTIMIZE_MOD) + trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin); +#endif } void JIT::emit_op_mov(Instruction* currentInstruction) @@ -1495,8 +1502,12 @@ void JIT::emit_op_profile_did_call(Instruction* currentInstruction) #define RECORD_JUMP_TARGET(targetOffset) \ do { m_labels[m_bytecodeIndex + (targetOffset)].used(); } while (false) -void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, CodePtr* ctiStringLengthTrampoline, CodePtr* ctiVirtualCallLink, CodePtr* ctiVirtualCall, CodePtr* ctiNativeCallThunk) +void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executablePool, JSGlobalData* globalData, TrampolineStructure *trampolines) { +#if ENABLE(JIT_OPTIMIZE_MOD) + Label softModBegin = align(); + softModulo(); +#endif #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) // (2) The second function provides fast property access for string length Label stringLengthBegin = align(); @@ -1827,11 +1838,14 @@ void JIT::privateCompileCTIMachineTrampolines(RefPtr<ExecutablePool>* executable CodeRef finalCode = patchBuffer.finalizeCode(); *executablePool = finalCode.m_executablePool; - *ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); - *ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); - *ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); + trampolines->ctiVirtualCallLink = trampolineAt(finalCode, virtualCallLinkBegin); + trampolines->ctiVirtualCall = trampolineAt(finalCode, virtualCallBegin); + trampolines->ctiNativeCallThunk = trampolineAt(finalCode, nativeCallThunk); +#if ENABLE(JIT_OPTIMIZE_MOD) + trampolines->ctiSoftModulo = trampolineAt(finalCode, softModBegin); +#endif #if ENABLE(JIT_OPTIMIZE_PROPERTY_ACCESS) - *ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); + trampolines->ctiStringLengthTrampoline = trampolineAt(finalCode, stringLengthBegin); #else UNUSED_PARAM(ctiStringLengthTrampoline); #endif @@ -2978,6 +2992,81 @@ void JIT::emitSlow_op_to_jsnumber(Instruction* currentInstruction, Vector<SlowCa #endif // USE(JSVALUE32_64) +// For both JSValue32_64 and JSValue32 +#if ENABLE(JIT_OPTIMIZE_MOD) +#if CPU(ARM_TRADITIONAL) +void JIT::softModulo() +{ + push(regS0); + push(regS1); + push(regT1); + push(regT3); +#if USE(JSVALUE32_64) + m_assembler.mov_r(regT3, regT2); + m_assembler.mov_r(regT2, regT0); +#else + m_assembler.mov_r(regT3, m_assembler.asr(regT2, 1)); + m_assembler.mov_r(regT2, m_assembler.asr(regT0, 1)); +#endif + m_assembler.mov_r(regT1, ARMAssembler::getOp2(0)); + + m_assembler.teq_r(regT3, ARMAssembler::getOp2(0)); + m_assembler.rsb_r(regT3, regT3, ARMAssembler::getOp2(0), ARMAssembler::MI); + m_assembler.eor_r(regT1, regT1, ARMAssembler::getOp2(1), ARMAssembler::MI); + + m_assembler.teq_r(regT2, ARMAssembler::getOp2(0)); + m_assembler.rsb_r(regT2, regT2, ARMAssembler::getOp2(0), ARMAssembler::MI); + m_assembler.eor_r(regT1, regT1, ARMAssembler::getOp2(2), ARMAssembler::MI); + + Jump exitBranch = branch32(LessThan, regT2, regT3); + + m_assembler.sub_r(regS1, regT3, ARMAssembler::getOp2(1)); + m_assembler.tst_r(regS1, regT3); + m_assembler.and_r(regT2, regT2, regS1, ARMAssembler::EQ); + m_assembler.and_r(regT0, regS1, regT3); + Jump exitBranch2 = branchTest32(Zero, regT0); + + m_assembler.clz_r(regS1, regT2); + m_assembler.clz_r(regS0, regT3); + m_assembler.sub_r(regS0, regS0, regS1); + + m_assembler.rsbs_r(regS0, regS0, ARMAssembler::getOp2(31)); + + m_assembler.mov_r(regS0, m_assembler.lsl(regS0, 1), ARMAssembler::NE); + + m_assembler.add_r(ARMRegisters::pc, ARMRegisters::pc, m_assembler.lsl(regS0, 2), ARMAssembler::NE); + m_assembler.mov_r(regT0, regT0); + + for (int i = 31; i > 0; --i) { + m_assembler.cmp_r(regT2, m_assembler.lsl(regT3, i)); + m_assembler.sub_r(regT2, regT2, m_assembler.lsl(regT3, i), ARMAssembler::CS); + } + + m_assembler.cmp_r(regT2, regT3); + m_assembler.sub_r(regT2, regT2, regT3, ARMAssembler::CS); + + exitBranch.link(this); + exitBranch2.link(this); + + m_assembler.teq_r(regT1, ARMAssembler::getOp2(0)); + m_assembler.rsb_r(regT2, regT2, ARMAssembler::getOp2(0), ARMAssembler::GT); + +#if USE(JSVALUE32_64) + m_assembler.mov_r(regT0, regT2); +#else + m_assembler.mov_r(regT0, m_assembler.lsl(regT2, 1)); + m_assembler.eor_r(regT0, regT0, ARMAssembler::getOp2(1)); +#endif + pop(regT3); + pop(regT1); + pop(regS1); + pop(regS0); + ret(); +} +#else +#error "JIT_OPTIMIZE_MOD not yet supported on this platform." +#endif // CPU(ARM_TRADITIONAL) +#endif } // namespace JSC #endif // ENABLE(JIT) |