Changeset 40963 in webkit for trunk/JavaScriptCore/jit/JIT.cpp


Ignore:
Timestamp:
Feb 12, 2009, 8:22:02 PM (16 years ago)
Author:
[email protected]
Message:

2009-02-12 Gavin Barraclough <[email protected]>

Reviewed by Sam Weinig.

Remove (/reduce) use of hard-wired register names from the JIT.
Currently there is no abstraction of registers used in the JIT,
which has a number of negative consequences. Hard-wiring x86
register names makes the JIT less portable to other platforms,
and prevents us from performing dynamic register allocation to
attempt to maintain more temporary values in machine registers.
(The latter will be more important on x86-64, where we have more
registers to make use of).

Also, remove MacroAssembler::mod32. This was not providing a
useful abstraction, and was not in keeping with the rest of the
MacroAssembler interface, in having specific register requirements.

  • assembler/MacroAssemblerX86Common.h:
  • jit/JIT.cpp: (JSC::JIT::compileOpStrictEq): (JSC::JIT::emitSlowScriptCheck): (JSC::JIT::privateCompileMainPass): (JSC::JIT::privateCompileSlowCases): (JSC::JIT::privateCompile): (JSC::JIT::privateCompileCTIMachineTrampolines):
  • jit/JIT.h:
  • jit/JITArithmetic.cpp: (JSC::JIT::compileFastArith_op_lshift): (JSC::JIT::compileFastArithSlow_op_lshift): (JSC::JIT::compileFastArith_op_rshift): (JSC::JIT::compileFastArithSlow_op_rshift): (JSC::JIT::compileFastArith_op_bitand): (JSC::JIT::compileFastArithSlow_op_bitand): (JSC::JIT::compileFastArith_op_mod): (JSC::JIT::compileFastArithSlow_op_mod): (JSC::JIT::compileFastArith_op_post_inc): (JSC::JIT::compileFastArithSlow_op_post_inc): (JSC::JIT::compileFastArith_op_post_dec): (JSC::JIT::compileFastArithSlow_op_post_dec): (JSC::JIT::compileFastArith_op_pre_inc): (JSC::JIT::compileFastArithSlow_op_pre_inc): (JSC::JIT::compileFastArith_op_pre_dec): (JSC::JIT::compileFastArithSlow_op_pre_dec): (JSC::JIT::compileFastArith_op_add): (JSC::JIT::compileFastArith_op_mul): (JSC::JIT::compileFastArith_op_sub): (JSC::JIT::compileBinaryArithOp):
  • jit/JITCall.cpp: (JSC::JIT::compileOpCallInitializeCallFrame): (JSC::JIT::compileOpCallSetupArgs): (JSC::JIT::compileOpCallEvalSetupArgs): (JSC::JIT::compileOpConstructSetupArgs): (JSC::JIT::compileOpCall): (JSC::JIT::compileOpCallSlowCase):
  • jit/JITInlineMethods.h: (JSC::JIT::emitGetVirtualRegister): (JSC::JIT::emitPutVirtualRegister): (JSC::JIT::emitNakedCall): (JSC::JIT::restoreArgumentReference): (JSC::JIT::restoreArgumentReferenceForTrampoline):
  • jit/JITPropertyAccess.cpp: (JSC::JIT::compileGetByIdHotPath): (JSC::JIT::compilePutByIdHotPath): (JSC::JIT::compileGetByIdSlowCase): (JSC::JIT::compilePutByIdSlowCase): (JSC::JIT::privateCompilePutByIdTransition): (JSC::JIT::privateCompilePatchGetArrayLength): (JSC::JIT::privateCompileGetByIdSelf): (JSC::JIT::privateCompileGetByIdProto): (JSC::JIT::privateCompileGetByIdSelfList): (JSC::JIT::privateCompileGetByIdProtoList): (JSC::JIT::privateCompileGetByIdChainList): (JSC::JIT::privateCompileGetByIdChain): (JSC::JIT::privateCompilePutByIdReplace):
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/JavaScriptCore/jit/JIT.cpp

    r40846 r40963  
    229229    unsigned src2 = currentInstruction[3].u.operand;
    230230
    231     emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx);
     231    emitGetVirtualRegisters(src1, regT0, src2, regT1);
    232232
    233233#if USE(ALTERNATE_JSIMMEDIATE)
    234234    // Jump to a slow case if either operand is a number, or if both are JSCell*s.
    235     move(X86::eax, X86::ecx);
    236     orPtr(X86::edx, X86::ecx);
    237     addSlowCase(emitJumpIfJSCell(X86::ecx));
    238     addSlowCase(emitJumpIfImmediateNumber(X86::ecx));
     235    move(regT0, regT2);
     236    orPtr(regT1, regT2);
     237    addSlowCase(emitJumpIfJSCell(regT2));
     238    addSlowCase(emitJumpIfImmediateNumber(regT2));
    239239
    240240    if (type == OpStrictEq)
    241         set32(Equal, X86::edx, X86::eax, X86::eax);
     241        set32(Equal, regT1, regT0, regT0);
    242242    else
    243         set32(NotEqual, X86::edx, X86::eax, X86::eax);
    244     emitTagAsBoolImmediate(X86::eax);
     243        set32(NotEqual, regT1, regT0, regT0);
     244    emitTagAsBoolImmediate(regT0);
    245245#else
    246246    bool negated = (type == OpNStrictEq);
    247247
    248248    // Check that both are immediates, if so check if they're equal
    249     Jump firstNotImmediate = emitJumpIfJSCell(X86::eax);
    250     Jump secondNotImmediate = emitJumpIfJSCell(X86::edx);
    251     Jump bothWereImmediatesButNotEqual = branchPtr(NotEqual, X86::edx, X86::eax);
     249    Jump firstNotImmediate = emitJumpIfJSCell(regT0);
     250    Jump secondNotImmediate = emitJumpIfJSCell(regT1);
     251    Jump bothWereImmediatesButNotEqual = branchPtr(NotEqual, regT1, regT0);
    252252
    253253    // They are equal - set the result to true. (Or false, if negated).
    254     move(ImmPtr(JSValuePtr::encode(jsBoolean(!negated))), X86::eax);
     254    move(ImmPtr(JSValuePtr::encode(jsBoolean(!negated))), regT0);
    255255    Jump bothWereImmediatesAndEqual = jump();
    256256
     
    259259    // otherwise these values are not equal.
    260260    firstNotImmediate.link(this);
    261     emitJumpSlowCaseIfJSCell(X86::edx);
    262     addSlowCase(branchPtr(Equal, X86::edx, ImmPtr(JSValuePtr::encode(js0()))));
     261    emitJumpSlowCaseIfJSCell(regT1);
     262    addSlowCase(branchPtr(Equal, regT1, ImmPtr(JSValuePtr::encode(js0()))));
    263263    Jump firstWasNotImmediate = jump();
    264264
     
    266266    // If eax is 0 jump to a slow case, otherwise these values are not equal.
    267267    secondNotImmediate.link(this);
    268     addSlowCase(branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(js0()))));
     268    addSlowCase(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0()))));
    269269
    270270    // We get here if the two values are different immediates, or one is 0 and the other is a JSCell.
     
    272272    bothWereImmediatesButNotEqual.link(this);
    273273    firstWasNotImmediate.link(this);
    274     move(ImmPtr(JSValuePtr::encode(jsBoolean(negated))), X86::eax);
     274    move(ImmPtr(JSValuePtr::encode(jsBoolean(negated))), regT0);
    275275   
    276276    bothWereImmediatesAndEqual.link(this);
     
    284284    Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister);
    285285    emitCTICall(Interpreter::cti_timeout_check);
    286     move(X86::eax, timeoutCheckRegister);
     286    move(regT0, timeoutCheckRegister);
    287287    skipTimeout.link(this);
    288288
     
    297297#define CTI_COMPILE_BINARY_OP(name) \
    298298    case name: { \
    299         emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \
    300         emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx); \
     299        emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); \
     300        emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2); \
    301301        emitCTICall(Interpreter::cti_##name); \
    302302        emitPutVirtualRegister(currentInstruction[1].u.operand); \
     
    306306#define CTI_COMPILE_UNARY_OP(name) \
    307307    case name: { \
    308         emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \
     308        emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); \
    309309        emitCTICall(Interpreter::cti_##name); \
    310310        emitPutVirtualRegister(currentInstruction[1].u.operand); \
     
    334334        switch (opcodeID) {
    335335        case op_mov: {
    336             emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
     336            emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
    337337            emitPutVirtualRegister(currentInstruction[1].u.operand);
    338338            NEXT_OPCODE(op_mov);
     
    345345            if (m_codeBlock->needsFullScopeChain())
    346346                emitCTICall(Interpreter::cti_op_end);
    347             emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
     347            ASSERT(returnValueRegister != callFrameRegister);
     348            emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
    348349            push(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register))));
    349350            ret();
     
    373374            unsigned target = currentInstruction[3].u.operand;
    374375            if (isOperandConstantImmediateInt(op2)) {
    375                 emitGetVirtualRegister(op1, X86::eax);
    376                 emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     376                emitGetVirtualRegister(op1, regT0);
     377                emitJumpSlowCaseIfNotImmediateInteger(regT0);
    377378#if USE(ALTERNATE_JSIMMEDIATE)
    378379                int32_t op2imm = getConstantOperandImmediateInt(op2);
     
    380381                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
    381382#endif
    382                 addJump(branch32(LessThan, X86::eax, Imm32(op2imm)), target + 3);
     383                addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3);
    383384            } else {
    384                 emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
    385                 emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
    386                 emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
    387                 addJump(branch32(LessThan, X86::eax, X86::edx), target + 3);
     385                emitGetVirtualRegisters(op1, regT0, op2, regT1);
     386                emitJumpSlowCaseIfNotImmediateInteger(regT0);
     387                emitJumpSlowCaseIfNotImmediateInteger(regT1);
     388                addJump(branch32(LessThan, regT0, regT1), target + 3);
    388389            }
    389390            NEXT_OPCODE(op_loop_if_less);
     
    396397            unsigned target = currentInstruction[3].u.operand;
    397398            if (isOperandConstantImmediateInt(op2)) {
    398                 emitGetVirtualRegister(op1, X86::eax);
    399                 emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     399                emitGetVirtualRegister(op1, regT0);
     400                emitJumpSlowCaseIfNotImmediateInteger(regT0);
    400401#if USE(ALTERNATE_JSIMMEDIATE)
    401402                int32_t op2imm = getConstantOperandImmediateInt(op2);
     
    403404                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
    404405#endif
    405                 addJump(branch32(LessThanOrEqual, X86::eax, Imm32(op2imm)), target + 3);
     406                addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target + 3);
    406407            } else {
    407                 emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
    408                 emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
    409                 emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
    410                 addJump(branch32(LessThanOrEqual, X86::eax, X86::edx), target + 3);
     408                emitGetVirtualRegisters(op1, regT0, op2, regT1);
     409                emitJumpSlowCaseIfNotImmediateInteger(regT0);
     410                emitJumpSlowCaseIfNotImmediateInteger(regT1);
     411                addJump(branch32(LessThanOrEqual, regT0, regT1), target + 3);
    411412            }
    412413            NEXT_OPCODE(op_loop_if_less);
     
    426427        }
    427428        case op_instanceof: {
    428             emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax); // value
    429             emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx); // baseVal
    430             emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // proto
     429            emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); // value
     430            emitGetVirtualRegister(currentInstruction[3].u.operand, regT2); // baseVal
     431            emitGetVirtualRegister(currentInstruction[4].u.operand, regT1); // proto
    431432
    432433            // check if any are immediates
    433             move(X86::eax, X86::ebx);
    434             orPtr(X86::ecx, X86::ebx);
    435             orPtr(X86::edx, X86::ebx);
    436             emitJumpSlowCaseIfNotJSCell(X86::ebx);
     434            move(regT0, regT3);
     435            orPtr(regT2, regT3);
     436            orPtr(regT1, regT3);
     437            emitJumpSlowCaseIfNotJSCell(regT3);
    437438
    438439            // check that all are object type - this is a bit of a bithack to avoid excess branching;
    439440            // we check that the sum of the three type codes from Structures is exactly 3 * ObjectType,
    440441            // this works because NumberType and StringType are smaller
    441             move(Imm32(3 * ObjectType), X86::ebx);
    442             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::eax);
    443             loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
    444             loadPtr(Address(X86::edx, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
    445             sub32(Address(X86::eax, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
    446             sub32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx);
    447             addSlowCase(branch32(NotEqual, Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), X86::ebx));
     442            move(Imm32(3 * ObjectType), regT3);
     443            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT0);
     444            loadPtr(Address(regT2, FIELD_OFFSET(JSCell, m_structure)), regT2);
     445            loadPtr(Address(regT1, FIELD_OFFSET(JSCell, m_structure)), regT1);
     446            sub32(Address(regT0, FIELD_OFFSET(Structure, m_typeInfo.m_type)), regT3);
     447            sub32(Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_type)), regT3);
     448            addSlowCase(branch32(NotEqual, Address(regT1, FIELD_OFFSET(Structure, m_typeInfo.m_type)), regT3));
    448449
    449450            // check that baseVal's flags include ImplementsHasInstance but not OverridesHasInstance
    450             load32(Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), X86::ecx);
    451             and32(Imm32(ImplementsHasInstance | OverridesHasInstance), X86::ecx);
    452             addSlowCase(branch32(NotEqual, X86::ecx, Imm32(ImplementsHasInstance)));
    453 
    454             emitGetVirtualRegister(currentInstruction[2].u.operand, X86::ecx); // reload value
    455             emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // reload proto
     451            load32(Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), regT2);
     452            and32(Imm32(ImplementsHasInstance | OverridesHasInstance), regT2);
     453            addSlowCase(branch32(NotEqual, regT2, Imm32(ImplementsHasInstance)));
     454
     455            emitGetVirtualRegister(currentInstruction[2].u.operand, regT2); // reload value
     456            emitGetVirtualRegister(currentInstruction[4].u.operand, regT1); // reload proto
    456457
    457458            // optimistically load true result
    458             move(ImmPtr(JSValuePtr::encode(jsBoolean(true))), X86::eax);
     459            move(ImmPtr(JSValuePtr::encode(jsBoolean(true))), regT0);
    459460
    460461            Label loop(this);
    461462
    462463            // load value's prototype
    463             loadPtr(Address(X86::ecx, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
    464             loadPtr(Address(X86::ecx, FIELD_OFFSET(Structure, m_prototype)), X86::ecx);
    465 
    466             Jump exit = branchPtr(Equal, X86::ecx, X86::edx);
    467 
    468             branchPtr(NotEqual, X86::ecx, ImmPtr(JSValuePtr::encode(jsNull())), loop);
    469 
    470             move(ImmPtr(JSValuePtr::encode(jsBoolean(false))), X86::eax);
     464            loadPtr(Address(regT2, FIELD_OFFSET(JSCell, m_structure)), regT2);
     465            loadPtr(Address(regT2, FIELD_OFFSET(Structure, m_prototype)), regT2);
     466
     467            Jump exit = branchPtr(Equal, regT2, regT1);
     468
     469            branchPtr(NotEqual, regT2, ImmPtr(JSValuePtr::encode(jsNull())), loop);
     470
     471            move(ImmPtr(JSValuePtr::encode(jsBoolean(false))), regT0);
    471472
    472473            exit.link(this);
     
    477478        }
    478479        case op_del_by_id: {
    479             emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
     480            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
    480481            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand));
    481482            emitPutJITStubArgConstant(ident, 2);
     
    509510        case op_get_global_var: {
    510511            JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[2].u.jsCell);
    511             move(ImmPtr(globalObject), X86::eax);
    512             emitGetVariableObjectRegister(X86::eax, currentInstruction[3].u.operand, X86::eax);
     512            move(ImmPtr(globalObject), regT0);
     513            emitGetVariableObjectRegister(regT0, currentInstruction[3].u.operand, regT0);
    513514            emitPutVirtualRegister(currentInstruction[1].u.operand);
    514515            NEXT_OPCODE(op_get_global_var);
    515516        }
    516517        case op_put_global_var: {
    517             emitGetVirtualRegister(currentInstruction[3].u.operand, X86::edx);
     518            emitGetVirtualRegister(currentInstruction[3].u.operand, regT1);
    518519            JSVariableObject* globalObject = static_cast<JSVariableObject*>(currentInstruction[1].u.jsCell);
    519             move(ImmPtr(globalObject), X86::eax);
    520             emitPutVariableObjectRegister(X86::edx, X86::eax, currentInstruction[2].u.operand);
     520            move(ImmPtr(globalObject), regT0);
     521            emitPutVariableObjectRegister(regT1, regT0, currentInstruction[2].u.operand);
    521522            NEXT_OPCODE(op_put_global_var);
    522523        }
     
    524525            int skip = currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain();
    525526
    526             emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::eax);
     527            emitGetFromCallFrameHeader(RegisterFile::ScopeChain, regT0);
    527528            while (skip--)
    528                 loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, next)), X86::eax);
    529 
    530             loadPtr(Address(X86::eax, FIELD_OFFSET(ScopeChainNode, object)), X86::eax);
    531             emitGetVariableObjectRegister(X86::eax, currentInstruction[2].u.operand, X86::eax);
     529                loadPtr(Address(regT0, FIELD_OFFSET(ScopeChainNode, next)), regT0);
     530
     531            loadPtr(Address(regT0, FIELD_OFFSET(ScopeChainNode, object)), regT0);
     532            emitGetVariableObjectRegister(regT0, currentInstruction[2].u.operand, regT0);
    532533            emitPutVirtualRegister(currentInstruction[1].u.operand);
    533534            NEXT_OPCODE(op_get_scoped_var);
     
    536537            int skip = currentInstruction[2].u.operand + m_codeBlock->needsFullScopeChain();
    537538
    538             emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::edx);
    539             emitGetVirtualRegister(currentInstruction[3].u.operand, X86::eax);
     539            emitGetFromCallFrameHeader(RegisterFile::ScopeChain, regT1);
     540            emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
    540541            while (skip--)
    541                 loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, next)), X86::edx);
    542 
    543             loadPtr(Address(X86::edx, FIELD_OFFSET(ScopeChainNode, object)), X86::edx);
    544             emitPutVariableObjectRegister(X86::eax, X86::edx, currentInstruction[1].u.operand);
     542                loadPtr(Address(regT1, FIELD_OFFSET(ScopeChainNode, next)), regT1);
     543
     544            loadPtr(Address(regT1, FIELD_OFFSET(ScopeChainNode, object)), regT1);
     545            emitPutVariableObjectRegister(regT0, regT1, currentInstruction[1].u.operand);
    545546            NEXT_OPCODE(op_put_scoped_var);
    546547        }
    547548        case op_tear_off_activation: {
    548             emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
     549            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
    549550            emitCTICall(Interpreter::cti_op_tear_off_activation);
    550551            NEXT_OPCODE(op_tear_off_activation);
     
    559560                emitCTICall(Interpreter::cti_op_ret_scopeChain);
    560561
     562            ASSERT(callFrameRegister != regT1);
     563            ASSERT(regT1 != returnValueRegister);
     564            ASSERT(returnValueRegister != callFrameRegister);
     565
    561566            // Return the result in %eax.
    562             emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
     567            emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister);
    563568
    564569            // Grab the return address.
    565             emitGetFromCallFrameHeader(RegisterFile::ReturnPC, X86::edx);
     570            emitGetFromCallFrameHeader(RegisterFile::ReturnPC, regT1);
    566571
    567572            // Restore our caller's "r".
     
    569574
    570575            // Return.
    571             push(X86::edx);
     576            push(regT1);
    572577            ret();
    573578
     
    589594        }
    590595        case op_construct_verify: {
    591             emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
    592 
    593             emitJumpSlowCaseIfNotJSCell(X86::eax);
    594             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
    595             addSlowCase(branch32(NotEqual, Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
     596            emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
     597
     598            emitJumpSlowCaseIfNotJSCell(regT0);
     599            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
     600            addSlowCase(branch32(NotEqual, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo) + FIELD_OFFSET(TypeInfo, m_type)), Imm32(ObjectType)));
    596601
    597602            NEXT_OPCODE(op_construct_verify);
    598603        }
    599604        case op_get_by_val: {
    600             emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
    601             emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
     605            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
     606            emitJumpSlowCaseIfNotImmediateInteger(regT1);
    602607#if USE(ALTERNATE_JSIMMEDIATE)
    603608            // This is technically incorrect - we're zero-extending an int32.  On the hot path this doesn't matter.
     
    607612            // to 64-bits is necessary since it's used in the address calculation.  We zero extend rather than sign
    608613            // extending since it makes it easier to re-tag the value in the slow case.
    609             zeroExtend32ToPtr(X86::edx, X86::edx);
     614            zeroExtend32ToPtr(regT1, regT1);
    610615#else
    611             emitFastArithImmToInt(X86::edx);
    612 #endif
    613             emitJumpSlowCaseIfNotJSCell(X86::eax);
    614             addSlowCase(branchPtr(NotEqual, Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
     616            emitFastArithImmToInt(regT1);
     617#endif
     618            emitJumpSlowCaseIfNotJSCell(regT0);
     619            addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_interpreter->m_jsArrayVptr)));
    615620
    616621            // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
    617             loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
    618             addSlowCase(branch32(AboveOrEqual, X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff))));
     622            loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT2);
     623            addSlowCase(branch32(AboveOrEqual, regT1, Address(regT0, FIELD_OFFSET(JSArray, m_fastAccessCutoff))));
    619624
    620625            // Get the value from the vector
    621             loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::eax);
     626            loadPtr(BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), regT0);
    622627            emitPutVirtualRegister(currentInstruction[1].u.operand);
    623628            NEXT_OPCODE(op_get_by_val);
     
    627632            emitPutJITStubArgConstant(ident, 1);
    628633            emitCTICall(Interpreter::cti_op_resolve_func);
    629             emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);
     634            emitPutVirtualRegister(currentInstruction[2].u.operand, regT1);
    630635            emitPutVirtualRegister(currentInstruction[1].u.operand);
    631636            NEXT_OPCODE(op_resolve_func);
     
    636641        }
    637642        case op_put_by_val: {
    638             emitGetVirtualRegisters(currentInstruction[1].u.operand, X86::eax, currentInstruction[2].u.operand, X86::edx);
    639             emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
     643            emitGetVirtualRegisters(currentInstruction[1].u.operand, regT0, currentInstruction[2].u.operand, regT1);
     644            emitJumpSlowCaseIfNotImmediateInteger(regT1);
    640645#if USE(ALTERNATE_JSIMMEDIATE)
    641646            // See comment in op_get_by_val.
    642             zeroExtend32ToPtr(X86::edx, X86::edx);
     647            zeroExtend32ToPtr(regT1, regT1);
    643648#else
    644             emitFastArithImmToInt(X86::edx);
    645 #endif
    646             emitJumpSlowCaseIfNotJSCell(X86::eax);
    647             addSlowCase(branchPtr(NotEqual, Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr)));
     649            emitFastArithImmToInt(regT1);
     650#endif
     651            emitJumpSlowCaseIfNotJSCell(regT0);
     652            addSlowCase(branchPtr(NotEqual, Address(regT0), ImmPtr(m_interpreter->m_jsArrayVptr)));
    648653
    649654            // This is an array; get the m_storage pointer into ecx, then check if the index is below the fast cutoff
    650             loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::ecx);
    651             Jump inFastVector = branch32(Below, X86::edx, Address(X86::eax, FIELD_OFFSET(JSArray, m_fastAccessCutoff)));
     655            loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT2);
     656            Jump inFastVector = branch32(Below, regT1, Address(regT0, FIELD_OFFSET(JSArray, m_fastAccessCutoff)));
    652657            // No; oh well, check if the access if within the vector - if so, we may still be okay.
    653             addSlowCase(branch32(AboveOrEqual, X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength))));
     658            addSlowCase(branch32(AboveOrEqual, regT1, Address(regT2, FIELD_OFFSET(ArrayStorage, m_vectorLength))));
    654659
    655660            // This is a write to the slow part of the vector; first, we have to check if this would be the first write to this location.
    656661            // FIXME: should be able to handle initial write to array; increment the the number of items in the array, and potentially update fast access cutoff.
    657             addSlowCase(branchTestPtr(Zero, BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0]))));
     662            addSlowCase(branchTestPtr(Zero, BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0]))));
    658663
    659664            // All good - put the value into the array.
    660665            inFastVector.link(this);
    661             emitGetVirtualRegister(currentInstruction[3].u.operand, X86::eax);
    662             storePtr(X86::eax, BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])));
     666            emitGetVirtualRegister(currentInstruction[3].u.operand, regT0);
     667            storePtr(regT0, BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])));
    663668            NEXT_OPCODE(op_put_by_val);
    664669        }
     
    668673
    669674            unsigned target = currentInstruction[2].u.operand;
    670             emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
    671 
    672             Jump isZero = branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(js0())));
    673             addJump(emitJumpIfImmediateInteger(X86::eax), target + 2);
    674 
    675             addJump(branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
    676             addSlowCase(branchPtr(NotEqual, X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
     675            emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
     676
     677            Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0())));
     678            addJump(emitJumpIfImmediateInteger(regT0), target + 2);
     679
     680            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
     681            addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
    677682
    678683            isZero.link(this);
     
    687692        }
    688693        case op_negate: {
    689             emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
     694            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
    690695            emitCTICall(Interpreter::cti_op_negate);
    691696            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    710715
    711716            // Check Structure of global object
    712             move(ImmPtr(globalObject), X86::eax);
    713             loadPtr(structureAddress, X86::edx);
    714             Jump noMatch = branchPtr(NotEqual, X86::edx, Address(X86::eax, FIELD_OFFSET(JSCell, m_structure))); // Structures don't match
     717            move(ImmPtr(globalObject), regT0);
     718            loadPtr(structureAddress, regT1);
     719            Jump noMatch = branchPtr(NotEqual, regT1, Address(regT0, FIELD_OFFSET(JSCell, m_structure))); // Structures don't match
    715720
    716721            // Load cached property
    717             loadPtr(Address(X86::eax, FIELD_OFFSET(JSGlobalObject, m_propertyStorage)), X86::eax);
    718             load32(offsetAddr, X86::edx);
    719             loadPtr(BaseIndex(X86::eax, X86::edx, ScalePtr), X86::eax);
     722            loadPtr(Address(regT0, FIELD_OFFSET(JSGlobalObject, m_propertyStorage)), regT0);
     723            load32(offsetAddr, regT1);
     724            loadPtr(BaseIndex(regT0, regT1, ScalePtr), regT0);
    720725            emitPutVirtualRegister(currentInstruction[1].u.operand);
    721726            Jump end = jump();
     
    741746            unsigned target = currentInstruction[3].u.operand;
    742747            if (isOperandConstantImmediateInt(op2)) {
    743                 emitGetVirtualRegister(op1, X86::eax);
    744                 emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     748                emitGetVirtualRegister(op1, regT0);
     749                emitJumpSlowCaseIfNotImmediateInteger(regT0);
    745750#if USE(ALTERNATE_JSIMMEDIATE)
    746751                int32_t op2imm = getConstantOperandImmediateInt(op2);
     
    748753                int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2)));
    749754#endif
    750                 addJump(branch32(GreaterThanOrEqual, X86::eax, Imm32(op2imm)), target + 3);
     755                addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3);
    751756            } else {
    752                 emitGetVirtualRegisters(op1, X86::eax, op2, X86::edx);
    753                 emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
    754                 emitJumpSlowCaseIfNotImmediateInteger(X86::edx);
    755                 addJump(branch32(GreaterThanOrEqual, X86::eax, X86::edx), target + 3);
     757                emitGetVirtualRegisters(op1, regT0, op2, regT1);
     758                emitJumpSlowCaseIfNotImmediateInteger(regT0);
     759                emitJumpSlowCaseIfNotImmediateInteger(regT1);
     760                addJump(branch32(GreaterThanOrEqual, regT0, regT1), target + 3);
    756761            }
    757762            NEXT_OPCODE(op_jnless);
    758763        }
    759764        case op_not: {
    760             emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
    761             xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
    762             addSlowCase(branchTestPtr(NonZero, X86::eax, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
    763             xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), X86::eax);
     765            emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
     766            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
     767            addSlowCase(branchTestPtr(NonZero, regT0, Imm32(static_cast<int32_t>(~JSImmediate::ExtendedPayloadBitBoolValue))));
     768            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool | JSImmediate::ExtendedPayloadBitBoolValue)), regT0);
    764769            emitPutVirtualRegister(currentInstruction[1].u.operand);
    765770            NEXT_OPCODE(op_not);
     
    767772        case op_jfalse: {
    768773            unsigned target = currentInstruction[2].u.operand;
    769             emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
    770 
    771             addJump(branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(js0()))), target + 2);
    772             Jump isNonZero = emitJumpIfImmediateInteger(X86::eax);
    773 
    774             addJump(branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))), target + 2);
    775             addSlowCase(branchPtr(NotEqual, X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))));
     774            emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
     775
     776            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0()))), target + 2);
     777            Jump isNonZero = emitJumpIfImmediateInteger(regT0);
     778
     779            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(false)))), target + 2);
     780            addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(true)))));
    776781
    777782            isNonZero.link(this);
     
    782787            unsigned target = currentInstruction[2].u.operand;
    783788
    784             emitGetVirtualRegister(src, X86::eax);
    785             Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
     789            emitGetVirtualRegister(src, regT0);
     790            Jump isImmediate = emitJumpIfNotJSCell(regT0);
    786791
    787792            // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
    788             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
    789             addJump(branchTest32(NonZero, Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
     793            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
     794            addJump(branchTest32(NonZero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
    790795            Jump wasNotImmediate = jump();
    791796
    792797            // Now handle the immediate cases - undefined & null
    793798            isImmediate.link(this);
    794             andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
    795             addJump(branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);           
     799            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
     800            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);           
    796801
    797802            wasNotImmediate.link(this);
     
    802807            unsigned target = currentInstruction[2].u.operand;
    803808
    804             emitGetVirtualRegister(src, X86::eax);
    805             Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
     809            emitGetVirtualRegister(src, regT0);
     810            Jump isImmediate = emitJumpIfNotJSCell(regT0);
    806811
    807812            // First, handle JSCell cases - check MasqueradesAsUndefined bit on the structure.
    808             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
    809             addJump(branchTest32(Zero, Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
     813            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
     814            addJump(branchTest32(Zero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined)), target + 2);
    810815            Jump wasNotImmediate = jump();
    811816
    812817            // Now handle the immediate cases - undefined & null
    813818            isImmediate.link(this);
    814             andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
    815             addJump(branchPtr(NotEqual, X86::eax, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);           
     819            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
     820            addJump(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsNull()))), target + 2);           
    816821
    817822            wasNotImmediate.link(this);
     
    824829        case op_unexpected_load: {
    825830            JSValuePtr v = m_codeBlock->unexpectedConstant(currentInstruction[2].u.operand);
    826             move(ImmPtr(JSValuePtr::encode(v)), X86::eax);
     831            move(ImmPtr(JSValuePtr::encode(v)), regT0);
    827832            emitPutVirtualRegister(currentInstruction[1].u.operand);
    828833            NEXT_OPCODE(op_unexpected_load);
     
    841846        }
    842847        case op_eq: {
    843             emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
    844             emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
    845             set32(Equal, X86::edx, X86::eax, X86::eax);
    846             emitTagAsBoolImmediate(X86::eax);
     848            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
     849            emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
     850            set32(Equal, regT1, regT0, regT0);
     851            emitTagAsBoolImmediate(regT0);
    847852            emitPutVirtualRegister(currentInstruction[1].u.operand);
    848853            NEXT_OPCODE(op_eq);
     
    861866        }
    862867        case op_bitnot: {
    863             emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
    864             emitJumpSlowCaseIfNotImmediateInteger(X86::eax);
     868            emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
     869            emitJumpSlowCaseIfNotImmediateInteger(regT0);
    865870#if USE(ALTERNATE_JSIMMEDIATE)
    866             not32(X86::eax);
    867             emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     871            not32(regT0);
     872            emitFastArithIntToImmNoCheck(regT0, regT0);
    868873#else
    869             xorPtr(Imm32(~JSImmediate::TagTypeNumber), X86::eax);
     874            xorPtr(Imm32(~JSImmediate::TagTypeNumber), regT0);
    870875#endif
    871876            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    876881            emitPutJITStubArgConstant(ident, 1);
    877882            emitCTICall(Interpreter::cti_op_resolve_with_base);
    878             emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);
     883            emitPutVirtualRegister(currentInstruction[2].u.operand, regT1);
    879884            emitPutVirtualRegister(currentInstruction[1].u.operand);
    880885            NEXT_OPCODE(op_resolve_with_base);
     
    893898        case op_jtrue: {
    894899            unsigned target = currentInstruction[2].u.operand;
    895             emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
    896 
    897             Jump isZero = branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(js0())));
    898             addJump(emitJumpIfImmediateInteger(X86::eax), target + 2);
    899 
    900             addJump(branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
    901             addSlowCase(branchPtr(NotEqual, X86::eax, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
     900            emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
     901
     902            Jump isZero = branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0())));
     903            addJump(emitJumpIfImmediateInteger(regT0), target + 2);
     904
     905            addJump(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(true)))), target + 2);
     906            addSlowCase(branchPtr(NotEqual, regT0, ImmPtr(JSValuePtr::encode(jsBoolean(false)))));
    902907
    903908            isZero.link(this);
     
    906911        CTI_COMPILE_BINARY_OP(op_less)
    907912        case op_neq: {
    908             emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
    909             emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
    910             set32(NotEqual, X86::edx, X86::eax, X86::eax);
    911             emitTagAsBoolImmediate(X86::eax);
     913            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
     914            emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
     915            set32(NotEqual, regT1, regT0, regT0);
     916            emitTagAsBoolImmediate(regT0);
    912917
    913918            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    921926        CTI_COMPILE_BINARY_OP(op_urshift)
    922927        case op_bitxor: {
    923             emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
    924             emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
    925             xorPtr(X86::edx, X86::eax);
    926             emitFastArithReTagImmediate(X86::eax, X86::eax);
     928            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
     929            emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
     930            xorPtr(regT1, regT0);
     931            emitFastArithReTagImmediate(regT0, regT0);
    927932            emitPutVirtualRegister(currentInstruction[1].u.operand);
    928933            NEXT_OPCODE(op_bitxor);
     
    936941        }
    937942        case op_bitor: {
    938             emitGetVirtualRegisters(currentInstruction[2].u.operand, X86::eax, currentInstruction[3].u.operand, X86::edx);
    939             emitJumpSlowCaseIfNotImmediateIntegers(X86::eax, X86::edx, X86::ecx);
    940             orPtr(X86::edx, X86::eax);
     943            emitGetVirtualRegisters(currentInstruction[2].u.operand, regT0, currentInstruction[3].u.operand, regT1);
     944            emitJumpSlowCaseIfNotImmediateIntegers(regT0, regT1, regT2);
     945            orPtr(regT1, regT0);
    941946            emitPutVirtualRegister(currentInstruction[1].u.operand);
    942947            NEXT_OPCODE(op_bitor);
    943948        }
    944949        case op_throw: {
    945             emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
     950            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
    946951            emitCTICall(Interpreter::cti_op_throw);
     952            ASSERT(regT0 == returnValueRegister);
    947953#if PLATFORM(X86_64)
    948954            addPtr(Imm32(0x48), X86::esp);
     
    965971        }
    966972        case op_get_pnames: {
    967             emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
     973            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
    968974            emitCTICall(Interpreter::cti_op_get_pnames);
    969975            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    971977        }
    972978        case op_next_pname: {
    973             emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
     979            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
    974980            unsigned target = currentInstruction[3].u.operand;
    975981            emitCTICall(Interpreter::cti_op_next_pname);
    976             Jump endOfIter = branchTestPtr(Zero, X86::eax);
     982            Jump endOfIter = branchTestPtr(Zero, regT0);
    977983            emitPutVirtualRegister(currentInstruction[1].u.operand);
    978984            addJump(jump(), target + 3);
     
    981987        }
    982988        case op_push_scope: {
    983             emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
     989            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
    984990            emitCTICall(Interpreter::cti_op_push_scope);
    985991            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    10071013        case op_to_jsnumber: {
    10081014            int srcVReg = currentInstruction[2].u.operand;
    1009             emitGetVirtualRegister(srcVReg, X86::eax);
     1015            emitGetVirtualRegister(srcVReg, regT0);
    10101016           
    1011             Jump wasImmediate = emitJumpIfImmediateInteger(X86::eax);
    1012 
    1013             emitJumpSlowCaseIfNotJSCell(X86::eax, srcVReg);
    1014             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
    1015             addSlowCase(branch32(NotEqual, Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
     1017            Jump wasImmediate = emitJumpIfImmediateInteger(regT0);
     1018
     1019            emitJumpSlowCaseIfNotJSCell(regT0, srcVReg);
     1020            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
     1021            addSlowCase(branch32(NotEqual, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_type)), Imm32(NumberType)));
    10161022           
    10171023            wasImmediate.link(this);
     
    10241030            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
    10251031            emitPutJITStubArgConstant(ident, 1);
    1026             emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
     1032            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2);
    10271033            emitCTICall(Interpreter::cti_op_push_new_scope);
    10281034            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    10431049        }
    10441050        case op_put_by_index: {
    1045             emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
     1051            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
    10461052            emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2);
    1047             emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
     1053            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);
    10481054            emitCTICall(Interpreter::cti_op_put_by_index);
    10491055            NEXT_OPCODE(op_put_by_index);
     
    10591065            jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
    10601066
    1061             emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
     1067            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);
    10621068            emitPutJITStubArgConstant(tableIndex, 2);
    10631069            emitCTICall(Interpreter::cti_op_switch_imm);
    1064             jump(X86::eax);
     1070            jump(regT0);
    10651071            NEXT_OPCODE(op_switch_imm);
    10661072        }
     
    10751081            jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size());
    10761082
    1077             emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
     1083            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);
    10781084            emitPutJITStubArgConstant(tableIndex, 2);
    10791085            emitCTICall(Interpreter::cti_op_switch_char);
    1080             jump(X86::eax);
     1086            jump(regT0);
    10811087            NEXT_OPCODE(op_switch_char);
    10821088        }
     
    10901096            m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset));
    10911097
    1092             emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);
     1098            emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2);
    10931099            emitPutJITStubArgConstant(tableIndex, 2);
    10941100            emitCTICall(Interpreter::cti_op_switch_string);
    1095             jump(X86::eax);
     1101            jump(regT0);
    10961102            NEXT_OPCODE(op_switch_string);
    10971103        }
    10981104        case op_del_by_val: {
    1099             emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
    1100             emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
     1105            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
     1106            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2);
    11011107            emitCTICall(Interpreter::cti_op_del_by_val);
    11021108            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    11041110        }
    11051111        case op_put_getter: {
    1106             emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
     1112            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
    11071113            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
    11081114            emitPutJITStubArgConstant(ident, 2);
    1109             emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
     1115            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);
    11101116            emitCTICall(Interpreter::cti_op_put_getter);
    11111117            NEXT_OPCODE(op_put_getter);
    11121118        }
    11131119        case op_put_setter: {
    1114             emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);
     1120            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2);
    11151121            Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand));
    11161122            emitPutJITStubArgConstant(ident, 2);
    1117             emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);
     1123            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2);
    11181124            emitCTICall(Interpreter::cti_op_put_setter);
    11191125            NEXT_OPCODE(op_put_setter);
     
    11391145            unsigned src1 = currentInstruction[2].u.operand;
    11401146
    1141             emitGetVirtualRegister(src1, X86::eax);
    1142             Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
    1143 
    1144             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
    1145             setTest32(NonZero, Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
     1147            emitGetVirtualRegister(src1, regT0);
     1148            Jump isImmediate = emitJumpIfNotJSCell(regT0);
     1149
     1150            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
     1151            setTest32(NonZero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
    11461152
    11471153            Jump wasNotImmediate = jump();
     
    11491155            isImmediate.link(this);
    11501156
    1151             andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
    1152             set32(Equal, X86::eax, Imm32(JSImmediate::FullTagTypeNull), X86::eax);
     1157            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
     1158            set32(Equal, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);
    11531159
    11541160            wasNotImmediate.link(this);
    11551161
    1156             emitTagAsBoolImmediate(X86::eax);
     1162            emitTagAsBoolImmediate(regT0);
    11571163            emitPutVirtualRegister(dst);
    11581164
     
    11631169            unsigned src1 = currentInstruction[2].u.operand;
    11641170
    1165             emitGetVirtualRegister(src1, X86::eax);
    1166             Jump isImmediate = emitJumpIfNotJSCell(X86::eax);
    1167 
    1168             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::ecx);
    1169             setTest32(Zero, Address(X86::ecx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), X86::eax);
     1171            emitGetVirtualRegister(src1, regT0);
     1172            Jump isImmediate = emitJumpIfNotJSCell(regT0);
     1173
     1174            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT2);
     1175            setTest32(Zero, Address(regT2, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(MasqueradesAsUndefined), regT0);
    11701176
    11711177            Jump wasNotImmediate = jump();
     
    11731179            isImmediate.link(this);
    11741180
    1175             andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), X86::eax);
    1176             set32(NotEqual, X86::eax, Imm32(JSImmediate::FullTagTypeNull), X86::eax);
     1181            andPtr(Imm32(~JSImmediate::ExtendedTagBitUndefined), regT0);
     1182            set32(NotEqual, regT0, Imm32(JSImmediate::FullTagTypeNull), regT0);
    11771183
    11781184            wasNotImmediate.link(this);
    11791185
    1180             emitTagAsBoolImmediate(X86::eax);
     1186            emitTagAsBoolImmediate(regT0);
    11811187            emitPutVirtualRegister(dst);
    11821188
     
    12141220        }
    12151221        case op_convert_this: {
    1216             emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);
    1217 
    1218             emitJumpSlowCaseIfNotJSCell(X86::eax);
    1219             loadPtr(Address(X86::eax, FIELD_OFFSET(JSCell, m_structure)), X86::edx);
    1220             addSlowCase(branchTest32(NonZero, Address(X86::edx, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
     1222            emitGetVirtualRegister(currentInstruction[1].u.operand, regT0);
     1223
     1224            emitJumpSlowCaseIfNotJSCell(regT0);
     1225            loadPtr(Address(regT0, FIELD_OFFSET(JSCell, m_structure)), regT1);
     1226            addSlowCase(branchTest32(NonZero, Address(regT1, FIELD_OFFSET(Structure, m_typeInfo.m_flags)), Imm32(NeedsThisConversion)));
    12211227
    12221228            NEXT_OPCODE(op_convert_this);
    12231229        }
    12241230        case op_profile_will_call: {
    1225             emitGetCTIParam(STUB_ARGS_profilerReference, X86::eax);
    1226             Jump noProfiler = branchTestPtr(Zero, Address(X86::eax));
    1227             emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::eax);
     1231            emitGetCTIParam(STUB_ARGS_profilerReference, regT0);
     1232            Jump noProfiler = branchTestPtr(Zero, Address(regT0));
     1233            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT0);
    12281234            emitCTICall(Interpreter::cti_op_profile_will_call);
    12291235            noProfiler.link(this);
     
    12321238        }
    12331239        case op_profile_did_call: {
    1234             emitGetCTIParam(STUB_ARGS_profilerReference, X86::eax);
    1235             Jump noProfiler = branchTestPtr(Zero, Address(X86::eax));
    1236             emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::eax);
     1240            emitGetCTIParam(STUB_ARGS_profilerReference, regT0);
     1241            Jump noProfiler = branchTestPtr(Zero, Address(regT0));
     1242            emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT0);
    12371243            emitCTICall(Interpreter::cti_op_profile_did_call);
    12381244            noProfiler.link(this);
     
    12931299            linkSlowCase(iter);
    12941300            linkSlowCase(iter);
    1295             emitPutJITStubArg(X86::eax, 1);
     1301            emitPutJITStubArg(regT0, 1);
    12961302            emitCTICall(Interpreter::cti_op_convert_this);
    12971303            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    13051311            linkSlowCase(iter);
    13061312            linkSlowCase(iter);
    1307             emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);
     1313            emitGetVirtualRegister(currentInstruction[2].u.operand, regT0);
    13081314            emitPutVirtualRegister(currentInstruction[1].u.operand);
    13091315
     
    13171323            linkSlowCase(iter);
    13181324            linkSlowCase(iter);
    1319             emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
     1325            emitFastArithIntToImmNoCheck(regT1, regT1);
    13201326            notImm.link(this);
    1321             emitPutJITStubArg(X86::eax, 1);
    1322             emitPutJITStubArg(X86::edx, 2);
     1327            emitPutJITStubArg(regT0, 1);
     1328            emitPutJITStubArg(regT1, 2);
    13231329            emitCTICall(Interpreter::cti_op_get_by_val);
    13241330            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    13281334            // First, check if this is an access to the vector
    13291335            linkSlowCase(iter);
    1330             branch32(AboveOrEqual, X86::edx, Address(X86::ecx, FIELD_OFFSET(ArrayStorage, m_vectorLength)), beginGetByValSlow);
     1336            branch32(AboveOrEqual, regT1, Address(regT2, FIELD_OFFSET(ArrayStorage, m_vectorLength)), beginGetByValSlow);
    13311337
    13321338            // okay, missed the fast region, but it is still in the vector.  Get the value.
    1333             loadPtr(BaseIndex(X86::ecx, X86::edx, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), X86::ecx);
     1339            loadPtr(BaseIndex(regT2, regT1, ScalePtr, FIELD_OFFSET(ArrayStorage, m_vector[0])), regT2);
    13341340            // Check whether the value loaded is zero; if so we need to return undefined.
    1335             branchTestPtr(Zero, X86::ecx, beginGetByValSlow);
    1336             move(X86::ecx, X86::eax);
    1337             emitPutVirtualRegister(currentInstruction[1].u.operand, X86::eax);
     1341            branchTestPtr(Zero, regT2, beginGetByValSlow);
     1342            move(regT2, regT0);
     1343            emitPutVirtualRegister(currentInstruction[1].u.operand, regT0);
    13381344
    13391345            NEXT_OPCODE(op_get_by_val);
     
    13561362            if (isOperandConstantImmediateInt(op2)) {
    13571363                linkSlowCase(iter);
    1358                 emitPutJITStubArg(X86::eax, 1);
    1359                 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);
     1364                emitPutJITStubArg(regT0, 1);
     1365                emitPutJITStubArgFromVirtualRegister(op2, 2, regT2);
    13601366                emitCTICall(Interpreter::cti_op_loop_if_less);
    1361                 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 3);
     1367                emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
    13621368            } else {
    13631369                linkSlowCase(iter);
    13641370                linkSlowCase(iter);
    1365                 emitPutJITStubArg(X86::eax, 1);
    1366                 emitPutJITStubArg(X86::edx, 2);
     1371                emitPutJITStubArg(regT0, 1);
     1372                emitPutJITStubArg(regT1, 2);
    13671373                emitCTICall(Interpreter::cti_op_loop_if_less);
    1368                 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 3);
     1374                emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
    13691375            }
    13701376            NEXT_OPCODE(op_loop_if_less);
     
    13831389            if (isOperandConstantImmediateInt(op2)) {
    13841390                linkSlowCase(iter);
    1385                 emitPutJITStubArg(X86::eax, 1);
    1386                 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx);
     1391                emitPutJITStubArg(regT0, 1);
     1392                emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, regT2);
    13871393                emitCTICall(Interpreter::cti_op_loop_if_lesseq);
    1388                 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 3);
     1394                emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
    13891395            } else {
    13901396                linkSlowCase(iter);
    13911397                linkSlowCase(iter);
    1392                 emitPutJITStubArg(X86::eax, 1);
    1393                 emitPutJITStubArg(X86::edx, 2);
     1398                emitPutJITStubArg(regT0, 1);
     1399                emitPutJITStubArg(regT1, 2);
    13941400                emitCTICall(Interpreter::cti_op_loop_if_lesseq);
    1395                 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 3);
     1401                emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3);
    13961402            }
    13971403            NEXT_OPCODE(op_loop_if_lesseq);
     
    14061412            linkSlowCase(iter);
    14071413            linkSlowCase(iter);
    1408             emitFastArithIntToImmNoCheck(X86::edx, X86::edx);
     1414            emitFastArithIntToImmNoCheck(regT1, regT1);
    14091415            notImm.link(this);
    1410             emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
    1411             emitPutJITStubArg(X86::eax, 1);
    1412             emitPutJITStubArg(X86::edx, 2);
    1413             emitPutJITStubArg(X86::ecx, 3);
     1416            emitGetVirtualRegister(currentInstruction[3].u.operand, regT2);
     1417            emitPutJITStubArg(regT0, 1);
     1418            emitPutJITStubArg(regT1, 2);
     1419            emitPutJITStubArg(regT2, 3);
    14141420            emitCTICall(Interpreter::cti_op_put_by_val);
    14151421            emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val));
     
    14181424            linkSlowCase(iter);
    14191425            linkSlowCase(iter);
    1420             emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx);
    1421             emitPutJITStubArg(X86::eax, 1);
    1422             emitPutJITStubArg(X86::edx, 2);
    1423             emitPutJITStubArg(X86::ecx, 3);
     1426            emitGetVirtualRegister(currentInstruction[3].u.operand, regT2);
     1427            emitPutJITStubArg(regT0, 1);
     1428            emitPutJITStubArg(regT1, 2);
     1429            emitPutJITStubArg(regT2, 3);
    14241430            emitCTICall(Interpreter::cti_op_put_by_val_array);
    14251431
     
    14281434        case op_loop_if_true: {
    14291435            linkSlowCase(iter);
    1430             emitPutJITStubArg(X86::eax, 1);
     1436            emitPutJITStubArg(regT0, 1);
    14311437            emitCTICall(Interpreter::cti_op_jtrue);
    14321438            unsigned target = currentInstruction[2].u.operand;
    1433             emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 2);
     1439            emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2);
    14341440            NEXT_OPCODE(op_loop_if_true);
    14351441        }
     
    14431449            if (isOperandConstantImmediateInt(op2)) {
    14441450                linkSlowCase(iter);
    1445                 emitPutJITStubArg(X86::eax, 1);
    1446                 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, X86::ecx);
     1451                emitPutJITStubArg(regT0, 1);
     1452                emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 2, regT2);
    14471453                emitCTICall(Interpreter::cti_op_jless);
    1448                 emitJumpSlowToHot(branchTest32(Zero, X86::eax), target + 3);
     1454                emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
    14491455            } else {
    14501456                linkSlowCase(iter);
    14511457                linkSlowCase(iter);
    1452                 emitPutJITStubArg(X86::eax, 1);
    1453                 emitPutJITStubArg(X86::edx, 2);
     1458                emitPutJITStubArg(regT0, 1);
     1459                emitPutJITStubArg(regT1, 2);
    14541460                emitCTICall(Interpreter::cti_op_jless);
    1455                 emitJumpSlowToHot(branchTest32(Zero, X86::eax), target + 3);
     1461                emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3);
    14561462            }
    14571463            NEXT_OPCODE(op_jnless);
     
    14591465        case op_not: {
    14601466            linkSlowCase(iter);
    1461             xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), X86::eax);
    1462             emitPutJITStubArg(X86::eax, 1);
     1467            xorPtr(Imm32(static_cast<int32_t>(JSImmediate::FullTagTypeBool)), regT0);
     1468            emitPutJITStubArg(regT0, 1);
    14631469            emitCTICall(Interpreter::cti_op_not);
    14641470            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    14671473        case op_jfalse: {
    14681474            linkSlowCase(iter);
    1469             emitPutJITStubArg(X86::eax, 1);
     1475            emitPutJITStubArg(regT0, 1);
    14701476            emitCTICall(Interpreter::cti_op_jtrue);
    14711477            unsigned target = currentInstruction[2].u.operand;
    1472             emitJumpSlowToHot(branchTest32(Zero, X86::eax), target + 2); // inverted!
     1478            emitJumpSlowToHot(branchTest32(Zero, regT0), target + 2); // inverted!
    14731479            NEXT_OPCODE(op_jfalse);
    14741480        }
     
    14791485        case op_bitnot: {
    14801486            linkSlowCase(iter);
    1481             emitPutJITStubArg(X86::eax, 1);
     1487            emitPutJITStubArg(regT0, 1);
    14821488            emitCTICall(Interpreter::cti_op_bitnot);
    14831489            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    14901496        case op_jtrue: {
    14911497            linkSlowCase(iter);
    1492             emitPutJITStubArg(X86::eax, 1);
     1498            emitPutJITStubArg(regT0, 1);
    14931499            emitCTICall(Interpreter::cti_op_jtrue);
    14941500            unsigned target = currentInstruction[2].u.operand;
    1495             emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 2);
     1501            emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2);
    14961502            NEXT_OPCODE(op_jtrue);
    14971503        }
     
    15021508        case op_bitxor: {
    15031509            linkSlowCase(iter);
    1504             emitPutJITStubArg(X86::eax, 1);
    1505             emitPutJITStubArg(X86::edx, 2);
     1510            emitPutJITStubArg(regT0, 1);
     1511            emitPutJITStubArg(regT1, 2);
    15061512            emitCTICall(Interpreter::cti_op_bitxor);
    15071513            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    15101516        case op_bitor: {
    15111517            linkSlowCase(iter);
    1512             emitPutJITStubArg(X86::eax, 1);
    1513             emitPutJITStubArg(X86::edx, 2);
     1518            emitPutJITStubArg(regT0, 1);
     1519            emitPutJITStubArg(regT1, 2);
    15141520            emitCTICall(Interpreter::cti_op_bitor);
    15151521            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    15181524        case op_eq: {
    15191525            linkSlowCase(iter);
    1520             emitPutJITStubArg(X86::eax, 1);
    1521             emitPutJITStubArg(X86::edx, 2);
     1526            emitPutJITStubArg(regT0, 1);
     1527            emitPutJITStubArg(regT1, 2);
    15221528            emitCTICall(Interpreter::cti_op_eq);
    15231529            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    15261532        case op_neq: {
    15271533            linkSlowCase(iter);
    1528             emitPutJITStubArg(X86::eax, 1);
    1529             emitPutJITStubArg(X86::edx, 2);
     1534            emitPutJITStubArg(regT0, 1);
     1535            emitPutJITStubArg(regT1, 2);
    15301536            emitCTICall(Interpreter::cti_op_neq);
    15311537            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    15381544            linkSlowCase(iter);
    15391545#endif
    1540             emitPutJITStubArg(X86::eax, 1);
    1541             emitPutJITStubArg(X86::edx, 2);
     1546            emitPutJITStubArg(regT0, 1);
     1547            emitPutJITStubArg(regT1, 2);
    15421548            emitCTICall(Interpreter::cti_op_stricteq);
    15431549            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    15501556            linkSlowCase(iter);
    15511557#endif
    1552             emitPutJITStubArg(X86::eax, 1);
    1553             emitPutJITStubArg(X86::edx, 2);
     1558            emitPutJITStubArg(regT0, 1);
     1559            emitPutJITStubArg(regT1, 2);
    15541560            emitCTICall(Interpreter::cti_op_nstricteq);
    15551561            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    15601566            linkSlowCase(iter);
    15611567            linkSlowCase(iter);
    1562             emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);
    1563             emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);
    1564             emitPutJITStubArgFromVirtualRegister(currentInstruction[4].u.operand, 3, X86::ecx);
     1568            emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2);
     1569            emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2);
     1570            emitPutJITStubArgFromVirtualRegister(currentInstruction[4].u.operand, 3, regT2);
    15651571            emitCTICall(Interpreter::cti_op_instanceof);
    15661572            emitPutVirtualRegister(currentInstruction[1].u.operand);
     
    15921598            linkSlowCase(iter);
    15931599
    1594             emitPutJITStubArg(X86::eax, 1);
     1600            emitPutJITStubArg(regT0, 1);
    15951601            emitCTICall(Interpreter::cti_op_to_jsnumber);
    15961602
     
    16281634
    16291635    // Could use a pop_m, but would need to offset the following instruction if so.
    1630     pop(X86::ecx);
    1631     emitPutToCallFrameHeader(X86::ecx, RegisterFile::ReturnPC);
     1636    pop(regT2);
     1637    emitPutToCallFrameHeader(regT2, RegisterFile::ReturnPC);
    16321638
    16331639    Jump slowRegisterFileCheck;
     
    16371643        emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock);
    16381644
    1639         emitGetCTIParam(STUB_ARGS_registerFile, X86::eax);
    1640         addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, X86::edx);
     1645        emitGetCTIParam(STUB_ARGS_registerFile, regT0);
     1646        addPtr(Imm32(m_codeBlock->m_numCalleeRegisters * sizeof(Register)), callFrameRegister, regT1);
    16411647       
    1642         slowRegisterFileCheck = branch32(GreaterThan, X86::edx, Address(X86::eax, FIELD_OFFSET(RegisterFile, m_end)));
     1648        slowRegisterFileCheck = branch32(GreaterThan, regT1, Address(regT0, FIELD_OFFSET(RegisterFile, m_end)));
    16431649        afterRegisterFileCheck = label();
    16441650    }
     
    17531759
    17541760    // Check eax is an array
    1755     Jump array_failureCases1 = emitJumpIfNotJSCell(X86::eax);
    1756     Jump array_failureCases2 = branchPtr(NotEqual, Address(X86::eax), ImmPtr(m_interpreter->m_jsArrayVptr));
     1761    Jump array_failureCases1 = emitJumpIfNotJSCell(regT0);
     1762    Jump array_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_interpreter->m_jsArrayVptr));
    17571763
    17581764    // Checks out okay! - get the length from the storage
    1759     loadPtr(Address(X86::eax, FIELD_OFFSET(JSArray, m_storage)), X86::eax);
    1760     load32(Address(X86::eax, FIELD_OFFSET(ArrayStorage, m_length)), X86::eax);
    1761 
    1762     Jump array_failureCases3 = branch32(Above, X86::eax, Imm32(JSImmediate::maxImmediateInt));
    1763 
    1764     // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
    1765     emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     1765    loadPtr(Address(regT0, FIELD_OFFSET(JSArray, m_storage)), regT0);
     1766    load32(Address(regT0, FIELD_OFFSET(ArrayStorage, m_length)), regT0);
     1767
     1768    Jump array_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
     1769
     1770    // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
     1771    emitFastArithIntToImmNoCheck(regT0, regT0);
    17661772
    17671773    ret();
     
    17711777
    17721778    // Check eax is a string
    1773     Jump string_failureCases1 = emitJumpIfNotJSCell(X86::eax);
    1774     Jump string_failureCases2 = branchPtr(NotEqual, Address(X86::eax), ImmPtr(m_interpreter->m_jsStringVptr));
     1779    Jump string_failureCases1 = emitJumpIfNotJSCell(regT0);
     1780    Jump string_failureCases2 = branchPtr(NotEqual, Address(regT0), ImmPtr(m_interpreter->m_jsStringVptr));
    17751781
    17761782    // Checks out okay! - get the length from the Ustring.
    1777     loadPtr(Address(X86::eax, FIELD_OFFSET(JSString, m_value) + FIELD_OFFSET(UString, m_rep)), X86::eax);
    1778     load32(Address(X86::eax, FIELD_OFFSET(UString::Rep, len)), X86::eax);
    1779 
    1780     Jump string_failureCases3 = branch32(Above, X86::eax, Imm32(JSImmediate::maxImmediateInt));
    1781 
    1782     // X86::eax contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
    1783     emitFastArithIntToImmNoCheck(X86::eax, X86::eax);
     1783    loadPtr(Address(regT0, FIELD_OFFSET(JSString, m_value) + FIELD_OFFSET(UString, m_rep)), regT0);
     1784    load32(Address(regT0, FIELD_OFFSET(UString::Rep, len)), regT0);
     1785
     1786    Jump string_failureCases3 = branch32(Above, regT0, Imm32(JSImmediate::maxImmediateInt));
     1787
     1788    // regT0 contains a 64 bit value (is positive, is zero extended) so we don't need sign extend here.
     1789    emitFastArithIntToImmNoCheck(regT0, regT0);
    17841790   
    17851791    ret();
     1792#endif
     1793
     1794#if !(PLATFORM(X86) || PLATFORM(X86_64))
     1795#error "This code is less portable than it looks this code assumes that regT3 is callee preserved, which happens to be true on x86/x86-64."
    17861796#endif
    17871797
     
    17911801
    17921802    // Load the callee CodeBlock* into eax
    1793     loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
    1794     loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
    1795     Jump hasCodeBlock1 = branchTestPtr(NonZero, X86::eax);
    1796     pop(X86::ebx);
     1803    loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT0);
     1804    loadPtr(Address(regT0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);
     1805    Jump hasCodeBlock1 = branchTestPtr(NonZero, regT0);
     1806    pop(regT3);
    17971807    restoreArgumentReference();
    17981808    Call callJSFunction1 = call();
    1799     emitGetJITStubArg(1, X86::ecx);
    1800     emitGetJITStubArg(3, X86::edx);
    1801     push(X86::ebx);
     1809    emitGetJITStubArg(1, regT2);
     1810    emitGetJITStubArg(3, regT1);
     1811    push(regT3);
    18021812    hasCodeBlock1.link(this);
    18031813
    18041814    // Check argCount matches callee arity.
    1805     Jump arityCheckOkay1 = branch32(Equal, Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
    1806     pop(X86::ebx);
    1807     emitPutJITStubArg(X86::ebx, 2);
    1808     emitPutJITStubArg(X86::eax, 4);
     1815    Jump arityCheckOkay1 = branch32(Equal, Address(regT0, FIELD_OFFSET(CodeBlock, m_numParameters)), regT1);
     1816    pop(regT3);
     1817    emitPutJITStubArg(regT3, 2);
     1818    emitPutJITStubArg(regT0, 4);
    18091819    restoreArgumentReference();
    18101820    Call callArityCheck1 = call();
    1811     move(X86::edx, callFrameRegister);
    1812     emitGetJITStubArg(1, X86::ecx);
    1813     emitGetJITStubArg(3, X86::edx);
    1814     push(X86::ebx);
     1821    move(regT1, callFrameRegister);
     1822    emitGetJITStubArg(1, regT2);
     1823    emitGetJITStubArg(3, regT1);
     1824    push(regT3);
    18151825    arityCheckOkay1.link(this);
    18161826   
    18171827    compileOpCallInitializeCallFrame();
    18181828
    1819     pop(X86::ebx);
    1820     emitPutJITStubArg(X86::ebx, 2);
     1829    pop(regT3);
     1830    emitPutJITStubArg(regT3, 2);
    18211831    restoreArgumentReference();
    18221832    Call callDontLazyLinkCall = call();
    1823     push(X86::ebx);
    1824 
    1825     jump(X86::eax);
     1833    push(regT3);
     1834
     1835    jump(regT0);
    18261836
    18271837    Label virtualCallLinkBegin = align();
    18281838
    18291839    // Load the callee CodeBlock* into eax
    1830     loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
    1831     loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
    1832     Jump hasCodeBlock2 = branchTestPtr(NonZero, X86::eax);
    1833     pop(X86::ebx);
     1840    loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT0);
     1841    loadPtr(Address(regT0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);
     1842    Jump hasCodeBlock2 = branchTestPtr(NonZero, regT0);
     1843    pop(regT3);
    18341844    restoreArgumentReference();
    18351845    Call callJSFunction2 = call();
    1836     emitGetJITStubArg(1, X86::ecx);
    1837     emitGetJITStubArg(3, X86::edx);
    1838     push(X86::ebx);
     1846    emitGetJITStubArg(1, regT2);
     1847    emitGetJITStubArg(3, regT1);
     1848    push(regT3);
    18391849    hasCodeBlock2.link(this);
    18401850
    18411851    // Check argCount matches callee arity.
    1842     Jump arityCheckOkay2 = branch32(Equal, Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
    1843     pop(X86::ebx);
    1844     emitPutJITStubArg(X86::ebx, 2);
    1845     emitPutJITStubArg(X86::eax, 4);
     1852    Jump arityCheckOkay2 = branch32(Equal, Address(regT0, FIELD_OFFSET(CodeBlock, m_numParameters)), regT1);
     1853    pop(regT3);
     1854    emitPutJITStubArg(regT3, 2);
     1855    emitPutJITStubArg(regT0, 4);
    18461856    restoreArgumentReference();
    18471857    Call callArityCheck2 = call();
    1848     move(X86::edx, callFrameRegister);
    1849     emitGetJITStubArg(1, X86::ecx);
    1850     emitGetJITStubArg(3, X86::edx);
    1851     push(X86::ebx);
     1858    move(regT1, callFrameRegister);
     1859    emitGetJITStubArg(1, regT2);
     1860    emitGetJITStubArg(3, regT1);
     1861    push(regT3);
    18521862    arityCheckOkay2.link(this);
    18531863
    18541864    compileOpCallInitializeCallFrame();
    18551865
    1856     pop(X86::ebx);
    1857     emitPutJITStubArg(X86::ebx, 2);
     1866    pop(regT3);
     1867    emitPutJITStubArg(regT3, 2);
    18581868    restoreArgumentReference();
    18591869    Call callLazyLinkCall = call();
    1860     push(X86::ebx);
    1861 
    1862     jump(X86::eax);
     1870    push(regT3);
     1871
     1872    jump(regT0);
    18631873
    18641874    Label virtualCallBegin = align();
    18651875
    18661876    // Load the callee CodeBlock* into eax
    1867     loadPtr(Address(X86::ecx, FIELD_OFFSET(JSFunction, m_body)), X86::eax);
    1868     loadPtr(Address(X86::eax, FIELD_OFFSET(FunctionBodyNode, m_code)), X86::eax);
    1869     Jump hasCodeBlock3 = branchTestPtr(NonZero, X86::eax);
    1870     pop(X86::ebx);
     1877    loadPtr(Address(regT2, FIELD_OFFSET(JSFunction, m_body)), regT0);
     1878    loadPtr(Address(regT0, FIELD_OFFSET(FunctionBodyNode, m_code)), regT0);
     1879    Jump hasCodeBlock3 = branchTestPtr(NonZero, regT0);
     1880    pop(regT3);
    18711881    restoreArgumentReference();
    18721882    Call callJSFunction3 = call();
    1873     emitGetJITStubArg(1, X86::ecx);
    1874     emitGetJITStubArg(3, X86::edx);
    1875     push(X86::ebx);
     1883    emitGetJITStubArg(1, regT2);
     1884    emitGetJITStubArg(3, regT1);
     1885    push(regT3);
    18761886    hasCodeBlock3.link(this);
    18771887
    18781888    // Check argCount matches callee arity.
    1879     Jump arityCheckOkay3 = branch32(Equal, Address(X86::eax, FIELD_OFFSET(CodeBlock, m_numParameters)), X86::edx);
    1880     pop(X86::ebx);
    1881     emitPutJITStubArg(X86::ebx, 2);
    1882     emitPutJITStubArg(X86::eax, 4);
     1889    Jump arityCheckOkay3 = branch32(Equal, Address(regT0, FIELD_OFFSET(CodeBlock, m_numParameters)), regT1);
     1890    pop(regT3);
     1891    emitPutJITStubArg(regT3, 2);
     1892    emitPutJITStubArg(regT0, 4);
    18831893    restoreArgumentReference();
    18841894    Call callArityCheck3 = call();
    1885     move(X86::edx, callFrameRegister);
    1886     emitGetJITStubArg(1, X86::ecx);
    1887     emitGetJITStubArg(3, X86::edx);
    1888     push(X86::ebx);
     1895    move(regT1, callFrameRegister);
     1896    emitGetJITStubArg(1, regT2);
     1897    emitGetJITStubArg(3, regT1);
     1898    push(regT3);
    18891899    arityCheckOkay3.link(this);
    18901900
     
    18921902
    18931903    // load ctiCode from the new codeBlock.
    1894     loadPtr(Address(X86::eax, FIELD_OFFSET(CodeBlock, m_jitCode)), X86::eax);
    1895 
    1896     jump(X86::eax);
     1904    loadPtr(Address(regT0, FIELD_OFFSET(CodeBlock, m_jitCode)), regT0);
     1905
     1906    jump(regT0);
    18971907
    18981908    // All trampolines constructed! copy the code, link up calls, and set the pointers on the Machine object.
Note: See TracChangeset for help on using the changeset viewer.