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

Side by Side Diff: src/arm/code-stubs-arm.cc

Issue 6324013: ARM: Add subtract to the type recording binary operation stub. (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/code-stubs-arm.h ('k') | src/arm/full-codegen-arm.cc » ('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 2415 matching lines...) Expand 10 before | Expand all | Expand 10 after
2426 2426
2427 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), 2427 OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
2428 "TypeRecordingBinaryOpStub_%s_%s_%s", 2428 "TypeRecordingBinaryOpStub_%s_%s_%s",
2429 op_name, 2429 op_name,
2430 overwrite_name, 2430 overwrite_name,
2431 TRBinaryOpIC::GetName(operands_type_)); 2431 TRBinaryOpIC::GetName(operands_type_));
2432 return name_; 2432 return name_;
2433 } 2433 }
2434 2434
2435 2435
2436 void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation(
2437 MacroAssembler* masm) {
2438 Register left = r1;
2439 Register right = r0;
2440
2441 ASSERT(right.is(r0));
2442
2443 switch (op_) {
2444 case Token::ADD:
2445 __ add(right, left, Operand(right), SetCC); // Add optimistically.
2446 __ Ret(vc);
2447 __ sub(right, right, Operand(left)); // Revert optimistic add.
2448 break;
2449 case Token::SUB:
2450 __ sub(right, left, Operand(right), SetCC); // Subtract optimistically.
2451 __ Ret(vc);
2452 __ sub(right, left, Operand(right)); // Revert optimistic subtract.
Alexandre 2011/01/25 16:51:15 Shouldn't it be an add(right, right, Operand(left)
Alexandre 2011/01/25 16:54:45 Sorry I messed up with these right and left. On 20
2453 break;
2454 default:
2455 UNREACHABLE();
2456 }
2457 }
2458
2459
2460 void TypeRecordingBinaryOpStub::GenerateVFPOperation(
2461 MacroAssembler* masm) {
2462 switch (op_) {
2463 case Token::ADD:
2464 __ vadd(d5, d6, d7);
2465 break;
2466 case Token::SUB:
2467 __ vsub(d5, d6, d7);
2468 break;
2469 default:
2470 UNREACHABLE();
2471 }
2472
2473 }
2474
2475
2436 // Generate the smi code. If the operation on smis are successful this return is 2476 // Generate the smi code. If the operation on smis are successful this return is
2437 // generated. If the result is not a smi and heap number allocation is not 2477 // generated. If the result is not a smi and heap number allocation is not
2438 // requested the code falls through. If number allocation is requested but a 2478 // requested the code falls through. If number allocation is requested but a
2439 // heap number cannot be allocated the code jumps to the lable gc_required. 2479 // heap number cannot be allocated the code jumps to the lable gc_required.
2440 void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, 2480 void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
2441 Label* gc_required, 2481 Label* gc_required,
2442 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { 2482 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
2443 Label not_smis; 2483 Label not_smis;
2444 2484
2445 ASSERT(op_ == Token::ADD); 2485 ASSERT(op_ == Token::ADD || op_ == Token::SUB);
2446 2486
2447 Register left = r1; 2487 Register left = r1;
2448 Register right = r0; 2488 Register right = r0;
2449 Register scratch1 = r7; 2489 Register scratch1 = r7;
2450 Register scratch2 = r9; 2490 Register scratch2 = r9;
2451 2491
2452 // Perform combined smi check on both operands. 2492 // Perform combined smi check on both operands.
2453 __ orr(scratch1, left, Operand(right)); 2493 __ orr(scratch1, left, Operand(right));
2454 STATIC_ASSERT(kSmiTag == 0); 2494 STATIC_ASSERT(kSmiTag == 0);
2455 __ tst(scratch1, Operand(kSmiTagMask)); 2495 __ tst(scratch1, Operand(kSmiTagMask));
2456 __ b(ne, &not_smis); 2496 __ b(ne, &not_smis);
2457 2497
2458 __ add(right, right, Operand(left), SetCC); // Add optimistically. 2498 GenerateOptimisticSmiOperation(masm);
2459
2460 // Return smi result if no overflow (r0 is the result).
2461 ASSERT(right.is(r0));
2462 __ Ret(vc);
2463
2464 // Result is not a smi. Revert the optimistic add.
2465 __ sub(right, right, Operand(left));
2466 2499
2467 // If heap number results are possible generate the result in an allocated 2500 // If heap number results are possible generate the result in an allocated
2468 // heap number. 2501 // heap number.
2469 if (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) { 2502 if (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) {
2470 FloatingPointHelper::Destination destination = 2503 FloatingPointHelper::Destination destination =
2471 CpuFeatures::IsSupported(VFP3) && Token::MOD != op_ ? 2504 CpuFeatures::IsSupported(VFP3) && Token::MOD != op_ ?
2472 FloatingPointHelper::kVFPRegisters : 2505 FloatingPointHelper::kVFPRegisters :
2473 FloatingPointHelper::kCoreRegisters; 2506 FloatingPointHelper::kCoreRegisters;
2474 2507
2475 Register heap_number_map = r6; 2508 Register heap_number_map = r6;
2476 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); 2509 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
2477 2510
2478 // Allocate new heap number for result. 2511 // Allocate new heap number for result.
2479 Register heap_number = r5; 2512 Register heap_number = r5;
2480 __ AllocateHeapNumber( 2513 __ AllocateHeapNumber(
2481 heap_number, scratch1, scratch2, heap_number_map, gc_required); 2514 heap_number, scratch1, scratch2, heap_number_map, gc_required);
2482 2515
2483 // Load the smis. 2516 // Load the smis.
2484 FloatingPointHelper::LoadSmis(masm, destination, scratch1, scratch2); 2517 FloatingPointHelper::LoadSmis(masm, destination, scratch1, scratch2);
2485 2518
2486 // Calculate the result. 2519 // Calculate the result.
2487 if (destination == FloatingPointHelper::kVFPRegisters) { 2520 if (destination == FloatingPointHelper::kVFPRegisters) {
2488 // Using VFP registers: 2521 // Using VFP registers:
2489 // d6: Left value 2522 // d6: Left value
2490 // d7: Right value 2523 // d7: Right value
2491 CpuFeatures::Scope scope(VFP3); 2524 CpuFeatures::Scope scope(VFP3);
2492 __ vadd(d5, d6, d7); 2525 GenerateVFPOperation(masm);
2493 2526
2494 __ sub(r0, heap_number, Operand(kHeapObjectTag)); 2527 __ sub(r0, heap_number, Operand(kHeapObjectTag));
2495 __ vstr(d5, r0, HeapNumber::kValueOffset); 2528 __ vstr(d5, r0, HeapNumber::kValueOffset);
2496 __ add(r0, r0, Operand(kHeapObjectTag)); 2529 __ add(r0, r0, Operand(kHeapObjectTag));
2497 __ Ret(); 2530 __ Ret();
2498 } else { 2531 } else {
2499 // Using core registers: 2532 // Using core registers:
2500 // r0: Left value (least significant part of mantissa). 2533 // r0: Left value (least significant part of mantissa).
2501 // r1: Left value (sign, exponent, top of mantissa). 2534 // r1: Left value (sign, exponent, top of mantissa).
2502 // r2: Right value (least significant part of mantissa). 2535 // r2: Right value (least significant part of mantissa).
(...skipping 20 matching lines...) Expand all
2523 __ pop(pc); 2556 __ pop(pc);
2524 } 2557 }
2525 } 2558 }
2526 __ bind(&not_smis); 2559 __ bind(&not_smis);
2527 } 2560 }
2528 2561
2529 2562
2530 void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) { 2563 void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
2531 Label not_smis, call_runtime; 2564 Label not_smis, call_runtime;
2532 2565
2533 ASSERT(op_ == Token::ADD); 2566 ASSERT(op_ == Token::ADD || op_ == Token::SUB);
2534 2567
2535 if (result_type_ == TRBinaryOpIC::UNINITIALIZED || 2568 if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
2536 result_type_ == TRBinaryOpIC::SMI) { 2569 result_type_ == TRBinaryOpIC::SMI) {
2537 // Only allow smi results. 2570 // Only allow smi results.
2538 GenerateSmiCode(masm, NULL, NO_HEAPNUMBER_RESULTS); 2571 GenerateSmiCode(masm, NULL, NO_HEAPNUMBER_RESULTS);
2539 } else { 2572 } else {
2540 // Allow heap number result and don't make a transition if a heap number 2573 // Allow heap number result and don't make a transition if a heap number
2541 // cannot be allocated. 2574 // cannot be allocated.
2542 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); 2575 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
2543 } 2576 }
(...skipping 11 matching lines...) Expand all
2555 ASSERT(operands_type_ == TRBinaryOpIC::STRING); 2588 ASSERT(operands_type_ == TRBinaryOpIC::STRING);
2556 ASSERT(op_ == Token::ADD); 2589 ASSERT(op_ == Token::ADD);
2557 // Try to add arguments as strings, otherwise, transition to the generic 2590 // Try to add arguments as strings, otherwise, transition to the generic
2558 // TRBinaryOpIC type. 2591 // TRBinaryOpIC type.
2559 GenerateAddStrings(masm); 2592 GenerateAddStrings(masm);
2560 GenerateTypeTransition(masm); 2593 GenerateTypeTransition(masm);
2561 } 2594 }
2562 2595
2563 2596
2564 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { 2597 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
2565 ASSERT(op_ == Token::ADD); 2598 ASSERT(op_ == Token::ADD || op_ == Token::SUB);
2566 2599
2567 ASSERT(operands_type_ == TRBinaryOpIC::INT32); 2600 ASSERT(operands_type_ == TRBinaryOpIC::INT32);
2568 2601
2569 GenerateTypeTransition(masm); 2602 GenerateTypeTransition(masm);
2570 } 2603 }
2571 2604
2572 2605
2573 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { 2606 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
2574 ASSERT(op_ == Token::ADD); 2607 ASSERT(op_ == Token::ADD || op_ == Token::SUB);
2575 2608
2576 Register scratch1 = r7; 2609 Register scratch1 = r7;
2577 Register scratch2 = r9; 2610 Register scratch2 = r9;
2578 2611
2579 Label not_number, call_runtime; 2612 Label not_number, call_runtime;
2580 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); 2613 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER);
2581 2614
2582 Register heap_number_map = r6; 2615 Register heap_number_map = r6;
2583 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); 2616 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
2584 2617
2585 // Load left and right operands into d6 and d7 or r0/r1 and r2/r3 depending on 2618 // Load left and right operands into d6 and d7 or r0/r1 and r2/r3 depending on
2586 // whether VFP3 is available. 2619 // whether VFP3 is available.
2587 FloatingPointHelper::Destination destination = 2620 FloatingPointHelper::Destination destination =
2588 CpuFeatures::IsSupported(VFP3) ? 2621 CpuFeatures::IsSupported(VFP3) ?
2589 FloatingPointHelper::kVFPRegisters : 2622 FloatingPointHelper::kVFPRegisters :
2590 FloatingPointHelper::kCoreRegisters; 2623 FloatingPointHelper::kCoreRegisters;
2591 FloatingPointHelper::LoadOperands(masm, 2624 FloatingPointHelper::LoadOperands(masm,
2592 destination, 2625 destination,
2593 heap_number_map, 2626 heap_number_map,
2594 scratch1, 2627 scratch1,
2595 scratch2, 2628 scratch2,
2596 &not_number); 2629 &not_number);
2597 if (destination == FloatingPointHelper::kVFPRegisters) { 2630 if (destination == FloatingPointHelper::kVFPRegisters) {
2598 // Use floating point instructions for the binary operation. 2631 // Use floating point instructions for the binary operation.
2599 CpuFeatures::Scope scope(VFP3); 2632 CpuFeatures::Scope scope(VFP3);
2600 __ vadd(d5, d6, d7); 2633 GenerateVFPOperation(masm);
2601 2634
2602 // Get a heap number object for the result - might be left or right if one 2635 // Get a heap number object for the result - might be left or right if one
2603 // of these are overwritable. 2636 // of these are overwritable.
2604 GenerateHeapResultAllocation( 2637 GenerateHeapResultAllocation(
2605 masm, r4, heap_number_map, scratch1, scratch2, &call_runtime); 2638 masm, r4, heap_number_map, scratch1, scratch2, &call_runtime);
2606 2639
2607 // Fill the result into the allocated heap number and return. 2640 // Fill the result into the allocated heap number and return.
2608 __ sub(r0, r4, Operand(kHeapObjectTag)); 2641 __ sub(r0, r4, Operand(kHeapObjectTag));
2609 __ vstr(d5, r0, HeapNumber::kValueOffset); 2642 __ vstr(d5, r0, HeapNumber::kValueOffset);
2610 __ add(r0, r0, Operand(kHeapObjectTag)); 2643 __ add(r0, r0, Operand(kHeapObjectTag));
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2644 2677
2645 __ bind(&not_number); 2678 __ bind(&not_number);
2646 GenerateTypeTransition(masm); 2679 GenerateTypeTransition(masm);
2647 2680
2648 __ bind(&call_runtime); 2681 __ bind(&call_runtime);
2649 GenerateCallRuntime(masm); 2682 GenerateCallRuntime(masm);
2650 } 2683 }
2651 2684
2652 2685
2653 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { 2686 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
2654 ASSERT(op_ == Token::ADD); 2687 ASSERT(op_ == Token::ADD || op_ == Token::SUB);
2655 2688
2656 Label call_runtime; 2689 Label call_runtime;
2657 2690
2658 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); 2691 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
2659 2692
2660 // If all else fails, use the runtime system to get the correct 2693 // If all else fails, use the runtime system to get the correct
2661 // result. 2694 // result.
2662 __ bind(&call_runtime); 2695 __ bind(&call_runtime);
2663 2696
2664 // Try to add strings before calling runtime. 2697 // Try to add strings before calling runtime.
(...skipping 23 matching lines...) Expand all
2688 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB); 2721 StringAddStub string_add_stub(NO_STRING_CHECK_IN_STUB);
2689 GenerateRegisterArgsPush(masm); 2722 GenerateRegisterArgsPush(masm);
2690 __ TailCallStub(&string_add_stub); 2723 __ TailCallStub(&string_add_stub);
2691 2724
2692 // At least one argument is not a string. 2725 // At least one argument is not a string.
2693 __ bind(&call_runtime); 2726 __ bind(&call_runtime);
2694 } 2727 }
2695 2728
2696 2729
2697 void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) { 2730 void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
2731 GenerateRegisterArgsPush(masm);
2698 switch (op_) { 2732 switch (op_) {
2699 case Token::ADD: 2733 case Token::ADD:
2700 GenerateRegisterArgsPush(masm);
2701 __ InvokeBuiltin(Builtins::ADD, JUMP_JS); 2734 __ InvokeBuiltin(Builtins::ADD, JUMP_JS);
2702 break; 2735 break;
2736 case Token::SUB:
2737 __ InvokeBuiltin(Builtins::SUB, JUMP_JS);
2738 break;
2703 default: 2739 default:
2704 UNREACHABLE(); 2740 UNREACHABLE();
2705 } 2741 }
2706 } 2742 }
2707 2743
2708 2744
2709 void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation( 2745 void TypeRecordingBinaryOpStub::GenerateHeapResultAllocation(
2710 MacroAssembler* masm, 2746 MacroAssembler* masm,
2711 Register result, 2747 Register result,
2712 Register heap_number_map, 2748 Register heap_number_map,
(...skipping 2907 matching lines...) Expand 10 before | Expand all | Expand 10 after
5620 __ pop(r1); 5656 __ pop(r1);
5621 __ Jump(r2); 5657 __ Jump(r2);
5622 } 5658 }
5623 5659
5624 5660
5625 #undef __ 5661 #undef __
5626 5662
5627 } } // namespace v8::internal 5663 } } // namespace v8::internal
5628 5664
5629 #endif // V8_TARGET_ARCH_ARM 5665 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « src/arm/code-stubs-arm.h ('k') | src/arm/full-codegen-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698