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

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

Issue 6391004: ARM: Add multiplication 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 2416 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 2427
2428 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), 2428 OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
2429 "TypeRecordingBinaryOpStub_%s_%s_%s", 2429 "TypeRecordingBinaryOpStub_%s_%s_%s",
2430 op_name, 2430 op_name,
2431 overwrite_name, 2431 overwrite_name,
2432 TRBinaryOpIC::GetName(operands_type_)); 2432 TRBinaryOpIC::GetName(operands_type_));
2433 return name_; 2433 return name_;
2434 } 2434 }
2435 2435
2436 2436
2437 void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation( 2437 void TypeRecordingBinaryOpStub::GenerateSmiSmiOperation(
2438 MacroAssembler* masm) { 2438 MacroAssembler* masm) {
2439 Register left = r1; 2439 Register left = r1;
2440 Register right = r0; 2440 Register right = r0;
2441 Register scratch1 = r7;
2442 Register scratch2 = r9;
2441 2443
2442 ASSERT(right.is(r0)); 2444 ASSERT(right.is(r0));
2445 STATIC_ASSERT(kSmiTag == 0);
2443 2446
2447 Label not_smi_result;
2444 switch (op_) { 2448 switch (op_) {
2445 case Token::ADD: 2449 case Token::ADD:
2446 __ add(right, left, Operand(right), SetCC); // Add optimistically. 2450 __ add(right, left, Operand(right), SetCC); // Add optimistically.
2447 __ Ret(vc); 2451 __ Ret(vc);
2448 __ sub(right, right, Operand(left)); // Revert optimistic add. 2452 __ sub(right, right, Operand(left)); // Revert optimistic add.
2449 break; 2453 break;
2450 case Token::SUB: 2454 case Token::SUB:
2451 __ sub(right, left, Operand(right), SetCC); // Subtract optimistically. 2455 __ sub(right, left, Operand(right), SetCC); // Subtract optimistically.
2452 __ Ret(vc); 2456 __ Ret(vc);
2453 __ sub(right, left, Operand(right)); // Revert optimistic subtract. 2457 __ sub(right, left, Operand(right)); // Revert optimistic subtract.
2454 break; 2458 break;
2459 case Token::MUL:
2460 // Remove tag from one of the operands. This way the multiplication result
2461 // will be a smi if it fits the smi range.
2462 __ SmiUntag(ip, right);
2463 // Do multiplication
2464 // scratch1 = lower 32 bits of ip * left.
2465 // scratch2 = higher 32 bits of ip * left.
2466 __ smull(scratch1, scratch2, left, ip);
2467 // Check for overflowing the smi range - no overflow if higher 33 bits of
2468 // the result are identical.
2469 __ mov(ip, Operand(scratch1, ASR, 31));
2470 __ cmp(ip, Operand(scratch2));
2471 __ b(ne, &not_smi_result);
2472 // Go slow on zero result to handle -0.
2473 __ tst(scratch1, Operand(scratch1));
2474 __ mov(right, Operand(scratch1), LeaveCC, ne);
2475 __ Ret(ne);
2476 // We need -0 if we were multiplying a negative number with 0 to get 0.
2477 // We know one of them was zero.
2478 __ add(scratch2, right, Operand(left), SetCC);
2479 __ mov(right, Operand(Smi::FromInt(0)), LeaveCC, pl);
2480 __ Ret(pl); // Return smi 0 if the non-zero one was positive.
2481 // We fall through here if we multiplied a negative number with 0, because
2482 // that would mean we should produce -0.
2483 break;
2455 default: 2484 default:
2456 UNREACHABLE(); 2485 UNREACHABLE();
2457 } 2486 }
2487 __ bind(&not_smi_result);
2458 } 2488 }
2459 2489
2460 2490
2461 void TypeRecordingBinaryOpStub::GenerateVFPOperation( 2491 void TypeRecordingBinaryOpStub::GenerateVFPOperation(
2462 MacroAssembler* masm) { 2492 MacroAssembler* masm) {
2463 switch (op_) { 2493 switch (op_) {
2464 case Token::ADD: 2494 case Token::ADD:
2465 __ vadd(d5, d6, d7); 2495 __ vadd(d5, d6, d7);
2466 break; 2496 break;
2467 case Token::SUB: 2497 case Token::SUB:
2468 __ vsub(d5, d6, d7); 2498 __ vsub(d5, d6, d7);
2469 break; 2499 break;
2500 case Token::MUL:
2501 __ vmul(d5, d6, d7);
2502 break;
2470 default: 2503 default:
2471 UNREACHABLE(); 2504 UNREACHABLE();
2472 } 2505 }
2473 } 2506 }
2474 2507
2475 2508
2476 // Generate the smi code. If the operation on smis are successful this return is 2509 // Generate the smi code. If the operation on smis are successful this return is
2477 // generated. If the result is not a smi and heap number allocation is not 2510 // generated. If the result is not a smi and heap number allocation is not
2478 // requested the code falls through. If number allocation is requested but a 2511 // requested the code falls through. If number allocation is requested but a
2479 // heap number cannot be allocated the code jumps to the lable gc_required. 2512 // heap number cannot be allocated the code jumps to the lable gc_required.
2480 void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, 2513 void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
2481 Label* gc_required, 2514 Label* gc_required,
2482 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { 2515 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
2483 Label not_smis; 2516 Label not_smis;
2484 2517
2485 ASSERT(op_ == Token::ADD || op_ == Token::SUB); 2518 ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
2486 2519
2487 Register left = r1; 2520 Register left = r1;
2488 Register right = r0; 2521 Register right = r0;
2489 Register scratch1 = r7; 2522 Register scratch1 = r7;
2490 Register scratch2 = r9; 2523 Register scratch2 = r9;
2491 2524
2492 // Perform combined smi check on both operands. 2525 // Perform combined smi check on both operands.
2493 __ orr(scratch1, left, Operand(right)); 2526 __ orr(scratch1, left, Operand(right));
2494 STATIC_ASSERT(kSmiTag == 0); 2527 STATIC_ASSERT(kSmiTag == 0);
2495 __ tst(scratch1, Operand(kSmiTagMask)); 2528 __ tst(scratch1, Operand(kSmiTagMask));
2496 __ b(ne, &not_smis); 2529 __ b(ne, &not_smis);
2497 2530
2498 GenerateOptimisticSmiOperation(masm); 2531 GenerateSmiSmiOperation(masm);
2499 2532
2500 // If heap number results are possible generate the result in an allocated 2533 // If heap number results are possible generate the result in an allocated
2501 // heap number. 2534 // heap number.
2502 if (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) { 2535 if (allow_heapnumber_results == ALLOW_HEAPNUMBER_RESULTS) {
2503 FloatingPointHelper::Destination destination = 2536 FloatingPointHelper::Destination destination =
2504 CpuFeatures::IsSupported(VFP3) && Token::MOD != op_ ? 2537 CpuFeatures::IsSupported(VFP3) && Token::MOD != op_ ?
2505 FloatingPointHelper::kVFPRegisters : 2538 FloatingPointHelper::kVFPRegisters :
2506 FloatingPointHelper::kCoreRegisters; 2539 FloatingPointHelper::kCoreRegisters;
2507 2540
2508 Register heap_number_map = r6; 2541 Register heap_number_map = r6;
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2556 __ pop(pc); 2589 __ pop(pc);
2557 } 2590 }
2558 } 2591 }
2559 __ bind(&not_smis); 2592 __ bind(&not_smis);
2560 } 2593 }
2561 2594
2562 2595
2563 void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) { 2596 void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
2564 Label not_smis, call_runtime; 2597 Label not_smis, call_runtime;
2565 2598
2566 ASSERT(op_ == Token::ADD || op_ == Token::SUB); 2599 ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
2567 2600
2568 if (result_type_ == TRBinaryOpIC::UNINITIALIZED || 2601 if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
2569 result_type_ == TRBinaryOpIC::SMI) { 2602 result_type_ == TRBinaryOpIC::SMI) {
2570 // Only allow smi results. 2603 // Only allow smi results.
2571 GenerateSmiCode(masm, NULL, NO_HEAPNUMBER_RESULTS); 2604 GenerateSmiCode(masm, NULL, NO_HEAPNUMBER_RESULTS);
2572 } else { 2605 } else {
2573 // Allow heap number result and don't make a transition if a heap number 2606 // Allow heap number result and don't make a transition if a heap number
2574 // cannot be allocated. 2607 // cannot be allocated.
2575 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); 2608 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
2576 } 2609 }
(...skipping 11 matching lines...) Expand all
2588 ASSERT(operands_type_ == TRBinaryOpIC::STRING); 2621 ASSERT(operands_type_ == TRBinaryOpIC::STRING);
2589 ASSERT(op_ == Token::ADD); 2622 ASSERT(op_ == Token::ADD);
2590 // Try to add arguments as strings, otherwise, transition to the generic 2623 // Try to add arguments as strings, otherwise, transition to the generic
2591 // TRBinaryOpIC type. 2624 // TRBinaryOpIC type.
2592 GenerateAddStrings(masm); 2625 GenerateAddStrings(masm);
2593 GenerateTypeTransition(masm); 2626 GenerateTypeTransition(masm);
2594 } 2627 }
2595 2628
2596 2629
2597 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { 2630 void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
2598 ASSERT(op_ == Token::ADD || op_ == Token::SUB); 2631 ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::SUB);
2599 2632
2600 ASSERT(operands_type_ == TRBinaryOpIC::INT32); 2633 ASSERT(operands_type_ == TRBinaryOpIC::INT32);
2601 2634
2602 GenerateTypeTransition(masm); 2635 GenerateTypeTransition(masm);
2603 } 2636 }
2604 2637
2605 2638
2606 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { 2639 void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
2607 ASSERT(op_ == Token::ADD || op_ == Token::SUB); 2640 ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
2608 2641
2609 Register scratch1 = r7; 2642 Register scratch1 = r7;
2610 Register scratch2 = r9; 2643 Register scratch2 = r9;
2611 2644
2612 Label not_number, call_runtime; 2645 Label not_number, call_runtime;
2613 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER); 2646 ASSERT(operands_type_ == TRBinaryOpIC::HEAP_NUMBER);
2614 2647
2615 Register heap_number_map = r6; 2648 Register heap_number_map = r6;
2616 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex); 2649 __ LoadRoot(heap_number_map, Heap::kHeapNumberMapRootIndex);
2617 2650
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2677 2710
2678 __ bind(&not_number); 2711 __ bind(&not_number);
2679 GenerateTypeTransition(masm); 2712 GenerateTypeTransition(masm);
2680 2713
2681 __ bind(&call_runtime); 2714 __ bind(&call_runtime);
2682 GenerateCallRuntime(masm); 2715 GenerateCallRuntime(masm);
2683 } 2716 }
2684 2717
2685 2718
2686 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { 2719 void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
2687 ASSERT(op_ == Token::ADD || op_ == Token::SUB); 2720 ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
2688 2721
2689 Label call_runtime; 2722 Label call_runtime;
2690 2723
2691 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS); 2724 GenerateSmiCode(masm, &call_runtime, ALLOW_HEAPNUMBER_RESULTS);
2692 2725
2693 // If all else fails, use the runtime system to get the correct 2726 // If all else fails, use the runtime system to get the correct
2694 // result. 2727 // result.
2695 __ bind(&call_runtime); 2728 __ bind(&call_runtime);
2696 2729
2697 // Try to add strings before calling runtime. 2730 // Try to add strings before calling runtime.
(...skipping 2962 matching lines...) Expand 10 before | Expand all | Expand 10 after
5660 __ pop(r1); 5693 __ pop(r1);
5661 __ Jump(r2); 5694 __ Jump(r2);
5662 } 5695 }
5663 5696
5664 5697
5665 #undef __ 5698 #undef __
5666 5699
5667 } } // namespace v8::internal 5700 } } // namespace v8::internal
5668 5701
5669 #endif // V8_TARGET_ARCH_ARM 5702 #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