Author: [email protected]
Date: Mon Jul  6 06:21:39 2009
New Revision: 2364

Modified:
    branches/bleeding_edge/src/x64/assembler-x64.cc
    branches/bleeding_edge/src/x64/assembler-x64.h
    branches/bleeding_edge/src/x64/codegen-x64.cc

Log:
X64: Make comparisons work on zero-extended smis.
Review URL: http://codereview.chromium.org/155083

Modified: branches/bleeding_edge/src/x64/assembler-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.cc     (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.cc     Mon Jul  6 06:21:39 2009
@@ -1449,7 +1449,7 @@
    last_pc_ = pc_;
    if (reg.is(rax)) {
      emit(0xA8);
-    emit(mask);
+    emit(mask.value_);  // Low byte emitted.
    } else {
      if (reg.code() > 3) {
        // Register is not one of al, bl, cl, dl.  Its encoding needs REX.
@@ -1470,6 +1470,15 @@
    emit(0xF6);
    emit_operand(rax, op);  // Operation code 0
    emit(mask.value_);  // Low byte emitted.
+}
+
+
+void Assembler::testl(Register dst, Register src) {
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  emit_optional_rex_32(dst, src);
+  emit(0x85);
+  emit_modrm(dst, src);
  }



Modified: branches/bleeding_edge/src/x64/assembler-x64.h
==============================================================================
--- branches/bleeding_edge/src/x64/assembler-x64.h      (original)
+++ branches/bleeding_edge/src/x64/assembler-x64.h      Mon Jul  6 06:21:39 2009
@@ -562,6 +562,14 @@
      immediate_arithmetic_op_8(0x7, dst, src);
    }

+  void cmpl(Register dst, Register src) {
+    arithmetic_op_32(0x3B, dst, src);
+  }
+
+  void cmpl(Register dst, Immediate src) {
+    immediate_arithmetic_op_32(0x7, dst, src);
+  }
+
    void cmpq(Register dst, Register src) {
      arithmetic_op(0x3B, dst, src);
    }
@@ -578,10 +586,6 @@
      immediate_arithmetic_op(0x7, dst, src);
    }

-  void cmpl(Register dst, Immediate src) {
-    immediate_arithmetic_op_32(0x7, dst, src);
-  }
-
    void cmpq(const Operand& dst, Immediate src) {
      immediate_arithmetic_op(0x7, dst, src);
    }
@@ -740,6 +744,7 @@

    void testb(Register reg, Immediate mask);
    void testb(const Operand& op, Immediate mask);
+  void testl(Register dst, Register src);
    void testl(Register reg, Immediate mask);
    void testl(const Operand& op, Immediate mask);
    void testq(const Operand& op, Register reg);

Modified: branches/bleeding_edge/src/x64/codegen-x64.cc
==============================================================================
--- branches/bleeding_edge/src/x64/codegen-x64.cc       (original)
+++ branches/bleeding_edge/src/x64/codegen-x64.cc       Mon Jul  6 06:21:39 2009
@@ -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(&not_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(&not_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);
    }

--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to