X64 Crankshaft: Add Typeof and TypeofIs to x64 lithium. Fix presubmit.

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6912 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
whesse@chromium.org 2011-02-23 11:29:11 +00:00
parent a0b8d5a55c
commit 65443b3879
2 changed files with 71 additions and 46 deletions

View File

@ -322,8 +322,7 @@ int LCodeGen::ToInteger32(LConstantOperand* op) const {
Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const { Handle<Object> LCodeGen::ToHandle(LConstantOperand* op) const {
Handle<Object> literal = chunk_->LookupLiteral(op); Handle<Object> literal = chunk_->LookupLiteral(op);
Representation r = chunk_->LookupLiteralRepresentation(op); ASSERT(chunk_->LookupLiteralRepresentation(op).IsTagged());
ASSERT(r.IsTagged());
return literal; return literal;
} }
@ -3175,63 +3174,42 @@ void LCodeGen::DoFunctionLiteral(LFunctionLiteral* instr) {
void LCodeGen::DoTypeof(LTypeof* instr) { void LCodeGen::DoTypeof(LTypeof* instr) {
Abort("Unimplemented: %s", "DoTypeof"); LOperand* input = instr->InputAt(0);
if (input->IsConstantOperand()) {
__ Push(ToHandle(LConstantOperand::cast(input)));
} else if (input->IsRegister()) {
__ push(ToRegister(input));
} else {
ASSERT(input->IsStackSlot());
__ push(ToOperand(input));
}
CallRuntime(Runtime::kTypeof, 1, instr);
} }
void LCodeGen::DoTypeofIs(LTypeofIs* instr) { void LCodeGen::DoTypeofIs(LTypeofIs* instr) {
Abort("Unimplemented: %s", "DoTypeofIs"); Register input = ToRegister(instr->InputAt(0));
}
void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
Register result = ToRegister(instr->result()); Register result = ToRegister(instr->result());
NearLabel true_label; Label true_label;
NearLabel false_label; Label false_label;
NearLabel done; NearLabel done;
EmitIsConstructCall(result); Condition final_branch_condition = EmitTypeofIs(&true_label,
__ j(equal, &true_label); &false_label,
input,
instr->type_literal());
__ j(final_branch_condition, &true_label);
__ bind(&false_label);
__ LoadRoot(result, Heap::kFalseValueRootIndex); __ LoadRoot(result, Heap::kFalseValueRootIndex);
__ jmp(&done); __ jmp(&done);
__ bind(&true_label); __ bind(&true_label);
__ LoadRoot(result, Heap::kTrueValueRootIndex); __ LoadRoot(result, Heap::kTrueValueRootIndex);
__ bind(&done); __ bind(&done);
} }
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
Register temp = ToRegister(instr->TempAt(0));
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
EmitIsConstructCall(temp);
EmitBranch(true_block, false_block, equal);
}
void LCodeGen::EmitIsConstructCall(Register temp) {
// Get the frame pointer for the calling frame.
__ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
// Skip the arguments adaptor frame if it exists.
NearLabel check_frame_marker;
__ SmiCompare(Operand(temp, StandardFrameConstants::kContextOffset),
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ j(not_equal, &check_frame_marker);
__ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
// Check the marker in the calling frame.
__ bind(&check_frame_marker);
__ SmiCompare(Operand(temp, StandardFrameConstants::kMarkerOffset),
Smi::FromInt(StackFrame::CONSTRUCT));
}
void LCodeGen::EmitPushConstantOperand(LOperand* operand) { void LCodeGen::EmitPushConstantOperand(LOperand* operand) {
ASSERT(operand->IsConstantOperand()); ASSERT(operand->IsConstantOperand());
LConstantOperand* const_op = LConstantOperand::cast(operand); LConstantOperand* const_op = LConstantOperand::cast(operand);
@ -3329,6 +3307,54 @@ Condition LCodeGen::EmitTypeofIs(Label* true_label,
} }
void LCodeGen::DoIsConstructCall(LIsConstructCall* instr) {
Register result = ToRegister(instr->result());
NearLabel true_label;
NearLabel false_label;
NearLabel done;
EmitIsConstructCall(result);
__ j(equal, &true_label);
__ LoadRoot(result, Heap::kFalseValueRootIndex);
__ jmp(&done);
__ bind(&true_label);
__ LoadRoot(result, Heap::kTrueValueRootIndex);
__ bind(&done);
}
void LCodeGen::DoIsConstructCallAndBranch(LIsConstructCallAndBranch* instr) {
Register temp = ToRegister(instr->TempAt(0));
int true_block = chunk_->LookupDestination(instr->true_block_id());
int false_block = chunk_->LookupDestination(instr->false_block_id());
EmitIsConstructCall(temp);
EmitBranch(true_block, false_block, equal);
}
void LCodeGen::EmitIsConstructCall(Register temp) {
// Get the frame pointer for the calling frame.
__ movq(temp, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
// Skip the arguments adaptor frame if it exists.
NearLabel check_frame_marker;
__ SmiCompare(Operand(temp, StandardFrameConstants::kContextOffset),
Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
__ j(not_equal, &check_frame_marker);
__ movq(temp, Operand(rax, StandardFrameConstants::kCallerFPOffset));
// Check the marker in the calling frame.
__ bind(&check_frame_marker);
__ SmiCompare(Operand(temp, StandardFrameConstants::kMarkerOffset),
Smi::FromInt(StackFrame::CONSTRUCT));
}
void LCodeGen::DoLazyBailout(LLazyBailout* instr) { void LCodeGen::DoLazyBailout(LLazyBailout* instr) {
// No code for lazy bailout instruction. Used to capture environment after a // No code for lazy bailout instruction. Used to capture environment after a
// call for populating the safepoint data with deoptimization data. // call for populating the safepoint data with deoptimization data.

View File

@ -1951,14 +1951,13 @@ LInstruction* LChunkBuilder::DoAccessArgumentsAt(HAccessArgumentsAt* instr) {
LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) { LInstruction* LChunkBuilder::DoTypeof(HTypeof* instr) {
Abort("Unimplemented: %s", "DoTypeof"); LTypeof* result = new LTypeof(UseAtStart(instr->value()));
return NULL; return MarkAsCall(DefineFixed(result, rax), instr);
} }
LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) { LInstruction* LChunkBuilder::DoTypeofIs(HTypeofIs* instr) {
Abort("Unimplemented: %s", "DoTypeofIs"); return DefineSameAsFirst(new LTypeofIs(UseRegister(instr->value())));
return NULL;
} }