Index: src/x64/codegen-x64.cc |
=================================================================== |
--- src/x64/codegen-x64.cc (revision 2363) |
+++ src/x64/codegen-x64.cc (working copy) |
@@ -2459,13 +2459,13 @@ |
// receiver. Use a scratch register to avoid destroying the result. |
Result scratch = allocator_->Allocate(); |
ASSERT(scratch.is_valid()); |
- __ movl(scratch.reg(), |
+ __ movq(scratch.reg(), |
FieldOperand(result.reg(), FixedArray::OffsetOfElementAt(0))); |
frame_->SetElementAt(arg_count + 1, &scratch); |
// We can reuse the result register now. |
frame_->Spill(result.reg()); |
- __ movl(result.reg(), |
+ __ movq(result.reg(), |
FieldOperand(result.reg(), FixedArray::OffsetOfElementAt(1))); |
frame_->SetElementAt(arg_count, &result); |
@@ -4316,12 +4316,8 @@ |
left_side = Result(left_reg); |
right_side = Result(right_val); |
// Test smi equality and comparison by signed int comparison. |
- if (IsUnsafeSmi(right_side.handle())) { |
- right_side.ToRegister(); |
- __ cmpq(left_side.reg(), right_side.reg()); |
- } else { |
- __ Cmp(left_side.reg(), right_side.handle()); |
- } |
+ // Both sides are smis, so we can use an Immediate. |
+ __ cmpl(left_side.reg(), Immediate(Smi::cast(*right_side.handle()))); |
left_side.Unuse(); |
right_side.Unuse(); |
dest->Split(cc); |
@@ -4373,7 +4369,8 @@ |
// When non-smi, call out to the compare stub. |
CompareStub stub(cc, strict); |
Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
- __ testq(answer.reg(), answer.reg()); // Both zero and sign flag right. |
+ // The result is a Smi, which is negative, zero, or positive. |
+ __ testl(answer.reg(), answer.reg()); // Both zero and sign flag right. |
answer.Unuse(); |
dest->Split(cc); |
} else { |
@@ -4393,11 +4390,7 @@ |
// When non-smi, call out to the compare stub. |
CompareStub stub(cc, strict); |
Result answer = frame_->CallStub(&stub, &left_side, &right_side); |
- if (cc == equal) { |
- __ testq(answer.reg(), answer.reg()); |
- } else { |
- __ cmpq(answer.reg(), Immediate(0)); |
- } |
+ __ testl(answer.reg(), answer.reg()); // Sets both zero and sign flags. |
answer.Unuse(); |
dest->true_target()->Branch(cc); |
dest->false_target()->Jump(); |
@@ -4405,7 +4398,7 @@ |
is_smi.Bind(); |
left_side = Result(left_reg); |
right_side = Result(right_reg); |
- __ cmpq(left_side.reg(), right_side.reg()); |
+ __ cmpl(left_side.reg(), right_side.reg()); |
right_side.Unuse(); |
left_side.Unuse(); |
dest->Split(cc); |
@@ -5446,6 +5439,7 @@ |
__ bind(¬_string); |
// HeapNumber => false iff +0, -0, or NaN. |
+ // These three cases set C3 when compared to zero in the FPU. |
__ Cmp(rdx, Factory::heap_number_map()); |
__ j(not_equal, &true_result); |
// TODO(x64): Don't use fp stack, use MMX registers? |
@@ -5455,9 +5449,9 @@ |
__ fucompp(); // Compare and pop both values. |
__ movq(kScratchRegister, rax); |
__ fnstsw_ax(); // Store fp status word in ax, no checking for exceptions. |
- __ testb(rax, Immediate(0x08)); // Test FP condition flag C3. |
+ __ testl(rax, Immediate(0x4000)); // Test FP condition flag C3, bit 16. |
__ movq(rax, kScratchRegister); |
- __ j(zero, &false_result); |
+ __ j(not_zero, &false_result); |
// Fall through to |true_result|. |
// Return 1/0 for true/false in rax. |
@@ -5627,7 +5621,11 @@ |
__ shl(rax, Immediate(12)); |
// If all bits in the mantissa are zero the number is Infinity, and |
// we return zero. Otherwise it is a NaN, and we return non-zero. |
- // So just return rax. |
+ // We cannot just return rax because only eax is tested on return. |
+ // TODO(X64): Solve this using movcc, when implemented. |
+ __ movq(kScratchRegister, rax); |
+ __ shr(kScratchRegister, Immediate(32)); |
+ __ or_(rax, kScratchRegister); |
__ ret(0); |
__ bind(¬_identical); |
@@ -5665,7 +5663,7 @@ |
Factory::heap_number_map()); |
// If heap number, handle it in the slow case. |
__ j(equal, &slow); |
- // Return non-equal (ebx is not zero) |
+ // Return non-equal. ebx (the lower half of rbx) is not zero. |
__ movq(rax, rbx); |
__ ret(0); |
@@ -5681,7 +5679,7 @@ |
Label first_non_object; |
__ CmpObjectType(rax, FIRST_JS_OBJECT_TYPE, rcx); |
__ j(below, &first_non_object); |
- // Return non-zero (rax is not zero) |
+ // Return non-zero (eax (not rax) is not zero) |
Label return_not_equal; |
ASSERT(kHeapObjectTag != 0); |
__ bind(&return_not_equal); |
@@ -5745,7 +5743,7 @@ |
BranchIfNonSymbol(masm, &call_builtin, rdx, kScratchRegister); |
// We've already checked for object identity, so if both operands |
- // are symbols they aren't equal. Register rax already holds a |
+ // are symbols they aren't equal. Register eax (not rax) already holds a |
// non-zero value, which indicates not equal, so just return. |
__ ret(2 * kPointerSize); |
} |