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

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

Issue 25050002: MIPS: Improve integer multiplication. (Closed) Base URL: https://github.com/v8/v8.git@gbl
Patch Set: Fixed nits. Created 7 years, 2 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
« no previous file with comments | « no previous file | src/mips/lithium-mips.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 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 1385 matching lines...) Expand 10 before | Expand all | Expand 10 after
1396 } 1396 }
1397 1397
1398 1398
1399 void LCodeGen::DoMulI(LMulI* instr) { 1399 void LCodeGen::DoMulI(LMulI* instr) {
1400 Register scratch = scratch0(); 1400 Register scratch = scratch0();
1401 Register result = ToRegister(instr->result()); 1401 Register result = ToRegister(instr->result());
1402 // Note that result may alias left. 1402 // Note that result may alias left.
1403 Register left = ToRegister(instr->left()); 1403 Register left = ToRegister(instr->left());
1404 LOperand* right_op = instr->right(); 1404 LOperand* right_op = instr->right();
1405 1405
1406 bool can_overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1407 bool bailout_on_minus_zero = 1406 bool bailout_on_minus_zero =
1408 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero); 1407 instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero);
1408 bool overflow = instr->hydrogen()->CheckFlag(HValue::kCanOverflow);
1409 1409
1410 if (right_op->IsConstantOperand() && !can_overflow) { 1410 if (right_op->IsConstantOperand()) {
1411 int32_t constant = ToInteger32(LConstantOperand::cast(right_op)); 1411 int32_t constant = ToInteger32(LConstantOperand::cast(right_op));
1412 1412
1413 if (bailout_on_minus_zero && (constant < 0)) { 1413 if (bailout_on_minus_zero && (constant < 0)) {
1414 // The case of a null constant will be handled separately. 1414 // The case of a null constant will be handled separately.
1415 // If constant is negative and left is null, the result should be -0. 1415 // If constant is negative and left is null, the result should be -0.
1416 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg)); 1416 DeoptimizeIf(eq, instr->environment(), left, Operand(zero_reg));
1417 } 1417 }
1418 1418
1419 switch (constant) { 1419 switch (constant) {
1420 case -1: 1420 case -1:
1421 __ Subu(result, zero_reg, left); 1421 if (overflow) {
1422 __ SubuAndCheckForOverflow(result, zero_reg, left, scratch);
1423 DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
1424 } else {
1425 __ Subu(result, zero_reg, left);
1426 }
1422 break; 1427 break;
1423 case 0: 1428 case 0:
1424 if (bailout_on_minus_zero) { 1429 if (bailout_on_minus_zero) {
1425 // If left is strictly negative and the constant is null, the 1430 // If left is strictly negative and the constant is null, the
1426 // result is -0. Deoptimize if required, otherwise return 0. 1431 // result is -0. Deoptimize if required, otherwise return 0.
1427 DeoptimizeIf(lt, instr->environment(), left, Operand(zero_reg)); 1432 DeoptimizeIf(lt, instr->environment(), left, Operand(zero_reg));
1428 } 1433 }
1429 __ mov(result, zero_reg); 1434 __ mov(result, zero_reg);
1430 break; 1435 break;
1431 case 1: 1436 case 1:
1432 // Nothing to do. 1437 // Nothing to do.
1433 __ Move(result, left); 1438 __ Move(result, left);
1434 break; 1439 break;
1435 default: 1440 default:
1436 // Multiplying by powers of two and powers of two plus or minus 1441 // Multiplying by powers of two and powers of two plus or minus
1437 // one can be done faster with shifted operands. 1442 // one can be done faster with shifted operands.
1438 // For other constants we emit standard code. 1443 // For other constants we emit standard code.
1439 int32_t mask = constant >> 31; 1444 int32_t mask = constant >> 31;
1440 uint32_t constant_abs = (constant + mask) ^ mask; 1445 uint32_t constant_abs = (constant + mask) ^ mask;
1441 1446
1442 if (IsPowerOf2(constant_abs) || 1447 if (IsPowerOf2(constant_abs)) {
1443 IsPowerOf2(constant_abs - 1) || 1448 int32_t shift = WhichPowerOf2(constant_abs);
1444 IsPowerOf2(constant_abs + 1)) { 1449 __ sll(result, left, shift);
1445 if (IsPowerOf2(constant_abs)) { 1450 // Correct the sign of the result if the constant is negative.
1446 int32_t shift = WhichPowerOf2(constant_abs); 1451 if (constant < 0) __ Subu(result, zero_reg, result);
1447 __ sll(result, left, shift); 1452 } else if (IsPowerOf2(constant_abs - 1)) {
1448 } else if (IsPowerOf2(constant_abs - 1)) { 1453 int32_t shift = WhichPowerOf2(constant_abs - 1);
1449 int32_t shift = WhichPowerOf2(constant_abs - 1); 1454 __ sll(scratch, left, shift);
1450 __ sll(scratch, left, shift); 1455 __ Addu(result, scratch, left);
1451 __ Addu(result, scratch, left); 1456 // Correct the sign of the result if the constant is negative.
1452 } else if (IsPowerOf2(constant_abs + 1)) { 1457 if (constant < 0) __ Subu(result, zero_reg, result);
1453 int32_t shift = WhichPowerOf2(constant_abs + 1); 1458 } else if (IsPowerOf2(constant_abs + 1)) {
1454 __ sll(scratch, left, shift); 1459 int32_t shift = WhichPowerOf2(constant_abs + 1);
1455 __ Subu(result, scratch, left); 1460 __ sll(scratch, left, shift);
1456 } 1461 __ Subu(result, scratch, left);
1457 1462 // Correct the sign of the result if the constant is negative.
1458 // Correct the sign of the result is the constant is negative. 1463 if (constant < 0) __ Subu(result, zero_reg, result);
1459 if (constant < 0) {
1460 __ Subu(result, zero_reg, result);
1461 }
1462
1463 } else { 1464 } else {
1464 // Generate standard code. 1465 // Generate standard code.
1465 __ li(at, constant); 1466 __ li(at, constant);
1466 __ Mul(result, left, at); 1467 __ Mul(result, left, at);
1467 } 1468 }
1468 } 1469 }
1469 1470
1470 } else { 1471 } else {
1471 Register right = EmitLoadRegister(right_op, scratch); 1472 ASSERT(right_op->IsRegister());
1472 if (bailout_on_minus_zero) { 1473 Register right = ToRegister(right_op);
1473 __ Or(ToRegister(instr->temp()), left, right);
1474 }
1475 1474
1476 if (can_overflow) { 1475 if (overflow) {
1477 // hi:lo = left * right. 1476 // hi:lo = left * right.
1478 if (instr->hydrogen()->representation().IsSmi()) { 1477 if (instr->hydrogen()->representation().IsSmi()) {
1479 __ SmiUntag(result, left); 1478 __ SmiUntag(result, left);
1480 __ mult(result, right); 1479 __ mult(result, right);
1481 __ mfhi(scratch); 1480 __ mfhi(scratch);
1482 __ mflo(result); 1481 __ mflo(result);
1483 } else { 1482 } else {
1484 __ mult(left, right); 1483 __ mult(left, right);
1485 __ mfhi(scratch); 1484 __ mfhi(scratch);
1486 __ mflo(result); 1485 __ mflo(result);
1487 } 1486 }
1488 __ sra(at, result, 31); 1487 __ sra(at, result, 31);
1489 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at)); 1488 DeoptimizeIf(ne, instr->environment(), scratch, Operand(at));
1490 } else { 1489 } else {
1491 if (instr->hydrogen()->representation().IsSmi()) { 1490 if (instr->hydrogen()->representation().IsSmi()) {
1492 __ SmiUntag(result, left); 1491 __ SmiUntag(result, left);
1493 __ Mul(result, result, right); 1492 __ Mul(result, result, right);
1494 } else { 1493 } else {
1495 __ Mul(result, left, right); 1494 __ Mul(result, left, right);
1496 } 1495 }
1497 } 1496 }
1498 1497
1499 if (bailout_on_minus_zero) { 1498 if (bailout_on_minus_zero) {
1500 // Bail out if the result is supposed to be negative zero.
1501 Label done; 1499 Label done;
1502 __ Branch(&done, ne, result, Operand(zero_reg)); 1500 __ Xor(at, left, right);
1503 DeoptimizeIf(lt, 1501 __ Branch(&done, ge, at, Operand(zero_reg));
1502 // Bail out if the result is minus zero.
1503 DeoptimizeIf(eq,
1504 instr->environment(), 1504 instr->environment(),
1505 ToRegister(instr->temp()), 1505 result,
1506 Operand(zero_reg)); 1506 Operand(zero_reg));
1507 __ bind(&done); 1507 __ bind(&done);
1508 } 1508 }
1509 } 1509 }
1510 } 1510 }
1511 1511
1512 1512
1513 void LCodeGen::DoBitI(LBitI* instr) { 1513 void LCodeGen::DoBitI(LBitI* instr) {
1514 LOperand* left_op = instr->left(); 1514 LOperand* left_op = instr->left();
1515 LOperand* right_op = instr->right(); 1515 LOperand* right_op = instr->right();
(...skipping 4252 matching lines...) Expand 10 before | Expand all | Expand 10 after
5768 __ Subu(scratch, result, scratch); 5768 __ Subu(scratch, result, scratch);
5769 __ lw(result, FieldMemOperand(scratch, 5769 __ lw(result, FieldMemOperand(scratch,
5770 FixedArray::kHeaderSize - kPointerSize)); 5770 FixedArray::kHeaderSize - kPointerSize));
5771 __ bind(&done); 5771 __ bind(&done);
5772 } 5772 }
5773 5773
5774 5774
5775 #undef __ 5775 #undef __
5776 5776
5777 } } // namespace v8::internal 5777 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/mips/lithium-mips.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698