| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index 3c6187d9d41aaccaa95d5788f086b954caf66121..9dca6b3e20a4fccd4f006cf20c110784eb44d538 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -1947,6 +1947,25 @@ void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoIsNumberAndBranch(LIsNumberAndBranch* instr) {
|
| + Representation r = instr->hydrogen()->value()->representation();
|
| + if (r.IsSmiOrInteger32() || r.IsDouble()) {
|
| + EmitBranch(instr, no_condition);
|
| + } else {
|
| + ASSERT(r.IsTagged());
|
| + Register reg = ToRegister(instr->value());
|
| + HType type = instr->hydrogen()->value()->type();
|
| + if (type.IsTaggedNumber()) {
|
| + EmitBranch(instr, no_condition);
|
| + }
|
| + __ JumpIfSmi(reg, instr->TrueLabel(chunk_));
|
| + __ CompareRoot(FieldOperand(reg, HeapObject::kMapOffset),
|
| + Heap::kHeapNumberMapRootIndex);
|
| + EmitBranch(instr, equal);
|
| + }
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoBranch(LBranch* instr) {
|
| Representation r = instr->hydrogen()->value()->representation();
|
| if (r.IsInteger32()) {
|
| @@ -2780,7 +2799,6 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
|
| int offset = access.offset();
|
|
|
| if (access.IsExternalMemory()) {
|
| - ASSERT(!access.representation().IsInteger32());
|
| Register result = ToRegister(instr->result());
|
| if (instr->object()->IsConstantOperand()) {
|
| ASSERT(result.is(rax));
|
| @@ -2802,18 +2820,10 @@ void LCodeGen::DoLoadNamedField(LLoadNamedField* instr) {
|
|
|
| Register result = ToRegister(instr->result());
|
| if (access.IsInobject()) {
|
| - if (access.representation().IsInteger32()) {
|
| - __ movl(result, FieldOperand(object, offset));
|
| - } else {
|
| - __ movq(result, FieldOperand(object, offset));
|
| - }
|
| + __ movq(result, FieldOperand(object, offset));
|
| } else {
|
| __ movq(result, FieldOperand(object, JSObject::kPropertiesOffset));
|
| - if (access.representation().IsInteger32()) {
|
| - __ movl(result, FieldOperand(result, offset));
|
| - } else {
|
| - __ movq(result, FieldOperand(result, offset));
|
| - }
|
| + __ movq(result, FieldOperand(result, offset));
|
| }
|
| }
|
|
|
| @@ -3510,7 +3520,7 @@ void LCodeGen::DoMathFloor(LMathFloor* instr) {
|
| __ bind(&negative_sign);
|
| // Truncate, then compare and compensate.
|
| __ cvttsd2si(output_reg, input_reg);
|
| - __ Cvtlsi2sd(xmm_scratch, output_reg);
|
| + __ cvtlsi2sd(xmm_scratch, output_reg);
|
| __ ucomisd(input_reg, xmm_scratch);
|
| __ j(equal, &done, Label::kNear);
|
| __ subl(output_reg, Immediate(1));
|
| @@ -3559,7 +3569,7 @@ void LCodeGen::DoMathRound(LMathRound* instr) {
|
| __ RecordComment("D2I conversion overflow");
|
| DeoptimizeIf(equal, instr->environment());
|
|
|
| - __ Cvtlsi2sd(xmm_scratch, output_reg);
|
| + __ cvtlsi2sd(xmm_scratch, output_reg);
|
| __ ucomisd(input_reg, xmm_scratch);
|
| __ j(equal, &restore, Label::kNear);
|
| __ subl(output_reg, Immediate(1));
|
| @@ -3926,7 +3936,6 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| int offset = access.offset();
|
|
|
| if (access.IsExternalMemory()) {
|
| - ASSERT(!access.representation().IsInteger32());
|
| ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
|
| Register value = ToRegister(instr->value());
|
| if (instr->object()->IsConstantOperand()) {
|
| @@ -4004,24 +4013,15 @@ void LCodeGen::DoStoreNamedField(LStoreNamedField* instr) {
|
| if (instr->value()->IsConstantOperand()) {
|
| LConstantOperand* operand_value = LConstantOperand::cast(instr->value());
|
| if (operand_value->IsRegister()) {
|
| - if (access.representation().IsInteger32()) {
|
| - __ movl(FieldOperand(write_register, offset),
|
| - ToRegister(operand_value));
|
| - } else {
|
| - __ movq(FieldOperand(write_register, offset),
|
| - ToRegister(operand_value));
|
| - }
|
| + __ movq(FieldOperand(write_register, offset),
|
| + ToRegister(operand_value));
|
| } else {
|
| Handle<Object> handle_value = ToHandle(operand_value);
|
| ASSERT(!instr->hydrogen()->NeedsWriteBarrier());
|
| __ Move(FieldOperand(write_register, offset), handle_value);
|
| }
|
| } else {
|
| - if (access.representation().IsInteger32()) {
|
| - __ movl(FieldOperand(write_register, offset), ToRegister(instr->value()));
|
| - } else {
|
| - __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));
|
| - }
|
| + __ movq(FieldOperand(write_register, offset), ToRegister(instr->value()));
|
| }
|
|
|
| if (instr->hydrogen()->NeedsWriteBarrier()) {
|
| @@ -4449,9 +4449,9 @@ void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
|
| LOperand* output = instr->result();
|
| ASSERT(output->IsDoubleRegister());
|
| if (input->IsRegister()) {
|
| - __ Cvtlsi2sd(ToDoubleRegister(output), ToRegister(input));
|
| + __ cvtlsi2sd(ToDoubleRegister(output), ToRegister(input));
|
| } else {
|
| - __ Cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
|
| + __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
|
| }
|
| }
|
|
|
| @@ -4623,7 +4623,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
| bool deoptimize_on_minus_zero,
|
| LEnvironment* env,
|
| NumberUntagDMode mode) {
|
| - Label convert, load_smi, done;
|
| + Label load_smi, done;
|
|
|
| if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
|
| // Smi check.
|
| @@ -4632,17 +4632,25 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
| // Heap number map check.
|
| __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
|
| Heap::kHeapNumberMapRootIndex);
|
| -
|
| - // On x64 it is safe to load at heap number offset before evaluating the map
|
| - // check, since all heap objects are at least two words long.
|
| - __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
| -
|
| - if (can_convert_undefined_to_nan) {
|
| - __ j(not_equal, &convert);
|
| + if (!can_convert_undefined_to_nan) {
|
| + DeoptimizeIf(not_equal, env);
|
| } else {
|
| + Label heap_number, convert;
|
| + __ j(equal, &heap_number, Label::kNear);
|
| +
|
| + // Convert undefined (and hole) to NaN. Compute NaN as 0/0.
|
| + __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
|
| DeoptimizeIf(not_equal, env);
|
| - }
|
|
|
| + __ bind(&convert);
|
| + __ xorps(result_reg, result_reg);
|
| + __ divsd(result_reg, result_reg);
|
| + __ jmp(&done, Label::kNear);
|
| +
|
| + __ bind(&heap_number);
|
| + }
|
| + // Heap number to XMM conversion.
|
| + __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
|
| if (deoptimize_on_minus_zero) {
|
| XMMRegister xmm_scratch = xmm0;
|
| __ xorps(xmm_scratch, xmm_scratch);
|
| @@ -4653,18 +4661,6 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
| DeoptimizeIf(not_zero, env);
|
| }
|
| __ jmp(&done, Label::kNear);
|
| -
|
| - if (can_convert_undefined_to_nan) {
|
| - __ bind(&convert);
|
| -
|
| - // Convert undefined (and hole) to NaN. Compute NaN as 0/0.
|
| - __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
|
| - DeoptimizeIf(not_equal, env);
|
| -
|
| - __ xorps(result_reg, result_reg);
|
| - __ divsd(result_reg, result_reg);
|
| - __ jmp(&done, Label::kNear);
|
| - }
|
| } else {
|
| ASSERT(mode == NUMBER_CANDIDATE_IS_SMI);
|
| }
|
| @@ -4672,7 +4668,7 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
| // Smi to XMM conversion
|
| __ bind(&load_smi);
|
| __ SmiToInteger32(kScratchRegister, input_reg);
|
| - __ Cvtlsi2sd(result_reg, kScratchRegister);
|
| + __ cvtlsi2sd(result_reg, kScratchRegister);
|
| __ bind(&done);
|
| }
|
|
|
| @@ -4725,16 +4721,12 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
|
| LOperand* input = instr->value();
|
| ASSERT(input->IsRegister());
|
| ASSERT(input->Equals(instr->result()));
|
| - Register input_reg = ToRegister(input);
|
|
|
| - if (instr->hydrogen()->value()->representation().IsSmi()) {
|
| - __ SmiToInteger32(input_reg, input_reg);
|
| - } else {
|
| - DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
|
| - __ JumpIfNotSmi(input_reg, deferred->entry());
|
| - __ SmiToInteger32(input_reg, input_reg);
|
| - __ bind(deferred->exit());
|
| - }
|
| + Register input_reg = ToRegister(input);
|
| + DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
|
| + __ JumpIfNotSmi(input_reg, deferred->entry());
|
| + __ SmiToInteger32(input_reg, input_reg);
|
| + __ bind(deferred->exit());
|
| }
|
|
|
|
|
|
|