| 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 |