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

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
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 1165 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698