summaryrefslogtreecommitdiffstats
path: root/JavaScriptCore/jit/JITOpcodes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'JavaScriptCore/jit/JITOpcodes.cpp')
-rw-r--r--JavaScriptCore/jit/JITOpcodes.cpp109
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)