Chromium Code Reviews| Index: runtime/vm/stub_code_x64.cc |
| =================================================================== |
| --- runtime/vm/stub_code_x64.cc (revision 15270) |
| +++ runtime/vm/stub_code_x64.cc (working copy) |
| @@ -2091,6 +2091,78 @@ |
| __ 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 = RAX; |
| + const Register right = RDX; |
| + // Preserve left, right and temp. |
| + __ pushq(left); |
| + __ pushq(right); |
| + // TOS + 0: saved right |
| + // TOS + 1: saved left |
| + // TOS + 2: return address |
| + // TOS + 3: right argument. |
| + // TOS + 4: left argument. |
| + __ movq(left, Address(RSP, 4 * kWordSize)); |
| + __ movq(right, Address(RSP, 3 * kWordSize)); |
| + Label reference_compare, done, check_mint, check_bigint; |
| + // If any of the arguments is Smi do reference compare. |
| + __ testq(left, Immediate(kSmiTagMask)); |
| + __ j(ZERO, &reference_compare); |
| + __ testq(right, Immediate(kSmiTagMask)); |
| + __ j(ZERO, &reference_compare); |
| + |
| + // Value compare for two doubles. |
| + __ CompareClassId(left, kDoubleCid); |
| + __ j(NOT_EQUAL, &check_mint, Assembler::kNearJump); |
| + __ CompareClassId(right, kDoubleCid); |
| + __ j(NOT_EQUAL, &done, Assembler::kNearJump); |
| + |
| + // Double values bitwise compare. |
| + __ movq(left, FieldAddress(left, Double::value_offset())); |
| + __ cmpq(left, FieldAddress(right, Double::value_offset())); |
| + __ jmp(&done, Assembler::kNearJump); |
| + |
| + __ Bind(&check_mint); |
| + __ CompareClassId(left, kMintCid); |
| + __ j(NOT_EQUAL, &check_bigint, Assembler::kNearJump); |
| + __ movq(left, FieldAddress(left, Mint::value_offset())); |
| + __ cmpq(left, FieldAddress(right, Mint::value_offset())); |
|
Florian Schneider
2012/11/23 10:33:40
right has not yet been checked for kMintCid here.
srdjan
2012/11/23 19:45:39
Done.
|
| + __ jmp(&done, Assembler::kNearJump); |
| + |
| + __ Bind(&check_bigint); |
| + __ CompareClassId(left, kBigintCid); |
| + __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); |
| + __ CompareClassId(right, kBigintCid); |
| + __ j(NOT_EQUAL, &reference_compare, Assembler::kNearJump); |
| + __ EnterFrame(0); |
| + __ ReserveAlignedFrameSpace(0); |
| + __ movq(RDI, left); |
| + __ movq(RSI, right); |
| + __ CallRuntime(kBigintCompareRuntimeEntry); |
| + // Result in RAX, 0 means equal. |
| + __ LeaveFrame(); |
| + __ cmpq(RAX, 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 and the head of the function.
|
| + __ cmpq(left, right); |
| + __ Bind(&done); |
| + __ popq(right); |
| + __ popq(left); |
| + __ ret(); |
| +} |
| + |
| } // namespace dart |
| #endif // defined TARGET_ARCH_X64 |