Chromium Code Reviews| Index: runtime/vm/stub_code_ia32.cc |
| =================================================================== |
| --- runtime/vm/stub_code_ia32.cc (revision 15270) |
| +++ runtime/vm/stub_code_ia32.cc (working copy) |
| @@ -2130,6 +2130,88 @@ |
| __ ret(); |
| } |
| + |
| +DECLARE_LEAF_RUNTIME_ENTRY(intptr_t, |
| + BigintCompare, |
| + RawBigint* left, |
| + RawBigint* right); |
| + |
| + |
| +// Does identical check (object references are equal or not equal) with special |
| +// checks for boxed numbers. |
| +// Left and right are pushed on stack. |
| +// Return ZF set. |
| +void StubCode::GenerateIdenticalWithNumberCheckStub(Assembler* assembler) { |
| + const Register left = EAX; |
| + const Register right = EDX; |
| + const Register temp = ECX; |
| + // Preserve left, right and temp. |
| + __ pushl(left); |
| + __ pushl(right); |
| + __ pushl(temp); |
| + // TOS + 0: saved temp |
| + // TOS + 1: saved right |
| + // TOS + 2: saved left |
| + // TOS + 3: return address |
| + // TOS + 4: right argument. |
| + // TOS + 5: left argument. |
| + __ movl(left, Address(ESP, 5 * kWordSize)); |
| + __ movl(right, Address(ESP, 4 * kWordSize)); |
| + Label reference_compare, done, check_mint, check_bigint; |
| + // If any of the arguments is Smi do reference compare. |
| + __ testl(left, Immediate(kSmiTagMask)); |
| + __ j(ZERO, &reference_compare, Assembler::kNearJump); |
| + __ testl(right, Immediate(kSmiTagMask)); |
| + __ j(ZERO, &reference_compare, Assembler::kNearJump); |
| + |
| + // Value compare for two doubles. |
| + __ CompareClassId(left, kDoubleCid, temp); |
| + __ j(NOT_EQUAL, &check_mint, Assembler::kNearJump); |
| + __ CompareClassId(right, kDoubleCid, temp); |
| + __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| + |
| + // Double values bitwise compare. |
| + __ movl(temp, FieldAddress(left, Double::value_offset() + 0 * kWordSize)); |
| + __ cmpl(temp, FieldAddress(right, Double::value_offset() + 0 * kWordSize)); |
| + __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| + __ movl(temp, FieldAddress(left, Double::value_offset() + 1 * kWordSize)); |
| + __ cmpl(temp, FieldAddress(right, Double::value_offset() + 1 * kWordSize)); |
| + __ jmp(&done, Assembler::kNearJump); |
| + |
| + __ Bind(&check_mint); |
| + __ CompareClassId(left, kMintCid, temp); |
| + __ j(NOT_EQUAL, &check_bigint, Assembler::kNearJump); |
| + __ movl(temp, FieldAddress(left, Mint::value_offset() + 0 * kWordSize)); |
| + __ cmpl(temp, FieldAddress(right, Mint::value_offset() + 0 * kWordSize)); |
|
Florian Schneider
2012/11/23 10:33:40
right has yet not been checked for kMintCid here.
srdjan
2012/11/23 19:45:39
Done.
|
| + __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| + __ movl(temp, FieldAddress(left, Mint::value_offset() + 1 * kWordSize)); |
| + __ cmpl(temp, FieldAddress(right, Mint::value_offset() + 1 * kWordSize)); |
| + __ jmp(&done, Assembler::kNearJump); |
| + |
| + __ Bind(&check_bigint); |
| + __ CompareClassId(left, kBigintCid, temp); |
| + __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); |
| + __ CompareClassId(right, kBigintCid, temp); |
| + __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); |
| + __ EnterFrame(0); |
| + __ ReserveAlignedFrameSpace(2 * kWordSize); |
| + __ movl(Address(ESP, 1 * kWordSize), left); |
| + __ movl(Address(ESP, 0 * kWordSize), right); |
| + __ CallRuntime(kBigintCompareRuntimeEntry); |
| + // Result in EAX, 0 means equal. |
| + __ LeaveFrame(); |
| + __ cmpl(EAX, Immediate(0)); |
| + __ jmp(&done); |
| + |
| + __ Bind(&reference_compare); |
|
Florian Schneider
2012/11/23 10:33:40
Please add a comment that the code relies on the a
srdjan
2012/11/23 19:45:39
Added comment at the beginning of method:
// Note:
|
| + __ cmpl(left, right); |
| + __ Bind(&done); |
| + __ popl(temp); |
| + __ popl(right); |
| + __ popl(left); |
| + __ ret(); |
| +} |
| + |
| } // namespace dart |
| #endif // defined TARGET_ARCH_IA32 |