Commit 98794903 authored by ager@chromium.org's avatar ager@chromium.org

Implement SUB and BIT_NOT unary operations in full codegenerator.

This change depends on landing the BIT_NOT unary op stub on arm. That
change is out for review.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@3727 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent ed224fc1
......@@ -1372,6 +1372,45 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break;
}
case Token::SUB: {
Comment cmt(masm_, "[ UnaryOperation (SUB)");
bool overwrite =
(expr->expression()->AsBinaryOperation() != NULL &&
expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericUnaryOpStub stub(Token::SUB, overwrite);
// GenericUnaryOpStub expects the argument to be in the
// accumulator register r0.
VisitForValue(expr->expression(), kAccumulator);
__ CallStub(&stub);
Apply(context_, r0);
break;
}
case Token::BIT_NOT: {
Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
bool overwrite =
(expr->expression()->AsBinaryOperation() != NULL &&
expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
// GenericUnaryOpStub expects the argument to be in the
// accumulator register r0.
VisitForValue(expr->expression(), kAccumulator);
// Avoid calling the stub for Smis.
Label smi, done;
__ tst(result_register(), Operand(kSmiTagMask));
__ b(eq, &smi);
// Non-smi: call stub leaving result in accumulator register.
__ CallStub(&stub);
__ b(&done);
// Perform operation directly on Smis.
__ bind(&smi);
__ mvn(result_register(), Operand(result_register()));
// Bit-clear inverted smi-tag.
__ bic(result_register(), result_register(), Operand(kSmiTagMask));
__ bind(&done);
Apply(context_, result_register());
}
default:
UNREACHABLE();
}
......
......@@ -387,17 +387,15 @@ void FullCodeGenSyntaxChecker::VisitCallRuntime(CallRuntime* expr) {
void FullCodeGenSyntaxChecker::VisitUnaryOperation(UnaryOperation* expr) {
switch (expr->op()) {
case Token::ADD:
case Token::BIT_NOT:
case Token::NOT:
case Token::SUB:
case Token::TYPEOF:
case Token::VOID:
Visit(expr->expression());
break;
case Token::BIT_NOT:
BAILOUT("UnaryOperation: BIT_NOT");
case Token::DELETE:
BAILOUT("UnaryOperation: DELETE");
case Token::SUB:
BAILOUT("UnaryOperation: SUB");
default:
UNREACHABLE();
}
......
......@@ -1476,6 +1476,44 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break;
}
case Token::SUB: {
Comment cmt(masm_, "[ UnaryOperation (SUB)");
bool overwrite =
(expr->expression()->AsBinaryOperation() != NULL &&
expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericUnaryOpStub stub(Token::SUB, overwrite);
// GenericUnaryOpStub expects the argument to be in the
// accumulator register eax.
VisitForValue(expr->expression(), kAccumulator);
__ CallStub(&stub);
Apply(context_, eax);
break;
}
case Token::BIT_NOT: {
Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
bool overwrite =
(expr->expression()->AsBinaryOperation() != NULL &&
expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
// GenericUnaryOpStub expects the argument to be in the
// accumulator register eax.
VisitForValue(expr->expression(), kAccumulator);
// Avoid calling the stub for Smis.
Label smi, done;
__ test(result_register(), Immediate(kSmiTagMask));
__ j(zero, &smi);
// Non-smi: call stub leaving result in accumulator register.
__ CallStub(&stub);
__ jmp(&done);
// Perform operation directly on Smis.
__ bind(&smi);
__ not_(result_register());
__ and_(result_register(), ~kSmiTagMask); // Remove inverted smi-tag.
__ bind(&done);
Apply(context_, result_register());
}
default:
UNREACHABLE();
}
......
......@@ -1474,8 +1474,7 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
Comment cmt(masm_, "[ UnaryOperation (ADD)");
VisitForValue(expr->expression(), kAccumulator);
Label no_conversion;
Condition is_smi;
is_smi = masm_->CheckSmi(result_register());
Condition is_smi = masm_->CheckSmi(result_register());
__ j(is_smi, &no_conversion);
__ push(result_register());
__ InvokeBuiltin(Builtins::TO_NUMBER, CALL_FUNCTION);
......@@ -1484,6 +1483,43 @@ void FullCodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
break;
}
case Token::SUB: {
Comment cmt(masm_, "[ UnaryOperation (SUB)");
bool overwrite =
(expr->expression()->AsBinaryOperation() != NULL &&
expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericUnaryOpStub stub(Token::SUB, overwrite);
// GenericUnaryOpStub expects the argument to be in the
// accumulator register rax.
VisitForValue(expr->expression(), kAccumulator);
__ CallStub(&stub);
Apply(context_, rax);
break;
}
case Token::BIT_NOT: {
Comment cmt(masm_, "[ UnaryOperation (BIT_NOT)");
bool overwrite =
(expr->expression()->AsBinaryOperation() != NULL &&
expr->expression()->AsBinaryOperation()->ResultOverwriteAllowed());
GenericUnaryOpStub stub(Token::BIT_NOT, overwrite);
// GenericUnaryOpStub expects the argument to be in the
// accumulator register rax.
VisitForValue(expr->expression(), kAccumulator);
// Avoid calling the stub for Smis.
Label smi, done;
Condition is_smi = masm_->CheckSmi(result_register());
__ j(is_smi, &smi);
// Non-smi: call stub leaving result in accumulator register.
__ CallStub(&stub);
__ jmp(&done);
// Perform operation directly on Smis.
__ bind(&smi);
__ SmiNot(result_register(), result_register());
__ bind(&done);
Apply(context_, result_register());
}
default:
UNREACHABLE();
}
......
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