Commit a10b3572 authored by commit-queue@webkit.org's avatar commit-queue@webkit.org
Browse files

2010-09-06 Chao-ying Fu <fu@mips.com>

        Reviewed by Oliver Hunt.

        Support JSVALUE32_64 on MIPS
        https://bugs.webkit.org/show_bug.cgi?id=43999

        Add missing functions to support JSVALUE32_64 on MIPS.
        Remove JSVALUE32 as the default for MIPS.

        * assembler/MIPSAssembler.h:
        (JSC::MIPSAssembler::divd):
        (JSC::MIPSAssembler::mthc1):
        (JSC::MIPSAssembler::cvtwd):
        * assembler/MacroAssemblerMIPS.h:
        (JSC::MacroAssemblerMIPS::neg32):
        (JSC::MacroAssemblerMIPS::branchOr32):
        (JSC::MacroAssemblerMIPS::set8):
        (JSC::MacroAssemblerMIPS::loadDouble):
        (JSC::MacroAssemblerMIPS::divDouble):
        (JSC::MacroAssemblerMIPS::convertInt32ToDouble):
        (JSC::MacroAssemblerMIPS::branchDouble):
        (JSC::MacroAssemblerMIPS::branchConvertDoubleToInt32):
        (JSC::MacroAssemblerMIPS::zeroDouble):
        * jit/JIT.h:
        * jit/JITOpcodes32_64.cpp:
        (JSC::JIT::privateCompileCTINativeCall):
        * jit/JITPropertyAccess32_64.cpp:
        (JSC::JIT::privateCompilePutByIdTransition):
        * jit/JITStubs.cpp:
        (JSC::JITThunks::JITThunks):
        * jit/JITStubs.h:
        * wtf/Platform.h:

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66846 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e60e1764
2010-09-06 Chao-ying Fu <fu@mips.com>
Reviewed by Oliver Hunt.
Support JSVALUE32_64 on MIPS
https://bugs.webkit.org/show_bug.cgi?id=43999
Add missing functions to support JSVALUE32_64 on MIPS.
Remove JSVALUE32 as the default for MIPS.
* assembler/MIPSAssembler.h:
(JSC::MIPSAssembler::divd):
(JSC::MIPSAssembler::mthc1):
(JSC::MIPSAssembler::cvtwd):
* assembler/MacroAssemblerMIPS.h:
(JSC::MacroAssemblerMIPS::neg32):
(JSC::MacroAssemblerMIPS::branchOr32):
(JSC::MacroAssemblerMIPS::set8):
(JSC::MacroAssemblerMIPS::loadDouble):
(JSC::MacroAssemblerMIPS::divDouble):
(JSC::MacroAssemblerMIPS::convertInt32ToDouble):
(JSC::MacroAssemblerMIPS::branchDouble):
(JSC::MacroAssemblerMIPS::branchConvertDoubleToInt32):
(JSC::MacroAssemblerMIPS::zeroDouble):
* jit/JIT.h:
* jit/JITOpcodes32_64.cpp:
(JSC::JIT::privateCompileCTINativeCall):
* jit/JITPropertyAccess32_64.cpp:
(JSC::JIT::privateCompilePutByIdTransition):
* jit/JITStubs.cpp:
(JSC::JITThunks::JITThunks):
* jit/JITStubs.h:
* wtf/Platform.h:
2010-09-06 Robert Hogan <robert@webkit.org>
Unreviewed, compile fix.
......
......@@ -529,6 +529,12 @@ public:
| (ft << OP_SH_FT));
}
void divd(FPRegisterID fd, FPRegisterID fs, FPRegisterID ft)
{
emitInst(0x46200003 | (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)
......@@ -560,6 +566,12 @@ public:
copDelayNop();
}
void mthc1(RegisterID rt, FPRegisterID fs)
{
emitInst(0x44e00000 | (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));
......@@ -581,6 +593,11 @@ public:
emitInst(0x46800021 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
}
void cvtwd(FPRegisterID fd, FPRegisterID fs)
{
emitInst(0x46200024 | (fd << OP_SH_FD) | (fs << OP_SH_FS));
}
void ceqd(FPRegisterID fs, FPRegisterID ft)
{
emitInst(0x46200032 | (fs << OP_SH_FS) | (ft << OP_SH_FT));
......
......@@ -281,6 +281,11 @@ public:
}
}
void neg32(RegisterID srcDest)
{
m_assembler.subu(srcDest, MIPSRegisters::zero, srcDest);
}
void not32(RegisterID srcDest)
{
m_assembler.nor(srcDest, srcDest, MIPSRegisters::zero);
......@@ -620,11 +625,6 @@ public:
return label;
}
Label loadPtrWithAddressOffsetPatch(Address address, RegisterID dest)
{
return loadPtrWithPatchToLEA(address, dest);
}
/* Need to use zero-extened load half-word for load16. */
void load16(ImplicitAddress address, RegisterID dest)
{
......@@ -1302,6 +1302,27 @@ public:
return branchSub32(cond, immTempRegister, dest);
}
Jump branchOr32(Condition cond, RegisterID src, RegisterID dest)
{
ASSERT((cond == Signed) || (cond == Zero) || (cond == NonZero));
if (cond == Signed) {
or32(src, dest);
// Check if dest is negative.
m_assembler.slt(cmpTempRegister, dest, MIPSRegisters::zero);
return branchNotEqual(cmpTempRegister, MIPSRegisters::zero);
}
if (cond == Zero) {
or32(src, dest);
return branchEqual(dest, MIPSRegisters::zero);
}
if (cond == NonZero) {
or32(src, dest);
return branchNotEqual(dest, MIPSRegisters::zero);
}
ASSERT(0);
return Jump();
}
// Miscellaneous operations:
void breakpoint()
......@@ -1351,6 +1372,17 @@ public:
m_assembler.nop();
}
void set8(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
{
set32(cond, left, right, dest);
}
void set8(Condition cond, RegisterID left, Imm32 right, RegisterID dest)
{
move(right, immTempRegister);
set32(cond, left, immTempRegister, dest);
}
void set32(Condition cond, RegisterID left, RegisterID right, RegisterID dest)
{
if (cond == Equal || cond == Zero) {
......@@ -1546,6 +1578,28 @@ public:
#endif
}
void loadDouble(const void* address, FPRegisterID dest)
{
#if WTF_MIPS_ISA(1)
/*
li addrTemp, address
lwc1 dest, 0(addrTemp)
lwc1 dest+1, 4(addrTemp)
*/
move(ImmPtr(address), addrTempRegister);
m_assembler.lwc1(dest, addrTempRegister, 0);
m_assembler.lwc1(FPRegisterID(dest + 1), addrTempRegister, 4);
#else
/*
li addrTemp, address
ldc1 dest, 0(addrTemp)
*/
move(ImmPtr(address), addrTempRegister);
m_assembler.ldc1(dest, addrTempRegister, 0);
#endif
}
void storeDouble(FPRegisterID src, ImplicitAddress address)
{
#if WTF_MIPS_ISA(1)
......@@ -1609,12 +1663,31 @@ public:
m_assembler.muld(dest, dest, fpTempRegister);
}
void divDouble(FPRegisterID src, FPRegisterID dest)
{
m_assembler.divd(dest, dest, src);
}
void convertInt32ToDouble(RegisterID src, FPRegisterID dest)
{
m_assembler.mtc1(src, fpTempRegister);
m_assembler.cvtdw(dest, fpTempRegister);
}
void convertInt32ToDouble(Address src, FPRegisterID dest)
{
load32(src, dataTempRegister);
m_assembler.mtc1(dataTempRegister, fpTempRegister);
m_assembler.cvtdw(dest, fpTempRegister);
}
void convertInt32ToDouble(AbsoluteAddress src, FPRegisterID dest)
{
load32(src.m_ptr, dataTempRegister);
m_assembler.mtc1(dataTempRegister, fpTempRegister);
m_assembler.cvtdw(dest, fpTempRegister);
}
void insertRelaxationWords()
{
/* We need four words for relaxation. */
......@@ -1667,7 +1740,7 @@ public:
return branchTrue();
}
if (cond == DoubleNotEqual) {
m_assembler.ceqd(left, right);
m_assembler.cueqd(left, right);
return branchFalse(); // false
}
if (cond == DoubleGreaterThan) {
......@@ -1690,6 +1763,10 @@ public:
m_assembler.cueqd(left, right);
return branchTrue();
}
if (cond == DoubleNotEqualOrUnordered) {
m_assembler.ceqd(left, right);
return branchFalse(); // false
}
if (cond == DoubleGreaterThanOrUnordered) {
m_assembler.coled(left, right);
return branchFalse(); // false
......@@ -1722,6 +1799,34 @@ public:
return branch32(Equal, dest, Imm32(0x7fffffff));
}
// Convert '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, 0).
void branchConvertDoubleToInt32(FPRegisterID src, RegisterID dest, JumpList& failureCases, FPRegisterID fpTemp)
{
m_assembler.cvtwd(fpTempRegister, src);
m_assembler.mfc1(dest, fpTempRegister);
// If the result is zero, it might have been -0.0, and the double comparison won't catch this!
failureCases.append(branch32(Equal, dest, MIPSRegisters::zero));
// Convert the integer result back to float & compare to the original value - if not equal or unordered (NaN) then jump.
convertInt32ToDouble(dest, fpTemp);
failureCases.append(branchDouble(DoubleNotEqualOrUnordered, fpTemp, src));
}
void zeroDouble(FPRegisterID dest)
{
#if WTF_MIPS_ISA_REV(2) && WTF_MIPS_FP64
m_assembler.mtc1(MIPSRegisters::zero, dest);
m_assembler.mthc1(MIPSRegisters::zero, dest);
#else
m_assembler.mtc1(MIPSRegisters::zero, dest);
m_assembler.mtc1(MIPSRegisters::zero, FPRegisterID(dest + 1));
#endif
}
private:
// If m_fixedWidth is true, we will generate a fixed number of instructions.
// Otherwise, we can emit any number of instructions.
......
......@@ -448,6 +448,52 @@ namespace JSC {
// sequencePutById
static const int sequencePutByIdInstructionSpace = 36;
static const int sequencePutByIdConstantSpace = 4;
#elif CPU(MIPS)
#if WTF_MIPS_ISA(1)
static const int patchOffsetPutByIdStructure = 16;
static const int patchOffsetPutByIdExternalLoad = 48;
static const int patchLengthPutByIdExternalLoad = 20;
static const int patchOffsetPutByIdPropertyMapOffset1 = 68;
static const int patchOffsetPutByIdPropertyMapOffset2 = 84;
static const int patchOffsetGetByIdStructure = 16;
static const int patchOffsetGetByIdBranchToSlowCase = 48;
static const int patchOffsetGetByIdExternalLoad = 48;
static const int patchLengthGetByIdExternalLoad = 20;
static const int patchOffsetGetByIdPropertyMapOffset1 = 68;
static const int patchOffsetGetByIdPropertyMapOffset2 = 88;
static const int patchOffsetGetByIdPutResult = 108;
#if ENABLE(OPCODE_SAMPLING)
#error "OPCODE_SAMPLING is not yet supported"
#else
static const int patchOffsetGetByIdSlowCaseCall = 44;
#endif
static const int patchOffsetOpCallCompareToJump = 32;
static const int patchOffsetMethodCheckProtoObj = 32;
static const int patchOffsetMethodCheckProtoStruct = 56;
static const int patchOffsetMethodCheckPutFunction = 88;
#else // WTF_MIPS_ISA(1)
static const int patchOffsetPutByIdStructure = 12;
static const int patchOffsetPutByIdExternalLoad = 44;
static const int patchLengthPutByIdExternalLoad = 16;
static const int patchOffsetPutByIdPropertyMapOffset1 = 60;
static const int patchOffsetPutByIdPropertyMapOffset2 = 76;
static const int patchOffsetGetByIdStructure = 12;
static const int patchOffsetGetByIdBranchToSlowCase = 44;
static const int patchOffsetGetByIdExternalLoad = 44;
static const int patchLengthGetByIdExternalLoad = 16;
static const int patchOffsetGetByIdPropertyMapOffset1 = 60;
static const int patchOffsetGetByIdPropertyMapOffset2 = 76;
static const int patchOffsetGetByIdPutResult = 92;
#if ENABLE(OPCODE_SAMPLING)
#error "OPCODE_SAMPLING is not yet supported"
#else
static const int patchOffsetGetByIdSlowCaseCall = 44;
#endif
static const int patchOffsetOpCallCompareToJump = 32;
static const int patchOffsetMethodCheckProtoObj = 32;
static const int patchOffsetMethodCheckProtoStruct = 52;
static const int patchOffsetMethodCheckPutFunction = 84;
#endif
#else
#error "JSVALUE32_64 not supported on this platform."
#endif
......
......@@ -244,6 +244,37 @@ JIT::Label JIT::privateCompileCTINativeCall(JSGlobalData* globalData, bool isCon
restoreReturnAddressBeforeReturn(regT3);
#elif CPU(MIPS)
// Load caller frame's scope chain into this callframe so that whatever we call can
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
// Calling convention: f(a0, a1, a2, a3);
// Host function signature: f(ExecState*);
// Allocate stack space for 16 bytes (8-byte aligned)
// 16 bytes (unused) for 4 arguments
subPtr(Imm32(16), stackPointerRegister);
// Setup arg0
move(callFrameRegister, MIPSRegisters::a0);
// Call
emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2);
loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
call(Address(regT2, executableOffsetToFunction));
// Restore stack space
addPtr(Imm32(16), stackPointerRegister);
restoreReturnAddressBeforeReturn(regT3);
#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
#else
......@@ -327,6 +358,39 @@ JIT::CodePtr JIT::privateCompileCTINativeCall(PassRefPtr<ExecutablePool> executa
restoreReturnAddressBeforeReturn(regT3);
#elif CPU(MIPS)
// Load caller frame's scope chain into this callframe so that whatever we call can
// get to its global data.
emitGetFromCallFrameHeaderPtr(RegisterFile::CallerFrame, regT0);
emitGetFromCallFrameHeaderPtr(RegisterFile::ScopeChain, regT1, regT0);
emitPutToCallFrameHeader(regT1, RegisterFile::ScopeChain);
preserveReturnAddressAfterCall(regT3); // Callee preserved
emitPutToCallFrameHeader(regT3, RegisterFile::ReturnPC);
// Calling convention: f(a0, a1, a2, a3);
// Host function signature: f(ExecState*);
// Allocate stack space for 16 bytes (8-byte aligned)
// 16 bytes (unused) for 4 arguments
subPtr(Imm32(16), stackPointerRegister);
// Setup arg0
move(callFrameRegister, MIPSRegisters::a0);
// Call
emitGetFromCallFrameHeaderPtr(RegisterFile::Callee, MIPSRegisters::a2);
loadPtr(Address(MIPSRegisters::a2, OBJECT_OFFSETOF(JSFunction, m_executable)), regT2);
move(regT0, callFrameRegister); // Eagerly restore caller frame register to avoid loading from stack.
// call the function
nativeCall = call();
// Restore stack space
addPtr(Imm32(16), stackPointerRegister);
restoreReturnAddressBeforeReturn(regT3);
#elif ENABLE(JIT_OPTIMIZE_NATIVE_CALL)
#error "JIT_OPTIMIZE_NATIVE_CALL not yet supported on this platform."
#else
......
......@@ -640,8 +640,14 @@ void JIT::privateCompilePutByIdTransition(StructureStubInfo* stubInfo, Structure
add32(Imm32(1), AbsoluteAddress(newStructure->addressOfCount()));
storePtr(ImmPtr(newStructure), Address(regT0, OBJECT_OFFSETOF(JSCell, m_structure)));
#if CPU(MIPS)
// For MIPS, we don't add sizeof(void*) to the stack offset.
load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT3);
load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT2);
#else
load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + sizeof(void*) + OBJECT_OFFSETOF(JSValue, u.asBits.payload)), regT3);
load32(Address(stackPointerRegister, OBJECT_OFFSETOF(JITStackFrame, args[2]) + sizeof(void*) + OBJECT_OFFSETOF(JSValue, u.asBits.tag)), regT2);
#endif
// Write the value
compilePutDirectOffset(regT0, regT2, regT3, newStructure, cachedOffset);
......
......@@ -311,6 +311,21 @@ extern "C" {
#define PRESERVEDR4_OFFSET 68
// See DEFINE_STUB_FUNCTION for more information.
#elif CPU(MIPS)
#define PRESERVED_GP_OFFSET 60
#define PRESERVED_S0_OFFSET 64
#define PRESERVED_S1_OFFSET 68
#define PRESERVED_S2_OFFSET 72
#define PRESERVED_RETURN_ADDRESS_OFFSET 76
#define THUNK_RETURN_ADDRESS_OFFSET 80
#define REGISTER_FILE_OFFSET 84
#define CALLFRAME_OFFSET 88
#define EXCEPTION_OFFSET 92
#define ENABLE_PROFILER_REFERENCE_OFFSET 96
#define GLOBAL_DATA_OFFSET 100
#define STACK_LENGTH 104
#else
#error "JIT not supported on this platform."
#endif
......@@ -465,95 +480,18 @@ SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
#elif CPU(MIPS)
asm volatile(
".text" "\n"
".align 2" "\n"
".set noreorder" "\n"
".set nomacro" "\n"
".set nomips16" "\n"
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
".ent " SYMBOL_STRING(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
"addiu $29,$29,-72" "\n"
"sw $31,44($29)" "\n"
"sw $18,40($29)" "\n"
"sw $17,36($29)" "\n"
"sw $16,32($29)" "\n"
#if WTF_MIPS_PIC
"sw $28,28($29)" "\n"
#endif
"move $16,$6 # set callFrameRegister" "\n"
"li $17,512 # set timeoutCheckRegister" "\n"
"move $25,$4 # move executableAddress to t9" "\n"
"sw $5,52($29) # store registerFile to current stack" "\n"
"sw $6,56($29) # store callFrame to curent stack" "\n"
"sw $7,60($29) # store exception to current stack" "\n"
"lw $8,88($29) # load enableProfilerReference from previous stack" "\n"
"lw $9,92($29) # load globalData from previous stack" "\n"
"sw $8,64($29) # store enableProfilerReference to current stack" "\n"
"jalr $25" "\n"
"sw $9,68($29) # store globalData to current stack" "\n"
"lw $16,32($29)" "\n"
"lw $17,36($29)" "\n"
"lw $18,40($29)" "\n"
"lw $31,44($29)" "\n"
"jr $31" "\n"
"addiu $29,$29,72" "\n"
".set reorder" "\n"
".set macro" "\n"
".end " SYMBOL_STRING(ctiTrampoline) "\n"
);
asm volatile(
".text" "\n"
".align 2" "\n"
".set noreorder" "\n"
".set nomacro" "\n"
".set nomips16" "\n"
".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
".ent " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
#if WTF_MIPS_PIC
"lw $28,28($29)" "\n"
".set macro" "\n"
"la $25," SYMBOL_STRING(cti_vm_throw) "\n"
".set nomacro" "\n"
"bal " SYMBOL_STRING(cti_vm_throw) "\n"
"move $4,$29" "\n"
#else
"jal " SYMBOL_STRING(cti_vm_throw) "\n"
"move $4,$29" "\n"
#endif
"lw $16,32($29)" "\n"
"lw $17,36($29)" "\n"
"lw $18,40($29)" "\n"
"lw $31,44($29)" "\n"
"jr $31" "\n"
"addiu $29,$29,72" "\n"
".set reorder" "\n"
".set macro" "\n"
".end " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
);
asm volatile(
".text" "\n"
".align 2" "\n"
".set noreorder" "\n"
".set nomacro" "\n"
".set nomips16" "\n"
".globl " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
".ent " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
SYMBOL_STRING(ctiOpThrowNotCaught) ":" "\n"
"lw $16,32($29)" "\n"
"lw $17,36($29)" "\n"
"lw $18,40($29)" "\n"
"lw $31,44($29)" "\n"
"jr $31" "\n"
"addiu $29,$29,72" "\n"
".set reorder" "\n"
".set macro" "\n"
".end " SYMBOL_STRING(ctiOpThrowNotCaught) "\n"
);
#define PRESERVED_GP_OFFSET 28
#define PRESERVED_S0_OFFSET 32
#define PRESERVED_S1_OFFSET 36
#define PRESERVED_S2_OFFSET 40
#define PRESERVED_RETURN_ADDRESS_OFFSET 44
#define THUNK_RETURN_ADDRESS_OFFSET 48
#define REGISTER_FILE_OFFSET 52
#define CALLFRAME_OFFSET 56
#define EXCEPTION_OFFSET 60
#define ENABLE_PROFILER_REFERENCE_OFFSET 64
#define GLOBAL_DATA_OFFSET 68
#define STACK_LENGTH 72
#elif COMPILER(MSVC) && CPU(X86)
......@@ -626,6 +564,98 @@ extern "C" {
#endif // USE(JSVALUE32_64)
#if CPU(MIPS)
asm volatile(
".text" "\n"
".align 2" "\n"
".set noreorder" "\n"
".set nomacro" "\n"
".set nomips16" "\n"
".globl " SYMBOL_STRING(ctiTrampoline) "\n"
".ent " SYMBOL_STRING(ctiTrampoline) "\n"
SYMBOL_STRING(ctiTrampoline) ":" "\n"
"addiu $29,$29,-" STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
"sw $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
"sw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
"sw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
"sw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
#if WTF_MIPS_PIC
"sw $28," STRINGIZE_VALUE_OF(PRESERVED_GP_OFFSET) "($29)" "\n"
#endif
"move $16,$6 # set callFrameRegister" "\n"
"li $17,512 # set timeoutCheckRegister" "\n"
"move $25,$4 # move executableAddress to t9" "\n"
"sw $5," STRINGIZE_VALUE_OF(REGISTER_FILE_OFFSET) "($29) # store registerFile to current stack" "\n"
"sw $6," STRINGIZE_VALUE_OF(CALLFRAME_OFFSET) "($29) # store callFrame to curent stack" "\n"
"sw $7," STRINGIZE_VALUE_OF(EXCEPTION_OFFSET) "($29) # store exception to current stack" "\n"
"lw $8," STRINGIZE_VALUE_OF(STACK_LENGTH + 16) "($29) # load enableProfilerReference from previous stack" "\n"
"lw $9," STRINGIZE_VALUE_OF(STACK_LENGTH + 20) "($29) # load globalData from previous stack" "\n"
"sw $8," STRINGIZE_VALUE_OF(ENABLE_PROFILER_REFERENCE_OFFSET) "($29) # store enableProfilerReference to current stack" "\n"
"jalr $25" "\n"
"sw $9," STRINGIZE_VALUE_OF(GLOBAL_DATA_OFFSET) "($29) # store globalData to current stack" "\n"
"lw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
"lw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
"lw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
"lw $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"
"jr $31" "\n"
"addiu $29,$29," STRINGIZE_VALUE_OF(STACK_LENGTH) "\n"
".set reorder" "\n"
".set macro" "\n"
".end " SYMBOL_STRING(ctiTrampoline) "\n"
);
asm volatile(
".text" "\n"
".align 2" "\n"
".set noreorder" "\n"
".set nomacro" "\n"
".set nomips16" "\n"
".globl " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
".ent " SYMBOL_STRING(ctiVMThrowTrampoline) "\n"
SYMBOL_STRING(ctiVMThrowTrampoline) ":" "\n"
#if WTF_MIPS_PIC
"lw $28," STRINGIZE_VALUE_OF(PRESERVED_GP_OFFSET) "($29)" "\n"
".set macro" "\n"
"la $25," SYMBOL_STRING(cti_vm_throw) "\n"
".set nomacro" "\n"
"bal " SYMBOL_STRING(cti_vm_throw) "\n"
"move $4,$29" "\n"
#else
"jal " SYMBOL_STRING(cti_vm_throw) "\n"
"move $4,$29" "\n"
#endif
"lw $16," STRINGIZE_VALUE_OF(PRESERVED_S0_OFFSET) "($29)" "\n"
"lw $17," STRINGIZE_VALUE_OF(PRESERVED_S1_OFFSET) "($29)" "\n"
"lw $18," STRINGIZE_VALUE_OF(PRESERVED_S2_OFFSET) "($29)" "\n"
"lw $31," STRINGIZE_VALUE_OF(PRESERVED_RETURN_ADDRESS_OFFSET) "($29)" "\n"