Commit 33c591b4 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

ARM: Add multiplication to the type recording binary operation stub

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6504 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent d07f1d62
...@@ -2434,13 +2434,17 @@ const char* TypeRecordingBinaryOpStub::GetName() { ...@@ -2434,13 +2434,17 @@ const char* TypeRecordingBinaryOpStub::GetName() {
} }
void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation( void TypeRecordingBinaryOpStub::GenerateSmiSmiOperation(
MacroAssembler* masm) { MacroAssembler* masm) {
Register left = r1; Register left = r1;
Register right = r0; Register right = r0;
Register scratch1 = r7;
Register scratch2 = r9;
ASSERT(right.is(r0)); ASSERT(right.is(r0));
STATIC_ASSERT(kSmiTag == 0);
Label not_smi_result;
switch (op_) { switch (op_) {
case Token::ADD: case Token::ADD:
__ add(right, left, Operand(right), SetCC); // Add optimistically. __ add(right, left, Operand(right), SetCC); // Add optimistically.
...@@ -2452,9 +2456,35 @@ void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation( ...@@ -2452,9 +2456,35 @@ void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation(
__ Ret(vc); __ Ret(vc);
__ sub(right, left, Operand(right)); // Revert optimistic subtract. __ sub(right, left, Operand(right)); // Revert optimistic subtract.
break; break;
case Token::MUL:
// Remove tag from one of the operands. This way the multiplication result
// will be a smi if it fits the smi range.
__ SmiUntag(ip, right);
// Do multiplication
// scratch1 = lower 32 bits of ip * left.
// scratch2 = higher 32 bits of ip * left.
__ smull(scratch1, scratch2, left, ip);
// Check for overflowing the smi range - no overflow if higher 33 bits of
// the result are identical.
__ mov(ip, Operand(scratch1, ASR, 31));
__ cmp(ip, Operand(scratch2));
__ b(ne, &not_smi_result);
// Go slow on zero result to handle -0.
__ tst(scratch1, Operand(scratch1));
__ mov(right, Operand(scratch1), LeaveCC, ne);
__ Ret(ne);
// We need -0 if we were multiplying a negative number with 0 to get 0.
// We know one of them was zero.
__ add(scratch2, right, Operand(left), SetCC);
__ mov(right, Operand(Smi::FromInt(0)), LeaveCC, pl);
__ Ret(pl); // Return smi 0 if the non-zero one was positive.
// We fall through here if we multiplied a negative number with 0, because
// that would mean we should produce -0.
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
__ bind(&not_smi_result);
} }
...@@ -2467,6 +2497,9 @@ void TypeRecordingBinaryOpStub::GenerateVFPOperation( ...@@ -2467,6 +2497,9 @@ void TypeRecordingBinaryOpStub::GenerateVFPOperation(
case Token::SUB: case Token::SUB:
__ vsub(d5, d6, d7); __ vsub(d5, d6, d7);
break; break;
case Token::MUL:
__ vmul(d5, d6, d7);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
...@@ -2482,7 +2515,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, ...@@ -2482,7 +2515,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
Label not_smis; Label not_smis;
ASSERT(op_ == Token::ADD || op_ == Token::SUB); ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
Register left = r1; Register left = r1;
Register right = r0; Register right = r0;
...@@ -2495,7 +2528,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, ...@@ -2495,7 +2528,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
__ tst(scratch1, Operand(kSmiTagMask)); __ tst(scratch1, Operand(kSmiTagMask));
__ b(ne, &not_smis); __ b(ne, &not_smis);
GenerateOptimisticSmiOperation(masm); GenerateSmiSmiOperation(masm);
// If heap number results are possible generate the result in an allocated // If heap number results are possible generate the result in an allocated
// heap number. // heap number.
...@@ -2563,7 +2596,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, ...@@ -2563,7 +2596,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) { void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
Label not_smis, call_runtime; Label not_smis, call_runtime;
ASSERT(op_ == Token::ADD || op_ == Token::SUB); ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
if (result_type_ == TRBinaryOpIC::UNINITIALIZED || if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
result_type_ == TRBinaryOpIC::SMI) { result_type_ == TRBinaryOpIC::SMI) {
...@@ -2595,7 +2628,7 @@ void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { ...@@ -2595,7 +2628,7 @@ void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD || op_ == Token::SUB); ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::SUB);
ASSERT(operands_type_ == TRBinaryOpIC::INT32); ASSERT(operands_type_ == TRBinaryOpIC::INT32);
...@@ -2604,7 +2637,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -2604,7 +2637,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD || op_ == Token::SUB); ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
Register scratch1 = r7; Register scratch1 = r7;
Register scratch2 = r9; Register scratch2 = r9;
...@@ -2684,7 +2717,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { ...@@ -2684,7 +2717,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD || op_ == Token::SUB); ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
Label call_runtime; Label call_runtime;
......
...@@ -288,7 +288,7 @@ class TypeRecordingBinaryOpStub: public CodeStub { ...@@ -288,7 +288,7 @@ class TypeRecordingBinaryOpStub: public CodeStub {
void Generate(MacroAssembler* masm); void Generate(MacroAssembler* masm);
void GenerateGeneric(MacroAssembler* masm); void GenerateGeneric(MacroAssembler* masm);
void GenerateOptimisticSmiOperation(MacroAssembler* masm); void GenerateSmiSmiOperation(MacroAssembler* masm);
void GenerateVFPOperation(MacroAssembler* masm); void GenerateVFPOperation(MacroAssembler* masm);
void GenerateSmiCode(MacroAssembler* masm, void GenerateSmiCode(MacroAssembler* masm,
Label* gc_required, Label* gc_required,
......
...@@ -1550,7 +1550,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, ...@@ -1550,7 +1550,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr,
void FullCodeGenerator::EmitBinaryOp(Token::Value op, void FullCodeGenerator::EmitBinaryOp(Token::Value op,
OverwriteMode mode) { OverwriteMode mode) {
__ pop(r1); __ pop(r1);
if (op == Token::ADD || op == Token::SUB) { if (op == Token::ADD || op == Token::SUB || op == Token::MUL) {
TypeRecordingBinaryOpStub stub(op, mode); TypeRecordingBinaryOpStub stub(op, mode);
__ CallStub(&stub); __ CallStub(&stub);
} else { } else {
......
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