Commit bac2da64 authored by palfia@homejinni.com's avatar palfia@homejinni.com

MIPS: Add Smi support to Shl

Port r15910 (8e65c434)

BUG=

Review URL: https://codereview.chromium.org/20808004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15913 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 3619dcf8
...@@ -1521,6 +1521,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) { ...@@ -1521,6 +1521,7 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
LOperand* right_op = instr->right(); LOperand* right_op = instr->right();
Register left = ToRegister(instr->left()); Register left = ToRegister(instr->left());
Register result = ToRegister(instr->result()); Register result = ToRegister(instr->result());
Register scratch = scratch0();
if (right_op->IsRegister()) { if (right_op->IsRegister()) {
// No need to mask the right operand on MIPS, it is built into the variable // No need to mask the right operand on MIPS, it is built into the variable
...@@ -1577,7 +1578,14 @@ void LCodeGen::DoShiftI(LShiftI* instr) { ...@@ -1577,7 +1578,14 @@ void LCodeGen::DoShiftI(LShiftI* instr) {
break; break;
case Token::SHL: case Token::SHL:
if (shift_count != 0) { if (shift_count != 0) {
__ sll(result, left, shift_count); if (instr->hydrogen_value()->representation().IsSmi() &&
instr->can_deopt()) {
__ sll(result, left, shift_count - 1);
__ SmiTagCheckOverflow(result, result, scratch);
DeoptimizeIf(lt, instr->environment(), scratch, Operand(zero_reg));
} else {
__ sll(result, left, shift_count);
}
} else { } else {
__ Move(result, left); __ Move(result, left);
} }
......
...@@ -713,9 +713,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) { ...@@ -713,9 +713,9 @@ LInstruction* LChunkBuilder::DoDeoptimize(HDeoptimize* instr) {
LInstruction* LChunkBuilder::DoShift(Token::Value op, LInstruction* LChunkBuilder::DoShift(Token::Value op,
HBitwiseBinaryOperation* instr) { HBitwiseBinaryOperation* instr) {
if (instr->representation().IsSmiOrTagged()) { if (instr->representation().IsTagged()) {
ASSERT(instr->left()->representation().IsSmiOrTagged()); ASSERT(instr->left()->representation().IsTagged());
ASSERT(instr->right()->representation().IsSmiOrTagged()); ASSERT(instr->right()->representation().IsTagged());
LOperand* left = UseFixed(instr->left(), a1); LOperand* left = UseFixed(instr->left(), a1);
LOperand* right = UseFixed(instr->right(), a0); LOperand* right = UseFixed(instr->right(), a0);
...@@ -723,25 +723,35 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op, ...@@ -723,25 +723,35 @@ LInstruction* LChunkBuilder::DoShift(Token::Value op,
return MarkAsCall(DefineFixed(result, v0), instr); return MarkAsCall(DefineFixed(result, v0), instr);
} }
ASSERT(instr->representation().IsInteger32()); ASSERT(instr->representation().IsSmiOrInteger32());
ASSERT(instr->left()->representation().IsInteger32()); ASSERT(instr->left()->representation().Equals(instr->representation()));
ASSERT(instr->right()->representation().IsInteger32()); ASSERT(instr->right()->representation().Equals(instr->representation()));
LOperand* left = UseRegisterAtStart(instr->left()); LOperand* left = UseRegisterAtStart(instr->left());
HValue* right_value = instr->right(); HValue* right_value = instr->right();
LOperand* right = NULL; LOperand* right = NULL;
int constant_value = 0; int constant_value = 0;
bool does_deopt = false;
if (right_value->IsConstant()) { if (right_value->IsConstant()) {
HConstant* constant = HConstant::cast(right_value); HConstant* constant = HConstant::cast(right_value);
right = chunk_->DefineConstantOperand(constant); right = chunk_->DefineConstantOperand(constant);
constant_value = constant->Integer32Value() & 0x1f; constant_value = constant->Integer32Value() & 0x1f;
// Left shifts can deoptimize if we shift by > 0 and the result cannot be
// truncated to smi.
if (instr->representation().IsSmi() && constant_value > 0) {
for (HUseIterator it(instr->uses()); !it.Done(); it.Advance()) {
if (!it.value()->CheckFlag(HValue::kTruncatingToSmi)) {
does_deopt = true;
break;
}
}
}
} else { } else {
right = UseRegisterAtStart(right_value); right = UseRegisterAtStart(right_value);
} }
// Shift operations can only deoptimize if we do a logical shift // Shift operations can deoptimize if we do a logical shift
// by 0 and the result cannot be truncated to int32. // by 0 and the result cannot be truncated to int32.
bool does_deopt = false;
if (op == Token::SHR && constant_value == 0) { if (op == Token::SHR && constant_value == 0) {
if (FLAG_opt_safe_uint32_operations) { if (FLAG_opt_safe_uint32_operations) {
does_deopt = !instr->CheckFlag(HInstruction::kUint32); does_deopt = !instr->CheckFlag(HInstruction::kUint32);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment