Commit 08d098e0 authored by whesse@chromium.org's avatar whesse@chromium.org

X64 implementation: VisitUnaryOperation, configure dtoa for X64 platform.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@2268 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 09df6ed2
......@@ -77,6 +77,11 @@
#define __NO_ISOCEXT
#endif /* __MINGW32__ */
/* On 64-bit systems, we need to make sure that a Long is only 32 bits. */
#ifdef V8_TARGET_ARCH_X64
#define Long int
#endif /* V8_TARGET_ARCH_X64 */
/* Make sure we use the David M. Gay version of strtod(). On Linux, we
* cannot use the same name (maybe the function does not have weak
* linkage?). */
......
......@@ -1434,10 +1434,164 @@ void CodeGenerator::VisitCallRuntime(CallRuntime* node) {
}
void CodeGenerator::VisitUnaryOperation(UnaryOperation* a) {
UNIMPLEMENTED();
void CodeGenerator::VisitUnaryOperation(UnaryOperation* node) {
// Note that because of NOT and an optimization in comparison of a typeof
// expression to a literal string, this function can fail to leave a value
// on top of the frame or in the cc register.
Comment cmnt(masm_, "[ UnaryOperation");
Token::Value op = node->op();
if (op == Token::NOT) {
// Swap the true and false targets but keep the same actual label
// as the fall through.
destination()->Invert();
LoadCondition(node->expression(), NOT_INSIDE_TYPEOF, destination(), true);
// Swap the labels back.
destination()->Invert();
} else if (op == Token::DELETE) {
Property* property = node->expression()->AsProperty();
if (property != NULL) {
Load(property->obj());
Load(property->key());
Result answer = frame_->InvokeBuiltin(Builtins::DELETE, CALL_FUNCTION, 2);
frame_->Push(&answer);
return;
}
Variable* variable = node->expression()->AsVariableProxy()->AsVariable();
if (variable != NULL) {
Slot* slot = variable->slot();
if (variable->is_global()) {
LoadGlobal();
frame_->Push(variable->name());
Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
CALL_FUNCTION, 2);
frame_->Push(&answer);
return;
} else if (slot != NULL && slot->type() == Slot::LOOKUP) {
// Call the runtime to look up the context holding the named
// variable. Sync the virtual frame eagerly so we can push the
// arguments directly into place.
frame_->SyncRange(0, frame_->element_count() - 1);
frame_->EmitPush(rsi);
frame_->EmitPush(variable->name());
Result context = frame_->CallRuntime(Runtime::kLookupContext, 2);
ASSERT(context.is_register());
frame_->EmitPush(context.reg());
context.Unuse();
frame_->EmitPush(variable->name());
Result answer = frame_->InvokeBuiltin(Builtins::DELETE,
CALL_FUNCTION, 2);
frame_->Push(&answer);
return;
}
// Default: Result of deleting non-global, not dynamically
// introduced variables is false.
frame_->Push(Factory::false_value());
} else {
// Default: Result of deleting expressions is true.
Load(node->expression()); // may have side-effects
frame_->SetElementAt(0, Factory::true_value());
}
} else if (op == Token::TYPEOF) {
// Special case for loading the typeof expression; see comment on
// LoadTypeofExpression().
LoadTypeofExpression(node->expression());
Result answer = frame_->CallRuntime(Runtime::kTypeof, 1);
frame_->Push(&answer);
} else if (op == Token::VOID) {
Expression* expression = node->expression();
if (expression && expression->AsLiteral() && (
expression->AsLiteral()->IsTrue() ||
expression->AsLiteral()->IsFalse() ||
expression->AsLiteral()->handle()->IsNumber() ||
expression->AsLiteral()->handle()->IsString() ||
expression->AsLiteral()->handle()->IsJSRegExp() ||
expression->AsLiteral()->IsNull())) {
// Omit evaluating the value of the primitive literal.
// It will be discarded anyway, and can have no side effect.
frame_->Push(Factory::undefined_value());
} else {
Load(node->expression());
frame_->SetElementAt(0, Factory::undefined_value());
}
} else {
Load(node->expression());
switch (op) {
case Token::NOT:
case Token::DELETE:
case Token::TYPEOF:
UNREACHABLE(); // handled above
break;
case Token::SUB: {
bool overwrite =
(node->AsBinaryOperation() != NULL &&
node->AsBinaryOperation()->ResultOverwriteAllowed());
UnarySubStub stub(overwrite);
// TODO(1222589): remove dependency of TOS being cached inside stub
Result operand = frame_->Pop();
Result answer = frame_->CallStub(&stub, &operand);
frame_->Push(&answer);
break;
}
case Token::BIT_NOT: {
// Smi check.
JumpTarget smi_label;
JumpTarget continue_label;
Result operand = frame_->Pop();
operand.ToRegister();
__ testl(operand.reg(), Immediate(kSmiTagMask));
smi_label.Branch(zero, &operand);
frame_->Push(&operand); // undo popping of TOS
Result answer = frame_->InvokeBuiltin(Builtins::BIT_NOT,
CALL_FUNCTION, 1);
continue_label.Jump(&answer);
smi_label.Bind(&answer);
answer.ToRegister();
frame_->Spill(answer.reg());
__ not_(answer.reg());
// Remove inverted smi-tag. The mask is sign-extended to 64 bits.
__ xor_(answer.reg(), Immediate(kSmiTagMask));
continue_label.Bind(&answer);
frame_->Push(&answer);
break;
}
case Token::ADD: {
// Smi check.
JumpTarget continue_label;
Result operand = frame_->Pop();
operand.ToRegister();
__ testl(operand.reg(), Immediate(kSmiTagMask));
continue_label.Branch(zero, &operand, taken);
frame_->Push(&operand);
Result answer = frame_->InvokeBuiltin(Builtins::TO_NUMBER,
CALL_FUNCTION, 1);
continue_label.Bind(&answer);
frame_->Push(&answer);
break;
}
default:
UNREACHABLE();
}
}
}
void CodeGenerator::VisitCountOperation(CountOperation* a) {
UNIMPLEMENTED();
}
......
......@@ -197,6 +197,14 @@ void VirtualFrame::EmitPush(Immediate immediate) {
}
void VirtualFrame::EmitPush(Handle<Object> value) {
ASSERT(stack_pointer_ == element_count() - 1);
elements_.Add(FrameElement::MemoryElement());
stack_pointer_++;
__ Push(value);
}
void VirtualFrame::Drop(int count) {
ASSERT(height() >= count);
int num_virtual_elements = (element_count() - 1) - stack_pointer_;
......
......@@ -376,6 +376,8 @@ class VirtualFrame : public ZoneObject {
void EmitPush(Register reg);
void EmitPush(const Operand& operand);
void EmitPush(Immediate immediate);
// Uses kScratchRegister, emits appropriate relocation info.
void EmitPush(Handle<Object> value);
// Push an element on the virtual frame.
void Push(Register reg);
......
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