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 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1176 Register left = ToRegister(instr->InputAt(0)); | 1176 Register left = ToRegister(instr->InputAt(0)); |
1177 Register right = ToRegister(instr->InputAt(1)); | 1177 Register right = ToRegister(instr->InputAt(1)); |
1178 | 1178 |
1179 __ PushSafepointRegistersAndDoubles(); | 1179 __ PushSafepointRegistersAndDoubles(); |
1180 GenericBinaryOpStub stub(op, OVERWRITE_LEFT, left, right); | 1180 GenericBinaryOpStub stub(op, OVERWRITE_LEFT, left, right); |
1181 __ CallStub(&stub); | 1181 __ CallStub(&stub); |
1182 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), | 1182 RecordSafepointWithRegistersAndDoubles(instr->pointer_map(), |
1183 0, | 1183 0, |
1184 Safepoint::kNoDeoptimizationIndex); | 1184 Safepoint::kNoDeoptimizationIndex); |
1185 // Overwrite the stored value of r0 with the result of the stub. | 1185 // Overwrite the stored value of r0 with the result of the stub. |
1186 __ str(r0, MemOperand(sp, DwVfpRegister::kNumAllocatableRegisters * | 1186 __ StoreToSafepointRegistersAndDoublesSlot(r0); |
1187 kDoubleSize)); | |
1188 __ PopSafepointRegistersAndDoubles(); | 1187 __ PopSafepointRegistersAndDoubles(); |
1189 } | 1188 } |
1190 | 1189 |
1191 | 1190 |
1192 void LCodeGen::DoMulI(LMulI* instr) { | 1191 void LCodeGen::DoMulI(LMulI* instr) { |
1193 Register scratch = scratch0(); | 1192 Register scratch = scratch0(); |
1194 Register left = ToRegister(instr->InputAt(0)); | 1193 Register left = ToRegister(instr->InputAt(0)); |
1195 Register right = EmitLoadRegister(instr->InputAt(1), scratch); | 1194 Register right = EmitLoadRegister(instr->InputAt(1), scratch); |
1196 | 1195 |
1197 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && | 1196 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero) && |
(...skipping 1302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2500 | 2499 |
2501 | 2500 |
2502 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { | 2501 void LCodeGen::DoCallConstantFunction(LCallConstantFunction* instr) { |
2503 ASSERT(ToRegister(instr->result()).is(r0)); | 2502 ASSERT(ToRegister(instr->result()).is(r0)); |
2504 __ mov(r1, Operand(instr->function())); | 2503 __ mov(r1, Operand(instr->function())); |
2505 CallKnownFunction(instr->function(), instr->arity(), instr); | 2504 CallKnownFunction(instr->function(), instr->arity(), instr); |
2506 } | 2505 } |
2507 | 2506 |
2508 | 2507 |
2509 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { | 2508 void LCodeGen::DoDeferredMathAbsTaggedHeapNumber(LUnaryMathOperation* instr) { |
2509 ASSERT(instr->InputAt(0)->Equals(instr->result())); | |
2510 Register input = ToRegister(instr->InputAt(0)); | 2510 Register input = ToRegister(instr->InputAt(0)); |
2511 Register scratch = scratch0(); | 2511 Register scratch = scratch0(); |
2512 | 2512 |
2513 // Deoptimize if not a heap number. | 2513 // Deoptimize if not a heap number. |
2514 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); | 2514 __ ldr(scratch, FieldMemOperand(input, HeapObject::kMapOffset)); |
2515 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); | 2515 __ LoadRoot(ip, Heap::kHeapNumberMapRootIndex); |
2516 __ cmp(scratch, Operand(ip)); | 2516 __ cmp(scratch, Operand(ip)); |
2517 DeoptimizeIf(ne, instr->environment()); | 2517 DeoptimizeIf(ne, instr->environment()); |
2518 | 2518 |
2519 Label done; | 2519 Label done; |
2520 | 2520 Register exponent = scratch0(); |
2521 Label negative; | 2521 scratch = no_reg; |
2522 __ ldr(scratch, FieldMemOperand(input, HeapNumber::kExponentOffset)); | 2522 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); |
2523 // Check the sign of the argument. If the argument is positive, just | 2523 // Check the sign of the argument. If the argument is positive, just |
2524 // return it. We do not need to patch the stack since |input| and | 2524 // return it. We do not need to patch the stack since |input| and |
2525 // |result| are the same register and |input| will be restored | 2525 // |result| are the same register and |input| would be restored |
2526 // unchanged by popping safepoint registers. | 2526 // unchanged by popping safepoint registers. |
2527 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 2527 __ tst(exponent, Operand(HeapNumber::kSignMask)); |
2528 __ b(ne, &negative); | 2528 __ b(eq, &done); |
2529 __ jmp(&done); | |
2530 | 2529 |
2531 __ bind(&negative); | 2530 // Input is negative. Reverse its sign. |
2532 // Preserve the value of all registers. | 2531 // Preserve the value of all registers. |
2533 __ PushSafepointRegisters(); | 2532 __ PushSafepointRegisters(); |
2534 | 2533 |
2535 Register tmp = input.is(r0) ? r1 : r0; | 2534 // Registers were saved at the safepoint, so we can use |
2535 // many scratch registers. | |
2536 Register tmp1 = input.is(r0) ? r1 : r0; | |
Mads Ager (chromium)
2011/01/27 08:27:56
Kevin had a nicer suggestion for these. We intend
Alexandre
2011/01/28 13:57:59
I like that! Done.
On 2011/01/27 08:27:56, Mads Ag
| |
2536 Register tmp2 = input.is(r2) ? r3 : r2; | 2537 Register tmp2 = input.is(r2) ? r3 : r2; |
2537 Register tmp3 = input.is(r4) ? r5 : r4; | 2538 Register tmp3 = input.is(r4) ? r5 : r4; |
2539 Register tmp4 = input.is(r6) ? r7 : r6; | |
2540 | |
2541 // exponent: floating point exponent value. | |
2538 | 2542 |
2539 Label allocated, slow; | 2543 Label allocated, slow; |
2540 __ LoadRoot(scratch, Heap::kHeapNumberMapRootIndex); | 2544 __ LoadRoot(tmp4, Heap::kHeapNumberMapRootIndex); |
2541 __ AllocateHeapNumber(tmp, tmp2, tmp3, scratch, &slow); | 2545 __ AllocateHeapNumber(tmp1, tmp2, tmp3, tmp4, &slow); |
2542 __ b(&allocated); | 2546 __ b(&allocated); |
2543 | 2547 |
2544 // Slow case: Call the runtime system to do the number allocation. | 2548 // Slow case: Call the runtime system to do the number allocation. |
2545 __ bind(&slow); | 2549 __ bind(&slow); |
2546 | 2550 |
2547 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 2551 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
2548 RecordSafepointWithRegisters( | 2552 RecordSafepointWithRegisters( |
2549 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); | 2553 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex); |
2550 // Set the pointer to the new heap number in tmp. | 2554 // Set the pointer to the new heap number in tmp. |
2551 if (!tmp.is(r0)) __ mov(tmp, Operand(r0)); | 2555 if (!tmp1.is(r0)) __ mov(tmp1, Operand(r0)); |
2552 | |
2553 // Restore input_reg after call to runtime. | 2556 // Restore input_reg after call to runtime. |
2554 MemOperand input_register_slot = masm()->SafepointRegisterSlot(input); | 2557 __ LoadFromSafepointRegisterSlot(input); |
2555 __ ldr(input, input_register_slot); | 2558 __ ldr(exponent, FieldMemOperand(input, HeapNumber::kExponentOffset)); |
2556 | 2559 |
2557 __ bind(&allocated); | 2560 __ bind(&allocated); |
2558 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kExponentOffset)); | 2561 // exponent: floating point exponent value. |
2559 __ bic(tmp2, tmp2, Operand(HeapNumber::kSignMask)); | 2562 // tmp1: allocated heap number. |
2560 __ str(tmp2, FieldMemOperand(tmp, HeapNumber::kExponentOffset)); | 2563 __ bic(exponent, exponent, Operand(HeapNumber::kSignMask)); |
2564 __ str(exponent, FieldMemOperand(tmp1, HeapNumber::kExponentOffset)); | |
2561 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); | 2565 __ ldr(tmp2, FieldMemOperand(input, HeapNumber::kMantissaOffset)); |
2562 __ str(tmp2, FieldMemOperand(tmp, HeapNumber::kMantissaOffset)); | 2566 __ str(tmp2, FieldMemOperand(tmp1, HeapNumber::kMantissaOffset)); |
2563 | 2567 |
2564 __ str(tmp, input_register_slot); | 2568 __ str(tmp1, masm()->SafepointRegisterSlot(input)); |
2565 __ PopSafepointRegisters(); | 2569 __ PopSafepointRegisters(); |
2566 | 2570 |
2567 __ bind(&done); | 2571 __ bind(&done); |
2568 } | 2572 } |
2569 | 2573 |
2570 | 2574 |
2571 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { | 2575 void LCodeGen::EmitIntegerMathAbs(LUnaryMathOperation* instr) { |
2572 Label is_positive; | |
2573 uint32_t kSignMask = 0x80000000u; | |
2574 Register input = ToRegister(instr->InputAt(0)); | 2576 Register input = ToRegister(instr->InputAt(0)); |
2575 __ tst(input, Operand(kSignMask)); | 2577 __ cmp(input, Operand(0)); |
2576 __ b(eq, &is_positive); | 2578 // We can make rsb conditional because the previous cmp instruction |
2577 __ rsb(input, input, Operand(0), SetCC); | 2579 // will clear the V (overflow) flag and rsb won't set this flag |
2580 // if input is positive. | |
2581 __ rsb(input, input, Operand(0), SetCC, mi); | |
2578 // Deoptimize on overflow. | 2582 // Deoptimize on overflow. |
2579 DeoptimizeIf(vs, instr->environment()); | 2583 DeoptimizeIf(vs, instr->environment()); |
2580 __ bind(&is_positive); | |
2581 } | 2584 } |
2582 | 2585 |
2583 | 2586 |
2584 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { | 2587 void LCodeGen::DoMathAbs(LUnaryMathOperation* instr) { |
2585 // Class for deferred case. | 2588 // Class for deferred case. |
2586 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { | 2589 class DeferredMathAbsTaggedHeapNumber: public LDeferredCode { |
2587 public: | 2590 public: |
2588 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, | 2591 DeferredMathAbsTaggedHeapNumber(LCodeGen* codegen, |
2589 LUnaryMathOperation* instr) | 2592 LUnaryMathOperation* instr) |
2590 : LDeferredCode(codegen), instr_(instr) { } | 2593 : LDeferredCode(codegen), instr_(instr) { } |
2591 virtual void Generate() { | 2594 virtual void Generate() { |
2592 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); | 2595 codegen()->DoDeferredMathAbsTaggedHeapNumber(instr_); |
2593 } | 2596 } |
2594 private: | 2597 private: |
2595 LUnaryMathOperation* instr_; | 2598 LUnaryMathOperation* instr_; |
2596 }; | 2599 }; |
2597 | 2600 |
2598 ASSERT(instr->InputAt(0)->Equals(instr->result())); | 2601 ASSERT(instr->InputAt(0)->Equals(instr->result())); |
2599 Representation r = instr->hydrogen()->value()->representation(); | 2602 Representation r = instr->hydrogen()->value()->representation(); |
2600 if (r.IsDouble()) { | 2603 if (r.IsDouble()) { |
2601 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); | 2604 DwVfpRegister input = ToDoubleRegister(instr->InputAt(0)); |
2602 // __ vabs(input, input); | 2605 __ vabs(input, input); |
2603 Abort("Double DoMathAbs unimplemented"); | |
2604 } else if (r.IsInteger32()) { | 2606 } else if (r.IsInteger32()) { |
2605 EmitIntegerMathAbs(instr); | 2607 EmitIntegerMathAbs(instr); |
2606 } else { | 2608 } else { |
2607 // Representation is tagged. | 2609 // Representation is tagged. |
2608 DeferredMathAbsTaggedHeapNumber* deferred = | 2610 DeferredMathAbsTaggedHeapNumber* deferred = |
2609 new DeferredMathAbsTaggedHeapNumber(this, instr); | 2611 new DeferredMathAbsTaggedHeapNumber(this, instr); |
2610 Register input = ToRegister(instr->InputAt(0)); | 2612 Register input = ToRegister(instr->InputAt(0)); |
2611 // Smi check. | 2613 // Smi check. |
2612 __ JumpIfNotSmi(input, deferred->entry()); | 2614 __ JumpIfNotSmi(input, deferred->entry()); |
2613 // If smi, handle it directly. | 2615 // If smi, handle it directly. |
(...skipping 1056 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3670 | 3672 |
3671 | 3673 |
3672 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { | 3674 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { |
3673 Abort("DoOsrEntry unimplemented."); | 3675 Abort("DoOsrEntry unimplemented."); |
3674 } | 3676 } |
3675 | 3677 |
3676 | 3678 |
3677 #undef __ | 3679 #undef __ |
3678 | 3680 |
3679 } } // namespace v8::internal | 3681 } } // namespace v8::internal |
OLD | NEW |