| Index: src/arm/codegen-arm.cc
|
| ===================================================================
|
| --- src/arm/codegen-arm.cc (revision 3713)
|
| +++ src/arm/codegen-arm.cc (working copy)
|
| @@ -4847,14 +4847,14 @@
|
| Label* lhs_not_nan,
|
| Label* slow,
|
| bool strict) {
|
| - Label lhs_is_smi;
|
| + Label rhs_is_smi;
|
| __ tst(r0, Operand(kSmiTagMask));
|
| - __ b(eq, &lhs_is_smi);
|
| + __ b(eq, &rhs_is_smi);
|
|
|
| - // Rhs is a Smi. Check whether the non-smi is a heap number.
|
| + // Lhs is a Smi. Check whether the rhs is a heap number.
|
| __ CompareObjectType(r0, r4, r4, HEAP_NUMBER_TYPE);
|
| if (strict) {
|
| - // If lhs was not a number and rhs was a Smi then strict equality cannot
|
| + // If rhs is not a number and lhs is a Smi then strict equality cannot
|
| // succeed. Return non-equal (r0 is already not zero)
|
| __ mov(pc, Operand(lr), LeaveCC, ne); // Return.
|
| } else {
|
| @@ -4863,57 +4863,67 @@
|
| __ b(ne, slow);
|
| }
|
|
|
| - // Rhs is a smi, lhs is a number.
|
| - __ push(lr);
|
| -
|
| + // Lhs (r1) is a smi, rhs (r0) is a number.
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| + // Convert lhs to a double in d7 .
|
| CpuFeatures::Scope scope(VFP3);
|
| - __ IntegerToDoubleConversionWithVFP3(r1, r3, r2);
|
| + __ mov(r7, Operand(r1, ASR, kSmiTagSize));
|
| + __ vmov(s15, r7);
|
| + __ vcvt(d7, s15);
|
| + // Load the double from rhs, tagged HeapNumber r0, to d6.
|
| + __ sub(r7, r0, Operand(kHeapObjectTag));
|
| + __ vldr(d6, r7, HeapNumber::kValueOffset);
|
| } else {
|
| + __ push(lr);
|
| + // Convert lhs to a double in r2, r3.
|
| __ mov(r7, Operand(r1));
|
| ConvertToDoubleStub stub1(r3, r2, r7, r6);
|
| __ Call(stub1.GetCode(), RelocInfo::CODE_TARGET);
|
| + // Load rhs to a double in r0, r1.
|
| + __ ldr(r1, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
|
| + __ ldr(r0, FieldMemOperand(r0, HeapNumber::kValueOffset));
|
| + __ pop(lr);
|
| }
|
|
|
| -
|
| - // r3 and r2 are rhs as double.
|
| - __ ldr(r1, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
|
| - __ ldr(r0, FieldMemOperand(r0, HeapNumber::kValueOffset));
|
| // We now have both loaded as doubles but we can skip the lhs nan check
|
| - // since it's a Smi.
|
| - __ pop(lr);
|
| + // since it's a smi.
|
| __ jmp(lhs_not_nan);
|
|
|
| - __ bind(&lhs_is_smi);
|
| - // Lhs is a Smi. Check whether the non-smi is a heap number.
|
| + __ bind(&rhs_is_smi);
|
| + // Rhs is a smi. Check whether the non-smi lhs is a heap number.
|
| __ CompareObjectType(r1, r4, r4, HEAP_NUMBER_TYPE);
|
| if (strict) {
|
| - // If lhs was not a number and rhs was a Smi then strict equality cannot
|
| + // If lhs is not a number and rhs is a smi then strict equality cannot
|
| // succeed. Return non-equal.
|
| __ mov(r0, Operand(1), LeaveCC, ne); // Non-zero indicates not equal.
|
| __ mov(pc, Operand(lr), LeaveCC, ne); // Return.
|
| } else {
|
| - // Smi compared non-strictly with a non-Smi non-heap-number. Call
|
| + // Smi compared non-strictly with a non-smi non-heap-number. Call
|
| // the runtime.
|
| __ b(ne, slow);
|
| }
|
|
|
| - // Lhs is a smi, rhs is a number.
|
| - // r0 is Smi and r1 is heap number.
|
| - __ push(lr);
|
| - __ ldr(r2, FieldMemOperand(r1, HeapNumber::kValueOffset));
|
| - __ ldr(r3, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
|
| -
|
| + // Rhs (r0) is a smi, lhs (r1) is a heap number.
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| + // Convert rhs to a double in d6 .
|
| CpuFeatures::Scope scope(VFP3);
|
| - __ IntegerToDoubleConversionWithVFP3(r0, r1, r0);
|
| + // Load the double from lhs, tagged HeapNumber r1, to d7.
|
| + __ sub(r7, r1, Operand(kHeapObjectTag));
|
| + __ vldr(d7, r7, HeapNumber::kValueOffset);
|
| + __ mov(r7, Operand(r0, ASR, kSmiTagSize));
|
| + __ vmov(s13, r7);
|
| + __ vcvt(d6, s13);
|
| } else {
|
| + __ push(lr);
|
| + // Load lhs to a double in r2, r3.
|
| + __ ldr(r3, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
|
| + __ ldr(r2, FieldMemOperand(r1, HeapNumber::kValueOffset));
|
| + // Convert rhs to a double in r0, r1.
|
| __ mov(r7, Operand(r0));
|
| ConvertToDoubleStub stub2(r1, r0, r7, r6);
|
| __ Call(stub2.GetCode(), RelocInfo::CODE_TARGET);
|
| + __ pop(lr);
|
| }
|
| -
|
| - __ pop(lr);
|
| // Fall through to both_loaded_as_doubles.
|
| }
|
|
|
| @@ -5062,10 +5072,18 @@
|
|
|
| // Both are heap numbers. Load them up then jump to the code we have
|
| // for that.
|
| - __ ldr(r2, FieldMemOperand(r1, HeapNumber::kValueOffset));
|
| - __ ldr(r3, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
|
| - __ ldr(r1, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
|
| - __ ldr(r0, FieldMemOperand(r0, HeapNumber::kValueOffset));
|
| + if (CpuFeatures::IsSupported(VFP3)) {
|
| + CpuFeatures::Scope scope(VFP3);
|
| + __ sub(r7, r0, Operand(kHeapObjectTag));
|
| + __ vldr(d6, r7, HeapNumber::kValueOffset);
|
| + __ sub(r7, r1, Operand(kHeapObjectTag));
|
| + __ vldr(d7, r7, HeapNumber::kValueOffset);
|
| + } else {
|
| + __ ldr(r2, FieldMemOperand(r1, HeapNumber::kValueOffset));
|
| + __ ldr(r3, FieldMemOperand(r1, HeapNumber::kValueOffset + kPointerSize));
|
| + __ ldr(r1, FieldMemOperand(r0, HeapNumber::kValueOffset + kPointerSize));
|
| + __ ldr(r0, FieldMemOperand(r0, HeapNumber::kValueOffset));
|
| + }
|
| __ jmp(both_loaded_as_doubles);
|
| }
|
|
|
| @@ -5117,21 +5135,19 @@
|
| // 3) Fall through to both_loaded_as_doubles.
|
| // 4) Jump to lhs_not_nan.
|
| // In cases 3 and 4 we have found out we were dealing with a number-number
|
| - // comparison and the numbers have been loaded into r0, r1, r2, r3 as doubles.
|
| + // comparison. If VFP3 is supported the double values of the numbers have
|
| + // been loaded into d7 and d6. Otherwise, the double values have been loaded
|
| + // into r0, r1, r2, and r3.
|
| EmitSmiNonsmiComparison(masm, &lhs_not_nan, &slow, strict_);
|
|
|
| __ bind(&both_loaded_as_doubles);
|
| - // r0, r1, r2, r3 are the double representations of the right hand side
|
| - // and the left hand side.
|
| -
|
| + // The arguments have been converted to doubles and stored in d6 and d7, if
|
| + // VFP3 is supported, or in r0, r1, r2, and r3.
|
| if (CpuFeatures::IsSupported(VFP3)) {
|
| __ bind(&lhs_not_nan);
|
| CpuFeatures::Scope scope(VFP3);
|
| Label no_nan;
|
| // ARMv7 VFP3 instructions to implement double precision comparison.
|
| - __ vmov(d6, r0, r1);
|
| - __ vmov(d7, r2, r3);
|
| -
|
| __ vcmp(d7, d6);
|
| __ vmrs(pc); // Move vector status bits to normal status bits.
|
| Label nan;
|
| @@ -5273,7 +5289,11 @@
|
| // The new heap number is in r5. r6 and r7 are scratch.
|
| AllocateHeapNumber(masm, &slow, r5, r6, r7);
|
|
|
| - if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
|
| + // If we have floating point hardware, inline ADD, SUB, MUL, and DIV,
|
| + // using registers d7 and d6 for the double values.
|
| + bool use_fp_registers = CpuFeatures::IsSupported(VFP3) &&
|
| + Token::MOD != operation;
|
| + if (use_fp_registers) {
|
| CpuFeatures::Scope scope(VFP3);
|
| __ mov(r7, Operand(r0, ASR, kSmiTagSize));
|
| __ vmov(s15, r7);
|
| @@ -5362,7 +5382,7 @@
|
| if (mode == OVERWRITE_RIGHT) {
|
| __ mov(r5, Operand(r0)); // Overwrite this heap number.
|
| }
|
| - if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
|
| + if (use_fp_registers) {
|
| CpuFeatures::Scope scope(VFP3);
|
| // Load the double from tagged HeapNumber r0 to d7.
|
| __ sub(r7, r0, Operand(kHeapObjectTag));
|
| @@ -5379,9 +5399,9 @@
|
| AllocateHeapNumber(masm, &slow, r5, r6, r7);
|
| }
|
|
|
| - if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
|
| + if (use_fp_registers) {
|
| CpuFeatures::Scope scope(VFP3);
|
| - // Convert smi in r0 to double in d7
|
| + // Convert smi in r0 to double in d7.
|
| __ mov(r7, Operand(r0, ASR, kSmiTagSize));
|
| __ vmov(s15, r7);
|
| __ vcvt(d7, s15);
|
| @@ -5404,7 +5424,7 @@
|
| if (mode == OVERWRITE_LEFT) {
|
| __ mov(r5, Operand(r1)); // Overwrite this heap number.
|
| }
|
| - if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
|
| + if (use_fp_registers) {
|
| CpuFeatures::Scope scope(VFP3);
|
| // Load the double from tagged HeapNumber r1 to d6.
|
| __ sub(r7, r1, Operand(kHeapObjectTag));
|
| @@ -5421,9 +5441,9 @@
|
| AllocateHeapNumber(masm, &slow, r5, r6, r7);
|
| }
|
|
|
| - if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) {
|
| + if (use_fp_registers) {
|
| CpuFeatures::Scope scope(VFP3);
|
| - // Convert smi in r1 to double in d6
|
| + // Convert smi in r1 to double in d6.
|
| __ mov(r7, Operand(r1, ASR, kSmiTagSize));
|
| __ vmov(s13, r7);
|
| __ vcvt(d6, s13);
|
| @@ -5441,11 +5461,7 @@
|
| __ bind(&do_the_call);
|
| // If we are inlining the operation using VFP3 instructions for
|
| // add, subtract, multiply, or divide, the arguments are in d6 and d7.
|
| - if (CpuFeatures::IsSupported(VFP3) &&
|
| - ((Token::MUL == operation) ||
|
| - (Token::DIV == operation) ||
|
| - (Token::ADD == operation) ||
|
| - (Token::SUB == operation))) {
|
| + if (use_fp_registers) {
|
| CpuFeatures::Scope scope(VFP3);
|
| // ARMv7 VFP3 instructions to implement
|
| // double precision, add, subtract, multiply, divide.
|
|
|