Commit 5e557d36 authored by ricow@chromium.org's avatar ricow@chromium.org

Add implementations of some more x64 lithium methods.

This puts us very close to being able to compile the empty function.

This changes only has a small number of 64 bit specific assembler instructions.

The remaining changes are much more platform specific and will go in another change.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6306 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 9b7525fa
......@@ -1583,7 +1583,7 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
} else if (r.IsTagged()) {
return DefineAsRegister(new LConstantT(instr->handle()));
} else {
Abort("unsupported constant of type double");
UNREACHABLE();
return NULL;
}
}
......
......@@ -1614,7 +1614,7 @@ LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
} else if (r.IsTagged()) {
return DefineAsRegister(new LConstantT(instr->handle()));
} else {
Abort("unsupported constant of type double");
UNREACHABLE();
return NULL;
}
}
......
......@@ -215,6 +215,7 @@ struct XMMRegister {
}
bool is_valid() const { return 0 <= code_ && code_ < kNumRegisters; }
bool is(XMMRegister reg) const { return code_ == reg.code_; }
int code() const {
ASSERT(is_valid());
return code_;
......
......@@ -73,13 +73,26 @@ void LCodeGen::Abort(const char* format, ...) {
void LCodeGen::Comment(const char* format, ...) {
Abort("Unimplemented: %s", "Comment");
if (!FLAG_code_comments) return;
char buffer[4 * KB];
StringBuilder builder(buffer, ARRAY_SIZE(buffer));
va_list arguments;
va_start(arguments, format);
builder.AddFormattedList(format, arguments);
va_end(arguments);
// Copy the string before recording it in the assembler to avoid
// issues when the stack allocated buffer goes out of scope.
size_t length = builder.position();
Vector<char> copy = Vector<char>::New(length + 1);
memcpy(copy.start(), builder.Finalize(), copy.length());
masm()->RecordComment(copy.start());
}
bool LCodeGen::GeneratePrologue() {
Abort("Unimplemented: %s", "GeneratePrologue");
return !is_aborted();
return false;
}
......@@ -131,7 +144,7 @@ bool LCodeGen::GenerateDeferredCode() {
bool LCodeGen::GenerateSafepointTable() {
Abort("Unimplemented: %s", "GeneratePrologue");
return !is_aborted();
return false;
}
......@@ -487,7 +500,8 @@ void LCodeGen::DoConstantD(LConstantD* instr) {
void LCodeGen::DoConstantT(LConstantT* instr) {
Abort("Unimplemented: %s", "DoConstantT");
ASSERT(instr->result()->IsRegister());
__ Move(ToRegister(instr->result()), instr->value());
}
......@@ -561,7 +575,20 @@ void LCodeGen::DoDeferredStackCheck(LGoto* instr) {
void LCodeGen::DoGoto(LGoto* instr) {
Abort("Unimplemented: %s", "DoGoto");
class DeferredStackCheck: public LDeferredCode {
public:
DeferredStackCheck(LCodeGen* codegen, LGoto* instr)
: LDeferredCode(codegen), instr_(instr) { }
virtual void Generate() { codegen()->DoDeferredStackCheck(instr_); }
private:
LGoto* instr_;
};
DeferredStackCheck* deferred = NULL;
if (instr->include_stack_check()) {
deferred = new DeferredStackCheck(this, instr);
}
EmitGoto(instr->block_id(), deferred);
}
......@@ -759,7 +786,16 @@ void LCodeGen::DoCmpTAndBranch(LCmpTAndBranch* instr) {
void LCodeGen::DoReturn(LReturn* instr) {
Abort("Unimplemented: %s", "DoReturn");
if (FLAG_trace) {
// Preserve the return value on the stack and rely on the runtime
// call to return the value in the same register.
__ push(rax);
__ CallRuntime(Runtime::kTraceExit, 1);
}
__ movq(rsp, rbp);
__ pop(rbp);
__ ret((ParameterCount() + 1) * kPointerSize);
}
......
......@@ -738,7 +738,65 @@ LInstruction* LChunkBuilder::DoArithmeticT(Token::Value op,
}
void LChunkBuilder::DoBasicBlock(HBasicBlock* block, HBasicBlock* next_block) {
Abort("Unimplemented: %s", "DoBasicBlock");
ASSERT(is_building());
current_block_ = block;
next_block_ = next_block;
if (block->IsStartBlock()) {
block->UpdateEnvironment(graph_->start_environment());
argument_count_ = 0;
} else if (block->predecessors()->length() == 1) {
// We have a single predecessor => copy environment and outgoing
// argument count from the predecessor.
ASSERT(block->phis()->length() == 0);
HBasicBlock* pred = block->predecessors()->at(0);
HEnvironment* last_environment = pred->last_environment();
ASSERT(last_environment != NULL);
// Only copy the environment, if it is later used again.
if (pred->end()->SecondSuccessor() == NULL) {
ASSERT(pred->end()->FirstSuccessor() == block);
} else {
if (pred->end()->FirstSuccessor()->block_id() > block->block_id() ||
pred->end()->SecondSuccessor()->block_id() > block->block_id()) {
last_environment = last_environment->Copy();
}
}
block->UpdateEnvironment(last_environment);
ASSERT(pred->argument_count() >= 0);
argument_count_ = pred->argument_count();
} else {
// We are at a state join => process phis.
HBasicBlock* pred = block->predecessors()->at(0);
// No need to copy the environment, it cannot be used later.
HEnvironment* last_environment = pred->last_environment();
for (int i = 0; i < block->phis()->length(); ++i) {
HPhi* phi = block->phis()->at(i);
last_environment->SetValueAt(phi->merged_index(), phi);
}
for (int i = 0; i < block->deleted_phis()->length(); ++i) {
last_environment->SetValueAt(block->deleted_phis()->at(i),
graph_->GetConstantUndefined());
}
block->UpdateEnvironment(last_environment);
// Pick up the outgoing argument count of one of the predecessors.
argument_count_ = pred->argument_count();
}
HInstruction* current = block->first();
int start = chunk_->instructions()->length();
while (current != NULL && !is_aborted()) {
// Code for constants in registers is generated lazily.
if (!current->EmitAtUses()) {
VisitInstruction(current);
}
current = current->next();
}
int end = chunk_->instructions()->length() - 1;
if (end >= start) {
block->set_first_instruction_index(start);
block->set_last_instruction_index(end);
}
block->set_argument_count(argument_count_);
next_block_ = NULL;
current_block_ = NULL;
}
......@@ -808,8 +866,11 @@ LEnvironment* LChunkBuilder::CreateEnvironment(HEnvironment* hydrogen_env) {
LInstruction* LChunkBuilder::DoGoto(HGoto* instr) {
Abort("Unimplemented: %s", "DoGoto");
return NULL;
LGoto* result = new LGoto(instr->FirstSuccessor()->block_id(),
instr->include_stack_check());
return (instr->include_stack_check())
? AssignPointerMap(result)
: result;
}
......@@ -1131,14 +1192,24 @@ LInstruction* LChunkBuilder::DoCheckMap(HCheckMap* instr) {
LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
Abort("Unimplemented: %s", "DoReturn");
return NULL;
return new LReturn(UseFixed(instr->value(), rax));
}
LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
Abort("Unimplemented: %s", "DoConstant");
return NULL;
Representation r = instr->representation();
if (r.IsInteger32()) {
int32_t value = instr->Integer32Value();
return DefineAsRegister(new LConstantI(value));
} else if (r.IsDouble()) {
double value = instr->DoubleValue();
return DefineAsRegister(new LConstantD(value));
} else if (r.IsTagged()) {
return DefineAsRegister(new LConstantT(instr->handle()));
} else {
UNREACHABLE();
return NULL;
}
}
......@@ -1254,8 +1325,8 @@ LInstruction* LChunkBuilder::DoOsrEntry(HOsrEntry* instr) {
LInstruction* LChunkBuilder::DoParameter(HParameter* instr) {
Abort("Unimplemented: %s", "DoParameter");
return NULL;
int spill_index = chunk()->GetParameterStackSlot(instr->index());
return DefineAsSpilled(new LParameter, spill_index);
}
......@@ -1295,14 +1366,39 @@ LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
}
LInstruction* LChunkBuilder::DoSimulate(HSimulate* instr) {
Abort("Unimplemented: %s", "DoSimulate");
HEnvironment* env = current_block_->last_environment();
ASSERT(env != NULL);
env->set_ast_id(instr->ast_id());
env->Drop(instr->pop_count());
for (int i = 0; i < instr->values()->length(); ++i) {
HValue* value = instr->values()->at(i);
if (instr->HasAssignedIndexAt(i)) {
env->Bind(instr->GetAssignedIndexAt(i), value);
} else {
env->Push(value);
}
}
ASSERT(env->length() == instr->environment_length());
// If there is an instruction pending deoptimization environment create a
// lazy bailout instruction to capture the environment.
if (pending_deoptimization_ast_id_ == instr->ast_id()) {
LLazyBailout* lazy_bailout = new LLazyBailout;
LInstruction* result = AssignEnvironment(lazy_bailout);
instructions_pending_deoptimization_environment_->
set_deoptimization_environment(result->environment());
ClearInstructionPendingDeoptimizationEnvironment();
return result;
}
return NULL;
}
LInstruction* LChunkBuilder::DoStackCheck(HStackCheck* instr) {
Abort("Unimplemented: %s", "DoStackCheck");
return NULL;
return MarkAsCall(new LStackCheck, instr);
}
......
......@@ -1274,8 +1274,6 @@ void MacroAssembler::Move(Register dst, Register src) {
}
void MacroAssembler::Move(Register dst, Handle<Object> source) {
ASSERT(!source->IsFailure());
if (source->IsSmi()) {
......
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