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;
|
||||
|
||||
// Generate inline code for mod of powers of 2 and negative powers of 2.
|
||||
case Token::MOD:
|
||||
if (!reversed &&
|
||||
|
@ -4057,8 +4057,7 @@ void CodeGenerator::GenerateMathPow(ZoneList<Expression*>* args) {
|
||||
|
||||
Label base_not_smi;
|
||||
Label handle_special_cases;
|
||||
__ testl(base.reg(), Immediate(kSmiTagMask));
|
||||
__ j(not_zero, &base_not_smi);
|
||||
__ JumpIfNotSmi(base.reg(), &base_not_smi);
|
||||
__ SmiToInteger32(base.reg(), base.reg());
|
||||
__ cvtlsi2sd(xmm0, base.reg());
|
||||
__ jmp(&handle_special_cases);
|
||||
@ -5965,9 +5964,80 @@ class DeferredInlineBinaryOperation: public DeferredCode {
|
||||
|
||||
|
||||
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);
|
||||
stub.GenerateCall(masm_, left_, right_);
|
||||
if (!dst_.is(rax)) __ movq(dst_, rax);
|
||||
__ bind(&done);
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user