From 5e557d3624a6b0047023ff713a12d470e0a50b72 Mon Sep 17 00:00:00 2001 From: "ricow@chromium.org" Date: Fri, 14 Jan 2011 10:27:25 +0000 Subject: [PATCH] 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 --- src/arm/lithium-arm.cc | 2 +- src/ia32/lithium-ia32.cc | 2 +- src/x64/assembler-x64.h | 1 + src/x64/lithium-codegen-x64.cc | 48 ++++++++++++++--- src/x64/lithium-x64.cc | 120 ++++++++++++++++++++++++++++++++++++----- src/x64/macro-assembler-x64.cc | 2 - 6 files changed, 153 insertions(+), 22 deletions(-) diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc index 041c034..a7dd71b 100644 --- a/src/arm/lithium-arm.cc +++ b/src/arm/lithium-arm.cc @@ -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; } } diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc index 8290310..a815b04 100644 --- a/src/ia32/lithium-ia32.cc +++ b/src/ia32/lithium-ia32.cc @@ -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; } } diff --git a/src/x64/assembler-x64.h b/src/x64/assembler-x64.h index 6822c1c..8b7f60a 100644 --- a/src/x64/assembler-x64.h +++ b/src/x64/assembler-x64.h @@ -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_; diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc index bca6cb1..e0250a0 100644 --- a/src/x64/lithium-codegen-x64.cc +++ b/src/x64/lithium-codegen-x64.cc @@ -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 copy = Vector::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); + } diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc index c8418bf..4a7b3aa 100644 --- a/src/x64/lithium-x64.cc +++ b/src/x64/lithium-x64.cc @@ -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); } diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc index 2846fe2..f95755d 100644 --- a/src/x64/macro-assembler-x64.cc +++ b/src/x64/macro-assembler-x64.cc @@ -1274,8 +1274,6 @@ void MacroAssembler::Move(Register dst, Register src) { } - - void MacroAssembler::Move(Register dst, Handle source) { ASSERT(!source->IsFailure()); if (source->IsSmi()) { -- 2.7.4