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

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

Issue 11316105: ARM: Use division instructions in lithium and stubs (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 8 years 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 | « no previous file | src/arm/lithium-arm.cc » ('j') | src/arm/lithium-codegen-arm.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2412 matching lines...) Expand 10 before | Expand all | Expand 10 after
2423 __ mov(right, Operand(scratch1), LeaveCC, ne); 2423 __ mov(right, Operand(scratch1), LeaveCC, ne);
2424 __ Ret(ne); 2424 __ Ret(ne);
2425 // We need -0 if we were multiplying a negative number with 0 to get 0. 2425 // We need -0 if we were multiplying a negative number with 0 to get 0.
2426 // We know one of them was zero. 2426 // We know one of them was zero.
2427 __ add(scratch2, right, Operand(left), SetCC); 2427 __ add(scratch2, right, Operand(left), SetCC);
2428 __ mov(right, Operand(Smi::FromInt(0)), LeaveCC, pl); 2428 __ mov(right, Operand(Smi::FromInt(0)), LeaveCC, pl);
2429 __ Ret(pl); // Return smi 0 if the non-zero one was positive. 2429 __ Ret(pl); // Return smi 0 if the non-zero one was positive.
2430 // We fall through here if we multiplied a negative number with 0, because 2430 // We fall through here if we multiplied a negative number with 0, because
2431 // that would mean we should produce -0. 2431 // that would mean we should produce -0.
2432 break; 2432 break;
2433 case Token::DIV: 2433 case Token::DIV: {
2434 Label div_with_sdiv;
2435
2436 // Check for 0 divisor.
2437 __ cmp(right, Operand(0));
2438 __ b(eq, &not_smi_result);
2439
2434 // Check for power of two on the right hand side. 2440 // Check for power of two on the right hand side.
2435 __ JumpIfNotPowerOfTwoOrZero(right, scratch1, &not_smi_result); 2441 __ sub(scratch1, right, Operand(1));
2436 // Check for positive and no remainder (scratch1 contains right - 1). 2442 __ tst(scratch1, right);
2437 __ orr(scratch2, scratch1, Operand(0x80000000u)); 2443 if (CpuFeatures::IsSupported(SUDIV)) {
2438 __ tst(left, scratch2); 2444 __ b(ne, &div_with_sdiv);
2439 __ b(ne, &not_smi_result); 2445 // Check for no remainder.
2446 __ tst(left, scratch1);
2447 __ b(ne, &not_smi_result);
2448 // Check for positive left hand side.
2449 __ cmp(left, Operand(0));
2450 __ b(mi, &div_with_sdiv);
2451 } else {
2452 __ b(ne, &not_smi_result);
2453 // Check for positive and no remainder.
2454 __ orr(scratch2, scratch1, Operand(0x80000000u));
2455 __ tst(left, scratch2);
2456 __ b(ne, &not_smi_result);
2457 }
2440 2458
2441 // Perform division by shifting. 2459 // Perform division by shifting.
2442 __ CountLeadingZeros(scratch1, scratch1, scratch2); 2460 __ CountLeadingZeros(scratch1, scratch1, scratch2);
2443 __ rsb(scratch1, scratch1, Operand(31)); 2461 __ rsb(scratch1, scratch1, Operand(31));
2444 __ mov(right, Operand(left, LSR, scratch1)); 2462 __ mov(right, Operand(left, LSR, scratch1));
2445 __ Ret(); 2463 __ Ret();
2464
2465 if (CpuFeatures::IsSupported(SUDIV)) {
2466 Label result_not_zero;
2467
2468 __ bind(&div_with_sdiv);
2469 // Do division.
2470 __ sdiv(scratch1, left, right);
2471 // Check that the remainder is zero.
2472 __ mls(scratch2, scratch1, right, left);
2473 __ cmp(scratch2, Operand(0));
2474 __ b(ne, &not_smi_result);
2475 // Check for negative zero result.
2476 __ cmp(scratch1, Operand(0));
2477 __ b(ne, &result_not_zero);
2478 __ cmp(right, Operand(0));
2479 __ b(lt, &not_smi_result);
2480 __ bind(&result_not_zero);
2481 // Check for the corner case of dividing the most negative smi by -1.
2482 __ cmp(scratch1, Operand(0x40000000));
2483 __ b(eq, &not_smi_result);
2484 // Tag and return the result.
2485 __ SmiTag(right, scratch1);
2486 __ Ret();
2487 }
2446 break; 2488 break;
2447 case Token::MOD: 2489 }
2448 // Check for two positive smis. 2490 case Token::MOD: {
2449 __ orr(scratch1, left, Operand(right)); 2491 Label modulo_with_sdiv;
2450 __ tst(scratch1, Operand(0x80000000u | kSmiTagMask));
2451 __ b(ne, &not_smi_result);
2452 2492
2453 // Check for power of two on the right hand side. 2493 if (CpuFeatures::IsSupported(SUDIV)) {
2454 __ JumpIfNotPowerOfTwoOrZero(right, scratch1, &not_smi_result); 2494 // Check for x % 0.
2495 __ cmp(right, Operand(0));
2496 __ b(eq, &not_smi_result);
2455 2497
2456 // Perform modulus by masking. 2498 // Check for two positive smis.
2499 __ orr(scratch1, left, Operand(right));
2500 __ tst(scratch1, Operand(0x80000000u));
2501 __ b(ne, &modulo_with_sdiv);
2502
2503 // Check for power of two on the right hand side.
2504 __ sub(scratch1, right, Operand(1));
2505 __ tst(scratch1, right);
2506 __ b(ne, &modulo_with_sdiv);
2507 } else {
2508 // Check for two positive smis.
2509 __ orr(scratch1, left, Operand(right));
2510 __ tst(scratch1, Operand(0x80000000u));
2511 __ b(ne, &not_smi_result);
2512
2513 // Check for power of two on the right hand side.
2514 __ JumpIfNotPowerOfTwoOrZero(right, scratch1, &not_smi_result);
2515 }
2516
2517 // Perform modulus by masking (scratch1 contains right - 1).
2457 __ and_(right, left, Operand(scratch1)); 2518 __ and_(right, left, Operand(scratch1));
2458 __ Ret(); 2519 __ Ret();
2520
2521 if (CpuFeatures::IsSupported(SUDIV)) {
2522 __ bind(&modulo_with_sdiv);
2523 __ mov(scratch2, right);
2524 // Perform modulus with sdiv and mls.
2525 __ sdiv(scratch1, left, right);
2526 __ mls(right, scratch1, right, left);
2527 // Return if the result is not 0.
2528 __ cmp(right, Operand(0));
2529 __ Ret(ne);
2530 // The result is 0, check for -0 case.
2531 __ cmp(left, Operand(0));
2532 __ Ret(pl);
2533 // This is a -0 case, restore the value of right.
2534 __ mov(right, scratch2);
2535 // We fall through here to not_smi_result to produce -0.
2536 }
2459 break; 2537 break;
2538 }
2460 case Token::BIT_OR: 2539 case Token::BIT_OR:
2461 __ orr(right, left, Operand(right)); 2540 __ orr(right, left, Operand(right));
2462 __ Ret(); 2541 __ Ret();
2463 break; 2542 break;
2464 case Token::BIT_AND: 2543 case Token::BIT_AND:
2465 __ and_(right, left, Operand(right)); 2544 __ and_(right, left, Operand(right));
2466 __ Ret(); 2545 __ Ret();
2467 break; 2546 break;
2468 case Token::BIT_XOR: 2547 case Token::BIT_XOR:
2469 __ eor(right, left, Operand(right)); 2548 __ eor(right, left, Operand(right));
(...skipping 5134 matching lines...) Expand 10 before | Expand all | Expand 10 after
7604 7683
7605 __ Pop(lr, r5, r1); 7684 __ Pop(lr, r5, r1);
7606 __ Ret(); 7685 __ Ret();
7607 } 7686 }
7608 7687
7609 #undef __ 7688 #undef __
7610 7689
7611 } } // namespace v8::internal 7690 } } // namespace v8::internal
7612 7691
7613 #endif // V8_TARGET_ARCH_ARM 7692 #endif // V8_TARGET_ARCH_ARM
OLDNEW
« no previous file with comments | « no previous file | src/arm/lithium-arm.cc » ('j') | src/arm/lithium-codegen-arm.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698