Changeset 40963 in webkit for trunk/JavaScriptCore/jit/JIT.cpp
- Timestamp:
- Feb 12, 2009, 8:22:02 PM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/jit/JIT.cpp
r40846 r40963 229 229 unsigned src2 = currentInstruction[3].u.operand; 230 230 231 emitGetVirtualRegisters(src1, X86::eax, src2, X86::edx);231 emitGetVirtualRegisters(src1, regT0, src2, regT1); 232 232 233 233 #if USE(ALTERNATE_JSIMMEDIATE) 234 234 // 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)); 239 239 240 240 if (type == OpStrictEq) 241 set32(Equal, X86::edx, X86::eax, X86::eax);241 set32(Equal, regT1, regT0, regT0); 242 242 else 243 set32(NotEqual, X86::edx, X86::eax, X86::eax);244 emitTagAsBoolImmediate( X86::eax);243 set32(NotEqual, regT1, regT0, regT0); 244 emitTagAsBoolImmediate(regT0); 245 245 #else 246 246 bool negated = (type == OpNStrictEq); 247 247 248 248 // 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); 252 252 253 253 // 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); 255 255 Jump bothWereImmediatesAndEqual = jump(); 256 256 … … 259 259 // otherwise these values are not equal. 260 260 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())))); 263 263 Jump firstWasNotImmediate = jump(); 264 264 … … 266 266 // If eax is 0 jump to a slow case, otherwise these values are not equal. 267 267 secondNotImmediate.link(this); 268 addSlowCase(branchPtr(Equal, X86::eax, ImmPtr(JSValuePtr::encode(js0()))));268 addSlowCase(branchPtr(Equal, regT0, ImmPtr(JSValuePtr::encode(js0())))); 269 269 270 270 // We get here if the two values are different immediates, or one is 0 and the other is a JSCell. … … 272 272 bothWereImmediatesButNotEqual.link(this); 273 273 firstWasNotImmediate.link(this); 274 move(ImmPtr(JSValuePtr::encode(jsBoolean(negated))), X86::eax);274 move(ImmPtr(JSValuePtr::encode(jsBoolean(negated))), regT0); 275 275 276 276 bothWereImmediatesAndEqual.link(this); … … 284 284 Jump skipTimeout = branchSub32(NonZero, Imm32(1), timeoutCheckRegister); 285 285 emitCTICall(Interpreter::cti_timeout_check); 286 move( X86::eax, timeoutCheckRegister);286 move(regT0, timeoutCheckRegister); 287 287 skipTimeout.link(this); 288 288 … … 297 297 #define CTI_COMPILE_BINARY_OP(name) \ 298 298 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); \ 301 301 emitCTICall(Interpreter::cti_##name); \ 302 302 emitPutVirtualRegister(currentInstruction[1].u.operand); \ … … 306 306 #define CTI_COMPILE_UNARY_OP(name) \ 307 307 case name: { \ 308 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx); \308 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); \ 309 309 emitCTICall(Interpreter::cti_##name); \ 310 310 emitPutVirtualRegister(currentInstruction[1].u.operand); \ … … 334 334 switch (opcodeID) { 335 335 case op_mov: { 336 emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);336 emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); 337 337 emitPutVirtualRegister(currentInstruction[1].u.operand); 338 338 NEXT_OPCODE(op_mov); … … 345 345 if (m_codeBlock->needsFullScopeChain()) 346 346 emitCTICall(Interpreter::cti_op_end); 347 emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax); 347 ASSERT(returnValueRegister != callFrameRegister); 348 emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister); 348 349 push(Address(callFrameRegister, RegisterFile::ReturnPC * static_cast<int>(sizeof(Register)))); 349 350 ret(); … … 373 374 unsigned target = currentInstruction[3].u.operand; 374 375 if (isOperandConstantImmediateInt(op2)) { 375 emitGetVirtualRegister(op1, X86::eax);376 emitJumpSlowCaseIfNotImmediateInteger( X86::eax);376 emitGetVirtualRegister(op1, regT0); 377 emitJumpSlowCaseIfNotImmediateInteger(regT0); 377 378 #if USE(ALTERNATE_JSIMMEDIATE) 378 379 int32_t op2imm = getConstantOperandImmediateInt(op2); … … 380 381 int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); 381 382 #endif 382 addJump(branch32(LessThan, X86::eax, Imm32(op2imm)), target + 3);383 addJump(branch32(LessThan, regT0, Imm32(op2imm)), target + 3); 383 384 } 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); 388 389 } 389 390 NEXT_OPCODE(op_loop_if_less); … … 396 397 unsigned target = currentInstruction[3].u.operand; 397 398 if (isOperandConstantImmediateInt(op2)) { 398 emitGetVirtualRegister(op1, X86::eax);399 emitJumpSlowCaseIfNotImmediateInteger( X86::eax);399 emitGetVirtualRegister(op1, regT0); 400 emitJumpSlowCaseIfNotImmediateInteger(regT0); 400 401 #if USE(ALTERNATE_JSIMMEDIATE) 401 402 int32_t op2imm = getConstantOperandImmediateInt(op2); … … 403 404 int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); 404 405 #endif 405 addJump(branch32(LessThanOrEqual, X86::eax, Imm32(op2imm)), target + 3);406 addJump(branch32(LessThanOrEqual, regT0, Imm32(op2imm)), target + 3); 406 407 } 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); 411 412 } 412 413 NEXT_OPCODE(op_loop_if_less); … … 426 427 } 427 428 case op_instanceof: { 428 emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax); // value429 emitGetVirtualRegister(currentInstruction[3].u.operand, X86::ecx); // baseVal430 emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // proto429 emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); // value 430 emitGetVirtualRegister(currentInstruction[3].u.operand, regT2); // baseVal 431 emitGetVirtualRegister(currentInstruction[4].u.operand, regT1); // proto 431 432 432 433 // 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); 437 438 438 439 // check that all are object type - this is a bit of a bithack to avoid excess branching; 439 440 // we check that the sum of the three type codes from Structures is exactly 3 * ObjectType, 440 441 // 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)); 448 449 449 450 // 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 value455 emitGetVirtualRegister(currentInstruction[4].u.operand, X86::edx); // reload proto451 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 456 457 457 458 // optimistically load true result 458 move(ImmPtr(JSValuePtr::encode(jsBoolean(true))), X86::eax);459 move(ImmPtr(JSValuePtr::encode(jsBoolean(true))), regT0); 459 460 460 461 Label loop(this); 461 462 462 463 // 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); 471 472 472 473 exit.link(this); … … 477 478 } 478 479 case op_del_by_id: { 479 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);480 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); 480 481 Identifier* ident = &(m_codeBlock->identifier(currentInstruction[3].u.operand)); 481 482 emitPutJITStubArgConstant(ident, 2); … … 509 510 case op_get_global_var: { 510 511 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); 513 514 emitPutVirtualRegister(currentInstruction[1].u.operand); 514 515 NEXT_OPCODE(op_get_global_var); 515 516 } 516 517 case op_put_global_var: { 517 emitGetVirtualRegister(currentInstruction[3].u.operand, X86::edx);518 emitGetVirtualRegister(currentInstruction[3].u.operand, regT1); 518 519 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); 521 522 NEXT_OPCODE(op_put_global_var); 522 523 } … … 524 525 int skip = currentInstruction[3].u.operand + m_codeBlock->needsFullScopeChain(); 525 526 526 emitGetFromCallFrameHeader(RegisterFile::ScopeChain, X86::eax);527 emitGetFromCallFrameHeader(RegisterFile::ScopeChain, regT0); 527 528 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); 532 533 emitPutVirtualRegister(currentInstruction[1].u.operand); 533 534 NEXT_OPCODE(op_get_scoped_var); … … 536 537 int skip = currentInstruction[2].u.operand + m_codeBlock->needsFullScopeChain(); 537 538 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); 540 541 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); 545 546 NEXT_OPCODE(op_put_scoped_var); 546 547 } 547 548 case op_tear_off_activation: { 548 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);549 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2); 549 550 emitCTICall(Interpreter::cti_op_tear_off_activation); 550 551 NEXT_OPCODE(op_tear_off_activation); … … 559 560 emitCTICall(Interpreter::cti_op_ret_scopeChain); 560 561 562 ASSERT(callFrameRegister != regT1); 563 ASSERT(regT1 != returnValueRegister); 564 ASSERT(returnValueRegister != callFrameRegister); 565 561 566 // Return the result in %eax. 562 emitGetVirtualRegister(currentInstruction[1].u.operand, X86::eax);567 emitGetVirtualRegister(currentInstruction[1].u.operand, returnValueRegister); 563 568 564 569 // Grab the return address. 565 emitGetFromCallFrameHeader(RegisterFile::ReturnPC, X86::edx);570 emitGetFromCallFrameHeader(RegisterFile::ReturnPC, regT1); 566 571 567 572 // Restore our caller's "r". … … 569 574 570 575 // Return. 571 push( X86::edx);576 push(regT1); 572 577 ret(); 573 578 … … 589 594 } 590 595 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))); 596 601 597 602 NEXT_OPCODE(op_construct_verify); 598 603 } 599 604 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); 602 607 #if USE(ALTERNATE_JSIMMEDIATE) 603 608 // This is technically incorrect - we're zero-extending an int32. On the hot path this doesn't matter. … … 607 612 // to 64-bits is necessary since it's used in the address calculation. We zero extend rather than sign 608 613 // 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); 610 615 #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))); 615 620 616 621 // 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)))); 619 624 620 625 // 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); 622 627 emitPutVirtualRegister(currentInstruction[1].u.operand); 623 628 NEXT_OPCODE(op_get_by_val); … … 627 632 emitPutJITStubArgConstant(ident, 1); 628 633 emitCTICall(Interpreter::cti_op_resolve_func); 629 emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);634 emitPutVirtualRegister(currentInstruction[2].u.operand, regT1); 630 635 emitPutVirtualRegister(currentInstruction[1].u.operand); 631 636 NEXT_OPCODE(op_resolve_func); … … 636 641 } 637 642 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); 640 645 #if USE(ALTERNATE_JSIMMEDIATE) 641 646 // See comment in op_get_by_val. 642 zeroExtend32ToPtr( X86::edx, X86::edx);647 zeroExtend32ToPtr(regT1, regT1); 643 648 #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))); 648 653 649 654 // 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))); 652 657 // 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)))); 654 659 655 660 // 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. 656 661 // 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])))); 658 663 659 664 // All good - put the value into the array. 660 665 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]))); 663 668 NEXT_OPCODE(op_put_by_val); 664 669 } … … 668 673 669 674 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))))); 677 682 678 683 isZero.link(this); … … 687 692 } 688 693 case op_negate: { 689 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);694 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); 690 695 emitCTICall(Interpreter::cti_op_negate); 691 696 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 710 715 711 716 // 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 match717 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 715 720 716 721 // 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); 720 725 emitPutVirtualRegister(currentInstruction[1].u.operand); 721 726 Jump end = jump(); … … 741 746 unsigned target = currentInstruction[3].u.operand; 742 747 if (isOperandConstantImmediateInt(op2)) { 743 emitGetVirtualRegister(op1, X86::eax);744 emitJumpSlowCaseIfNotImmediateInteger( X86::eax);748 emitGetVirtualRegister(op1, regT0); 749 emitJumpSlowCaseIfNotImmediateInteger(regT0); 745 750 #if USE(ALTERNATE_JSIMMEDIATE) 746 751 int32_t op2imm = getConstantOperandImmediateInt(op2); … … 748 753 int32_t op2imm = static_cast<int32_t>(JSImmediate::rawValue(getConstantOperand(op2))); 749 754 #endif 750 addJump(branch32(GreaterThanOrEqual, X86::eax, Imm32(op2imm)), target + 3);755 addJump(branch32(GreaterThanOrEqual, regT0, Imm32(op2imm)), target + 3); 751 756 } 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); 756 761 } 757 762 NEXT_OPCODE(op_jnless); 758 763 } 759 764 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); 764 769 emitPutVirtualRegister(currentInstruction[1].u.operand); 765 770 NEXT_OPCODE(op_not); … … 767 772 case op_jfalse: { 768 773 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))))); 776 781 777 782 isNonZero.link(this); … … 782 787 unsigned target = currentInstruction[2].u.operand; 783 788 784 emitGetVirtualRegister(src, X86::eax);785 Jump isImmediate = emitJumpIfNotJSCell( X86::eax);789 emitGetVirtualRegister(src, regT0); 790 Jump isImmediate = emitJumpIfNotJSCell(regT0); 786 791 787 792 // 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); 790 795 Jump wasNotImmediate = jump(); 791 796 792 797 // Now handle the immediate cases - undefined & null 793 798 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); 796 801 797 802 wasNotImmediate.link(this); … … 802 807 unsigned target = currentInstruction[2].u.operand; 803 808 804 emitGetVirtualRegister(src, X86::eax);805 Jump isImmediate = emitJumpIfNotJSCell( X86::eax);809 emitGetVirtualRegister(src, regT0); 810 Jump isImmediate = emitJumpIfNotJSCell(regT0); 806 811 807 812 // 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); 810 815 Jump wasNotImmediate = jump(); 811 816 812 817 // Now handle the immediate cases - undefined & null 813 818 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); 816 821 817 822 wasNotImmediate.link(this); … … 824 829 case op_unexpected_load: { 825 830 JSValuePtr v = m_codeBlock->unexpectedConstant(currentInstruction[2].u.operand); 826 move(ImmPtr(JSValuePtr::encode(v)), X86::eax);831 move(ImmPtr(JSValuePtr::encode(v)), regT0); 827 832 emitPutVirtualRegister(currentInstruction[1].u.operand); 828 833 NEXT_OPCODE(op_unexpected_load); … … 841 846 } 842 847 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); 847 852 emitPutVirtualRegister(currentInstruction[1].u.operand); 848 853 NEXT_OPCODE(op_eq); … … 861 866 } 862 867 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); 865 870 #if USE(ALTERNATE_JSIMMEDIATE) 866 not32( X86::eax);867 emitFastArithIntToImmNoCheck( X86::eax, X86::eax);871 not32(regT0); 872 emitFastArithIntToImmNoCheck(regT0, regT0); 868 873 #else 869 xorPtr(Imm32(~JSImmediate::TagTypeNumber), X86::eax);874 xorPtr(Imm32(~JSImmediate::TagTypeNumber), regT0); 870 875 #endif 871 876 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 876 881 emitPutJITStubArgConstant(ident, 1); 877 882 emitCTICall(Interpreter::cti_op_resolve_with_base); 878 emitPutVirtualRegister(currentInstruction[2].u.operand, X86::edx);883 emitPutVirtualRegister(currentInstruction[2].u.operand, regT1); 879 884 emitPutVirtualRegister(currentInstruction[1].u.operand); 880 885 NEXT_OPCODE(op_resolve_with_base); … … 893 898 case op_jtrue: { 894 899 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))))); 902 907 903 908 isZero.link(this); … … 906 911 CTI_COMPILE_BINARY_OP(op_less) 907 912 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); 912 917 913 918 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 921 926 CTI_COMPILE_BINARY_OP(op_urshift) 922 927 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); 927 932 emitPutVirtualRegister(currentInstruction[1].u.operand); 928 933 NEXT_OPCODE(op_bitxor); … … 936 941 } 937 942 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); 941 946 emitPutVirtualRegister(currentInstruction[1].u.operand); 942 947 NEXT_OPCODE(op_bitor); 943 948 } 944 949 case op_throw: { 945 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);950 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2); 946 951 emitCTICall(Interpreter::cti_op_throw); 952 ASSERT(regT0 == returnValueRegister); 947 953 #if PLATFORM(X86_64) 948 954 addPtr(Imm32(0x48), X86::esp); … … 965 971 } 966 972 case op_get_pnames: { 967 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);973 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); 968 974 emitCTICall(Interpreter::cti_op_get_pnames); 969 975 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 971 977 } 972 978 case op_next_pname: { 973 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, X86::ecx);979 emitPutJITStubArgFromVirtualRegister(currentInstruction[2].u.operand, 1, regT2); 974 980 unsigned target = currentInstruction[3].u.operand; 975 981 emitCTICall(Interpreter::cti_op_next_pname); 976 Jump endOfIter = branchTestPtr(Zero, X86::eax);982 Jump endOfIter = branchTestPtr(Zero, regT0); 977 983 emitPutVirtualRegister(currentInstruction[1].u.operand); 978 984 addJump(jump(), target + 3); … … 981 987 } 982 988 case op_push_scope: { 983 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);989 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2); 984 990 emitCTICall(Interpreter::cti_op_push_scope); 985 991 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1007 1013 case op_to_jsnumber: { 1008 1014 int srcVReg = currentInstruction[2].u.operand; 1009 emitGetVirtualRegister(srcVReg, X86::eax);1015 emitGetVirtualRegister(srcVReg, regT0); 1010 1016 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))); 1016 1022 1017 1023 wasImmediate.link(this); … … 1024 1030 Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand)); 1025 1031 emitPutJITStubArgConstant(ident, 1); 1026 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, X86::ecx);1032 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 2, regT2); 1027 1033 emitCTICall(Interpreter::cti_op_push_new_scope); 1028 1034 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1043 1049 } 1044 1050 case op_put_by_index: { 1045 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);1051 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2); 1046 1052 emitPutJITStubArgConstant(currentInstruction[2].u.operand, 2); 1047 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);1053 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2); 1048 1054 emitCTICall(Interpreter::cti_op_put_by_index); 1049 1055 NEXT_OPCODE(op_put_by_index); … … 1059 1065 jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size()); 1060 1066 1061 emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);1067 emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2); 1062 1068 emitPutJITStubArgConstant(tableIndex, 2); 1063 1069 emitCTICall(Interpreter::cti_op_switch_imm); 1064 jump( X86::eax);1070 jump(regT0); 1065 1071 NEXT_OPCODE(op_switch_imm); 1066 1072 } … … 1075 1081 jumpTable->ctiOffsets.grow(jumpTable->branchOffsets.size()); 1076 1082 1077 emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);1083 emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2); 1078 1084 emitPutJITStubArgConstant(tableIndex, 2); 1079 1085 emitCTICall(Interpreter::cti_op_switch_char); 1080 jump( X86::eax);1086 jump(regT0); 1081 1087 NEXT_OPCODE(op_switch_char); 1082 1088 } … … 1090 1096 m_switches.append(SwitchRecord(jumpTable, m_bytecodeIndex, defaultOffset)); 1091 1097 1092 emitPutJITStubArgFromVirtualRegister(scrutinee, 1, X86::ecx);1098 emitPutJITStubArgFromVirtualRegister(scrutinee, 1, regT2); 1093 1099 emitPutJITStubArgConstant(tableIndex, 2); 1094 1100 emitCTICall(Interpreter::cti_op_switch_string); 1095 jump( X86::eax);1101 jump(regT0); 1096 1102 NEXT_OPCODE(op_switch_string); 1097 1103 } 1098 1104 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); 1101 1107 emitCTICall(Interpreter::cti_op_del_by_val); 1102 1108 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1104 1110 } 1105 1111 case op_put_getter: { 1106 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);1112 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2); 1107 1113 Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand)); 1108 1114 emitPutJITStubArgConstant(ident, 2); 1109 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);1115 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2); 1110 1116 emitCTICall(Interpreter::cti_op_put_getter); 1111 1117 NEXT_OPCODE(op_put_getter); 1112 1118 } 1113 1119 case op_put_setter: { 1114 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, X86::ecx);1120 emitPutJITStubArgFromVirtualRegister(currentInstruction[1].u.operand, 1, regT2); 1115 1121 Identifier* ident = &(m_codeBlock->identifier(currentInstruction[2].u.operand)); 1116 1122 emitPutJITStubArgConstant(ident, 2); 1117 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, X86::ecx);1123 emitPutJITStubArgFromVirtualRegister(currentInstruction[3].u.operand, 3, regT2); 1118 1124 emitCTICall(Interpreter::cti_op_put_setter); 1119 1125 NEXT_OPCODE(op_put_setter); … … 1139 1145 unsigned src1 = currentInstruction[2].u.operand; 1140 1146 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); 1146 1152 1147 1153 Jump wasNotImmediate = jump(); … … 1149 1155 isImmediate.link(this); 1150 1156 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); 1153 1159 1154 1160 wasNotImmediate.link(this); 1155 1161 1156 emitTagAsBoolImmediate( X86::eax);1162 emitTagAsBoolImmediate(regT0); 1157 1163 emitPutVirtualRegister(dst); 1158 1164 … … 1163 1169 unsigned src1 = currentInstruction[2].u.operand; 1164 1170 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); 1170 1176 1171 1177 Jump wasNotImmediate = jump(); … … 1173 1179 isImmediate.link(this); 1174 1180 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); 1177 1183 1178 1184 wasNotImmediate.link(this); 1179 1185 1180 emitTagAsBoolImmediate( X86::eax);1186 emitTagAsBoolImmediate(regT0); 1181 1187 emitPutVirtualRegister(dst); 1182 1188 … … 1214 1220 } 1215 1221 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))); 1221 1227 1222 1228 NEXT_OPCODE(op_convert_this); 1223 1229 } 1224 1230 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); 1228 1234 emitCTICall(Interpreter::cti_op_profile_will_call); 1229 1235 noProfiler.link(this); … … 1232 1238 } 1233 1239 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); 1237 1243 emitCTICall(Interpreter::cti_op_profile_did_call); 1238 1244 noProfiler.link(this); … … 1293 1299 linkSlowCase(iter); 1294 1300 linkSlowCase(iter); 1295 emitPutJITStubArg( X86::eax, 1);1301 emitPutJITStubArg(regT0, 1); 1296 1302 emitCTICall(Interpreter::cti_op_convert_this); 1297 1303 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1305 1311 linkSlowCase(iter); 1306 1312 linkSlowCase(iter); 1307 emitGetVirtualRegister(currentInstruction[2].u.operand, X86::eax);1313 emitGetVirtualRegister(currentInstruction[2].u.operand, regT0); 1308 1314 emitPutVirtualRegister(currentInstruction[1].u.operand); 1309 1315 … … 1317 1323 linkSlowCase(iter); 1318 1324 linkSlowCase(iter); 1319 emitFastArithIntToImmNoCheck( X86::edx, X86::edx);1325 emitFastArithIntToImmNoCheck(regT1, regT1); 1320 1326 notImm.link(this); 1321 emitPutJITStubArg( X86::eax, 1);1322 emitPutJITStubArg( X86::edx, 2);1327 emitPutJITStubArg(regT0, 1); 1328 emitPutJITStubArg(regT1, 2); 1323 1329 emitCTICall(Interpreter::cti_op_get_by_val); 1324 1330 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1328 1334 // First, check if this is an access to the vector 1329 1335 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); 1331 1337 1332 1338 // 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); 1334 1340 // 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); 1338 1344 1339 1345 NEXT_OPCODE(op_get_by_val); … … 1356 1362 if (isOperandConstantImmediateInt(op2)) { 1357 1363 linkSlowCase(iter); 1358 emitPutJITStubArg( X86::eax, 1);1359 emitPutJITStubArgFromVirtualRegister(op2, 2, X86::ecx);1364 emitPutJITStubArg(regT0, 1); 1365 emitPutJITStubArgFromVirtualRegister(op2, 2, regT2); 1360 1366 emitCTICall(Interpreter::cti_op_loop_if_less); 1361 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 3);1367 emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); 1362 1368 } else { 1363 1369 linkSlowCase(iter); 1364 1370 linkSlowCase(iter); 1365 emitPutJITStubArg( X86::eax, 1);1366 emitPutJITStubArg( X86::edx, 2);1371 emitPutJITStubArg(regT0, 1); 1372 emitPutJITStubArg(regT1, 2); 1367 1373 emitCTICall(Interpreter::cti_op_loop_if_less); 1368 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 3);1374 emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); 1369 1375 } 1370 1376 NEXT_OPCODE(op_loop_if_less); … … 1383 1389 if (isOperandConstantImmediateInt(op2)) { 1384 1390 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); 1387 1393 emitCTICall(Interpreter::cti_op_loop_if_lesseq); 1388 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 3);1394 emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); 1389 1395 } else { 1390 1396 linkSlowCase(iter); 1391 1397 linkSlowCase(iter); 1392 emitPutJITStubArg( X86::eax, 1);1393 emitPutJITStubArg( X86::edx, 2);1398 emitPutJITStubArg(regT0, 1); 1399 emitPutJITStubArg(regT1, 2); 1394 1400 emitCTICall(Interpreter::cti_op_loop_if_lesseq); 1395 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 3);1401 emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 3); 1396 1402 } 1397 1403 NEXT_OPCODE(op_loop_if_lesseq); … … 1406 1412 linkSlowCase(iter); 1407 1413 linkSlowCase(iter); 1408 emitFastArithIntToImmNoCheck( X86::edx, X86::edx);1414 emitFastArithIntToImmNoCheck(regT1, regT1); 1409 1415 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); 1414 1420 emitCTICall(Interpreter::cti_op_put_by_val); 1415 1421 emitJumpSlowToHot(jump(), OPCODE_LENGTH(op_put_by_val)); … … 1418 1424 linkSlowCase(iter); 1419 1425 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); 1424 1430 emitCTICall(Interpreter::cti_op_put_by_val_array); 1425 1431 … … 1428 1434 case op_loop_if_true: { 1429 1435 linkSlowCase(iter); 1430 emitPutJITStubArg( X86::eax, 1);1436 emitPutJITStubArg(regT0, 1); 1431 1437 emitCTICall(Interpreter::cti_op_jtrue); 1432 1438 unsigned target = currentInstruction[2].u.operand; 1433 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 2);1439 emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2); 1434 1440 NEXT_OPCODE(op_loop_if_true); 1435 1441 } … … 1443 1449 if (isOperandConstantImmediateInt(op2)) { 1444 1450 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); 1447 1453 emitCTICall(Interpreter::cti_op_jless); 1448 emitJumpSlowToHot(branchTest32(Zero, X86::eax), target + 3);1454 emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); 1449 1455 } else { 1450 1456 linkSlowCase(iter); 1451 1457 linkSlowCase(iter); 1452 emitPutJITStubArg( X86::eax, 1);1453 emitPutJITStubArg( X86::edx, 2);1458 emitPutJITStubArg(regT0, 1); 1459 emitPutJITStubArg(regT1, 2); 1454 1460 emitCTICall(Interpreter::cti_op_jless); 1455 emitJumpSlowToHot(branchTest32(Zero, X86::eax), target + 3);1461 emitJumpSlowToHot(branchTest32(Zero, regT0), target + 3); 1456 1462 } 1457 1463 NEXT_OPCODE(op_jnless); … … 1459 1465 case op_not: { 1460 1466 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); 1463 1469 emitCTICall(Interpreter::cti_op_not); 1464 1470 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1467 1473 case op_jfalse: { 1468 1474 linkSlowCase(iter); 1469 emitPutJITStubArg( X86::eax, 1);1475 emitPutJITStubArg(regT0, 1); 1470 1476 emitCTICall(Interpreter::cti_op_jtrue); 1471 1477 unsigned target = currentInstruction[2].u.operand; 1472 emitJumpSlowToHot(branchTest32(Zero, X86::eax), target + 2); // inverted!1478 emitJumpSlowToHot(branchTest32(Zero, regT0), target + 2); // inverted! 1473 1479 NEXT_OPCODE(op_jfalse); 1474 1480 } … … 1479 1485 case op_bitnot: { 1480 1486 linkSlowCase(iter); 1481 emitPutJITStubArg( X86::eax, 1);1487 emitPutJITStubArg(regT0, 1); 1482 1488 emitCTICall(Interpreter::cti_op_bitnot); 1483 1489 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1490 1496 case op_jtrue: { 1491 1497 linkSlowCase(iter); 1492 emitPutJITStubArg( X86::eax, 1);1498 emitPutJITStubArg(regT0, 1); 1493 1499 emitCTICall(Interpreter::cti_op_jtrue); 1494 1500 unsigned target = currentInstruction[2].u.operand; 1495 emitJumpSlowToHot(branchTest32(NonZero, X86::eax), target + 2);1501 emitJumpSlowToHot(branchTest32(NonZero, regT0), target + 2); 1496 1502 NEXT_OPCODE(op_jtrue); 1497 1503 } … … 1502 1508 case op_bitxor: { 1503 1509 linkSlowCase(iter); 1504 emitPutJITStubArg( X86::eax, 1);1505 emitPutJITStubArg( X86::edx, 2);1510 emitPutJITStubArg(regT0, 1); 1511 emitPutJITStubArg(regT1, 2); 1506 1512 emitCTICall(Interpreter::cti_op_bitxor); 1507 1513 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1510 1516 case op_bitor: { 1511 1517 linkSlowCase(iter); 1512 emitPutJITStubArg( X86::eax, 1);1513 emitPutJITStubArg( X86::edx, 2);1518 emitPutJITStubArg(regT0, 1); 1519 emitPutJITStubArg(regT1, 2); 1514 1520 emitCTICall(Interpreter::cti_op_bitor); 1515 1521 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1518 1524 case op_eq: { 1519 1525 linkSlowCase(iter); 1520 emitPutJITStubArg( X86::eax, 1);1521 emitPutJITStubArg( X86::edx, 2);1526 emitPutJITStubArg(regT0, 1); 1527 emitPutJITStubArg(regT1, 2); 1522 1528 emitCTICall(Interpreter::cti_op_eq); 1523 1529 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1526 1532 case op_neq: { 1527 1533 linkSlowCase(iter); 1528 emitPutJITStubArg( X86::eax, 1);1529 emitPutJITStubArg( X86::edx, 2);1534 emitPutJITStubArg(regT0, 1); 1535 emitPutJITStubArg(regT1, 2); 1530 1536 emitCTICall(Interpreter::cti_op_neq); 1531 1537 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1538 1544 linkSlowCase(iter); 1539 1545 #endif 1540 emitPutJITStubArg( X86::eax, 1);1541 emitPutJITStubArg( X86::edx, 2);1546 emitPutJITStubArg(regT0, 1); 1547 emitPutJITStubArg(regT1, 2); 1542 1548 emitCTICall(Interpreter::cti_op_stricteq); 1543 1549 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1550 1556 linkSlowCase(iter); 1551 1557 #endif 1552 emitPutJITStubArg( X86::eax, 1);1553 emitPutJITStubArg( X86::edx, 2);1558 emitPutJITStubArg(regT0, 1); 1559 emitPutJITStubArg(regT1, 2); 1554 1560 emitCTICall(Interpreter::cti_op_nstricteq); 1555 1561 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1560 1566 linkSlowCase(iter); 1561 1567 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); 1565 1571 emitCTICall(Interpreter::cti_op_instanceof); 1566 1572 emitPutVirtualRegister(currentInstruction[1].u.operand); … … 1592 1598 linkSlowCase(iter); 1593 1599 1594 emitPutJITStubArg( X86::eax, 1);1600 emitPutJITStubArg(regT0, 1); 1595 1601 emitCTICall(Interpreter::cti_op_to_jsnumber); 1596 1602 … … 1628 1634 1629 1635 // 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); 1632 1638 1633 1639 Jump slowRegisterFileCheck; … … 1637 1643 emitPutImmediateToCallFrameHeader(m_codeBlock, RegisterFile::CodeBlock); 1638 1644 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); 1641 1647 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))); 1643 1649 afterRegisterFileCheck = label(); 1644 1650 } … … 1753 1759 1754 1760 // 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)); 1757 1763 1758 1764 // 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::eaxcontains 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); 1766 1772 1767 1773 ret(); … … 1771 1777 1772 1778 // 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)); 1775 1781 1776 1782 // 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::eaxcontains 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); 1784 1790 1785 1791 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." 1786 1796 #endif 1787 1797 … … 1791 1801 1792 1802 // 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); 1797 1807 restoreArgumentReference(); 1798 1808 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); 1802 1812 hasCodeBlock1.link(this); 1803 1813 1804 1814 // 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); 1809 1819 restoreArgumentReference(); 1810 1820 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); 1815 1825 arityCheckOkay1.link(this); 1816 1826 1817 1827 compileOpCallInitializeCallFrame(); 1818 1828 1819 pop( X86::ebx);1820 emitPutJITStubArg( X86::ebx, 2);1829 pop(regT3); 1830 emitPutJITStubArg(regT3, 2); 1821 1831 restoreArgumentReference(); 1822 1832 Call callDontLazyLinkCall = call(); 1823 push( X86::ebx);1824 1825 jump( X86::eax);1833 push(regT3); 1834 1835 jump(regT0); 1826 1836 1827 1837 Label virtualCallLinkBegin = align(); 1828 1838 1829 1839 // 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); 1834 1844 restoreArgumentReference(); 1835 1845 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); 1839 1849 hasCodeBlock2.link(this); 1840 1850 1841 1851 // 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); 1846 1856 restoreArgumentReference(); 1847 1857 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); 1852 1862 arityCheckOkay2.link(this); 1853 1863 1854 1864 compileOpCallInitializeCallFrame(); 1855 1865 1856 pop( X86::ebx);1857 emitPutJITStubArg( X86::ebx, 2);1866 pop(regT3); 1867 emitPutJITStubArg(regT3, 2); 1858 1868 restoreArgumentReference(); 1859 1869 Call callLazyLinkCall = call(); 1860 push( X86::ebx);1861 1862 jump( X86::eax);1870 push(regT3); 1871 1872 jump(regT0); 1863 1873 1864 1874 Label virtualCallBegin = align(); 1865 1875 1866 1876 // 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); 1871 1881 restoreArgumentReference(); 1872 1882 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); 1876 1886 hasCodeBlock3.link(this); 1877 1887 1878 1888 // 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); 1883 1893 restoreArgumentReference(); 1884 1894 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); 1889 1899 arityCheckOkay3.link(this); 1890 1900 … … 1892 1902 1893 1903 // 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); 1897 1907 1898 1908 // 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.