Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: src/arm/lithium-codegen-arm.cc

Issue 6366016: ARM: Add support for DoMathAbs with double inputs.... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/arm/disasm-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « src/arm/disasm-arm.cc ('k') | src/arm/macro-assembler-arm.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698