Commit 12c74ba0 authored by sgjesse@chromium.org's avatar sgjesse@chromium.org

ARM: Add subtract to the type recording binary operation stub.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6476 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 2b47762e
...@@ -2433,6 +2433,46 @@ const char* TypeRecordingBinaryOpStub::GetName() { ...@@ -2433,6 +2433,46 @@ const char* TypeRecordingBinaryOpStub::GetName() {
} }
void TypeRecordingBinaryOpStub::GenerateOptimisticSmiOperation(
MacroAssembler* masm) {
Register left = r1;
Register right = r0;
ASSERT(right.is(r0));
switch (op_) {
case Token::ADD:
__ add(right, left, Operand(right), SetCC); // Add optimistically.
__ Ret(vc);
__ sub(right, right, Operand(left)); // Revert optimistic add.
break;
case Token::SUB:
__ sub(right, left, Operand(right), SetCC); // Subtract optimistically.
__ Ret(vc);
__ sub(right, left, Operand(right)); // Revert optimistic subtract.
break;
default:
UNREACHABLE();
}
}
void TypeRecordingBinaryOpStub::GenerateVFPOperation(
MacroAssembler* masm) {
switch (op_) {
case Token::ADD:
__ vadd(d5, d6, d7);
break;
case Token::SUB:
__ vsub(d5, d6, d7);
break;
default:
UNREACHABLE();
}
}
// Generate the smi code. If the operation on smis are successful this return is // Generate the smi code. If the operation on smis are successful this return is
// generated. If the result is not a smi and heap number allocation is not // generated. If the result is not a smi and heap number allocation is not
// requested the code falls through. If number allocation is requested but a // requested the code falls through. If number allocation is requested but a
...@@ -2442,7 +2482,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, ...@@ -2442,7 +2482,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
Label not_smis; Label not_smis;
ASSERT(op_ == Token::ADD); ASSERT(op_ == Token::ADD || op_ == Token::SUB);
Register left = r1; Register left = r1;
Register right = r0; Register right = r0;
...@@ -2455,14 +2495,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, ...@@ -2455,14 +2495,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
__ tst(scratch1, Operand(kSmiTagMask)); __ tst(scratch1, Operand(kSmiTagMask));
__ b(ne, &not_smis); __ b(ne, &not_smis);
__ add(right, right, Operand(left), SetCC); // Add optimistically. GenerateOptimisticSmiOperation(masm);
// Return smi result if no overflow (r0 is the result).
ASSERT(right.is(r0));
__ Ret(vc);
// Result is not a smi. Revert the optimistic add.
__ sub(right, right, Operand(left));
// 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.
...@@ -2489,7 +2522,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, ...@@ -2489,7 +2522,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm,
// d6: Left value // d6: Left value
// d7: Right value // d7: Right value
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
__ vadd(d5, d6, d7); GenerateVFPOperation(masm);
__ sub(r0, heap_number, Operand(kHeapObjectTag)); __ sub(r0, heap_number, Operand(kHeapObjectTag));
__ vstr(d5, r0, HeapNumber::kValueOffset); __ vstr(d5, r0, HeapNumber::kValueOffset);
...@@ -2530,7 +2563,7 @@ void TypeRecordingBinaryOpStub::GenerateSmiCode(MacroAssembler* masm, ...@@ -2530,7 +2563,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); ASSERT(op_ == Token::ADD || op_ == Token::SUB);
if (result_type_ == TRBinaryOpIC::UNINITIALIZED || if (result_type_ == TRBinaryOpIC::UNINITIALIZED ||
result_type_ == TRBinaryOpIC::SMI) { result_type_ == TRBinaryOpIC::SMI) {
...@@ -2562,7 +2595,7 @@ void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) { ...@@ -2562,7 +2595,7 @@ void TypeRecordingBinaryOpStub::GenerateStringStub(MacroAssembler* masm) {
void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD); ASSERT(op_ == Token::ADD || op_ == Token::SUB);
ASSERT(operands_type_ == TRBinaryOpIC::INT32); ASSERT(operands_type_ == TRBinaryOpIC::INT32);
...@@ -2571,7 +2604,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) { ...@@ -2571,7 +2604,7 @@ void TypeRecordingBinaryOpStub::GenerateInt32Stub(MacroAssembler* masm) {
void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD); ASSERT(op_ == Token::ADD || op_ == Token::SUB);
Register scratch1 = r7; Register scratch1 = r7;
Register scratch2 = r9; Register scratch2 = r9;
...@@ -2597,7 +2630,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { ...@@ -2597,7 +2630,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
if (destination == FloatingPointHelper::kVFPRegisters) { if (destination == FloatingPointHelper::kVFPRegisters) {
// Use floating point instructions for the binary operation. // Use floating point instructions for the binary operation.
CpuFeatures::Scope scope(VFP3); CpuFeatures::Scope scope(VFP3);
__ vadd(d5, d6, d7); GenerateVFPOperation(masm);
// Get a heap number object for the result - might be left or right if one // Get a heap number object for the result - might be left or right if one
// of these are overwritable. // of these are overwritable.
...@@ -2651,7 +2684,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) { ...@@ -2651,7 +2684,7 @@ void TypeRecordingBinaryOpStub::GenerateHeapNumberStub(MacroAssembler* masm) {
void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) { void TypeRecordingBinaryOpStub::GenerateGeneric(MacroAssembler* masm) {
ASSERT(op_ == Token::ADD); ASSERT(op_ == Token::ADD || op_ == Token::SUB);
Label call_runtime; Label call_runtime;
...@@ -2695,11 +2728,14 @@ void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) { ...@@ -2695,11 +2728,14 @@ void TypeRecordingBinaryOpStub::GenerateAddStrings(MacroAssembler* masm) {
void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) { void TypeRecordingBinaryOpStub::GenerateCallRuntime(MacroAssembler* masm) {
GenerateRegisterArgsPush(masm);
switch (op_) { switch (op_) {
case Token::ADD: case Token::ADD:
GenerateRegisterArgsPush(masm);
__ InvokeBuiltin(Builtins::ADD, JUMP_JS); __ InvokeBuiltin(Builtins::ADD, JUMP_JS);
break; break;
case Token::SUB:
__ InvokeBuiltin(Builtins::SUB, JUMP_JS);
break;
default: default:
UNREACHABLE(); UNREACHABLE();
} }
......
...@@ -288,6 +288,8 @@ class TypeRecordingBinaryOpStub: public CodeStub { ...@@ -288,6 +288,8 @@ 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 GenerateVFPOperation(MacroAssembler* masm);
void GenerateSmiCode(MacroAssembler* masm, void GenerateSmiCode(MacroAssembler* masm,
Label* gc_required, Label* gc_required,
SmiCodeGenerateHeapNumberResults heapnumber_results); SmiCodeGenerateHeapNumberResults heapnumber_results);
......
...@@ -1548,7 +1548,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(Expression* expr, ...@@ -1548,7 +1548,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) { if (op == Token::ADD || op == Token::SUB) {
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