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();
}
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();
}
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();
}
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);
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();
}