Commit 4ce06204 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

ARM: Add inlined smi binary operations in full code generator

Review URL: http://codereview.chromium.org/6529022

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6806 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent abbcadf2
This diff is collapsed.
...@@ -331,6 +331,7 @@ FullCodeGenerator::ConstantOperand FullCodeGenerator::GetConstantOperand( ...@@ -331,6 +331,7 @@ FullCodeGenerator::ConstantOperand FullCodeGenerator::GetConstantOperand(
} else if (right->IsSmiLiteral()) { } else if (right->IsSmiLiteral()) {
return kRightConstant; return kRightConstant;
} else if (left->IsSmiLiteral() && !Token::IsShiftOp(op)) { } else if (left->IsSmiLiteral() && !Token::IsShiftOp(op)) {
// Don't inline shifts with constant left hand side.
return kLeftConstant; return kLeftConstant;
} else { } else {
return kNoConstants; return kNoConstants;
...@@ -1644,6 +1645,9 @@ void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr, ...@@ -1644,6 +1645,9 @@ void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr,
bool left_is_constant_smi, bool left_is_constant_smi,
Smi* value) { Smi* value) {
NearLabel call_stub, done; NearLabel call_stub, done;
// Optimistically add smi value with unknown object. If result overflows or is
// not a smi then we had either a smi overflow or added a smi with a tagged
// pointer.
__ add(Operand(eax), Immediate(value)); __ add(Operand(eax), Immediate(value));
__ j(overflow, &call_stub); __ j(overflow, &call_stub);
JumpPatchSite patch_site(masm_); JumpPatchSite patch_site(masm_);
...@@ -1652,8 +1656,7 @@ void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr, ...@@ -1652,8 +1656,7 @@ void FullCodeGenerator::EmitConstantSmiAdd(Expression* expr,
// Undo the optimistic add operation and call the shared stub. // Undo the optimistic add operation and call the shared stub.
__ bind(&call_stub); __ bind(&call_stub);
__ sub(Operand(eax), Immediate(value)); __ sub(Operand(eax), Immediate(value));
Token::Value op = Token::ADD; TypeRecordingBinaryOpStub stub(Token::ADD, mode);
TypeRecordingBinaryOpStub stub(op, mode);
if (left_is_constant_smi) { if (left_is_constant_smi) {
__ mov(edx, Immediate(value)); __ mov(edx, Immediate(value));
} else { } else {
...@@ -1672,6 +1675,9 @@ void FullCodeGenerator::EmitConstantSmiSub(Expression* expr, ...@@ -1672,6 +1675,9 @@ void FullCodeGenerator::EmitConstantSmiSub(Expression* expr,
bool left_is_constant_smi, bool left_is_constant_smi,
Smi* value) { Smi* value) {
NearLabel call_stub, done; NearLabel call_stub, done;
// Optimistically subtract smi value with unknown object. If result overflows
// or is not a smi then we had either a smi overflow or added a smi with a
// tagged pointer.
if (left_is_constant_smi) { if (left_is_constant_smi) {
__ mov(ecx, eax); __ mov(ecx, eax);
__ mov(eax, Immediate(value)); __ mov(eax, Immediate(value));
...@@ -1692,8 +1698,7 @@ void FullCodeGenerator::EmitConstantSmiSub(Expression* expr, ...@@ -1692,8 +1698,7 @@ void FullCodeGenerator::EmitConstantSmiSub(Expression* expr,
__ mov(edx, eax); __ mov(edx, eax);
__ mov(eax, Immediate(value)); __ mov(eax, Immediate(value));
} }
Token::Value op = Token::SUB; TypeRecordingBinaryOpStub stub(Token::SUB, mode);
TypeRecordingBinaryOpStub stub(op, mode);
EmitCallIC(stub.GetCode(), &patch_site); EmitCallIC(stub.GetCode(), &patch_site);
__ bind(&done); __ bind(&done);
...@@ -1729,7 +1734,7 @@ void FullCodeGenerator::EmitConstantSmiShiftOp(Expression* expr, ...@@ -1729,7 +1734,7 @@ void FullCodeGenerator::EmitConstantSmiShiftOp(Expression* expr,
__ shl(edx, shift_value - 1); __ shl(edx, shift_value - 1);
} }
// Convert int result to smi, checking that it is in int range. // Convert int result to smi, checking that it is in int range.
ASSERT(kSmiTagSize == 1); // Adjust code if not the case. STATIC_ASSERT(kSmiTagSize == 1); // Adjust code if not the case.
__ add(edx, Operand(edx)); __ add(edx, Operand(edx));
__ j(overflow, &call_stub); __ j(overflow, &call_stub);
__ mov(eax, edx); // Put result back into eax. __ mov(eax, edx); // Put result back into eax.
...@@ -1742,6 +1747,8 @@ void FullCodeGenerator::EmitConstantSmiShiftOp(Expression* expr, ...@@ -1742,6 +1747,8 @@ void FullCodeGenerator::EmitConstantSmiShiftOp(Expression* expr,
} }
break; break;
case Token::SHR: case Token::SHR:
// SHR must return a positive value. When shifting by 0 or 1 we need to
// check that smi tagging the result will not create a negative value.
if (shift_value < 2) { if (shift_value < 2) {
__ mov(edx, eax); __ mov(edx, eax);
__ SmiUntag(edx); __ SmiUntag(edx);
......
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