Port handling of heap numbers in deferred code for binary ops from
ia32 to x64. Review URL: http://codereview.chromium.org/1692015 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@4560 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
c815de4f52
commit
b83486c5f6
@ -2339,6 +2339,7 @@ Result CodeGenerator::ConstantSmiBinaryOperation(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// Generate inline code for mod of powers of 2 and negative powers of 2.
|
// Generate inline code for mod of powers of 2 and negative powers of 2.
|
||||||
case Token::MOD:
|
case Token::MOD:
|
||||||
if (!reversed &&
|
if (!reversed &&
|
||||||
|
@ -4057,8 +4057,7 @@ void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
|
|||||||
|
|
||||||
Label base_not_smi;
|
Label base_not_smi;
|
||||||
Label handle_special_cases;
|
Label handle_special_cases;
|
||||||
__ testl(base.reg(), Immediate(kSmiTagMask));
|
__ JumpIfNotSmi(base.reg(), &base_not_smi);
|
||||||
__ j(not_zero, &base_not_smi);
|
|
||||||
__ SmiToInteger32(base.reg(), base.reg());
|
__ SmiToInteger32(base.reg(), base.reg());
|
||||||
__ cvtlsi2sd(xmm0, base.reg());
|
__ cvtlsi2sd(xmm0, base.reg());
|
||||||
__ jmp(&handle_special_cases);
|
__ jmp(&handle_special_cases);
|
||||||
@ -5965,9 +5964,80 @@ class DeferredInlineBinaryOperation: public DeferredCode {
|
|||||||
|
|
||||||
|
|
||||||
void DeferredInlineBinaryOperation::Generate() {
|
void DeferredInlineBinaryOperation::Generate() {
|
||||||
|
Label done;
|
||||||
|
if ((op_ == Token::ADD)
|
||||||
|
|| (op_ ==Token::SUB)
|
||||||
|
|| (op_ == Token::MUL)
|
||||||
|
|| (op_ == Token::DIV)) {
|
||||||
|
Label call_runtime, after_alloc_failure;
|
||||||
|
Label left_smi, right_smi, load_right, do_op;
|
||||||
|
__ JumpIfSmi(left_, &left_smi);
|
||||||
|
__ CompareRoot(FieldOperand(left_, HeapObject::kMapOffset),
|
||||||
|
Heap::kHeapNumberMapRootIndex);
|
||||||
|
__ j(not_equal, &call_runtime);
|
||||||
|
__ movsd(xmm0, FieldOperand(left_, HeapNumber::kValueOffset));
|
||||||
|
if (mode_ == OVERWRITE_LEFT) {
|
||||||
|
__ movq(dst_, left_);
|
||||||
|
}
|
||||||
|
__ jmp(&load_right);
|
||||||
|
|
||||||
|
__ bind(&left_smi);
|
||||||
|
__ SmiToInteger32(left_, left_);
|
||||||
|
__ cvtlsi2sd(xmm0, left_);
|
||||||
|
__ Integer32ToSmi(left_, left_);
|
||||||
|
if (mode_ == OVERWRITE_LEFT) {
|
||||||
|
Label alloc_failure;
|
||||||
|
__ push(left_);
|
||||||
|
__ AllocateHeapNumber(dst_, left_, &after_alloc_failure);
|
||||||
|
__ pop(left_);
|
||||||
|
}
|
||||||
|
|
||||||
|
__ bind(&load_right);
|
||||||
|
__ JumpIfSmi(right_, &right_smi);
|
||||||
|
__ CompareRoot(FieldOperand(right_, HeapObject::kMapOffset),
|
||||||
|
Heap::kHeapNumberMapRootIndex);
|
||||||
|
__ j(not_equal, &call_runtime);
|
||||||
|
__ movsd(xmm1, FieldOperand(right_, HeapNumber::kValueOffset));
|
||||||
|
if (mode_ == OVERWRITE_RIGHT) {
|
||||||
|
__ movq(dst_, right_);
|
||||||
|
} else if (mode_ == NO_OVERWRITE) {
|
||||||
|
Label alloc_failure;
|
||||||
|
__ push(left_);
|
||||||
|
__ AllocateHeapNumber(dst_, left_, &after_alloc_failure);
|
||||||
|
__ pop(left_);
|
||||||
|
}
|
||||||
|
__ jmp(&do_op);
|
||||||
|
|
||||||
|
__ bind(&right_smi);
|
||||||
|
__ SmiToInteger32(right_, right_);
|
||||||
|
__ cvtlsi2sd(xmm1, right_);
|
||||||
|
__ Integer32ToSmi(right_, right_);
|
||||||
|
if (mode_ == OVERWRITE_RIGHT || mode_ == NO_OVERWRITE) {
|
||||||
|
Label alloc_failure;
|
||||||
|
__ push(left_);
|
||||||
|
__ AllocateHeapNumber(dst_, left_, &after_alloc_failure);
|
||||||
|
__ pop(left_);
|
||||||
|
}
|
||||||
|
|
||||||
|
__ bind(&do_op);
|
||||||
|
switch (op_) {
|
||||||
|
case Token::ADD: __ addsd(xmm0, xmm1); break;
|
||||||
|
case Token::SUB: __ subsd(xmm0, xmm1); break;
|
||||||
|
case Token::MUL: __ mulsd(xmm0, xmm1); break;
|
||||||
|
case Token::DIV: __ divsd(xmm0, xmm1); break;
|
||||||
|
default: UNREACHABLE();
|
||||||
|
}
|
||||||
|
__ movsd(FieldOperand(dst_, HeapNumber::kValueOffset), xmm0);
|
||||||
|
__ jmp(&done);
|
||||||
|
|
||||||
|
__ bind(&after_alloc_failure);
|
||||||
|
__ pop(left_);
|
||||||
|
__ bind(&call_runtime);
|
||||||
|
}
|
||||||
GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB);
|
GenericBinaryOpStub stub(op_, mode_, NO_SMI_CODE_IN_STUB);
|
||||||
stub.GenerateCall(masm_, left_, right_);
|
stub.GenerateCall(masm_, left_, right_);
|
||||||
if (!dst_.is(rax)) __ movq(dst_, rax);
|
if (!dst_.is(rax)) __ movq(dst_, rax);
|
||||||
|
__ bind(&done);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user