}
+void FastCodeGenerator::Move(Location destination, Slot* source) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ break;
+ case Location::TEMP:
+ __ ldr(ip, MemOperand(fp, SlotOffset(source)));
+ __ push(ip);
+ break;
+ }
+}
+
+
+void FastCodeGenerator::Move(Location destination, Literal* expr) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ break;
+ case Location::TEMP:
+ __ mov(ip, Operand(expr->handle()));
+ __ push(ip);
+ break;
+ }
+}
+
+
+void FastCodeGenerator::Move(Slot* destination, Location source) {
+ switch (source.type()) {
+ case Location::NOWHERE:
+ UNREACHABLE();
+ case Location::TEMP:
+ __ pop(ip);
+ __ str(ip, MemOperand(fp, SlotOffset(destination)));
+ break;
+ }
+}
+
+
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
// The context is the first argument.
}
-void FastCodeGenerator::VisitBlock(Block* stmt) {
- Comment cmnt(masm_, "[ Block");
- SetStatementPosition(stmt);
- VisitStatements(stmt->statements());
-}
-
-
-void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
- Comment cmnt(masm_, "[ ExpressionStatement");
- SetStatementPosition(stmt);
- Visit(stmt->expression());
-}
-
-
void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt);
__ mov(r0, Operand(expr->AsLiteral()->handle()));
} else {
Visit(expr);
- ASSERT(expr->location().is_temporary());
- __ pop(r0);
+ Move(r0, expr->location());
}
if (FLAG_trace) {
__ mov(r0, Operand(boilerplate));
__ stm(db_w, sp, cp.bit() | r0.bit());
__ CallRuntime(Runtime::kNewClosure, 2);
-
- if (expr->location().is_temporary()) {
- __ push(r0);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), r0);
}
__ mov(r2, Operand(expr->name()));
Handle<Code> ic(Builtins::builtin(Builtins::LoadIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
- if (expr->location().is_temporary()) {
- // Replace the global object with the result.
- __ str(r0, MemOperand(sp));
- } else {
- ASSERT(expr->location().is_nowhere());
- __ pop();
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ pop();
+ break;
+ case Location::TEMP:
+ // Replace the global object with the result.
+ __ str(r0, MemOperand(sp));
+ break;
}
} else {
Comment cmnt(masm_, "Stack slot");
- Slot* slot = rewrite->AsSlot();
- ASSERT(slot != NULL);
- if (expr->location().is_temporary()) {
- __ ldr(ip, MemOperand(fp, SlotOffset(slot)));
- __ push(ip);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
- }
-}
-
-
-void FastCodeGenerator::VisitLiteral(Literal* expr) {
- if (expr->location().is_temporary()) {
- __ mov(ip, Operand(expr->AsLiteral()->handle()));
- __ push(ip);
- } else {
- ASSERT(expr->location().is_nowhere());
+ Move(expr->location(), rewrite->AsSlot());
}
}
default: UNREACHABLE();
}
}
- if (expr->location().is_nowhere() && result_saved) {
- __ pop();
- } else if (expr->location().is_temporary() && !result_saved) {
- ASSERT(expr->location().is_temporary());
- __ push(r0);
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ if (result_saved) __ pop();
+ break;
+ case Location::TEMP:
+ if (!result_saved) __ push(r0);
+ break;
}
}
__ stm(db_w, sp, r4.bit() | r3.bit() | r2.bit() | r1.bit());
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
__ bind(&done);
- if (expr->location().is_temporary()) {
- __ push(r0);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), r0);
}
__ RecordWrite(r1, r2, r0);
}
- Location destination = expr->location();
- if (destination.is_nowhere() && result_saved) {
- __ pop();
- } else if (destination.is_temporary() && !result_saved) {
- __ push(r0);
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ if (result_saved) __ pop();
+ break;
+ case Location::TEMP:
+ if (!result_saved) __ push(r0);
+ break;
}
}
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- if (destination.is_temporary()) {
- __ str(r0, MemOperand(sp));
- } else {
- ASSERT(destination.is_nowhere());
- __ pop();
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ pop();
+ break;
+ case Location::TEMP:
+ __ str(r0, MemOperand(sp));
+ break;
}
} else {
// discarded result. Always perform the assignment.
__ mov(ip, Operand(rhs->AsLiteral()->handle()));
__ str(ip, MemOperand(fp, SlotOffset(var->slot())));
- if (destination.is_temporary()) {
- // Case 'temp <- (var = constant)'. Save result.
- __ push(ip);
- }
+ Move(expr->location(), ip);
} else {
ASSERT(rhs->location().is_temporary());
Visit(rhs);
- if (destination.is_temporary()) {
- // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
- // temporary on the stack.
- __ ldr(ip, MemOperand(sp));
- } else {
- ASSERT(destination.is_nowhere());
- // Case 'var = temp'. Discard right-hand-side temporary.
- __ pop(ip);
+ // Load right-hand side into ip.
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ // Case 'var = temp'. Discard right-hand-side temporary.
+ __ pop(ip);
+ break;
+ case Location::TEMP:
+ // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
+ // temporary on the stack.
+ __ ldr(ip, MemOperand(sp));
+ break;
}
+ // Do the slot assignment.
__ str(ip, MemOperand(fp, SlotOffset(var->slot())));
}
}
__ Call(ic, RelocInfo::CODE_TARGET_CONTEXT);
// Restore context register.
__ ldr(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
- if (expr->location().is_temporary()) {
- __ str(r0, MemOperand(sp));
- } else {
- ASSERT(expr->location().is_nowhere());
- __ pop();
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ pop();
+ break;
+ case Location::TEMP:
+ __ str(r0, MemOperand(sp));
+ break;
}
}
}
__ CallRuntime(function, arg_count);
- if (expr->location().is_temporary()) {
- __ push(r0);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), r0);
}
if (destination.is_temporary()) __ pop();
// Save or discard the right-hand value as needed.
if (right->AsLiteral() != NULL) {
- if (destination.is_temporary()) {
- __ mov(ip, Operand(right->AsLiteral()->handle()));
- __ push(ip);
- } else {
- ASSERT(destination.is_nowhere());
- }
+ Move(destination, right->AsLiteral());
} else {
Visit(right);
- ASSERT(right->location().is_temporary());
- if (destination.is_nowhere()) {
- __ pop();
- } else {
- ASSERT(destination.is_temporary());
- }
+ Move(destination, right->location());
}
__ bind(&done);
int FastCodeGenerator::SlotOffset(Slot* slot) {
+ ASSERT(slot != NULL);
// Offset is negative because higher indexes are at lower addresses.
int offset = -slot->index() * kPointerSize;
// Adjust by a (parameter or local) base offset.
}
+void FastCodeGenerator::Move(Location destination, Location source) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ break;
+
+ case Location::TEMP:
+ switch (source.type()) {
+ case Location::NOWHERE:
+ UNREACHABLE();
+ case Location::TEMP:
+ break;
+ }
+ break;
+ }
+}
+
+
+// All platform macro assemblers in {ia32,x64,arm} have a push(Register)
+// function.
+void FastCodeGenerator::Move(Location destination, Register source) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ break;
+ case Location::TEMP:
+ masm_->push(source);
+ break;
+ }
+}
+
+
+// All platform macro assemblers in {ia32,x64,arm} have a pop(Register)
+// function.
+void FastCodeGenerator::Move(Register destination, Location source) {
+ switch (source.type()) {
+ case Location::NOWHERE:
+ UNREACHABLE();
+ case Location::TEMP:
+ masm_->pop(destination);
+ }
+}
+
+
void FastCodeGenerator::VisitDeclarations(
ZoneList<Declaration*>* declarations) {
int length = declarations->length();
}
+void FastCodeGenerator::VisitBlock(Block* stmt) {
+ Comment cmnt(masm_, "[ Block");
+ SetStatementPosition(stmt);
+ VisitStatements(stmt->statements());
+}
+
+
+void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
+ Comment cmnt(masm_, "[ ExpressionStatement");
+ SetStatementPosition(stmt);
+ Visit(stmt->expression());
+}
+
+
void FastCodeGenerator::VisitEmptyStatement(EmptyStatement* stmt) {
Comment cmnt(masm_, "[ EmptyStatement");
SetStatementPosition(stmt);
}
+void FastCodeGenerator::VisitLiteral(Literal* expr) {
+ Move(expr->location(), expr);
+}
+
+
void FastCodeGenerator::VisitCatchExtensionObject(CatchExtensionObject* expr) {
UNREACHABLE();
}
private:
int SlotOffset(Slot* slot);
+ void Move(Location destination, Location source);
+
+ void Move(Location destination, Register source);
+ void Move(Location destination, Slot* source);
+ void Move(Location destination, Literal* source);
+
+ void Move(Register destination, Location source);
+ void Move(Slot* destination, Location source);
+
void VisitDeclarations(ZoneList<Declaration*>* declarations);
Handle<JSFunction> BuildBoilerplate(FunctionLiteral* fun);
void DeclareGlobals(Handle<FixedArray> pairs);
}
+void FastCodeGenerator::Move(Location destination, Slot* source) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ break;
+ case Location::TEMP:
+ __ push(Operand(ebp, SlotOffset(source)));
+ break;
+ }
+}
+
+
+void FastCodeGenerator::Move(Location destination, Literal* expr) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ break;
+ case Location::TEMP:
+ __ push(Immediate(expr->handle()));
+ break;
+ }
+}
+
+
+void FastCodeGenerator::Move(Slot* destination, Location source) {
+ switch (source.type()) {
+ case Location::NOWHERE:
+ UNREACHABLE();
+ case Location::TEMP:
+ __ pop(Operand(ebp, SlotOffset(destination)));
+ break;
+ }
+}
+
+
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
__ push(esi); // The context is the first argument.
}
-void FastCodeGenerator::VisitBlock(Block* stmt) {
- Comment cmnt(masm_, "[ Block");
- SetStatementPosition(stmt);
- VisitStatements(stmt->statements());
-}
-
-
-void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
- Comment cmnt(masm_, "[ ExpressionStatement");
- SetStatementPosition(stmt);
- Visit(stmt->expression());
-}
-
-
void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt);
__ mov(eax, expr->AsLiteral()->handle());
} else {
Visit(expr);
- ASSERT(expr->location().is_temporary());
- __ pop(eax);
+ Move(eax, expr->location());
}
if (FLAG_trace) {
__ push(esi);
__ push(Immediate(boilerplate));
__ CallRuntime(Runtime::kNewClosure, 2);
-
- if (expr->location().is_temporary()) {
- __ push(eax);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), eax);
}
// indicate that the inobject property case was inlined. Ensure there
// is no test eax instruction here. Remember that the assembler may
// choose to do peephole optimization (eg, push/pop elimination).
- if (expr->location().is_temporary()) {
- // Replace the global object with the result.
- __ mov(Operand(esp, 0), eax);
- } else {
- ASSERT(expr->location().is_nowhere());
- __ add(Operand(esp), Immediate(kPointerSize));
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ add(Operand(esp), Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ // Replace the global object with the result.
+ __ mov(Operand(esp, 0), eax);
+ break;
}
} else {
Comment cmnt(masm_, "Stack slot");
- Slot* slot = rewrite->AsSlot();
- ASSERT(slot != NULL);
- if (expr->location().is_temporary()) {
- __ push(Operand(ebp, SlotOffset(slot)));
- } else {
- ASSERT(expr->location().is_nowhere());
- }
- }
-}
-
-
-void FastCodeGenerator::VisitLiteral(Literal* expr) {
- if (expr->location().is_temporary()) {
- __ push(Immediate(expr->handle()));
- } else {
- ASSERT(expr->location().is_nowhere());
+ Move(expr->location(), rewrite->AsSlot());
}
}
case ObjectLiteral::Property::COMPUTED:
if (key->handle()->IsSymbol()) {
Visit(value);
- ASSERT(value->location().is_temporary());
- __ pop(eax);
+ Move(eax, value->location());
__ mov(ecx, Immediate(key->handle()));
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
default: UNREACHABLE();
}
}
- if (expr->location().is_nowhere() && result_saved) {
- __ add(Operand(esp), Immediate(kPointerSize));
- } else if (expr->location().is_temporary() && !result_saved) {
- __ push(eax);
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ if (!result_saved) __ push(eax);
+ break;
}
}
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
// Label done:
__ bind(&done);
- if (expr->location().is_temporary()) {
- __ push(eax);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), eax);
}
__ RecordWrite(ebx, offset, eax, ecx);
}
- Location destination = expr->location();
- if (destination.is_nowhere() && result_saved) {
- __ add(Operand(esp), Immediate(kPointerSize));
- } else if (destination.is_temporary() && !result_saved) {
- __ push(eax);
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ if (result_saved) __ add(Operand(esp), Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ if (!result_saved) __ push(eax);
+ break;
}
}
ASSERT(var->is_global() || var->slot() != NULL);
Expression* rhs = expr->value();
- Location destination = expr->location();
if (var->is_global()) {
// Assignment to a global variable, use inline caching. Right-hand-side
// value is passed in eax, variable name in ecx, and the global object
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- if (destination.is_temporary()) {
- __ mov(Operand(esp, 0), eax);
- } else {
- ASSERT(destination.is_nowhere());
- __ add(Operand(esp), Immediate(kPointerSize));
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ add(Operand(esp), Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ __ mov(Operand(esp, 0), eax);
+ break;
}
} else {
// Local or parameter assignment.
// discarded result. Always perform the assignment.
__ mov(eax, rhs->AsLiteral()->handle());
__ mov(Operand(ebp, SlotOffset(var->slot())), eax);
- if (destination.is_temporary()) {
- // Case 'temp <- (var = constant)'. Save result.
- __ push(eax);
- }
+ Move(expr->location(), eax);
} else {
ASSERT(rhs->location().is_temporary());
Visit(rhs);
- if (destination.is_temporary()) {
- // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
- // temporary on the stack.
- __ mov(eax, Operand(esp, 0));
- __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
- } else {
- ASSERT(destination.is_nowhere());
- // Case 'var = temp'. Discard right-hand-side temporary.
- __ pop(Operand(ebp, SlotOffset(var->slot())));
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ // Case 'var = temp'. Discard right-hand-side temporary.
+ Move(var->slot(), rhs->location());
+ break;
+ case Location::TEMP:
+ // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
+ // temporary on the stack.
+ __ mov(eax, Operand(esp, 0));
+ __ mov(Operand(ebp, SlotOffset(var->slot())), eax);
+ break;
}
}
}
// Restore context register.
__ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS.
- if (expr->location().is_temporary()) {
- __ mov(Operand(esp, 0), eax);
- } else {
- ASSERT(expr->location().is_nowhere());
- __ add(Operand(esp), Immediate(kPointerSize));
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ add(Operand(esp), Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ __ mov(Operand(esp, 0), eax);
+ break;
}
}
}
__ CallRuntime(function, arg_count);
- if (expr->location().is_temporary()) {
- __ push(eax);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), eax);
}
} else {
Visit(left);
ASSERT(left->location().is_temporary());
- if (destination.is_temporary()) {
- // Copy the left-hand value into eax because we may need it as the
- // final result.
- __ mov(eax, Operand(esp, 0));
- } else {
- // Pop the left-hand value into eax because we will not need it as the
- // final result.
- __ pop(eax);
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ // Pop the left-hand value into eax because we will not need it as the
+ // final result.
+ __ pop(eax);
+ break;
+ case Location::TEMP:
+ // Copy the left-hand value into eax because we may need it as the
+ // final result.
+ __ mov(eax, Operand(esp, 0));
+ break;
}
}
// The left-hand value is in eax. It is also on the stack iff the
}
// Save or discard the right-hand value as needed.
if (right->AsLiteral() != NULL) {
- if (destination.is_temporary()) {
- __ push(Immediate(right->AsLiteral()->handle()));
- } else {
- ASSERT(destination.is_nowhere());
- }
+ Move(destination, right->AsLiteral());
} else {
Visit(right);
- ASSERT(right->location().is_temporary());
- if (destination.is_nowhere()) {
- __ add(Operand(esp), Immediate(kPointerSize));
- } else {
- ASSERT(destination.is_temporary());
- }
+ Move(destination, right->location());
}
__ bind(&done);
class Location BASE_EMBEDDED {
public:
+ enum Type { NOWHERE, TEMP };
+
static Location Temporary() { return Location(TEMP); }
static Location Nowhere() { return Location(NOWHERE); }
bool is_temporary() { return type_ == TEMP; }
bool is_nowhere() { return type_ == NOWHERE; }
- private:
- enum Type { TEMP, NOWHERE };
+ Type type() { return type_; }
+ private:
explicit Location(Type type) : type_(type) {}
Type type_;
}
+void FastCodeGenerator::Move(Location destination, Slot* source) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ break;
+ case Location::TEMP:
+ __ push(Operand(rbp, SlotOffset(source)));
+ break;
+ }
+}
+
+
+void FastCodeGenerator::Move(Location destination, Literal* expr) {
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ break;
+ case Location::TEMP:
+ __ Push(expr->handle());
+ break;
+ }
+}
+
+
+void FastCodeGenerator::Move(Slot* destination, Location source) {
+ switch (source.type()) {
+ case Location::NOWHERE:
+ UNREACHABLE();
+ case Location::TEMP:
+ __ pop(Operand(rbp, SlotOffset(destination)));
+ break;
+ }
+}
+
+
void FastCodeGenerator::DeclareGlobals(Handle<FixedArray> pairs) {
// Call the runtime to declare the globals.
__ push(rsi); // The context is the first argument.
}
-void FastCodeGenerator::VisitBlock(Block* stmt) {
- Comment cmnt(masm_, "[ Block");
- SetStatementPosition(stmt);
- VisitStatements(stmt->statements());
-}
-
-
-void FastCodeGenerator::VisitExpressionStatement(ExpressionStatement* stmt) {
- Comment cmnt(masm_, "[ ExpressionStatement");
- SetStatementPosition(stmt);
- Visit(stmt->expression());
-}
-
-
void FastCodeGenerator::VisitReturnStatement(ReturnStatement* stmt) {
Comment cmnt(masm_, "[ ReturnStatement");
SetStatementPosition(stmt);
__ Move(rax, expr->AsLiteral()->handle());
} else {
Visit(expr);
- ASSERT(expr->location().is_temporary());
- __ pop(rax);
+ Move(rax, expr->location());
}
if (FLAG_trace) {
__ push(rsi);
__ Push(boilerplate);
__ CallRuntime(Runtime::kNewClosure, 2);
-
- if (expr->location().is_temporary()) {
- __ push(rax);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), rax);
}
// A test rax instruction following the call is used by the IC to
// indicate that the inobject property case was inlined. Ensure there
// is no test rax instruction here.
- if (expr->location().is_temporary()) {
- // Replace the global object with the result.
- __ movq(Operand(rsp, 0), rax);
- } else {
- ASSERT(expr->location().is_nowhere());
- __ addq(rsp, Immediate(kPointerSize));
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ addq(rsp, Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ // Replace the global object with the result.
+ __ movq(Operand(rsp, 0), rax);
+ break;
}
} else {
Comment cmnt(masm_, "Stack slot");
- Slot* slot = rewrite->AsSlot();
- ASSERT(slot != NULL);
- if (expr->location().is_temporary()) {
- __ push(Operand(rbp, SlotOffset(slot)));
- } else {
- ASSERT(expr->location().is_nowhere());
- }
- }
-}
-
-
-void FastCodeGenerator::VisitLiteral(Literal* expr) {
- if (expr->location().is_temporary()) {
- __ Push(expr->handle());
- } else {
- ASSERT(expr->location().is_nowhere());
+ Move(expr->location(), rewrite->AsSlot());
}
}
default: UNREACHABLE();
}
}
- if (expr->location().is_nowhere() && result_saved) {
- __ addq(rsp, Immediate(kPointerSize));
- } else if (expr->location().is_temporary() && !result_saved) {
- __ push(rax);
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ if (result_saved) __ addq(rsp, Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ if (!result_saved) __ push(rax);
+ break;
}
}
__ CallRuntime(Runtime::kMaterializeRegExpLiteral, 4);
// Label done:
__ bind(&done);
- if (expr->location().is_temporary()) {
- __ push(rax);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), rax);
}
__ RecordWrite(rbx, offset, rax, rcx);
}
- Location destination = expr->location();
- if (destination.is_nowhere() && result_saved) {
- __ addq(rsp, Immediate(kPointerSize));
- } else if (destination.is_temporary() && !result_saved) {
- __ push(rax);
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ if (result_saved) __ addq(rsp, Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ if (!result_saved) __ push(rax);
+ break;
}
}
Handle<Code> ic(Builtins::builtin(Builtins::StoreIC_Initialize));
__ Call(ic, RelocInfo::CODE_TARGET);
// Overwrite the global object on the stack with the result if needed.
- if (destination.is_temporary()) {
- __ movq(Operand(rsp, 0), rax);
- } else {
- __ addq(rsp, Immediate(kPointerSize));
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ addq(rsp, Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ __ movq(Operand(rsp, 0), rax);
+ break;
}
} else {
// Local or parameter assignment.
// discarded result. Always perform the assignment.
__ Move(kScratchRegister, rhs->AsLiteral()->handle());
__ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
- if (destination.is_temporary()) {
- // Case 'temp <- (var = constant)'. Save result.
- __ push(kScratchRegister);
- }
+ Move(expr->location(), kScratchRegister);
} else {
ASSERT(rhs->location().is_temporary());
Visit(rhs);
- if (destination.is_temporary()) {
- // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side temporary
- // on the stack.
- __ movq(kScratchRegister, Operand(rsp, 0));
- __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
- } else {
- ASSERT(destination.is_nowhere());
- // Case 'var = temp'. Discard right-hand-side temporary.
- __ pop(Operand(rbp, SlotOffset(var->slot())));
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ // Case 'var = temp'. Discard right-hand-side temporary.
+ Move(var->slot(), rhs->location());
+ break;
+ case Location::TEMP:
+ // Case 'temp1 <- (var = temp0)'. Preserve right-hand-side
+ // temporary on the stack.
+ __ movq(kScratchRegister, Operand(rsp, 0));
+ __ movq(Operand(rbp, SlotOffset(var->slot())), kScratchRegister);
+ break;
}
}
}
// Restore context register.
__ movq(rsi, Operand(rbp, StandardFrameConstants::kContextOffset));
// Discard the function left on TOS.
- if (expr->location().is_temporary()) {
- __ movq(Operand(rsp, 0), rax);
- } else {
- ASSERT(expr->location().is_nowhere());
- __ addq(rsp, Immediate(kPointerSize));
+ switch (expr->location().type()) {
+ case Location::NOWHERE:
+ __ addq(rsp, Immediate(kPointerSize));
+ break;
+ case Location::TEMP:
+ __ movq(Operand(rsp, 0), rax);
+ break;
}
}
}
__ CallRuntime(function, arg_count);
- if (expr->location().is_temporary()) {
- __ push(rax);
- } else {
- ASSERT(expr->location().is_nowhere());
- }
+ Move(expr->location(), rax);
}
} else {
Visit(left);
ASSERT(left->location().is_temporary());
- if (destination.is_temporary()) {
- // Copy the left-hand value into rax because we may need it as the
- // final result.
- __ movq(rax, Operand(rsp, 0));
- } else {
- // Pop the left-hand value into rax because we will not need it as the
- // final result.
- __ pop(rax);
+ switch (destination.type()) {
+ case Location::NOWHERE:
+ // Pop the left-hand value into rax because we will not need it as the
+ // final result.
+ __ pop(rax);
+ break;
+ case Location::TEMP:
+ // Copy the left-hand value into rax because we may need it as the
+ // final result.
+ __ movq(rax, Operand(rsp, 0));
+ break;
}
}
// The left-hand value is in rax. It is also on the stack iff the
}
// Save or discard the right-hand value as needed.
if (right->AsLiteral() != NULL) {
- if (destination.is_temporary()) {
- __ Push(right->AsLiteral()->handle());
- } else {
- ASSERT(destination.is_nowhere());
- }
+ Move(destination, right->AsLiteral());
} else {
Visit(right);
- ASSERT(right->location().is_temporary());
- if (destination.is_nowhere()) {
- __ addq(rsp, Immediate(kPointerSize));
- } else {
- ASSERT(destination.is_temporary());
- }
+ Move(destination, right->location());
}
__ bind(&done);