[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

eric at webkit.org eric at webkit.org
Thu Apr 8 02:08:55 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 191008414dad7f96f6a45f2ff5c5e8aecf5b1436
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Mar 4 03:57:34 2010 +0000

    2010-03-03  Chao-ying Fu  <fu at mips.com>
    
            Reviewed by Gavin Barraclough.
    
            MIPS JIT Supports
            https://bugs.webkit.org/show_bug.cgi?id=30144
    
            The following changes enable MIPS YARR and YARR_JIT.
    
            * assembler/AbstractMacroAssembler.h:
            (JSC::AbstractMacroAssembler::Imm32::Imm32):
            * assembler/MIPSAssembler.h: Added.
            (JSC::MIPSRegisters::):
            (JSC::MIPSAssembler::MIPSAssembler):
            (JSC::MIPSAssembler::):
            (JSC::MIPSAssembler::JmpSrc::JmpSrc):
            (JSC::MIPSAssembler::JmpDst::JmpDst):
            (JSC::MIPSAssembler::JmpDst::isUsed):
            (JSC::MIPSAssembler::JmpDst::used):
            (JSC::MIPSAssembler::emitInst):
            (JSC::MIPSAssembler::nop):
            (JSC::MIPSAssembler::loadDelayNop):
            (JSC::MIPSAssembler::copDelayNop):
            (JSC::MIPSAssembler::move):
            (JSC::MIPSAssembler::li):
            (JSC::MIPSAssembler::lui):
            (JSC::MIPSAssembler::addiu):
            (JSC::MIPSAssembler::addu):
            (JSC::MIPSAssembler::subu):
            (JSC::MIPSAssembler::mult):
            (JSC::MIPSAssembler::mfhi):
            (JSC::MIPSAssembler::mflo):
            (JSC::MIPSAssembler::mul):
            (JSC::MIPSAssembler::andInsn):
            (JSC::MIPSAssembler::andi):
            (JSC::MIPSAssembler::nor):
            (JSC::MIPSAssembler::orInsn):
            (JSC::MIPSAssembler::ori):
            (JSC::MIPSAssembler::xorInsn):
            (JSC::MIPSAssembler::xori):
            (JSC::MIPSAssembler::slt):
            (JSC::MIPSAssembler::sltu):
            (JSC::MIPSAssembler::sltiu):
            (JSC::MIPSAssembler::sll):
            (JSC::MIPSAssembler::sllv):
            (JSC::MIPSAssembler::sra):
            (JSC::MIPSAssembler::srav):
            (JSC::MIPSAssembler::lw):
            (JSC::MIPSAssembler::lwl):
            (JSC::MIPSAssembler::lwr):
            (JSC::MIPSAssembler::lhu):
            (JSC::MIPSAssembler::sw):
            (JSC::MIPSAssembler::jr):
            (JSC::MIPSAssembler::jalr):
            (JSC::MIPSAssembler::jal):
            (JSC::MIPSAssembler::bkpt):
            (JSC::MIPSAssembler::bgez):
            (JSC::MIPSAssembler::bltz):
            (JSC::MIPSAssembler::beq):
            (JSC::MIPSAssembler::bne):
            (JSC::MIPSAssembler::bc1t):
            (JSC::MIPSAssembler::bc1f):
            (JSC::MIPSAssembler::newJmpSrc):
            (JSC::MIPSAssembler::appendJump):
            (JSC::MIPSAssembler::addd):
            (JSC::MIPSAssembler::subd):
            (JSC::MIPSAssembler::muld):
            (JSC::MIPSAssembler::lwc1):
            (JSC::MIPSAssembler::ldc1):
            (JSC::MIPSAssembler::swc1):
            (JSC::MIPSAssembler::sdc1):
            (JSC::MIPSAssembler::mtc1):
            (JSC::MIPSAssembler::mfc1):
            (JSC::MIPSAssembler::truncwd):
            (JSC::MIPSAssembler::cvtdw):
            (JSC::MIPSAssembler::ceqd):
            (JSC::MIPSAssembler::cngtd):
            (JSC::MIPSAssembler::cnged):
            (JSC::MIPSAssembler::cltd):
            (JSC::MIPSAssembler::cled):
            (JSC::MIPSAssembler::cueqd):
            (JSC::MIPSAssembler::coled):
            (JSC::MIPSAssembler::coltd):
            (JSC::MIPSAssembler::culed):
            (JSC::MIPSAssembler::cultd):
            (JSC::MIPSAssembler::label):
            (JSC::MIPSAssembler::align):
            (JSC::MIPSAssembler::getRelocatedAddress):
            (JSC::MIPSAssembler::getDifferenceBetweenLabels):
            (JSC::MIPSAssembler::size):
            (JSC::MIPSAssembler::executableCopy):
            (JSC::MIPSAssembler::getCallReturnOffset):
            (JSC::MIPSAssembler::linkJump):
            (JSC::MIPSAssembler::linkCall):
            (JSC::MIPSAssembler::linkPointer):
            (JSC::MIPSAssembler::relinkJump):
            (JSC::MIPSAssembler::relinkCall):
            (JSC::MIPSAssembler::repatchInt32):
            (JSC::MIPSAssembler::repatchPointer):
            (JSC::MIPSAssembler::repatchLoadPtrToLEA):
            (JSC::MIPSAssembler::relocateJumps):
            (JSC::MIPSAssembler::linkWithOffset):
            (JSC::MIPSAssembler::linkCallInternal):
            * assembler/MacroAssembler.h:
            * assembler/MacroAssemblerMIPS.h: Added.
            (JSC::MacroAssemblerMIPS::MacroAssemblerMIPS):
            (JSC::MacroAssemblerMIPS::):
            (JSC::MacroAssemblerMIPS::add32):
            (JSC::MacroAssemblerMIPS::and32):
            (JSC::MacroAssemblerMIPS::lshift32):
            (JSC::MacroAssemblerMIPS::mul32):
            (JSC::MacroAssemblerMIPS::not32):
            (JSC::MacroAssemblerMIPS::or32):
            (JSC::MacroAssemblerMIPS::rshift32):
            (JSC::MacroAssemblerMIPS::sub32):
            (JSC::MacroAssemblerMIPS::xor32):
            (JSC::MacroAssemblerMIPS::load32):
            (JSC::MacroAssemblerMIPS::load32WithUnalignedHalfWords):
            (JSC::MacroAssemblerMIPS::load32WithAddressOffsetPatch):
            (JSC::MacroAssemblerMIPS::loadPtrWithPatchToLEA):
            (JSC::MacroAssemblerMIPS::loadPtrWithAddressOffsetPatch):
            (JSC::MacroAssemblerMIPS::load16):
            (JSC::MacroAssemblerMIPS::store32WithAddressOffsetPatch):
            (JSC::MacroAssemblerMIPS::store32):
            (JSC::MacroAssemblerMIPS::supportsFloatingPoint):
            (JSC::MacroAssemblerMIPS::supportsFloatingPointTruncate):
            (JSC::MacroAssemblerMIPS::pop):
            (JSC::MacroAssemblerMIPS::push):
            (JSC::MacroAssemblerMIPS::move):
            (JSC::MacroAssemblerMIPS::swap):
            (JSC::MacroAssemblerMIPS::signExtend32ToPtr):
            (JSC::MacroAssemblerMIPS::zeroExtend32ToPtr):
            (JSC::MacroAssemblerMIPS::branch32):
            (JSC::MacroAssemblerMIPS::branch32WithUnalignedHalfWords):
            (JSC::MacroAssemblerMIPS::branch16):
            (JSC::MacroAssemblerMIPS::branchTest32):
            (JSC::MacroAssemblerMIPS::jump):
            (JSC::MacroAssemblerMIPS::branchAdd32):
            (JSC::MacroAssemblerMIPS::branchMul32):
            (JSC::MacroAssemblerMIPS::branchSub32):
            (JSC::MacroAssemblerMIPS::breakpoint):
            (JSC::MacroAssemblerMIPS::nearCall):
            (JSC::MacroAssemblerMIPS::call):
            (JSC::MacroAssemblerMIPS::ret):
            (JSC::MacroAssemblerMIPS::set32):
            (JSC::MacroAssemblerMIPS::setTest32):
            (JSC::MacroAssemblerMIPS::moveWithPatch):
            (JSC::MacroAssemblerMIPS::branchPtrWithPatch):
            (JSC::MacroAssemblerMIPS::storePtrWithPatch):
            (JSC::MacroAssemblerMIPS::tailRecursiveCall):
            (JSC::MacroAssemblerMIPS::makeTailRecursiveCall):
            (JSC::MacroAssemblerMIPS::loadDouble):
            (JSC::MacroAssemblerMIPS::storeDouble):
            (JSC::MacroAssemblerMIPS::addDouble):
            (JSC::MacroAssemblerMIPS::subDouble):
            (JSC::MacroAssemblerMIPS::mulDouble):
            (JSC::MacroAssemblerMIPS::convertInt32ToDouble):
            (JSC::MacroAssemblerMIPS::insertRelaxationWords):
            (JSC::MacroAssemblerMIPS::branchTrue):
            (JSC::MacroAssemblerMIPS::branchFalse):
            (JSC::MacroAssemblerMIPS::branchEqual):
            (JSC::MacroAssemblerMIPS::branchNotEqual):
            (JSC::MacroAssemblerMIPS::branchDouble):
            (JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
            (JSC::MacroAssemblerMIPS::linkCall):
            (JSC::MacroAssemblerMIPS::repatchCall):
            * jit/ExecutableAllocator.h:
            (JSC::ExecutableAllocator::cacheFlush):
            * wtf/Platform.h:
            * yarr/RegexJIT.cpp:
            (JSC::Yarr::RegexGenerator::generateEnter):
            (JSC::Yarr::RegexGenerator::generateReturn):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@55500 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index d59c8cc..fdee5ea 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,176 @@
+2010-03-03  Chao-ying Fu  <fu at mips.com>
+
+        Reviewed by Gavin Barraclough.
+
+        MIPS JIT Supports
+        https://bugs.webkit.org/show_bug.cgi?id=30144
+
+        The following changes enable MIPS YARR and YARR_JIT.
+
+        * assembler/AbstractMacroAssembler.h:
+        (JSC::AbstractMacroAssembler::Imm32::Imm32):
+        * assembler/MIPSAssembler.h: Added.
+        (JSC::MIPSRegisters::):
+        (JSC::MIPSAssembler::MIPSAssembler):
+        (JSC::MIPSAssembler::):
+        (JSC::MIPSAssembler::JmpSrc::JmpSrc):
+        (JSC::MIPSAssembler::JmpDst::JmpDst):
+        (JSC::MIPSAssembler::JmpDst::isUsed):
+        (JSC::MIPSAssembler::JmpDst::used):
+        (JSC::MIPSAssembler::emitInst):
+        (JSC::MIPSAssembler::nop):
+        (JSC::MIPSAssembler::loadDelayNop):
+        (JSC::MIPSAssembler::copDelayNop):
+        (JSC::MIPSAssembler::move):
+        (JSC::MIPSAssembler::li):
+        (JSC::MIPSAssembler::lui):
+        (JSC::MIPSAssembler::addiu):
+        (JSC::MIPSAssembler::addu):
+        (JSC::MIPSAssembler::subu):
+        (JSC::MIPSAssembler::mult):
+        (JSC::MIPSAssembler::mfhi):
+        (JSC::MIPSAssembler::mflo):
+        (JSC::MIPSAssembler::mul):
+        (JSC::MIPSAssembler::andInsn):
+        (JSC::MIPSAssembler::andi):
+        (JSC::MIPSAssembler::nor):
+        (JSC::MIPSAssembler::orInsn):
+        (JSC::MIPSAssembler::ori):
+        (JSC::MIPSAssembler::xorInsn):
+        (JSC::MIPSAssembler::xori):
+        (JSC::MIPSAssembler::slt):
+        (JSC::MIPSAssembler::sltu):
+        (JSC::MIPSAssembler::sltiu):
+        (JSC::MIPSAssembler::sll):
+        (JSC::MIPSAssembler::sllv):
+        (JSC::MIPSAssembler::sra):
+        (JSC::MIPSAssembler::srav):
+        (JSC::MIPSAssembler::lw):
+        (JSC::MIPSAssembler::lwl):
+        (JSC::MIPSAssembler::lwr):
+        (JSC::MIPSAssembler::lhu):
+        (JSC::MIPSAssembler::sw):
+        (JSC::MIPSAssembler::jr):
+        (JSC::MIPSAssembler::jalr):
+        (JSC::MIPSAssembler::jal):
+        (JSC::MIPSAssembler::bkpt):
+        (JSC::MIPSAssembler::bgez):
+        (JSC::MIPSAssembler::bltz):
+        (JSC::MIPSAssembler::beq):
+        (JSC::MIPSAssembler::bne):
+        (JSC::MIPSAssembler::bc1t):
+        (JSC::MIPSAssembler::bc1f):
+        (JSC::MIPSAssembler::newJmpSrc):
+        (JSC::MIPSAssembler::appendJump):
+        (JSC::MIPSAssembler::addd):
+        (JSC::MIPSAssembler::subd):
+        (JSC::MIPSAssembler::muld):
+        (JSC::MIPSAssembler::lwc1):
+        (JSC::MIPSAssembler::ldc1):
+        (JSC::MIPSAssembler::swc1):
+        (JSC::MIPSAssembler::sdc1):
+        (JSC::MIPSAssembler::mtc1):
+        (JSC::MIPSAssembler::mfc1):
+        (JSC::MIPSAssembler::truncwd):
+        (JSC::MIPSAssembler::cvtdw):
+        (JSC::MIPSAssembler::ceqd):
+        (JSC::MIPSAssembler::cngtd):
+        (JSC::MIPSAssembler::cnged):
+        (JSC::MIPSAssembler::cltd):
+        (JSC::MIPSAssembler::cled):
+        (JSC::MIPSAssembler::cueqd):
+        (JSC::MIPSAssembler::coled):
+        (JSC::MIPSAssembler::coltd):
+        (JSC::MIPSAssembler::culed):
+        (JSC::MIPSAssembler::cultd):
+        (JSC::MIPSAssembler::label):
+        (JSC::MIPSAssembler::align):
+        (JSC::MIPSAssembler::getRelocatedAddress):
+        (JSC::MIPSAssembler::getDifferenceBetweenLabels):
+        (JSC::MIPSAssembler::size):
+        (JSC::MIPSAssembler::executableCopy):
+        (JSC::MIPSAssembler::getCallReturnOffset):
+        (JSC::MIPSAssembler::linkJump):
+        (JSC::MIPSAssembler::linkCall):
+        (JSC::MIPSAssembler::linkPointer):
+        (JSC::MIPSAssembler::relinkJump):
+        (JSC::MIPSAssembler::relinkCall):
+        (JSC::MIPSAssembler::repatchInt32):
+        (JSC::MIPSAssembler::repatchPointer):
+        (JSC::MIPSAssembler::repatchLoadPtrToLEA):
+        (JSC::MIPSAssembler::relocateJumps):
+        (JSC::MIPSAssembler::linkWithOffset):
+        (JSC::MIPSAssembler::linkCallInternal):
+        * assembler/MacroAssembler.h:
+        * assembler/MacroAssemblerMIPS.h: Added.
+        (JSC::MacroAssemblerMIPS::MacroAssemblerMIPS):
+        (JSC::MacroAssemblerMIPS::):
+        (JSC::MacroAssemblerMIPS::add32):
+        (JSC::MacroAssemblerMIPS::and32):
+        (JSC::MacroAssemblerMIPS::lshift32):
+        (JSC::MacroAssemblerMIPS::mul32):
+        (JSC::MacroAssemblerMIPS::not32):
+        (JSC::MacroAssemblerMIPS::or32):
+        (JSC::MacroAssemblerMIPS::rshift32):
+        (JSC::MacroAssemblerMIPS::sub32):
+        (JSC::MacroAssemblerMIPS::xor32):
+        (JSC::MacroAssemblerMIPS::load32):
+        (JSC::MacroAssemblerMIPS::load32WithUnalignedHalfWords):
+        (JSC::MacroAssemblerMIPS::load32WithAddressOffsetPatch):
+        (JSC::MacroAssemblerMIPS::loadPtrWithPatchToLEA):
+        (JSC::MacroAssemblerMIPS::loadPtrWithAddressOffsetPatch):
+        (JSC::MacroAssemblerMIPS::load16):
+        (JSC::MacroAssemblerMIPS::store32WithAddressOffsetPatch):
+        (JSC::MacroAssemblerMIPS::store32):
+        (JSC::MacroAssemblerMIPS::supportsFloatingPoint):
+        (JSC::MacroAssemblerMIPS::supportsFloatingPointTruncate):
+        (JSC::MacroAssemblerMIPS::pop):
+        (JSC::MacroAssemblerMIPS::push):
+        (JSC::MacroAssemblerMIPS::move):
+        (JSC::MacroAssemblerMIPS::swap):
+        (JSC::MacroAssemblerMIPS::signExtend32ToPtr):
+        (JSC::MacroAssemblerMIPS::zeroExtend32ToPtr):
+        (JSC::MacroAssemblerMIPS::branch32):
+        (JSC::MacroAssemblerMIPS::branch32WithUnalignedHalfWords):
+        (JSC::MacroAssemblerMIPS::branch16):
+        (JSC::MacroAssemblerMIPS::branchTest32):
+        (JSC::MacroAssemblerMIPS::jump):
+        (JSC::MacroAssemblerMIPS::branchAdd32):
+        (JSC::MacroAssemblerMIPS::branchMul32):
+        (JSC::MacroAssemblerMIPS::branchSub32):
+        (JSC::MacroAssemblerMIPS::breakpoint):
+        (JSC::MacroAssemblerMIPS::nearCall):
+        (JSC::MacroAssemblerMIPS::call):
+        (JSC::MacroAssemblerMIPS::ret):
+        (JSC::MacroAssemblerMIPS::set32):
+        (JSC::MacroAssemblerMIPS::setTest32):
+        (JSC::MacroAssemblerMIPS::moveWithPatch):
+        (JSC::MacroAssemblerMIPS::branchPtrWithPatch):
+        (JSC::MacroAssemblerMIPS::storePtrWithPatch):
+        (JSC::MacroAssemblerMIPS::tailRecursiveCall):
+        (JSC::MacroAssemblerMIPS::makeTailRecursiveCall):
+        (JSC::MacroAssemblerMIPS::loadDouble):
+        (JSC::MacroAssemblerMIPS::storeDouble):
+        (JSC::MacroAssemblerMIPS::addDouble):
+        (JSC::MacroAssemblerMIPS::subDouble):
+        (JSC::MacroAssemblerMIPS::mulDouble):
+        (JSC::MacroAssemblerMIPS::convertInt32ToDouble):
+        (JSC::MacroAssemblerMIPS::insertRelaxationWords):
+        (JSC::MacroAssemblerMIPS::branchTrue):
+        (JSC::MacroAssemblerMIPS::branchFalse):
+        (JSC::MacroAssemblerMIPS::branchEqual):
+        (JSC::MacroAssemblerMIPS::branchNotEqual):
+        (JSC::MacroAssemblerMIPS::branchDouble):
+        (JSC::MacroAssemblerMIPS::branchTruncateDoubleToInt32):
+        (JSC::MacroAssemblerMIPS::linkCall):
+        (JSC::MacroAssemblerMIPS::repatchCall):
+        * jit/ExecutableAllocator.h:
+        (JSC::ExecutableAllocator::cacheFlush):
+        * wtf/Platform.h:
+        * yarr/RegexJIT.cpp:
+        (JSC::Yarr::RegexGenerator::generateEnter):
+        (JSC::Yarr::RegexGenerator::generateReturn):
+
 2010-03-03  Steve Falkenburg  <sfalken at apple.com>
 
         Windows build fix.
diff --git a/JavaScriptCore/assembler/AbstractMacroAssembler.h b/JavaScriptCore/assembler/AbstractMacroAssembler.h
index 198e8d1..248552c 100644
--- a/JavaScriptCore/assembler/AbstractMacroAssembler.h
+++ b/JavaScriptCore/assembler/AbstractMacroAssembler.h
@@ -173,7 +173,7 @@ public:
     struct Imm32 {
         explicit Imm32(int32_t value)
             : m_value(value)
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
             , m_isPointer(false)
 #endif
         {
@@ -182,7 +182,7 @@ public:
 #if !CPU(X86_64)
         explicit Imm32(ImmPtr ptr)
             : m_value(ptr.asIntptr())
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
             , m_isPointer(true)
 #endif
         {
@@ -190,13 +190,14 @@ public:
 #endif
 
         int32_t m_value;
-#if CPU(ARM)
+#if CPU(ARM) || CPU(MIPS)
         // We rely on being able to regenerate code to recover exception handling
         // information.  Since ARMv7 supports 16-bit immediates there is a danger
         // that if pointer values change the layout of the generated code will change.
         // To avoid this problem, always generate pointers (and thus Imm32s constructed
         // from ImmPtrs) with a code sequence that is able  to represent  any pointer
         // value - don't use a more compact form in these cases.
+        // Same for MIPS.
         bool m_isPointer;
 #endif
     };
diff --git a/JavaScriptCore/assembler/MIPSAssembler.h b/JavaScriptCore/assembler/MIPSAssembler.h
new file mode 100644
index 0000000..47b1b4f
--- /dev/null
+++ b/JavaScriptCore/assembler/MIPSAssembler.h
@@ -0,0 +1,937 @@
+/*
+ * Copyright (C) 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2009 University of Szeged
+ * All rights reserved.
+ * Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MIPS TECHNOLOGIES, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MIPS TECHNOLOGIES, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MIPSAssembler_h
+#define MIPSAssembler_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER) && CPU(MIPS)
+
+#include "AssemblerBuffer.h"
+#include <wtf/Assertions.h>
+#include <wtf/SegmentedVector.h>
+
+namespace JSC {
+
+typedef uint32_t MIPSWord;
+
+namespace MIPSRegisters {
+typedef enum {
+    r0 = 0,
+    r1,
+    r2,
+    r3,
+    r4,
+    r5,
+    r6,
+    r7,
+    r8,
+    r9,
+    r10,
+    r11,
+    r12,
+    r13,
+    r14,
+    r15,
+    r16,
+    r17,
+    r18,
+    r19,
+    r20,
+    r21,
+    r22,
+    r23,
+    r24,
+    r25,
+    r26,
+    r27,
+    r28,
+    r29,
+    r30,
+    r31,
+    zero = r0,
+    at = r1,
+    v0 = r2,
+    v1 = r3,
+    a0 = r4,
+    a1 = r5,
+    a2 = r6,
+    a3 = r7,
+    t0 = r8,
+    t1 = r9,
+    t2 = r10,
+    t3 = r11,
+    t4 = r12,
+    t5 = r13,
+    t6 = r14,
+    t7 = r15,
+    s0 = r16,
+    s1 = r17,
+    s2 = r18,
+    s3 = r19,
+    s4 = r20,
+    s5 = r21,
+    s6 = r22,
+    s7 = r23,
+    t8 = r24,
+    t9 = r25,
+    k0 = r26,
+    k1 = r27,
+    gp = r28,
+    sp = r29,
+    fp = r30,
+    ra = r31
+} RegisterID;
+
+typedef enum {
+    f0,
+    f1,
+    f2,
+    f3,
+    f4,
+    f5,
+    f6,
+    f7,
+    f8,
+    f9,
+    f10,
+    f11,
+    f12,
+    f13,
+    f14,
+    f15,
+    f16,
+    f17,
+    f18,
+    f19,
+    f20,
+    f21,
+    f22,
+    f23,
+    f24,
+    f25,
+    f26,
+    f27,
+    f28,
+    f29,
+    f30,
+    f31
+} FPRegisterID;
+
+} // namespace MIPSRegisters
+
+class MIPSAssembler {
+public:
+    typedef MIPSRegisters::RegisterID RegisterID;
+    typedef MIPSRegisters::FPRegisterID FPRegisterID;
+    typedef SegmentedVector<int, 64> Jumps;
+
+    MIPSAssembler()
+    {
+    }
+
+    // MIPS instruction opcode field position
+    enum {
+        OP_SH_RD = 11,
+        OP_SH_RT = 16,
+        OP_SH_RS = 21,
+        OP_SH_SHAMT = 6,
+        OP_SH_CODE = 16,
+        OP_SH_FD = 6,
+        OP_SH_FS = 11,
+        OP_SH_FT = 16
+    };
+
+    class JmpSrc {
+        friend class MIPSAssembler;
+    public:
+        JmpSrc()
+            : m_offset(-1)
+        {
+        }
+
+    private:
+        JmpSrc(int offset)
+            : m_offset(offset)
+        {
+        }
+
+        int m_offset;
+    };
+
+    class JmpDst {
+        friend class MIPSAssembler;
+    public:
+        JmpDst()
+            : m_offset(-1)
+            , m_used(false)
+        {
+        }
+
+        bool isUsed() const { return m_used; }
+        void used() { m_used = true; }
+    private:
+        JmpDst(int offset)
+            : m_offset(offset)
+            , m_used(false)
+        {
+            ASSERT(m_offset == offset);
+        }
+
+        int m_offset : 31;
+        int m_used : 1;
+    };
+
+    void emitInst(MIPSWord op)
+    {
+        void* oldBase = m_buffer.data();
+
+        m_buffer.putInt(op);
+
+        void* newBase = m_buffer.data();
+        if (oldBase != newBase)
+            relocateJumps(oldBase, newBase);
+    }
+
+    void nop()
+    {
+        emitInst(0x00000000);
+    }
+
+    /* Need to insert one load data delay nop for mips1.  */
+    void loadDelayNop()
+    {
+#if WTF_MIPS_ISA(1)
+        nop();
+#endif
+    }
+
+    /* Need to insert one coprocessor access delay nop for mips1.  */
+    void copDelayNop()
+    {
+#if WTF_MIPS_ISA(1)
+        nop();
+#endif
+    }
+
+    void move(RegisterID rd, RegisterID rs)
+    {
+        /* addu */
+        emitInst(0x00000021 | (rd << OP_SH_RD) | (rs << OP_SH_RS));
+    }
+
+    /* Set an immediate value to a register.  This may generate 1 or 2
+       instructions.  */
+    void li(RegisterID dest, int imm)
+    {
+        if (imm >= -32768 && imm <= 32767)
+            addiu(dest, MIPSRegisters::zero, imm);
+        else if (imm >= 0 && imm < 65536)
+            ori(dest, MIPSRegisters::zero, imm);
+        else {
+            lui(dest, imm >> 16);
+            if (imm & 0xffff)
+                ori(dest, dest, imm);
+        }
+    }
+
+    void lui(RegisterID rt, int imm)
+    {
+        emitInst(0x3c000000 | (rt << OP_SH_RT) | (imm & 0xffff));
+    }
+
+    void addiu(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x24000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void addu(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000021 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void subu(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000023 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void mult(RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000018 | (rs << OP_SH_RS) | (rt << OP_SH_RT));
+    }
+
+    void mfhi(RegisterID rd)
+    {
+        emitInst(0x00000010 | (rd << OP_SH_RD));
+    }
+
+    void mflo(RegisterID rd)
+    {
+        emitInst(0x00000012 | (rd << OP_SH_RD));
+    }
+
+    void mul(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+#if WTF_MIPS_ISA_AT_LEAST(32) 
+        emitInst(0x70000002 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+#else
+        mult(rs, rt);
+        mflo(rd);
+#endif
+    }
+
+    void andInsn(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000024 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void andi(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x30000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void nor(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000027 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void orInsn(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000025 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void ori(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x34000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void xorInsn(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x00000026 | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void xori(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x38000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void slt(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x0000002a | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void sltu(RegisterID rd, RegisterID rs, RegisterID rt)
+    {
+        emitInst(0x0000002b | (rd << OP_SH_RD) | (rs << OP_SH_RS)
+                 | (rt << OP_SH_RT));
+    }
+
+    void sltiu(RegisterID rt, RegisterID rs, int imm)
+    {
+        emitInst(0x2c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (imm & 0xffff));
+    }
+
+    void sll(RegisterID rd, RegisterID rt, int shamt)
+    {
+        emitInst(0x00000000 | (rd << OP_SH_RD) | (rt << OP_SH_RT)
+                 | ((shamt & 0x1f) << OP_SH_SHAMT));
+    }
+
+    void sllv(RegisterID rd, RegisterID rt, int rs)
+    {
+        emitInst(0x00000004 | (rd << OP_SH_RD) | (rt << OP_SH_RT)
+                 | (rs << OP_SH_RS));
+    }
+
+    void sra(RegisterID rd, RegisterID rt, int shamt)
+    {
+        emitInst(0x00000003 | (rd << OP_SH_RD) | (rt << OP_SH_RT)
+                 | ((shamt & 0x1f) << OP_SH_SHAMT));
+    }
+
+    void srav(RegisterID rd, RegisterID rt, RegisterID rs)
+    {
+        emitInst(0x00000007 | (rd << OP_SH_RD) | (rt << OP_SH_RT)
+                 | (rs << OP_SH_RS));
+    }
+
+    void lw(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x8c000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void lwl(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x88000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void lwr(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x98000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void lhu(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0x94000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        loadDelayNop();
+    }
+
+    void sw(RegisterID rt, RegisterID rs, int offset)
+    {
+        emitInst(0xac000000 | (rt << OP_SH_RT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+    }
+
+    void jr(RegisterID rs)
+    {
+        emitInst(0x00000008 | (rs << OP_SH_RS));
+    }
+
+    void jalr(RegisterID rs)
+    {
+        emitInst(0x0000f809 | (rs << OP_SH_RS));
+    }
+
+    void jal()
+    {
+        emitInst(0x0c000000);
+    }
+
+    void bkpt()
+    {
+        int value = 512; /* BRK_BUG */
+        emitInst(0x0000000d | ((value & 0x3ff) << OP_SH_CODE));
+    }
+
+    void bgez(RegisterID rs, int imm)
+    {
+        emitInst(0x04010000 | (rs << OP_SH_RS) | (imm & 0xffff));
+    }
+
+    void bltz(RegisterID rs, int imm)
+    {
+        emitInst(0x04000000 | (rs << OP_SH_RS) | (imm & 0xffff));
+    }
+
+    void beq(RegisterID rs, RegisterID rt, int imm)
+    {
+        emitInst(0x10000000 | (rs << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff));
+    }
+
+    void bne(RegisterID rs, RegisterID rt, int imm)
+    {
+        emitInst(0x14000000 | (rs << OP_SH_RS) | (rt << OP_SH_RT) | (imm & 0xffff));
+    }
+
+    void bc1t()
+    {
+        emitInst(0x45010000);
+    }
+
+    void bc1f()
+    {
+        emitInst(0x45000000);
+    }
+
+    JmpSrc newJmpSrc()
+    {
+        return JmpSrc(m_buffer.size());
+    }
+
+    void appendJump()
+    {
+        m_jumps.append(m_buffer.size());
+    }
+
+    void addd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200000 | (fd << OP_SH_FD) | (fs << OP_SH_FS)
+                 | (ft << OP_SH_FT));
+    }
+
+    void subd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200001 | (fd << OP_SH_FD) | (fs << OP_SH_FS)
+                 | (ft << OP_SH_FT));
+    }
+
+    void muld(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200002 | (fd << OP_SH_FD) | (fs << OP_SH_FS)
+                 | (ft << OP_SH_FT));
+    }
+
+    void lwc1(FPRegisterID ft, RegisterID rs, int offset)
+    {
+        emitInst(0xc4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+        copDelayNop();
+    }
+
+    void ldc1(FPRegisterID ft, RegisterID rs, int offset)
+    {
+        emitInst(0xd4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+    }
+
+    void swc1(FPRegisterID ft, RegisterID rs, int offset)
+    {
+        emitInst(0xe4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+    }
+
+    void sdc1(FPRegisterID ft, RegisterID rs, int offset)
+    {
+        emitInst(0xf4000000 | (ft << OP_SH_FT) | (rs << OP_SH_RS)
+                 | (offset & 0xffff));
+    }
+
+    void mtc1(RegisterID rt, FPRegisterID fs)
+    {
+        emitInst(0x44800000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
+        copDelayNop();
+    }
+
+    void mfc1(RegisterID rt, FPRegisterID fs)
+    {
+        emitInst(0x44000000 | (fs << OP_SH_FS) | (rt << OP_SH_RT));
+        copDelayNop();
+    }
+
+    void truncwd(FPRegisterID fd, FPRegisterID fs)
+    {
+        emitInst(0x4620000d | (fd << OP_SH_FD) | (fs << OP_SH_FS));
+    }
+
+    void cvtdw(FPRegisterID fd, FPRegisterID fs)
+    {
+        emitInst(0x46800021 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
+    }
+
+    void ceqd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200032 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cngtd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x4620003f | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cnged(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x4620003d | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cltd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x4620003c | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cled(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x4620003e | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cueqd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200033 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void coled(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200036 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void coltd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200034 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void culed(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200037 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    void cultd(FPRegisterID fs, FPRegisterID ft)
+    {
+        emitInst(0x46200035 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
+        copDelayNop();
+    }
+
+    // General helpers
+
+    JmpDst label()
+    {
+        return JmpDst(m_buffer.size());
+    }
+
+    JmpDst align(int alignment)
+    {
+        while (!m_buffer.isAligned(alignment))
+            bkpt();
+
+        return label();
+    }
+
+    static void* getRelocatedAddress(void* code, JmpSrc jump)
+    {
+        ASSERT(jump.m_offset != -1);
+        void* b = reinterpret_cast<void*>((reinterpret_cast<intptr_t>(code)) + jump.m_offset);
+        return b;
+    }
+
+    static void* getRelocatedAddress(void* code, JmpDst label)
+    {
+        void* b = reinterpret_cast<void*>((reinterpret_cast<intptr_t>(code)) + label.m_offset);
+        return b;
+    }
+
+    static int getDifferenceBetweenLabels(JmpDst from, JmpDst to)
+    {
+        return to.m_offset - from.m_offset;
+    }
+
+    static int getDifferenceBetweenLabels(JmpDst from, JmpSrc to)
+    {
+        return to.m_offset - from.m_offset;
+    }
+
+    static int getDifferenceBetweenLabels(JmpSrc from, JmpDst to)
+    {
+        return to.m_offset - from.m_offset;
+    }
+
+    // Assembler admin methods:
+
+    size_t size() const
+    {
+        return m_buffer.size();
+    }
+
+    void* executableCopy(ExecutablePool* allocator)
+    {
+        void *result = m_buffer.executableCopy(allocator);
+        if (!result)
+            return 0;
+
+        relocateJumps(m_buffer.data(), result);
+        return result;
+    }
+
+    static unsigned getCallReturnOffset(JmpSrc call)
+    {
+        // The return address is after a call and a delay slot instruction
+        return call.m_offset;
+    }
+
+    // Linking & patching:
+    //
+    // 'link' and 'patch' methods are for use on unprotected code - such as the code
+    // within the AssemblerBuffer, and code being patched by the patch buffer.  Once
+    // code has been finalized it is (platform support permitting) within a non-
+    // writable region of memory; to modify the code in an execute-only execuable
+    // pool the 'repatch' and 'relink' methods should be used.
+
+    void linkJump(JmpSrc from, JmpDst to)
+    {
+        ASSERT(to.m_offset != -1);
+        ASSERT(from.m_offset != -1);
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(m_buffer.data()) + from.m_offset);
+        MIPSWord* toPos = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(m_buffer.data()) + to.m_offset);
+
+        ASSERT(!(*(insn - 1)) && !(*(insn - 2)) && !(*(insn - 3)) && !(*(insn - 5)));
+        insn = insn - 6;
+        linkWithOffset(insn, toPos);
+    }
+
+    static void linkJump(void* code, JmpSrc from, void* to)
+    {
+        ASSERT(from.m_offset != -1);
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
+
+        ASSERT(!(*(insn - 1)) && !(*(insn - 2)) && !(*(insn - 3)) && !(*(insn - 5)));
+        insn = insn - 6;
+        linkWithOffset(insn, to);
+    }
+
+    static void linkCall(void* code, JmpSrc from, void* to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
+        linkCallInternal(insn, to);
+    }
+
+    static void linkPointer(void* code, JmpDst from, void* to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(code) + from.m_offset);
+        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
+        *insn = (*insn & 0xffff0000) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
+        insn++;
+        ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
+        *insn = (*insn & 0xffff0000) | (reinterpret_cast<intptr_t>(to) & 0xffff);
+    }
+
+    static void relinkJump(void* from, void* to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+
+        ASSERT(!(*(insn - 1)) && !(*(insn - 5)));
+        insn = insn - 6;
+        int flushSize = linkWithOffset(insn, to);
+
+        ExecutableAllocator::cacheFlush(insn, flushSize);
+    }
+
+    static void relinkCall(void* from, void* to)
+    {
+        void* start;
+        int size = linkCallInternal(from, to);
+        if (size == sizeof(MIPSWord))
+            start = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(from) - 2 * sizeof(MIPSWord));
+        else
+            start = reinterpret_cast<void*>(reinterpret_cast<intptr_t>(from) - 4 * sizeof(MIPSWord));
+
+        ExecutableAllocator::cacheFlush(start, size);
+    }
+
+    static void repatchInt32(void* from, int32_t to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
+        *insn = (*insn & 0xffff0000) | ((to >> 16) & 0xffff);
+        insn++;
+        ASSERT((*insn & 0xfc000000) == 0x34000000); // ori
+        *insn = (*insn & 0xffff0000) | (to & 0xffff);
+        insn--;
+        ExecutableAllocator::cacheFlush(insn, 2 * sizeof(MIPSWord));
+    }
+
+    static void repatchPointer(void* from, void* to)
+    {
+        repatchInt32(from, reinterpret_cast<int32_t>(to));
+    }
+
+    static void repatchLoadPtrToLEA(void* from)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+        insn = insn + 3;
+        ASSERT((*insn & 0xfc000000) == 0x8c000000); // lw
+        /* lw -> addiu */
+        *insn = 0x24000000 | (*insn & 0x03ffffff);
+
+        ExecutableAllocator::cacheFlush(insn, sizeof(MIPSWord));
+    }
+
+private:
+
+    /* Update each jump in the buffer of newBase.  */
+    void relocateJumps(void* oldBase, void* newBase)
+    {
+        // Check each jump
+        for (Jumps::Iterator iter = m_jumps.begin(); iter != m_jumps.end(); ++iter) {
+            int pos = *iter;
+            MIPSWord* insn = reinterpret_cast<MIPSWord*>(reinterpret_cast<intptr_t>(newBase) + pos);
+            insn = insn + 2;
+            // Need to make sure we have 5 valid instructions after pos
+            if ((unsigned int)pos >= m_buffer.size() - 5 * sizeof(MIPSWord))
+                continue;
+
+            if ((*insn & 0xfc000000) == 0x08000000) { // j
+                int offset = *insn & 0x03ffffff;
+                int oldInsnAddress = (int)insn - (int)newBase + (int)oldBase;
+                int topFourBits = (oldInsnAddress + 4) >> 28;
+                int oldTargetAddress = (topFourBits << 28) | (offset << 2);
+                int newTargetAddress = oldTargetAddress - (int)oldBase + (int)newBase;
+                int newInsnAddress = (int)insn;
+                if (((newInsnAddress + 4) >> 28) == (newTargetAddress >> 28))
+                    *insn = 0x08000000 | ((newTargetAddress >> 2) & 0x3ffffff);
+                else {
+                    /* lui */
+                    *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
+                    /* ori */
+                    *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
+                    /* jr */
+                    *(insn + 2) = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
+                }
+            } else if ((*insn & 0xffe00000) == 0x3c000000) { // lui
+                int high = (*insn & 0xffff) << 16;
+                int low = *(insn + 1) & 0xffff;
+                int oldTargetAddress = high | low;
+                int newTargetAddress = oldTargetAddress - (int)oldBase + (int)newBase;
+                /* lui */
+                *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
+                /* ori */
+                *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
+            }
+        }
+    }
+
+    static int linkWithOffset(MIPSWord* insn, void* to)
+    {
+        ASSERT((*insn & 0xfc000000) == 0x10000000 // beq
+               || (*insn & 0xfc000000) == 0x14000000 // bne
+               || (*insn & 0xffff0000) == 0x45010000 // bc1t
+               || (*insn & 0xffff0000) == 0x45000000); // bc1f
+        intptr_t diff = (reinterpret_cast<intptr_t>(to)
+                         - reinterpret_cast<intptr_t>(insn) - 4) >> 2;
+
+        if (diff < -32768 || diff > 32767 || *(insn + 2) != 0x10000003) {
+            /*
+                Convert the sequence:
+                  beq $2, $3, target
+                  nop
+                  b 1f
+                  nop
+                  nop
+                  nop
+                1:
+
+                to the new sequence if possible:
+                  bne $2, $3, 1f
+                  nop
+                  j    target
+                  nop
+                  nop
+                  nop
+                1:
+
+                OR to the new sequence:
+                  bne $2, $3, 1f
+                  nop
+                  lui $25, target >> 16
+                  ori $25, $25, target & 0xffff
+                  jr $25
+                  nop
+                1:
+
+                Note: beq/bne/bc1t are converted to bne/beq/bc1f.
+            */
+
+            if (*(insn + 2) == 0x10000003) {
+                if ((*insn & 0xfc000000) == 0x10000000) // beq
+                    *insn = (*insn & 0x03ff0000) | 0x14000005; // bne
+                else if ((*insn & 0xfc000000) == 0x14000000) // bne
+                    *insn = (*insn & 0x03ff0000) | 0x10000005; // beq
+                else if ((*insn & 0xffff0000) == 0x45010000) // bc1t
+                    *insn = 0x45000005; // bc1f
+                else
+                    ASSERT(0);
+            }
+
+            insn = insn + 2;
+            if ((reinterpret_cast<intptr_t>(insn) + 4) >> 28
+                == reinterpret_cast<intptr_t>(to) >> 28) {
+                *insn = 0x08000000 | ((reinterpret_cast<intptr_t>(to) >> 2) & 0x3ffffff);
+                *(insn + 1) = 0;
+                return 4 * sizeof(MIPSWord);
+            }
+
+            intptr_t newTargetAddress = reinterpret_cast<intptr_t>(to);
+            /* lui */
+            *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((newTargetAddress >> 16) & 0xffff);
+            /* ori */
+            *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (newTargetAddress & 0xffff);
+            /* jr */
+            *(insn + 2) = 0x00000008 | (MIPSRegisters::t9 << OP_SH_RS);
+            return 5 * sizeof(MIPSWord);
+        }
+
+        *insn = (*insn & 0xffff0000) | (diff & 0xffff);
+        return sizeof(MIPSWord);
+    }
+
+    static int linkCallInternal(void* from, void* to)
+    {
+        MIPSWord* insn = reinterpret_cast<MIPSWord*>(from);
+        insn = insn - 4;
+
+        if ((*(insn + 2) & 0xfc000000) == 0x0c000000) { // jal
+            if ((reinterpret_cast<intptr_t>(from) - 4) >> 28
+                == reinterpret_cast<intptr_t>(to) >> 28) {
+                *(insn + 2) = 0x0c000000 | ((reinterpret_cast<intptr_t>(to) >> 2) & 0x3ffffff);
+                return sizeof(MIPSWord);
+            }
+
+            /* lui $25, (to >> 16) & 0xffff */
+            *insn = 0x3c000000 | (MIPSRegisters::t9 << OP_SH_RT) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
+            /* ori $25, $25, to & 0xffff */
+            *(insn + 1) = 0x34000000 | (MIPSRegisters::t9 << OP_SH_RT) | (MIPSRegisters::t9 << OP_SH_RS) | (reinterpret_cast<intptr_t>(to) & 0xffff);
+            /* jalr $25 */
+            *(insn + 2) = 0x0000f809 | (MIPSRegisters::t9 << OP_SH_RS);
+            return 3 * sizeof(MIPSWord);
+        }
+
+        ASSERT((*insn & 0xffe00000) == 0x3c000000); // lui
+        ASSERT((*(insn + 1) & 0xfc000000) == 0x34000000); // ori
+
+        /* lui */
+        *insn = (*insn & 0xffff0000) | ((reinterpret_cast<intptr_t>(to) >> 16) & 0xffff);
+        /* ori */
+        *(insn + 1) = (*(insn + 1) & 0xffff0000) | (reinterpret_cast<intptr_t>(to) & 0xffff);
+        return 2 * sizeof(MIPSWord);
+    }
+
+    AssemblerBuffer m_buffer;
+    Jumps m_jumps;
+};
+
+} // namespace JSC
+
+#endif // ENABLE(ASSEMBLER) && CPU(MIPS)
+
+#endif // MIPSAssembler_h
diff --git a/JavaScriptCore/assembler/MacroAssembler.h b/JavaScriptCore/assembler/MacroAssembler.h
index 76bd205..d15c0d9 100644
--- a/JavaScriptCore/assembler/MacroAssembler.h
+++ b/JavaScriptCore/assembler/MacroAssembler.h
@@ -38,6 +38,12 @@ namespace JSC { typedef MacroAssemblerARMv7 MacroAssemblerBase; };
 #include "MacroAssemblerARM.h"
 namespace JSC { typedef MacroAssemblerARM MacroAssemblerBase; };
 
+#elif CPU(MIPS)
+#include "MacroAssemblerMIPS.h"
+namespace JSC {
+typedef MacroAssemblerMIPS MacroAssemblerBase;
+};
+
 #elif CPU(X86)
 #include "MacroAssemblerX86.h"
 namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; };
diff --git a/JavaScriptCore/assembler/MacroAssemblerMIPS.h b/JavaScriptCore/assembler/MacroAssemblerMIPS.h
new file mode 100644
index 0000000..08b3a66
--- /dev/null
+++ b/JavaScriptCore/assembler/MacroAssemblerMIPS.h
@@ -0,0 +1,1660 @@
+/*
+ * Copyright (C) 2008 Apple Inc. All rights reserved.
+ * Copyright (C) 2010 MIPS Technologies, Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY MIPS TECHNOLOGIES, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL MIPS TECHNOLOGIES, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef MacroAssemblerMIPS_h
+#define MacroAssemblerMIPS_h
+
+#include <wtf/Platform.h>
+
+#if ENABLE(ASSEMBLER) && CPU(MIPS)
+
+#include "AbstractMacroAssembler.h"
+#include "MIPSAssembler.h"
+
+namespace JSC {
+
+class MacroAssemblerMIPS : public AbstractMacroAssembler<MIPSAssembler> {
+public:
+
+    MacroAssemblerMIPS()
+        : m_fixedWidth(false)
+    {
+    }
+
+    static const Scale ScalePtr = TimesFour;
+
+    // For storing immediate number
+    static const RegisterID immTempRegister = MIPSRegisters::t0;
+    // For storing data loaded from the memory
+    static const RegisterID dataTempRegister = MIPSRegisters::t1;
+    // For storing address base
+    static const RegisterID addrTempRegister = MIPSRegisters::t2;
+    // For storing compare result
+    static const RegisterID cmpTempRegister = MIPSRegisters::t3;
+
+    // FP temp register
+    static const FPRegisterID fpTempRegister = MIPSRegisters::f16;
+
+    enum Condition {
+        Equal,
+        NotEqual,
+        Above,
+        AboveOrEqual,
+        Below,
+        BelowOrEqual,
+        GreaterThan,
+        GreaterThanOrEqual,
+        LessThan,
+        LessThanOrEqual,
+        Overflow,
+        Signed,
+        Zero,
+        NonZero
+    };
+
+    enum DoubleCondition {
+        DoubleEqual,
+        DoubleNotEqual,
+        DoubleGreaterThan,
+        DoubleGreaterThanOrEqual,
+        DoubleLessThan,
+        DoubleLessThanOrEqual,
+        DoubleEqualOrUnordered,
+        DoubleNotEqualOrUnordered,
+        DoubleGreaterThanOrUnordered,
+        DoubleGreaterThanOrEqualOrUnordered,
+        DoubleLessThanOrUnordered,
+        DoubleLessThanOrEqualOrUnordered
+    };
+
+    static const RegisterID stackPointerRegister = MIPSRegisters::sp;
+    static const RegisterID returnAddressRegister = MIPSRegisters::ra;
+
+    // Integer arithmetic operations:
+    //
+    // Operations are typically two operand - operation(source, srcDst)
+    // For many operations the source may be an Imm32, the srcDst operand
+    // may often be a memory location (explictly described using an Address
+    // object).
+
+    void add32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.addu(dest, dest, src);
+    }
+
+    void add32(Imm32 imm, RegisterID dest)
+    {
+        add32(imm, dest, dest);
+    }
+
+    void add32(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        if (!imm.m_isPointer && imm.m_value >= -32768 && imm.m_value <= 32767
+            && !m_fixedWidth) {
+            /*
+              addiu     dest, src, imm
+            */
+            m_assembler.addiu(dest, src, imm.m_value);
+        } else {
+            /*
+              li        immTemp, imm
+              addu      dest, src, immTemp
+            */
+            move(imm, immTempRegister);
+            m_assembler.addu(dest, src, immTempRegister);
+        }
+    }
+
+    void add32(Imm32 imm, Address address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+              lw        dataTemp, offset(base)
+              li        immTemp, imm
+              addu      dataTemp, dataTemp, immTemp
+              sw        dataTemp, offset(base)
+            */
+            m_assembler.lw(dataTempRegister, address.base, address.offset);
+            if (!imm.m_isPointer
+                && imm.m_value >= -32768 && imm.m_value <= 32767
+                && !m_fixedWidth)
+                m_assembler.addiu(dataTempRegister, dataTempRegister,
+                                  imm.m_value);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.addu(dataTempRegister, dataTempRegister,
+                                 immTempRegister);
+            }
+            m_assembler.sw(dataTempRegister, address.base, address.offset);
+        } else {
+            /*
+              lui       addrTemp, (offset + 0x8000) >> 16
+              addu      addrTemp, addrTemp, base
+              lw        dataTemp, (offset & 0xffff)(addrTemp)
+              li        immtemp, imm
+              addu      dataTemp, dataTemp, immTemp
+              sw        dataTemp, (offset & 0xffff)(addrTemp)
+            */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lw(dataTempRegister, addrTempRegister, address.offset);
+
+            if (imm.m_value >= -32768 && imm.m_value <= 32767 && !m_fixedWidth)
+                m_assembler.addiu(dataTempRegister, dataTempRegister,
+                                  imm.m_value);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.addu(dataTempRegister, dataTempRegister,
+                                 immTempRegister);
+            }
+            m_assembler.sw(dataTempRegister, addrTempRegister, address.offset);
+        }
+    }
+
+    void add32(Address src, RegisterID dest)
+    {
+        load32(src, dataTempRegister);
+        add32(dataTempRegister, dest);
+    }
+
+    void add32(RegisterID src, Address dest)
+    {
+        if (dest.offset >= -32768 && dest.offset <= 32767 && !m_fixedWidth) {
+            /*
+              lw        dataTemp, offset(base)
+              addu      dataTemp, dataTemp, src
+              sw        dataTemp, offset(base)
+            */
+            m_assembler.lw(dataTempRegister, dest.base, dest.offset);
+            m_assembler.addu(dataTempRegister, dataTempRegister, src);
+            m_assembler.sw(dataTempRegister, dest.base, dest.offset);
+        } else {
+            /*
+              lui       addrTemp, (offset + 0x8000) >> 16
+              addu      addrTemp, addrTemp, base
+              lw        dataTemp, (offset & 0xffff)(addrTemp)
+              addu      dataTemp, dataTemp, src
+              sw        dataTemp, (offset & 0xffff)(addrTemp)
+            */
+            m_assembler.lui(addrTempRegister, (dest.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, dest.base);
+            m_assembler.lw(dataTempRegister, addrTempRegister, dest.offset);
+            m_assembler.addu(dataTempRegister, dataTempRegister, src);
+            m_assembler.sw(dataTempRegister, addrTempRegister, dest.offset);
+        }
+    }
+
+    void add32(Imm32 imm, AbsoluteAddress address)
+    {
+        /*
+           li   addrTemp, address
+           li   immTemp, imm
+           lw   dataTemp, 0(addrTemp)
+           addu dataTemp, dataTemp, immTemp
+           sw   dataTemp, 0(addrTemp)
+        */
+        move(ImmPtr(address.m_ptr), addrTempRegister);
+        m_assembler.lw(dataTempRegister, addrTempRegister, 0);
+        if (!imm.m_isPointer && imm.m_value >= -32768 && imm.m_value <= 32767
+            && !m_fixedWidth)
+            m_assembler.addiu(dataTempRegister, dataTempRegister, imm.m_value);
+        else {
+            move(imm, immTempRegister);
+            m_assembler.addu(dataTempRegister, dataTempRegister, immTempRegister);
+        }
+        m_assembler.sw(dataTempRegister, addrTempRegister, 0);
+    }
+
+    void and32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.andInsn(dest, dest, src);
+    }
+
+    void and32(Imm32 imm, RegisterID dest)
+    {
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+            move(MIPSRegisters::zero, dest);
+        else if (!imm.m_isPointer && imm.m_value > 0 && imm.m_value < 65535
+                 && !m_fixedWidth)
+            m_assembler.andi(dest, dest, imm.m_value);
+        else {
+            /*
+              li        immTemp, imm
+              and       dest, dest, immTemp
+            */
+            move(imm, immTempRegister);
+            m_assembler.andInsn(dest, dest, immTempRegister);
+        }
+    }
+
+    void lshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.sll(dest, dest, imm.m_value);
+    }
+
+    void lshift32(RegisterID shiftAmount, RegisterID dest)
+    {
+        m_assembler.sllv(dest, dest, shiftAmount);
+    }
+
+    void mul32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.mul(dest, dest, src);
+    }
+
+    void mul32(Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+            move(MIPSRegisters::zero, dest);
+        else if (!imm.m_isPointer && imm.m_value == 1 && !m_fixedWidth)
+            move(src, dest);
+        else {
+            /*
+                li      dataTemp, imm
+                mul     dest, src, dataTemp
+            */
+            move(imm, dataTempRegister);
+            m_assembler.mul(dest, src, dataTempRegister);
+        }
+    }
+
+    void not32(RegisterID srcDest)
+    {
+        m_assembler.nor(srcDest, srcDest, MIPSRegisters::zero);
+    }
+
+    void or32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.orInsn(dest, dest, src);
+    }
+
+    void or32(Imm32 imm, RegisterID dest)
+    {
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+            return;
+
+        if (!imm.m_isPointer && imm.m_value > 0 && imm.m_value < 65535
+            && !m_fixedWidth) {
+            m_assembler.ori(dest, dest, imm.m_value);
+            return;
+        }
+
+        /*
+            li      dataTemp, imm
+            or      dest, dest, dataTemp
+        */
+        move(imm, dataTempRegister);
+        m_assembler.orInsn(dest, dest, dataTempRegister);
+    }
+
+    void rshift32(RegisterID shiftAmount, RegisterID dest)
+    {
+        m_assembler.srav(dest, dest, shiftAmount);
+    }
+
+    void rshift32(Imm32 imm, RegisterID dest)
+    {
+        m_assembler.sra(dest, dest, imm.m_value);
+    }
+
+    void sub32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.subu(dest, dest, src);
+    }
+
+    void sub32(Imm32 imm, RegisterID dest)
+    {
+        if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
+            && !m_fixedWidth) {
+            /*
+              addiu     dest, src, imm
+            */
+            m_assembler.addiu(dest, dest, -imm.m_value);
+        } else {
+            /*
+              li        immTemp, imm
+              subu      dest, src, immTemp
+            */
+            move(imm, immTempRegister);
+            m_assembler.subu(dest, dest, immTempRegister);
+        }
+    }
+
+    void sub32(Imm32 imm, Address address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+              lw        dataTemp, offset(base)
+              li        immTemp, imm
+              subu      dataTemp, dataTemp, immTemp
+              sw        dataTemp, offset(base)
+            */
+            m_assembler.lw(dataTempRegister, address.base, address.offset);
+            if (!imm.m_isPointer
+                && imm.m_value >= -32767 && imm.m_value <= 32768
+                && !m_fixedWidth)
+                m_assembler.addiu(dataTempRegister, dataTempRegister,
+                                  -imm.m_value);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.subu(dataTempRegister, dataTempRegister,
+                                 immTempRegister);
+            }
+            m_assembler.sw(dataTempRegister, address.base, address.offset);
+        } else {
+            /*
+              lui       addrTemp, (offset + 0x8000) >> 16
+              addu      addrTemp, addrTemp, base
+              lw        dataTemp, (offset & 0xffff)(addrTemp)
+              li        immtemp, imm
+              subu      dataTemp, dataTemp, immTemp
+              sw        dataTemp, (offset & 0xffff)(addrTemp)
+            */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lw(dataTempRegister, addrTempRegister, address.offset);
+
+            if (!imm.m_isPointer
+                && imm.m_value >= -32767 && imm.m_value <= 32768
+                && !m_fixedWidth)
+                m_assembler.addiu(dataTempRegister, dataTempRegister,
+                                  -imm.m_value);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.subu(dataTempRegister, dataTempRegister,
+                                 immTempRegister);
+            }
+            m_assembler.sw(dataTempRegister, addrTempRegister, address.offset);
+        }
+    }
+
+    void sub32(Address src, RegisterID dest)
+    {
+        load32(src, dataTempRegister);
+        sub32(dataTempRegister, dest);
+    }
+
+    void sub32(Imm32 imm, AbsoluteAddress address)
+    {
+        /*
+           li   addrTemp, address
+           li   immTemp, imm
+           lw   dataTemp, 0(addrTemp)
+           subu dataTemp, dataTemp, immTemp
+           sw   dataTemp, 0(addrTemp)
+        */
+        move(ImmPtr(address.m_ptr), addrTempRegister);
+        m_assembler.lw(dataTempRegister, addrTempRegister, 0);
+
+        if (!imm.m_isPointer && imm.m_value >= -32767 && imm.m_value <= 32768
+            && !m_fixedWidth) {
+            m_assembler.addiu(dataTempRegister, dataTempRegister,
+                              -imm.m_value);
+        } else {
+            move(imm, immTempRegister);
+            m_assembler.subu(dataTempRegister, dataTempRegister, immTempRegister);
+        }
+        m_assembler.sw(dataTempRegister, addrTempRegister, 0);
+    }
+
+    void xor32(RegisterID src, RegisterID dest)
+    {
+        m_assembler.xorInsn(dest, dest, src);
+    }
+
+    void xor32(Imm32 imm, RegisterID dest)
+    {
+        /*
+            li  immTemp, imm
+            xor dest, dest, immTemp
+        */
+        move(imm, immTempRegister);
+        m_assembler.xorInsn(dest, dest, immTempRegister);
+    }
+
+    // Memory access operations:
+    //
+    // Loads are of the form load(address, destination) and stores of the form
+    // store(source, address).  The source for a store may be an Imm32.  Address
+    // operand objects to loads and store will be implicitly constructed if a
+    // register is passed.
+
+    void load32(ImplicitAddress address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth)
+            m_assembler.lw(dest, address.base, address.offset);
+        else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                lw      dest, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lw(dest, addrTempRegister, address.offset);
+        }
+    }
+
+    void load32(BaseIndex address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lw      dest, address.offset(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lw(dest, addrTempRegister, address.offset);
+        } else {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lui     immTemp, (address.offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, immTemp
+                lw      dest, (address.offset & 0xffff)(at)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister,
+                             immTempRegister);
+            m_assembler.lw(dest, addrTempRegister, address.offset);
+        }
+    }
+
+    void load32WithUnalignedHalfWords(BaseIndex address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32764
+            && !m_fixedWidth) {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                (Big-Endian)
+                lwl     dest, address.offset(addrTemp)
+                lwr     dest, address.offset+3(addrTemp)
+                (Little-Endian)
+                lwl     dest, address.offset+3(addrTemp)
+                lwr     dest, address.offset(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+#if CPU(BIG_ENDIAN)
+            m_assembler.lwl(dest, addrTempRegister, address.offset);
+            m_assembler.lwr(dest, addrTempRegister, address.offset + 3);
+#else
+            m_assembler.lwl(dest, addrTempRegister, address.offset + 3);
+            m_assembler.lwr(dest, addrTempRegister, address.offset);
+
+#endif
+        } else {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lui     immTemp, address.offset >> 16
+                ori     immTemp, immTemp, address.offset & 0xffff
+                addu    addrTemp, addrTemp, immTemp
+                (Big-Endian)
+                lw      dest, 0(at)
+                lw      dest, 3(at)
+                (Little-Endian)
+                lw      dest, 3(at)
+                lw      dest, 0(at)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lui(immTempRegister, address.offset >> 16);
+            m_assembler.ori(immTempRegister, immTempRegister, address.offset);
+            m_assembler.addu(addrTempRegister, addrTempRegister,
+                             immTempRegister);
+#if CPU(BIG_ENDIAN)
+            m_assembler.lwl(dest, addrTempRegister, 0);
+            m_assembler.lwr(dest, addrTempRegister, 3);
+#else
+            m_assembler.lwl(dest, addrTempRegister, 3);
+            m_assembler.lwr(dest, addrTempRegister, 0);
+#endif
+        }
+    }
+
+    void load32(void* address, RegisterID dest)
+    {
+        /*
+            li  addrTemp, address
+            lw  dest, 0(addrTemp)
+        */
+        move(ImmPtr(address), addrTempRegister);
+        m_assembler.lw(dest, addrTempRegister, 0);
+    }
+
+    DataLabel32 load32WithAddressOffsetPatch(Address address, RegisterID dest)
+    {
+        m_fixedWidth = true;
+        /*
+            lui addrTemp, address.offset >> 16
+            ori addrTemp, addrTemp, address.offset & 0xffff
+            addu        addrTemp, addrTemp, address.base
+            lw  dest, 0(addrTemp)
+        */
+        DataLabel32 dataLabel(this);
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.lw(dest, addrTempRegister, 0);
+        m_fixedWidth = false;
+        return dataLabel;
+    }
+
+    Label loadPtrWithPatchToLEA(Address address, RegisterID dest)
+    {
+        m_fixedWidth = true;
+        /*
+            lui         addrTemp, address.offset >> 16
+            ori         addrTemp, addrTemp, address.offset & 0xffff
+            addu        addrTemp, addrTemp, address.base
+            lw          dest, 0(addrTemp)
+        */
+        Label label(this);
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.lw(dest, addrTempRegister, 0);
+        m_fixedWidth = false;
+        return label;
+    }
+
+    Label loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
+    {
+        return loadPtrWithPatchToLEA(address, dest);
+    }
+
+    /* Need to use zero-extened load half-word for load16.  */
+    void load16(BaseIndex address, RegisterID dest)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lhu     dest, address.offset(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lhu(dest, addrTempRegister, address.offset);
+        } else {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lui     immTemp, (address.offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, immTemp
+                lhu     dest, (address.offset & 0xffff)(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister,
+                             immTempRegister);
+            m_assembler.lhu(dest, addrTempRegister, address.offset);
+        }
+    }
+
+    DataLabel32 store32WithAddressOffsetPatch(RegisterID src, Address address)
+    {
+        m_fixedWidth = true;
+        /*
+            lui addrTemp, address.offset >> 16
+            ori addrTemp, addrTemp, address.offset & 0xffff
+            addu        addrTemp, addrTemp, address.base
+            sw  src, 0(addrTemp)
+        */
+        DataLabel32 dataLabel(this);
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.sw(src, addrTempRegister, 0);
+        m_fixedWidth = false;
+        return dataLabel;
+    }
+
+    void store32(RegisterID src, ImplicitAddress address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth)
+            m_assembler.sw(src, address.base, address.offset);
+        else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                sw      src, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.sw(src, addrTempRegister, address.offset);
+        }
+    }
+
+    void store32(RegisterID src, BaseIndex address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                sw      src, address.offset(addrTemp)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.sw(src, addrTempRegister, address.offset);
+        } else {
+            /*
+                sll     addrTemp, address.index, address.scale
+                addu    addrTemp, addrTemp, address.base
+                lui     immTemp, (address.offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, immTemp
+                sw      src, (address.offset & 0xffff)(at)
+            */
+            m_assembler.sll(addrTempRegister, address.index, address.scale);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.lui(immTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister,
+                             immTempRegister);
+            m_assembler.sw(src, addrTempRegister, address.offset);
+        }
+    }
+
+    void store32(Imm32 imm, ImplicitAddress address)
+    {
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            if (!imm.m_isPointer && !imm.m_value)
+                m_assembler.sw(MIPSRegisters::zero, address.base,
+                               address.offset);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.sw(immTempRegister, address.base, address.offset);
+            }
+        } else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                sw      immTemp, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+                m_assembler.sw(MIPSRegisters::zero, addrTempRegister,
+                               address.offset);
+            else {
+                move(imm, immTempRegister);
+                m_assembler.sw(immTempRegister, addrTempRegister,
+                               address.offset);
+            }
+        }
+    }
+
+    void store32(RegisterID src, void* address)
+    {
+        /*
+            li  addrTemp, address
+            sw  src, 0(addrTemp)
+        */
+        move(ImmPtr(address), addrTempRegister);
+        m_assembler.sw(src, addrTempRegister, 0);
+    }
+
+    void store32(Imm32 imm, void* address)
+    {
+        /*
+            li  immTemp, imm
+            li  addrTemp, address
+            sw  src, 0(addrTemp)
+        */
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth) {
+            move(ImmPtr(address), addrTempRegister);
+            m_assembler.sw(MIPSRegisters::zero, addrTempRegister, 0);
+        } else {
+            move(imm, immTempRegister);
+            move(ImmPtr(address), addrTempRegister);
+            m_assembler.sw(immTempRegister, addrTempRegister, 0);
+        }
+    }
+
+    // Floating-point operations:
+
+    bool supportsFloatingPoint() const
+    {
+#if WTF_MIPS_DOUBLE_FLOAT
+        return true;
+#else
+        return false;
+#endif
+    }
+
+    bool supportsFloatingPointTruncate() const
+    {
+#if WTF_MIPS_DOUBLE_FLOAT && WTF_MIPS_ISA_AT_LEAST(2)
+        return true;
+#else
+        return false;
+#endif
+    }
+
+    // Stack manipulation operations:
+    //
+    // The ABI is assumed to provide a stack abstraction to memory,
+    // containing machine word sized units of data.  Push and pop
+    // operations add and remove a single register sized unit of data
+    // to or from the stack.  Peek and poke operations read or write
+    // values on the stack, without moving the current stack position.
+
+    void pop(RegisterID dest)
+    {
+        m_assembler.lw(dest, MIPSRegisters::sp, 0);
+        m_assembler.addiu(MIPSRegisters::sp, MIPSRegisters::sp, 4);
+    }
+
+    void push(RegisterID src)
+    {
+        m_assembler.addiu(MIPSRegisters::sp, MIPSRegisters::sp, -4);
+        m_assembler.sw(src, MIPSRegisters::sp, 0);
+    }
+
+    void push(Address address)
+    {
+        load32(address, dataTempRegister);
+        push(dataTempRegister);
+    }
+
+    void push(Imm32 imm)
+    {
+        move(imm, immTempRegister);
+        push(immTempRegister);
+    }
+
+    // Register move operations:
+    //
+    // Move values in registers.
+
+    void move(Imm32 imm, RegisterID dest)
+    {
+        if (!imm.m_isPointer && !imm.m_value && !m_fixedWidth)
+            move(MIPSRegisters::zero, dest);
+        else if (imm.m_isPointer || m_fixedWidth) {
+            m_assembler.lui(dest, imm.m_value >> 16);
+            m_assembler.ori(dest, dest, imm.m_value);
+        } else
+            m_assembler.li(dest, imm.m_value);
+    }
+
+    void move(RegisterID src, RegisterID dest)
+    {
+        if (src != dest || m_fixedWidth)
+            m_assembler.move(dest, src);
+    }
+
+    void move(ImmPtr imm, RegisterID dest)
+    {
+        move(Imm32(imm), dest);
+    }
+
+    void swap(RegisterID reg1, RegisterID reg2)
+    {
+        move(reg1, immTempRegister);
+        move(reg2, reg1);
+        move(immTempRegister, reg2);
+    }
+
+    void signExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        if (src != dest || m_fixedWidth)
+            move(src, dest);
+    }
+
+    void zeroExtend32ToPtr(RegisterID src, RegisterID dest)
+    {
+        if (src != dest || m_fixedWidth)
+            move(src, dest);
+    }
+
+    // Forwards / external control flow operations:
+    //
+    // This set of jump and conditional branch operations return a Jump
+    // object which may linked at a later point, allow forwards jump,
+    // or jumps that will require external linkage (after the code has been
+    // relocated).
+    //
+    // For branches, signed <, >, <= and >= are denoted as l, g, le, and ge
+    // respecitvely, for unsigned comparisons the names b, a, be, and ae are
+    // used (representing the names 'below' and 'above').
+    //
+    // Operands to the comparision are provided in the expected order, e.g.
+    // jle32(reg1, Imm32(5)) will branch if the value held in reg1, when
+    // treated as a signed 32bit value, is less than or equal to 5.
+    //
+    // jz and jnz test whether the first operand is equal to zero, and take
+    // an optional second operand of a mask under which to perform the test.
+
+    Jump branch32(Condition cond, RegisterID left, RegisterID right)
+    {
+        if (cond == Equal || cond == Zero)
+            return branchEqual(left, right);
+        if (cond == NotEqual || cond == NonZero)
+            return branchNotEqual(left, right);
+        if (cond == Above) {
+            m_assembler.sltu(cmpTempRegister, right, left);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == AboveOrEqual) {
+            m_assembler.sltu(cmpTempRegister, left, right);
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Below) {
+            m_assembler.sltu(cmpTempRegister, left, right);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == BelowOrEqual) {
+            m_assembler.sltu(cmpTempRegister, right, left);
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == GreaterThan) {
+            m_assembler.slt(cmpTempRegister, right, left);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == GreaterThanOrEqual) {
+            m_assembler.slt(cmpTempRegister, left, right);
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == LessThan) {
+            m_assembler.slt(cmpTempRegister, left, right);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == LessThanOrEqual) {
+            m_assembler.slt(cmpTempRegister, right, left);
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Overflow) {
+            /*
+                xor     cmpTemp, left, right
+                bgez    No_overflow, cmpTemp    # same sign bit -> no overflow
+                nop
+                subu    cmpTemp, left, right
+                xor     cmpTemp, cmpTemp, left
+                bgez    No_overflow, cmpTemp    # same sign bit -> no overflow
+                nop
+                b       Overflow
+                nop
+                nop
+                nop
+                nop
+                nop
+              No_overflow:
+            */
+            m_assembler.xorInsn(cmpTempRegister, left, right);
+            m_assembler.bgez(cmpTempRegister, 11);
+            m_assembler.nop();
+            m_assembler.subu(cmpTempRegister, left, right);
+            m_assembler.xorInsn(cmpTempRegister, cmpTempRegister, left);
+            m_assembler.bgez(cmpTempRegister, 7);
+            m_assembler.nop();
+            return jump();
+        }
+        if (cond == Signed) {
+            m_assembler.subu(cmpTempRegister, left, right);
+            // Check if the result is negative.
+            m_assembler.slt(cmpTempRegister, cmpTempRegister,
+                            MIPSRegisters::zero);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        ASSERT(0);
+
+        return Jump();
+    }
+
+    Jump branch32(Condition cond, RegisterID left, Imm32 right)
+    {
+        move(right, immTempRegister);
+        return branch32(cond, left, immTempRegister);
+    }
+
+    Jump branch32(Condition cond, RegisterID left, Address right)
+    {
+        load32(right, dataTempRegister);
+        return branch32(cond, left, dataTempRegister);
+    }
+
+    Jump branch32(Condition cond, Address left, RegisterID right)
+    {
+        load32(left, dataTempRegister);
+        return branch32(cond, dataTempRegister, right);
+    }
+
+    Jump branch32(Condition cond, Address left, Imm32 right)
+    {
+        load32(left, dataTempRegister);
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branch32(Condition cond, BaseIndex left, Imm32 right)
+    {
+        load32(left, dataTempRegister);
+        // Be careful that the previous load32() uses immTempRegister.
+        // So, we need to put move() after load32().
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branch32WithUnalignedHalfWords(Condition cond, BaseIndex left, Imm32 right)
+    {
+        load32WithUnalignedHalfWords(left, dataTempRegister);
+        // Be careful that the previous load32WithUnalignedHalfWords()
+        // uses immTempRegister.
+        // So, we need to put move() after load32WithUnalignedHalfWords().
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branch32(Condition cond, AbsoluteAddress left, RegisterID right)
+    {
+        load32(left.m_ptr, dataTempRegister);
+        return branch32(cond, dataTempRegister, right);
+    }
+
+    Jump branch32(Condition cond, AbsoluteAddress left, Imm32 right)
+    {
+        load32(left.m_ptr, dataTempRegister);
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branch16(Condition cond, BaseIndex left, RegisterID right)
+    {
+        load16(left, dataTempRegister);
+        return branch32(cond, dataTempRegister, right);
+    }
+
+    Jump branch16(Condition cond, BaseIndex left, Imm32 right)
+    {
+        ASSERT(!(right.m_value & 0xFFFF0000));
+        load16(left, dataTempRegister);
+        // Be careful that the previous load16() uses immTempRegister.
+        // So, we need to put move() after load16().
+        move(right, immTempRegister);
+        return branch32(cond, dataTempRegister, immTempRegister);
+    }
+
+    Jump branchTest32(Condition cond, RegisterID reg, RegisterID mask)
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        m_assembler.andInsn(cmpTempRegister, reg, mask);
+        if (cond == Zero)
+            return branchEqual(cmpTempRegister, MIPSRegisters::zero);
+        return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+    }
+
+    Jump branchTest32(Condition cond, RegisterID reg, Imm32 mask = Imm32(-1))
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        if (mask.m_value == -1 && !m_fixedWidth) {
+            if (cond == Zero)
+                return branchEqual(reg, MIPSRegisters::zero);
+            return branchNotEqual(reg, MIPSRegisters::zero);
+        }
+        move(mask, immTempRegister);
+        return branchTest32(cond, reg, immTempRegister);
+    }
+
+    Jump branchTest32(Condition cond, Address address, Imm32 mask = Imm32(-1))
+    {
+        load32(address, dataTempRegister);
+        return branchTest32(cond, dataTempRegister, mask);
+    }
+
+    Jump branchTest32(Condition cond, BaseIndex address, Imm32 mask = Imm32(-1))
+    {
+        load32(address, dataTempRegister);
+        return branchTest32(cond, dataTempRegister, mask);
+    }
+
+    Jump jump()
+    {
+        return branchEqual(MIPSRegisters::zero, MIPSRegisters::zero);
+    }
+
+    void jump(RegisterID target)
+    {
+        m_assembler.jr(target);
+        m_assembler.nop();
+    }
+
+    void jump(Address address)
+    {
+        m_fixedWidth = true;
+        load32(address, MIPSRegisters::t9);
+        m_assembler.jr(MIPSRegisters::t9);
+        m_assembler.nop();
+        m_fixedWidth = false;
+    }
+
+    // Arithmetic control flow operations:
+    //
+    // This set of conditional branch operations branch based
+    // on the result of an arithmetic operation.  The operation
+    // is performed as normal, storing the result.
+    //
+    // * jz operations branch if the result is zero.
+    // * jo operations branch if the (signed) arithmetic
+    //   operation caused an overflow to occur.
+
+    Jump branchAdd32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        if (cond == Overflow) {
+            /*
+                move    dest, dataTemp
+                xor     cmpTemp, dataTemp, src
+                bltz    cmpTemp, No_overflow    # diff sign bit -> no overflow
+                addu    dest, dataTemp, src
+                xor     cmpTemp, dest, dataTemp
+                bgez    cmpTemp, No_overflow    # same sign big -> no overflow
+                nop
+                b       Overflow
+                nop
+                nop
+                nop
+                nop
+                nop
+            No_overflow:
+            */
+            move(dest, dataTempRegister);
+            m_assembler.xorInsn(cmpTempRegister, dataTempRegister, src);
+            m_assembler.bltz(cmpTempRegister, 10);
+            m_assembler.addu(dest, dataTempRegister, src);
+            m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister);
+            m_assembler.bgez(cmpTempRegister, 7);
+            m_assembler.nop();
+            return jump();
+        }
+        if (cond == Signed) {
+            add32(src, dest);
+            // Check if dest is negative.
+            m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Zero) {
+            add32(src, dest);
+            return branchEqual(dest, MIPSRegisters::zero);
+        }
+        if (cond == NonZero) {
+            add32(src, dest);
+            return branchNotEqual(dest, MIPSRegisters::zero);
+        }
+        ASSERT(0);
+        return Jump();
+    }
+
+    Jump branchAdd32(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        move(imm, immTempRegister);
+        return branchAdd32(cond, immTempRegister, dest);
+    }
+
+    Jump branchMul32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        if (cond == Overflow) {
+            /*
+                mult    src, dest
+                mfhi    dataTemp
+                mflo    dest
+                sra     addrTemp, dest, 31
+                beq     dataTemp, addrTemp, No_overflow # all sign bits (bit 63 to bit 31) are the same -> no overflow
+                nop
+                b       Overflow
+                nop
+                nop
+                nop
+                nop
+                nop
+            No_overflow:
+            */
+            m_assembler.mult(src, dest);
+            m_assembler.mfhi(dataTempRegister);
+            m_assembler.mflo(dest);
+            m_assembler.sra(addrTempRegister, dest, 31);
+            m_assembler.beq(dataTempRegister, addrTempRegister, 7);
+            m_assembler.nop();
+            return jump();
+        }
+        if (cond == Signed) {
+            mul32(src, dest);
+            // Check if dest is negative.
+            m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Zero) {
+            mul32(src, dest);
+            return branchEqual(dest, MIPSRegisters::zero);
+        }
+        if (cond == NonZero) {
+            mul32(src, dest);
+            return branchNotEqual(dest, MIPSRegisters::zero);
+        }
+        ASSERT(0);
+        return Jump();
+    }
+
+    Jump branchMul32(Condition cond, Imm32 imm, RegisterID src, RegisterID dest)
+    {
+        move(imm, immTempRegister);
+        move(src, dest);
+        return branchMul32(cond, immTempRegister, dest);
+    }
+
+    Jump branchSub32(Condition cond, RegisterID src, RegisterID dest)
+    {
+        ASSERT((cond == Overflow) || (cond == Signed) || (cond == Zero) || (cond == NonZero));
+        if (cond == Overflow) {
+            /*
+                move    dest, dataTemp
+                xor     cmpTemp, dataTemp, src
+                bgez    cmpTemp, No_overflow    # same sign bit -> no overflow
+                subu    dest, dataTemp, src
+                xor     cmpTemp, dest, dataTemp
+                bgez    cmpTemp, No_overflow    # same sign bit -> no overflow
+                nop
+                b       Overflow
+                nop
+                nop
+                nop
+                nop
+                nop
+            No_overflow:
+            */
+            move(dest, dataTempRegister);
+            m_assembler.xorInsn(cmpTempRegister, dataTempRegister, src);
+            m_assembler.bgez(cmpTempRegister, 10);
+            m_assembler.subu(dest, dataTempRegister, src);
+            m_assembler.xorInsn(cmpTempRegister, dest, dataTempRegister);
+            m_assembler.bgez(cmpTempRegister, 7);
+            m_assembler.nop();
+            return jump();
+        }
+        if (cond == Signed) {
+            sub32(src, dest);
+            // Check if dest is negative.
+            m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
+            return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
+        }
+        if (cond == Zero) {
+            sub32(src, dest);
+            return branchEqual(dest, MIPSRegisters::zero);
+        }
+        if (cond == NonZero) {
+            sub32(src, dest);
+            return branchNotEqual(dest, MIPSRegisters::zero);
+        }
+        ASSERT(0);
+        return Jump();
+    }
+
+    Jump branchSub32(Condition cond, Imm32 imm, RegisterID dest)
+    {
+        move(imm, immTempRegister);
+        return branchSub32(cond, immTempRegister, dest);
+    }
+
+    // Miscellaneous operations:
+
+    void breakpoint()
+    {
+        m_assembler.bkpt();
+    }
+
+    Call nearCall()
+    {
+        /* We need two words for relaxation.  */
+        m_assembler.nop();
+        m_assembler.nop();
+        m_assembler.jal();
+        m_assembler.nop();
+        return Call(m_assembler.newJmpSrc(), Call::LinkableNear);
+    }
+
+    Call call()
+    {
+        m_assembler.lui(MIPSRegisters::t9, 0);
+        m_assembler.ori(MIPSRegisters::t9, MIPSRegisters::t9, 0);
+        m_assembler.jalr(MIPSRegisters::t9);
+        m_assembler.nop();
+        return Call(m_assembler.newJmpSrc(), Call::Linkable);
+    }
+
+    Call call(RegisterID target)
+    {
+        m_assembler.jalr(target);
+        m_assembler.nop();
+        return Call(m_assembler.newJmpSrc(), Call::None);
+    }
+
+    Call call(Address address)
+    {
+        m_fixedWidth = true;
+        load32(address, MIPSRegisters::t9);
+        m_assembler.jalr(MIPSRegisters::t9);
+        m_assembler.nop();
+        m_fixedWidth = false;
+        return Call(m_assembler.newJmpSrc(), Call::None);
+    }
+
+    void ret()
+    {
+        m_assembler.jr(MIPSRegisters::ra);
+        m_assembler.nop();
+    }
+
+    void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
+    {
+        if (cond == Equal || cond == Zero) {
+            m_assembler.xorInsn(dest, left, right);
+            m_assembler.sltiu(dest, dest, 1);
+        } else if (cond == NotEqual || cond == NonZero) {
+            m_assembler.xorInsn(dest, left, right);
+            m_assembler.sltu(dest, MIPSRegisters::zero, dest);
+        } else if (cond == Above)
+            m_assembler.sltu(dest, right, left);
+        else if (cond == AboveOrEqual) {
+            m_assembler.sltu(dest, left, right);
+            m_assembler.xori(dest, dest, 1);
+        } else if (cond == Below)
+            m_assembler.sltu(dest, left, right);
+        else if (cond == BelowOrEqual) {
+            m_assembler.sltu(dest, right, left);
+            m_assembler.xori(dest, dest, 1);
+        } else if (cond == GreaterThan)
+            m_assembler.slt(dest, right, left);
+        else if (cond == GreaterThanOrEqual) {
+            m_assembler.slt(dest, left, right);
+            m_assembler.xori(dest, dest, 1);
+        } else if (cond == LessThan)
+            m_assembler.slt(dest, left, right);
+        else if (cond == LessThanOrEqual) {
+            m_assembler.slt(dest, right, left);
+            m_assembler.xori(dest, dest, 1);
+        } else if (cond == Overflow) {
+            /*
+                xor     cmpTemp, left, right
+                bgez    Done, cmpTemp   # same sign bit -> no overflow
+                move    dest, 0
+                subu    cmpTemp, left, right
+                xor     cmpTemp, cmpTemp, left # diff sign bit -> overflow
+                slt     dest, cmpTemp, 0
+              Done:
+            */
+            m_assembler.xorInsn(cmpTempRegister, left, right);
+            m_assembler.bgez(cmpTempRegister, 4);
+            m_assembler.move(dest, MIPSRegisters::zero);
+            m_assembler.subu(cmpTempRegister, left, right);
+            m_assembler.xorInsn(cmpTempRegister, cmpTempRegister, left);
+            m_assembler.slt(dest, cmpTempRegister, MIPSRegisters::zero);
+        } else if (cond == Signed) {
+            m_assembler.subu(dest, left, right);
+            // Check if the result is negative.
+            m_assembler.slt(dest, dest, MIPSRegisters::zero);
+        }
+    }
+
+    void set32(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
+    {
+        move(right, immTempRegister);
+        set32(cond, left, immTempRegister, dest);
+    }
+
+    void setTest32(Condition cond, Address address, Imm32 mask, RegisterID dest)
+    {
+        ASSERT((cond == Zero) || (cond == NonZero));
+        load32(address, dataTempRegister);
+        if (mask.m_value == -1 && !m_fixedWidth) {
+            if (cond == Zero)
+                m_assembler.sltiu(dest, dataTempRegister, 1);
+            else
+                m_assembler.sltu(dest, MIPSRegisters::zero, dataTempRegister);
+        } else {
+            move(mask, immTempRegister);
+            m_assembler.andInsn(cmpTempRegister, dataTempRegister,
+                                 immTempRegister);
+            if (cond == Zero)
+                m_assembler.sltiu(dest, cmpTempRegister, 1);
+            else
+                m_assembler.sltu(dest, MIPSRegisters::zero, cmpTempRegister);
+        }
+    }
+
+    DataLabel32 moveWithPatch(Imm32 imm, RegisterID dest)
+    {
+        m_fixedWidth = true;
+        DataLabel32 label(this);
+        move(imm, dest);
+        m_fixedWidth = false;
+        return label;
+    }
+
+    DataLabelPtr moveWithPatch(ImmPtr initialValue, RegisterID dest)
+    {
+        m_fixedWidth = true;
+        DataLabelPtr label(this);
+        move(initialValue, dest);
+        m_fixedWidth = false;
+        return label;
+    }
+
+    Jump branchPtrWithPatch(Condition cond, RegisterID left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        m_fixedWidth = true;
+        dataLabel = moveWithPatch(initialRightValue, immTempRegister);
+        Jump temp = branch32(cond, left, immTempRegister);
+        m_fixedWidth = false;
+        return temp;
+    }
+
+    Jump branchPtrWithPatch(Condition cond, Address left, DataLabelPtr& dataLabel, ImmPtr initialRightValue = ImmPtr(0))
+    {
+        m_fixedWidth = true;
+        load32(left, dataTempRegister);
+        dataLabel = moveWithPatch(initialRightValue, immTempRegister);
+        Jump temp = branch32(cond, dataTempRegister, immTempRegister);
+        m_fixedWidth = false;
+        return temp;
+    }
+
+    DataLabelPtr storePtrWithPatch(ImmPtr initialValue, ImplicitAddress address)
+    {
+        m_fixedWidth = true;
+        DataLabelPtr dataLabel = moveWithPatch(initialValue, dataTempRegister);
+        store32(dataTempRegister, address);
+        m_fixedWidth = false;
+        return dataLabel;
+    }
+
+    DataLabelPtr storePtrWithPatch(ImplicitAddress address)
+    {
+        return storePtrWithPatch(ImmPtr(0), address);
+    }
+
+    Call tailRecursiveCall()
+    {
+        // Like a normal call, but don't update the returned address register
+        m_fixedWidth = true;
+        move(Imm32(0), MIPSRegisters::t9);
+        m_assembler.jr(MIPSRegisters::t9);
+        m_assembler.nop();
+        m_fixedWidth = false;
+        return Call(m_assembler.newJmpSrc(), Call::Linkable);
+    }
+
+    Call makeTailRecursiveCall(Jump oldJump)
+    {
+        oldJump.link(this);
+        return tailRecursiveCall();
+    }
+
+    void loadDouble(ImplicitAddress address, FPRegisterID dest)
+    {
+#if WTF_MIPS_ISA(1)
+        /*
+            li          addrTemp, address.offset
+            addu        addrTemp, addrTemp, base
+            lwc1        dest, 0(addrTemp)
+            lwc1        dest+1, 4(addrTemp)
+         */
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.lwc1(dest, addrTempRegister, 0);
+        m_assembler.lwc1(FPRegisterID(dest + 1), addrTempRegister, 4);
+#else
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth) {
+            m_assembler.ldc1(dest, address.base, address.offset);
+        } else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                ldc1    dest, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.ldc1(dest, addrTempRegister, address.offset);
+        }
+#endif
+    }
+
+    void storeDouble(FPRegisterID src, ImplicitAddress address)
+    {
+#if WTF_MIPS_ISA(1)
+        /*
+            li          addrTemp, address.offset
+            addu        addrTemp, addrTemp, base
+            swc1        dest, 0(addrTemp)
+            swc1        dest+1, 4(addrTemp)
+         */
+        move(Imm32(address.offset), addrTempRegister);
+        m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+        m_assembler.swc1(src, addrTempRegister, 0);
+        m_assembler.swc1(FPRegisterID(src + 1), addrTempRegister, 4);
+#else
+        if (address.offset >= -32768 && address.offset <= 32767
+            && !m_fixedWidth)
+            m_assembler.sdc1(src, address.base, address.offset);
+        else {
+            /*
+                lui     addrTemp, (offset + 0x8000) >> 16
+                addu    addrTemp, addrTemp, base
+                sdc1    src, (offset & 0xffff)(addrTemp)
+              */
+            m_assembler.lui(addrTempRegister, (address.offset + 0x8000) >> 16);
+            m_assembler.addu(addrTempRegister, addrTempRegister, address.base);
+            m_assembler.sdc1(src, addrTempRegister, address.offset);
+        }
+#endif
+    }
+
+    void addDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.addd(dest, dest, src);
+    }
+
+    void addDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        m_assembler.addd(dest, dest, fpTempRegister);
+    }
+
+    void subDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.subd(dest, dest, src);
+    }
+
+    void subDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        m_assembler.subd(dest, dest, fpTempRegister);
+    }
+
+    void mulDouble(FPRegisterID src, FPRegisterID dest)
+    {
+        m_assembler.muld(dest, dest, src);
+    }
+
+    void mulDouble(Address src, FPRegisterID dest)
+    {
+        loadDouble(src, fpTempRegister);
+        m_assembler.muld(dest, dest, fpTempRegister);
+    }
+
+    void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
+    {
+        m_assembler.mtc1(src, fpTempRegister);
+        m_assembler.cvtdw(dest, fpTempRegister);
+    }
+
+    void insertRelaxationWords()
+    {
+        /* We need four words for relaxation. */
+        m_assembler.beq(MIPSRegisters::zero, MIPSRegisters::zero, 3); // Jump over nops;
+        m_assembler.nop();
+        m_assembler.nop();
+        m_assembler.nop();
+    }
+
+    Jump branchTrue()
+    {
+        m_assembler.appendJump();
+        m_assembler.bc1t();
+        m_assembler.nop();
+        insertRelaxationWords();
+        return Jump(m_assembler.newJmpSrc());
+    }
+
+    Jump branchFalse()
+    {
+        m_assembler.appendJump();
+        m_assembler.bc1f();
+        m_assembler.nop();
+        insertRelaxationWords();
+        return Jump(m_assembler.newJmpSrc());
+    }
+
+    Jump branchEqual(RegisterID rs, RegisterID rt)
+    {
+        m_assembler.appendJump();
+        m_assembler.beq(rs, rt, 0);
+        m_assembler.nop();
+        insertRelaxationWords();
+        return Jump(m_assembler.newJmpSrc());
+    }
+
+    Jump branchNotEqual(RegisterID rs, RegisterID rt)
+    {
+        m_assembler.appendJump();
+        m_assembler.bne(rs, rt, 0);
+        m_assembler.nop();
+        insertRelaxationWords();
+        return Jump(m_assembler.newJmpSrc());
+    }
+
+    Jump branchDouble(DoubleCondition cond, FPRegisterID left, FPRegisterID right)
+    {
+        if (cond == DoubleEqual) {
+            m_assembler.ceqd(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleNotEqual) {
+            m_assembler.ceqd(left, right);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleGreaterThan) {
+            m_assembler.cngtd(left, right);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleGreaterThanOrEqual) {
+            m_assembler.cnged(right, left);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleLessThan) {
+            m_assembler.cltd(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleLessThanOrEqual) {
+            m_assembler.cled(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleEqualOrUnordered) {
+            m_assembler.cueqd(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleGreaterThanOrUnordered) {
+            m_assembler.coled(left, right);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleGreaterThanOrEqualOrUnordered) {
+            m_assembler.coltd(left, right);
+            return branchFalse(); // false
+        }
+        if (cond == DoubleLessThanOrUnordered) {
+            m_assembler.cultd(left, right);
+            return branchTrue();
+        }
+        if (cond == DoubleLessThanOrEqualOrUnordered) {
+            m_assembler.culed(left, right);
+            return branchTrue();
+        }
+        ASSERT(0);
+
+        return Jump();
+    }
+
+    // Truncates 'src' to an integer, and places the resulting 'dest'.
+    // If the result is not representable as a 32 bit value, branch.
+    // May also branch for some values that are representable in 32 bits
+    // (specifically, in this case, INT_MAX 0x7fffffff).
+    Jump branchTruncateDoubleToInt32(FPRegisterID src, RegisterID dest)
+    {
+        m_assembler.truncwd(fpTempRegister, src);
+        m_assembler.mfc1(dest, fpTempRegister);
+        return branch32(Equal, dest, Imm32(0x7fffffff));
+    }
+
+private:
+    // If m_fixedWidth is true, we will generate a fixed number of instructions.
+    // Otherwise, we can emit any number of instructions.
+    bool m_fixedWidth;
+
+    friend class LinkBuffer;
+    friend class RepatchBuffer;
+
+    static void linkCall(void* code, Call call, FunctionPtr function)
+    {
+        MIPSAssembler::linkCall(code, call.m_jmp, function.value());
+    }
+
+    static void repatchCall(CodeLocationCall call, CodeLocationLabel destination)
+    {
+        MIPSAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
+    }
+
+    static void repatchCall(CodeLocationCall call, FunctionPtr destination)
+    {
+        MIPSAssembler::relinkCall(call.dataLocation(), destination.executableAddress());
+    }
+
+};
+
+}
+
+#endif // ENABLE(ASSEMBLER) && CPU(MIPS)
+
+#endif // MacroAssemblerMIPS_h
diff --git a/JavaScriptCore/jit/ExecutableAllocator.h b/JavaScriptCore/jit/ExecutableAllocator.h
index 1fb8ff7..8f46dee 100644
--- a/JavaScriptCore/jit/ExecutableAllocator.h
+++ b/JavaScriptCore/jit/ExecutableAllocator.h
@@ -43,6 +43,10 @@
 #include <e32std.h>
 #endif
 
+#if CPU(MIPS) && OS(LINUX)
+#include <sys/cachectl.h>
+#endif
+
 #if OS(WINCE)
 // From pkfuncs.h (private header file from the Platform Builder)
 #define CACHE_SYNC_ALL 0x07F
@@ -190,6 +194,32 @@ public:
     static void cacheFlush(void*, size_t)
     {
     }
+#elif CPU(MIPS)
+    static void cacheFlush(void* code, size_t size)
+    {
+#if COMPILER(GCC) && (GCC_VERSION >= 40300)
+#if WTF_MIPS_ISA_REV(2) && (GCC_VERSION < 40403)
+        int lineSize;
+        asm("rdhwr %0, $1" : "=r" (lineSize));
+        //
+        // Modify "start" and "end" to avoid GCC 4.3.0-4.4.2 bug in
+        // mips_expand_synci_loop that may execute synci one more time.
+        // "start" points to the fisrt byte of the cache line.
+        // "end" points to the last byte of the line before the last cache line.
+        // Because size is always a multiple of 4, this is safe to set
+        // "end" to the last byte.
+        //
+        intptr_t start = reinterpret_cast<intptr_t>(code) & (-lineSize);
+        intptr_t end = ((reinterpret_cast<intptr_t>(code) + size - 1) & (-lineSize)) - 1;
+        __builtin___clear_cache(reinterpret_cast<char*>(start), reinterpret_cast<char*>(end));
+#else
+        intptr_t end = reinterpret_cast<intptr_t>(code) + size;
+        __builtin___clear_cache(reinterpret_cast<char*>(code), reinterpret_cast<char*>(end));
+#endif
+#else
+        _flush_cache(reinterpret_cast<char*>(code), size, BCACHE);
+#endif
+    }
 #elif CPU(ARM_THUMB2) && OS(IPHONE_OS)
     static void cacheFlush(void* code, size_t size)
     {
diff --git a/JavaScriptCore/wtf/Platform.h b/JavaScriptCore/wtf/Platform.h
index 470bbd0..9ce65e4 100644
--- a/JavaScriptCore/wtf/Platform.h
+++ b/JavaScriptCore/wtf/Platform.h
@@ -104,6 +104,23 @@
 #define WTF_CPU_IA64 1
 #endif
 
+/* CPU(MIPS) - MIPS 32-bit */
+/* Note: Only O32 ABI is tested, so we enable it for O32 ABI for now.  */
+#if (defined(mips) || defined(__mips__)) \
+    && defined(_ABIO32)
+#define WTF_CPU_MIPS 1
+#if defined(__MIPSEB__)
+#define WTF_CPU_BIG_ENDIAN 1
+#endif
+#define WTF_MIPS_PIC (defined __PIC__)
+#define WTF_MIPS_ARCH __mips
+#define WTF_MIPS_ISA(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH == v)
+#define WTF_MIPS_ISA_AT_LEAST(v) (defined WTF_MIPS_ARCH && WTF_MIPS_ARCH >= v)
+#define WTF_MIPS_ARCH_REV __mips_isa_rev
+#define WTF_MIPS_ISA_REV(v) (defined WTF_MIPS_ARCH_REV && WTF_MIPS_ARCH_REV == v)
+#define WTF_MIPS_DOUBLE_FLOAT (defined __mips_hard_float && !defined __mips_single_float)
+#endif /* MIPS */
+
 /* CPU(PPC) - PowerPC 32-bit */
 #if   defined(__ppc__)     \
     || defined(__PPC__)     \
@@ -830,7 +847,7 @@
 #if !defined(WTF_USE_JSVALUE64) && !defined(WTF_USE_JSVALUE32) && !defined(WTF_USE_JSVALUE32_64)
 #if (CPU(X86_64) && (OS(UNIX) || OS(WINDOWS))) || CPU(IA64) || CPU(ALPHA)
 #define WTF_USE_JSVALUE64 1
-#elif CPU(ARM) || CPU(PPC64)
+#elif CPU(ARM) || CPU(PPC64) || CPU(MIPS)
 #define WTF_USE_JSVALUE32 1
 #elif OS(WINDOWS) && COMPILER(MINGW)
 /* Using JSVALUE32_64 causes padding/alignement issues for JITStubArg
@@ -950,7 +967,8 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
     || (CPU(X86) && OS(WINDOWS) && COMPILER(MSVC)) \
     || (CPU(X86) && OS(LINUX) && GCC_VERSION >= 40100) \
     || (CPU(X86_64) && OS(LINUX) && GCC_VERSION >= 40100) \
-    || (CPU(ARM_TRADITIONAL) && OS(LINUX))
+    || (CPU(ARM_TRADITIONAL) && OS(LINUX)) \
+    || (CPU(MIPS) && OS(LINUX))
 #define ENABLE_YARR 1
 #define ENABLE_YARR_JIT 1
 #endif
diff --git a/JavaScriptCore/yarr/RegexJIT.cpp b/JavaScriptCore/yarr/RegexJIT.cpp
index fcb8d86..271d453 100644
--- a/JavaScriptCore/yarr/RegexJIT.cpp
+++ b/JavaScriptCore/yarr/RegexJIT.cpp
@@ -54,6 +54,16 @@ class RegexGenerator : private MacroAssembler {
     static const RegisterID regT1 = ARMRegisters::r6;
 
     static const RegisterID returnRegister = ARMRegisters::r0;
+#elif CPU(MIPS)
+    static const RegisterID input = MIPSRegisters::a0;
+    static const RegisterID index = MIPSRegisters::a1;
+    static const RegisterID length = MIPSRegisters::a2;
+    static const RegisterID output = MIPSRegisters::a3;
+
+    static const RegisterID regT0 = MIPSRegisters::t4;
+    static const RegisterID regT1 = MIPSRegisters::t5;
+
+    static const RegisterID returnRegister = MIPSRegisters::v0;
 #elif CPU(X86)
     static const RegisterID input = X86Registers::eax;
     static const RegisterID index = X86Registers::edx;
@@ -1313,6 +1323,8 @@ class RegexGenerator : private MacroAssembler {
         push(ARMRegisters::r5);
         push(ARMRegisters::r6);
         move(ARMRegisters::r3, output);
+#elif CPU(MIPS)
+        // Do nothing.
 #endif
     }
 
@@ -1330,6 +1342,8 @@ class RegexGenerator : private MacroAssembler {
         pop(ARMRegisters::r6);
         pop(ARMRegisters::r5);
         pop(ARMRegisters::r4);
+#elif CPU(MIPS)
+        // Do nothing
 #endif
         ret();
     }

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list