Revision: 6504
Author: [email protected]
Date: Wed Jan 26 12:25:33 2011
Log: ARM: Add multiplication to the type recording binary operation stub
Review URL: http://codereview.chromium.org/6391004
http://code.google.com/p/v8/source/detail?r=6504
Modified:
/branches/bleeding_edge/src/arm/code-stubs-arm.cc
/branches/bleeding_edge/src/arm/code-stubs-arm.h
/branches/bleeding_edge/src/arm/full-codegen-arm.cc
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.cc Wed Jan 26 04:31:35
2011
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.cc Wed Jan 26 12:25:33
2011
@@ -2434,13 +2434,17 @@
}
-void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation(
+void TypeRecordingBinaryOpStub::GenerateSmiSmiOperation(
MacroAssembler* masm) {
Register left = r1;
Register right = r0;
+ Register scratch1 = r7;
+ Register scratch2 = r9;
ASSERT(right.is(r0));
-
+ STATIC_ASSERT(kSmiTag == 0);
+
+ Label not_smi_result;
switch (op_) {
case Token::ADD:
__ add(right, left, Operand(right), SetCC); // Add optimistically.
@@ -2452,9 +2456,35 @@
__ Ret(vc);
__ sub(right, left, Operand(right)); // Revert optimistic subtract.
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, ¬_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:
UNREACHABLE();
}
+ __ bind(¬_smi_result);
}
@@ -2467,6 +2497,9 @@
case Token::SUB:
__ vsub(d5, d6, d7);
break;
+ case Token::MUL:
+ __ vmul(d5, d6, d7);
+ break;
default:
UNREACHABLE();
}
@@ -2482,7 +2515,7 @@
SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
Label not_smis;
- ASSERT(op_ == Token::ADD || op_ == Token::SUB);
+ ASSERT(op_ == Token::ADD || op_ == Token::SUB || op_ == Token::MUL);
Register left = r1;
Register right = r0;
@@ -2495,7 +2528,7 @@
__ tst(scratch1, Operand(kSmiTagMask));
__ b(ne, ¬_smis);
- GenerateOptimisticSmiOperation(masm);
+ GenerateSmiSmiOperation(masm);
// If heap number results are possible generate the result in an
allocated
// heap number.
@@ -2563,7 +2596,7 @@
void TypeRecordingBinaryOpStub::GenerateSmiStub(MacroAssembler* masm) {
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 ||
result_type_ == TRBinaryOpIC::SMI) {
@@ -2595,7 +2628,7 @@
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);
@@ -2604,7 +2637,7 @@
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 scratch2 = r9;
@@ -2684,7 +2717,7 @@
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;
=======================================
--- /branches/bleeding_edge/src/arm/code-stubs-arm.h Tue Jan 25 23:41:02
2011
+++ /branches/bleeding_edge/src/arm/code-stubs-arm.h Wed Jan 26 12:25:33
2011
@@ -288,7 +288,7 @@
void Generate(MacroAssembler* masm);
void GenerateGeneric(MacroAssembler* masm);
- void GenerateOptimisticSmiOperation(MacroAssembler* masm);
+ void GenerateSmiSmiOperation(MacroAssembler* masm);
void GenerateVFPOperation(MacroAssembler* masm);
void GenerateSmiCode(MacroAssembler* masm,
Label* gc_required,
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Jan 26 07:28:17
2011
+++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Wed Jan 26 12:25:33
2011
@@ -1550,7 +1550,7 @@
void FullCodeGenerator::EmitBinaryOp(Token::Value op,
OverwriteMode mode) {
__ pop(r1);
- if (op == Token::ADD || op == Token::SUB) {
+ if (op == Token::ADD || op == Token::SUB || op == Token::MUL) {
TypeRecordingBinaryOpStub stub(op, mode);
__ CallStub(&stub);
} else {
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev