Index: src/arm/codegen-arm.cc |
=================================================================== |
--- src/arm/codegen-arm.cc (revision 3700) |
+++ src/arm/codegen-arm.cc (working copy) |
@@ -5273,10 +5273,14 @@ |
// The new heap number is in r5. r6 and r7 are scratch. |
AllocateHeapNumber(masm, &slow, r5, r6, r7); |
- if (CpuFeatures::IsSupported(VFP3)) { |
+ if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) { |
CpuFeatures::Scope scope(VFP3); |
- __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); |
- __ IntegerToDoubleConversionWithVFP3(r1, r1, r0); |
+ __ mov(r7, Operand(r0, ASR, kSmiTagSize)); |
+ __ vmov(s15, r7); |
+ __ vcvt(d7, s15); |
+ __ mov(r7, Operand(r1, ASR, kSmiTagSize)); |
+ __ vmov(s13, r7); |
+ __ vcvt(d6, s13); |
} else { |
// Write Smi from r0 to r3 and r2 in double format. r6 is scratch. |
__ mov(r7, Operand(r0)); |
@@ -5358,9 +5362,16 @@ |
if (mode == OVERWRITE_RIGHT) { |
__ mov(r5, Operand(r0)); // Overwrite this heap number. |
} |
- // Calling convention says that second double is in r2 and r3. |
- __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset)); |
- __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + 4)); |
+ if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) { |
+ CpuFeatures::Scope scope(VFP3); |
+ // Load the double from tagged HeapNumber r0 to d7. |
+ __ sub(r7, r0, Operand(kHeapObjectTag)); |
+ __ vldr(d7, r7, HeapNumber::kValueOffset); |
+ } else { |
+ // Calling convention says that second double is in r2 and r3. |
+ __ ldr(r2, FieldMemOperand(r0, HeapNumber::kValueOffset)); |
+ __ ldr(r3, FieldMemOperand(r0, HeapNumber::kValueOffset + 4)); |
+ } |
__ jmp(&finished_loading_r0); |
__ bind(&r0_is_smi); |
if (mode == OVERWRITE_RIGHT) { |
@@ -5368,10 +5379,12 @@ |
AllocateHeapNumber(masm, &slow, r5, r6, r7); |
} |
- |
- if (CpuFeatures::IsSupported(VFP3)) { |
+ if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) { |
CpuFeatures::Scope scope(VFP3); |
- __ IntegerToDoubleConversionWithVFP3(r0, r3, r2); |
+ // Convert smi in r0 to double in d7 |
+ __ mov(r7, Operand(r0, ASR, kSmiTagSize)); |
+ __ vmov(s15, r7); |
+ __ vcvt(d7, s15); |
} else { |
// Write Smi from r0 to r3 and r2 in double format. |
__ mov(r7, Operand(r0)); |
@@ -5391,9 +5404,16 @@ |
if (mode == OVERWRITE_LEFT) { |
__ mov(r5, Operand(r1)); // Overwrite this heap number. |
} |
- // Calling convention says that first double is in r0 and r1. |
- __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset)); |
- __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + 4)); |
+ if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) { |
+ CpuFeatures::Scope scope(VFP3); |
+ // Load the double from tagged HeapNumber r1 to d6. |
+ __ sub(r7, r1, Operand(kHeapObjectTag)); |
+ __ vldr(d6, r7, HeapNumber::kValueOffset); |
+ } else { |
+ // Calling convention says that first double is in r0 and r1. |
+ __ ldr(r0, FieldMemOperand(r1, HeapNumber::kValueOffset)); |
+ __ ldr(r1, FieldMemOperand(r1, HeapNumber::kValueOffset + 4)); |
+ } |
__ jmp(&finished_loading_r1); |
__ bind(&r1_is_smi); |
if (mode == OVERWRITE_LEFT) { |
@@ -5401,9 +5421,12 @@ |
AllocateHeapNumber(masm, &slow, r5, r6, r7); |
} |
- if (CpuFeatures::IsSupported(VFP3)) { |
+ if (CpuFeatures::IsSupported(VFP3) && Token::MOD != operation) { |
CpuFeatures::Scope scope(VFP3); |
- __ IntegerToDoubleConversionWithVFP3(r1, r1, r0); |
+ // Convert smi in r1 to double in d6 |
+ __ mov(r7, Operand(r1, ASR, kSmiTagSize)); |
+ __ vmov(s13, r7); |
+ __ vcvt(d6, s13); |
} else { |
// Write Smi from r1 to r1 and r0 in double format. |
__ mov(r7, Operand(r1)); |
@@ -5416,12 +5439,8 @@ |
__ bind(&finished_loading_r1); |
__ bind(&do_the_call); |
- // r0: Left value (least significant part of mantissa). |
- // r1: Left value (sign, exponent, top of mantissa). |
- // r2: Right value (least significant part of mantissa). |
- // r3: Right value (sign, exponent, top of mantissa). |
- // r5: Address of heap number for result. |
- |
+ // 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) || |
@@ -5430,8 +5449,6 @@ |
CpuFeatures::Scope scope(VFP3); |
// ARMv7 VFP3 instructions to implement |
// double precision, add, subtract, multiply, divide. |
- __ vmov(d6, r0, r1); |
- __ vmov(d7, r2, r3); |
if (Token::MUL == operation) { |
__ vmul(d5, d6, d7); |
@@ -5444,15 +5461,20 @@ |
} else { |
UNREACHABLE(); |
} |
- |
- __ vmov(r0, r1, d5); |
- |
- __ str(r0, FieldMemOperand(r5, HeapNumber::kValueOffset)); |
- __ str(r1, FieldMemOperand(r5, HeapNumber::kValueOffset + 4)); |
- __ mov(r0, Operand(r5)); |
+ __ sub(r0, r5, Operand(kHeapObjectTag)); |
+ __ vstr(d5, r0, HeapNumber::kValueOffset); |
+ __ add(r0, r0, Operand(kHeapObjectTag)); |
__ mov(pc, lr); |
return; |
} |
+ |
+ // If we did not inline the operation, then the arguments are in: |
+ // r0: Left value (least significant part of mantissa). |
+ // r1: Left value (sign, exponent, top of mantissa). |
+ // r2: Right value (least significant part of mantissa). |
+ // r3: Right value (sign, exponent, top of mantissa). |
+ // r5: Address of heap number for result. |
+ |
__ push(lr); // For later. |
__ push(r5); // Address of heap number that is answer. |
__ AlignStack(0); |