OLD | NEW |
1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 1156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1167 Register left = ToRegister(instr->InputAt(0)); | 1167 Register left = ToRegister(instr->InputAt(0)); |
1168 Register right = ToRegister(instr->InputAt(1)); | 1168 Register right = ToRegister(instr->InputAt(1)); |
1169 | 1169 |
1170 __ PushSafepointRegistersAndDoubles(); | 1170 __ PushSafepointRegistersAndDoubles(); |
1171 GenericBinaryOpStub stub(op, OVERWRITE_LEFT, left, right); | 1171 GenericBinaryOpStub stub(op, OVERWRITE_LEFT, left, right); |
1172 __ CallStub(&stub); | 1172 __ CallStub(&stub); |
1173 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), | 1173 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), |
1174 0, | 1174 0, |
1175 Safepoint::kNoDeoptimizationIndex); | 1175 Safepoint::kNoDeoptimizationIndex); |
1176 // Overwrite the stored value of r0 with the result of the stub. | 1176 // Overwrite the stored value of r0 with the result of the stub. |
1177 __ str(r0, MemOperand(sp, DwVfpRegister::kNumAllocatableRegisters * | 1177 __ StoreToSafepointRegistersAndDoublesSlot(r0); |
1178 kDoubleSize)); | |
1179 __ PopSafepointRegistersAndDoubles(); | 1178 __ PopSafepointRegistersAndDoubles(); |
1180 } | 1179 } |
1181 | 1180 |
1182 | 1181 |
1183 void LCodeGen::DoMulI(LMulI* instr) { | 1182 void LCodeGen::DoMulI(LMulI* instr) { |
1184 Register scratch = scratch0(); | 1183 Register scratch = scratch0(); |
1185 Register left = ToRegister(instr->InputAt(0)); | 1184 Register left = ToRegister(instr->InputAt(0)); |
1186 Register right = EmitLoadRegister(instr->InputAt(1), scratch); | 1185 Register right = EmitLoadRegister(instr->InputAt(1), scratch); |
1187 | 1186 |
1188 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && | 1187 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && |
(...skipping 1329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2518 | 2517 |
2519 | 2518 |
2520 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2519 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2521 ASSERT(ToRegister(instr->result()).is(r0)); | 2520 ASSERT(ToRegister(instr->result()).is(r0)); |
2522 __ mov(r1, Operand(instr->function())); | 2521 __ mov(r1, Operand(instr->function())); |
2523 CallKnownFunction(instr->function(), instr->arity(), instr); | 2522 CallKnownFunction(instr->function(), instr->arity(), instr); |
2524 } | 2523 } |
2525 | 2524 |
2526 | 2525 |
2527 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2526 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
| 2527 ASSERT(instr->InputAt(0)->Equals(instr->result())); |
2528 Register input = ToRegister(instr->InputAt(0)); | 2528 Register input = ToRegister(instr->InputAt(0)); |
2529 Register scratch = scratch0(); | 2529 Register scratch = scratch0(); |
2530 | 2530 |
2531 // Deoptimize if not a heap number. | 2531 // Deoptimize if not a heap number. |
2532 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 2532 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
2533 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 2533 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
2534 __ cmp(scratch, Operand(ip)); | 2534 __ cmp(scratch, Operand(ip)); |
2535 DeoptimizeIf(ne, instr->environment()); | 2535 DeoptimizeIf(ne, instr->environment()); |
2536 | 2536 |
2537 Label done; | 2537 Label done; |
2538 | 2538 Register exponent = scratch0(); |
2539 Label negative; | 2539 scratch = no_reg; |
2540 __ ldr(scratch, FieldMemOperand(input, HeapNumber::kExponentOffset)); | 2540 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); |
2541 // Check the sign of the argument. If the argument is positive, just | 2541 // Check the sign of the argument. If the argument is positive, just |
2542 // return it. We do not need to patch the stack since |input| and | 2542 // return it. We do not need to patch the stack since |input| and |
2543 // |result| are the same register and |input| will be restored | 2543 // |result| are the same register and |input| would be restored |
2544 // unchanged by popping safepoint registers. | 2544 // unchanged by popping safepoint registers. |
2545 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 2545 __ tst(exponent, Operand(HeapNumber::kSignMask)); |
2546 __ b(ne, &negative); | 2546 __ b(eq, &done); |
2547 __ jmp(&done); | |
2548 | 2547 |
2549 __ bind(&negative); | 2548 // Input is negative. Reverse its sign. |
2550 // Preserve the value of all registers. | 2549 // Preserve the value of all registers. |
2551 __ PushSafepointRegisters(); | 2550 __ PushSafepointRegisters(); |
2552 | 2551 |
2553 Register tmp = input.is(r0) ? r1 : r0; | 2552 // Registers were saved at the safepoint, so we can use |
2554 Register tmp2 = input.is(r2) ? r3 : r2; | 2553 // many scratch registers. |
2555 Register tmp3 = input.is(r4) ? r5 : r4; | 2554 Register tmp1 = input.is(r1) ? r0 : r1; |
| 2555 Register tmp2 = input.is(r2) ? r0 : r2; |
| 2556 Register tmp3 = input.is(r3) ? r0 : r3; |
| 2557 Register tmp4 = input.is(r4) ? r0 : r4; |
| 2558 |
| 2559 // exponent: floating point exponent value. |
2556 | 2560 |
2557 Label allocated, slow; | 2561 Label allocated, slow; |
2558 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 2562 __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex); |
2559 __ AllocateHeapNumber(tmp, tmp2, tmp3, scratch, &slow); | 2563 __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow); |
2560 __ b(&allocated); | 2564 __ b(&allocated); |
2561 | 2565 |
2562 // Slow case: Call the runtime system to do the number allocation. | 2566 // Slow case: Call the runtime system to do the number allocation. |
2563 __ bind(&slow); | 2567 __ bind(&slow); |
2564 | 2568 |
2565 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 2569 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
2566 RecordSafepointWithRegisters( | 2570 RecordSafepointWithRegisters( |
2567 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); | 2571 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); |
2568 // Set the pointer to the new heap number in tmp. | 2572 // Set the pointer to the new heap number in tmp. |
2569 if (!tmp.is(r0)) __ mov(tmp, Operand(r0)); | 2573 if (!tmp1.is(r0)) __ mov(tmp1, Operand(r0)); |
2570 | |
2571 // Restore input_reg after call to runtime. | 2574 // Restore input_reg after call to runtime. |
2572 MemOperand input_register_slot = masm()->SafepointRegisterSlot(input); | 2575 __ LoadFromSafepointRegisterSlot(input); |
2573 __ ldr(input, input_register_slot); | 2576 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); |
2574 | 2577 |
2575 __ bind(&allocated); | 2578 __ bind(&allocated); |
2576 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kExponentOffset)); | 2579 // exponent: floating point exponent value. |
2577 __ bic(tmp2, tmp2, Operand(HeapNumber::kSignMask)); | 2580 // tmp1: allocated heap number. |
2578 __ str(tmp2, FieldMemOperand(tmp, HeapNumber::kExponentOffset)); | 2581 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask)); |
| 2582 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); |
2579 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); | 2583 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); |
2580 __ str(tmp2, FieldMemOperand(tmp, HeapNumber::kMantissaOffset)); | 2584 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); |
2581 | 2585 |
2582 __ str(tmp, input_register_slot); | 2586 __ str(tmp1, masm()->SafepointRegisterSlot(input)); |
2583 __ PopSafepointRegisters(); | 2587 __ PopSafepointRegisters(); |
2584 | 2588 |
2585 __ bind(&done); | 2589 __ bind(&done); |
2586 } | 2590 } |
2587 | 2591 |
2588 | 2592 |
2589 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { | 2593 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { |
2590 Label is_positive; | |
2591 uint32_t kSignMask = 0x80000000u; | |
2592 Register input = ToRegister(instr->InputAt(0)); | 2594 Register input = ToRegister(instr->InputAt(0)); |
2593 __ tst(input, Operand(kSignMask)); | 2595 __ cmp(input, Operand(0)); |
2594 __ b(eq, &is_positive); | 2596 // We can make rsb conditional because the previous cmp instruction |
2595 __ rsb(input, input, Operand(0), SetCC); | 2597 // will clear the V (overflow) flag and rsb won't set this flag |
| 2598 // if input is positive. |
| 2599 __ rsb(input, input, Operand(0), SetCC, mi); |
2596 // Deoptimize on overflow. | 2600 // Deoptimize on overflow. |
2597 DeoptimizeIf(vs, instr->environment()); | 2601 DeoptimizeIf(vs, instr->environment()); |
2598 __ bind(&is_positive); | |
2599 } | 2602 } |
2600 | 2603 |
2601 | 2604 |
2602 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 2605 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
2603 // Class for deferred case. | 2606 // Class for deferred case. |
2604 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 2607 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
2605 public: | 2608 public: |
2606 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 2609 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
2607 LUnaryMathOperation* instr) | 2610 LUnaryMathOperation* instr) |
2608 : LDeferredCode(codegen), instr_(instr) { } | 2611 : LDeferredCode(codegen), instr_(instr) { } |
2609 virtual void Generate() { | 2612 virtual void Generate() { |
2610 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 2613 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
2611 } | 2614 } |
2612 private: | 2615 private: |
2613 LUnaryMathOperation* instr_; | 2616 LUnaryMathOperation* instr_; |
2614 }; | 2617 }; |
2615 | 2618 |
2616 ASSERT(instr->InputAt(0)->Equals(instr->result())); | 2619 ASSERT(instr->InputAt(0)->Equals(instr->result())); |
2617 Representation r = instr->hydrogen()->value()->representation(); | 2620 Representation r = instr->hydrogen()->value()->representation(); |
2618 if (r.IsDouble()) { | 2621 if (r.IsDouble()) { |
2619 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); | 2622 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); |
2620 // __ vabs(input, input); | 2623 __ vabs(input, input); |
2621 Abort("Double DoMathAbs unimplemented"); | |
2622 } else if (r.IsInteger32()) { | 2624 } else if (r.IsInteger32()) { |
2623 EmitIntegerMathAbs(instr); | 2625 EmitIntegerMathAbs(instr); |
2624 } else { | 2626 } else { |
2625 // Representation is tagged. | 2627 // Representation is tagged. |
2626 DeferredMathAbsTaggedHeapNumber* deferred = | 2628 DeferredMathAbsTaggedHeapNumber* deferred = |
2627 new DeferredMathAbsTaggedHeapNumber(this, instr); | 2629 new DeferredMathAbsTaggedHeapNumber(this, instr); |
2628 Register input = ToRegister(instr->InputAt(0)); | 2630 Register input = ToRegister(instr->InputAt(0)); |
2629 // Smi check. | 2631 // Smi check. |
2630 __ JumpIfNotSmi(input, deferred->entry()); | 2632 __ JumpIfNotSmi(input, deferred->entry()); |
2631 // If smi, handle it directly. | 2633 // If smi, handle it directly. |
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3688 | 3690 |
3689 | 3691 |
3690 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 3692 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
3691 Abort("DoOsrEntry unimplemented."); | 3693 Abort("DoOsrEntry unimplemented."); |
3692 } | 3694 } |
3693 | 3695 |
3694 | 3696 |
3695 #undef __ | 3697 #undef __ |
3696 | 3698 |
3697 } } // namespace v8::internal | 3699 } } // namespace v8::internal |
OLD | NEW |