| Index: src/x64/lithium-codegen-x64.cc
|
| diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
|
| index cc635100b18dcab10c9e4e9c02aee8ab50206464..ef715a07653b9a6a38bbfb5d80883e21e2585fed 100644
|
| --- a/src/x64/lithium-codegen-x64.cc
|
| +++ b/src/x64/lithium-codegen-x64.cc
|
| @@ -1886,6 +1886,13 @@ void LCodeGen::EmitBranch(InstrType instr, Condition cc) {
|
| }
|
|
|
|
|
| +template<class InstrType>
|
| +void LCodeGen::EmitFalseBranch(InstrType instr, Condition cc) {
|
| + int false_block = instr->FalseDestination(chunk_);
|
| + __ j(cc, chunk_->GetAssemblyLabel(false_block));
|
| +}
|
| +
|
| +
|
| void LCodeGen::DoDebugBreak(LDebugBreak* instr) {
|
| __ int3();
|
| }
|
| @@ -2159,6 +2166,29 @@ void LCodeGen::DoCmpObjectEqAndBranch(LCmpObjectEqAndBranch* instr) {
|
| }
|
|
|
|
|
| +void LCodeGen::DoCmpHoleAndBranch(LCmpHoleAndBranch* instr) {
|
| + if (instr->hydrogen()->representation().IsTagged()) {
|
| + Register input_reg = ToRegister(instr->object());
|
| + __ Cmp(input_reg, factory()->the_hole_value());
|
| + EmitBranch(instr, equal);
|
| + return;
|
| + }
|
| +
|
| + XMMRegister input_reg = ToDoubleRegister(instr->object());
|
| + __ ucomisd(input_reg, input_reg);
|
| + EmitFalseBranch(instr, parity_odd);
|
| +
|
| + __ subq(rsp, Immediate(kDoubleSize));
|
| + __ movsd(MemOperand(rsp, 0), input_reg);
|
| + __ addq(rsp, Immediate(kDoubleSize));
|
| +
|
| + int size = sizeof(kHoleNanUpper32);
|
| + __ cmpl(MemOperand(rsp, -size),
|
| + Immediate(kHoleNanUpper32));
|
| + EmitBranch(instr, equal);
|
| +}
|
| +
|
| +
|
| Condition LCodeGen::EmitIsObject(Register input,
|
| Label* is_not_object,
|
| Label* is_object) {
|
| @@ -4609,36 +4639,6 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
|
| Register reg = ToRegister(instr->result());
|
| Register tmp = ToRegister(instr->temp());
|
|
|
| - bool convert_hole = false;
|
| - HValue* change_input = instr->hydrogen()->value();
|
| - if (change_input->IsLoadKeyed()) {
|
| - HLoadKeyed* load = HLoadKeyed::cast(change_input);
|
| - convert_hole = load->UsesMustHandleHole();
|
| - }
|
| -
|
| - Label no_special_nan_handling;
|
| - Label done;
|
| - if (convert_hole) {
|
| - XMMRegister input_reg = ToDoubleRegister(instr->value());
|
| - __ ucomisd(input_reg, input_reg);
|
| - __ j(parity_odd, &no_special_nan_handling);
|
| - __ subq(rsp, Immediate(kDoubleSize));
|
| - __ movsd(MemOperand(rsp, 0), input_reg);
|
| - __ cmpl(MemOperand(rsp, sizeof(kHoleNanLower32)),
|
| - Immediate(kHoleNanUpper32));
|
| - Label canonicalize;
|
| - __ j(not_equal, &canonicalize);
|
| - __ addq(rsp, Immediate(kDoubleSize));
|
| - __ Move(reg, factory()->the_hole_value());
|
| - __ jmp(&done);
|
| - __ bind(&canonicalize);
|
| - __ addq(rsp, Immediate(kDoubleSize));
|
| - __ Set(kScratchRegister, BitCast<uint64_t>(
|
| - FixedDoubleArray::canonical_not_the_hole_nan_as_double()));
|
| - __ movq(input_reg, kScratchRegister);
|
| - }
|
| -
|
| - __ bind(&no_special_nan_handling);
|
| DeferredNumberTagD* deferred = new(zone()) DeferredNumberTagD(this, instr);
|
| if (FLAG_inline_new) {
|
| __ AllocateHeapNumber(reg, tmp, deferred->entry());
|
| @@ -4647,8 +4647,6 @@ void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
|
| }
|
| __ bind(deferred->exit());
|
| __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
|
| -
|
| - __ bind(&done);
|
| }
|
|
|
|
|
| @@ -4692,22 +4690,20 @@ void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
|
|
|
| void LCodeGen::EmitNumberUntagD(Register input_reg,
|
| XMMRegister result_reg,
|
| - bool allow_undefined_as_nan,
|
| + bool can_convert_undefined_to_nan,
|
| bool deoptimize_on_minus_zero,
|
| LEnvironment* env,
|
| NumberUntagDMode mode) {
|
| Label load_smi, done;
|
|
|
| - STATIC_ASSERT(NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE >
|
| - NUMBER_CANDIDATE_IS_ANY_TAGGED);
|
| - if (mode >= NUMBER_CANDIDATE_IS_ANY_TAGGED) {
|
| + if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED) {
|
| // Smi check.
|
| __ JumpIfSmi(input_reg, &load_smi, Label::kNear);
|
|
|
| // Heap number map check.
|
| __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
|
| Heap::kHeapNumberMapRootIndex);
|
| - if (!allow_undefined_as_nan) {
|
| + if (!can_convert_undefined_to_nan) {
|
| DeoptimizeIf(not_equal, env);
|
| } else {
|
| Label heap_number, convert;
|
| @@ -4715,10 +4711,6 @@ void LCodeGen::EmitNumberUntagD(Register input_reg,
|
|
|
| // Convert undefined (and hole) to NaN. Compute NaN as 0/0.
|
| __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
|
| - if (mode == NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE) {
|
| - __ j(equal, &convert, Label::kNear);
|
| - __ CompareRoot(input_reg, Heap::kTheHoleValueRootIndex);
|
| - }
|
| DeoptimizeIf(not_equal, env);
|
|
|
| __ bind(&convert);
|
| @@ -4831,19 +4823,12 @@ void LCodeGen::DoNumberUntagD(LNumberUntagD* instr) {
|
| Register input_reg = ToRegister(input);
|
| XMMRegister result_reg = ToDoubleRegister(result);
|
|
|
| - NumberUntagDMode mode = NUMBER_CANDIDATE_IS_ANY_TAGGED;
|
| HValue* value = instr->hydrogen()->value();
|
| - if (value->type().IsSmi()) {
|
| - mode = NUMBER_CANDIDATE_IS_SMI;
|
| - } else if (value->IsLoadKeyed()) {
|
| - HLoadKeyed* load = HLoadKeyed::cast(value);
|
| - if (load->UsesMustHandleHole()) {
|
| - mode = NUMBER_CANDIDATE_IS_ANY_TAGGED_CONVERT_HOLE;
|
| - }
|
| - }
|
| + NumberUntagDMode mode = value->representation().IsSmi()
|
| + ? NUMBER_CANDIDATE_IS_SMI : NUMBER_CANDIDATE_IS_ANY_TAGGED;
|
|
|
| EmitNumberUntagD(input_reg, result_reg,
|
| - instr->hydrogen()->allow_undefined_as_nan(),
|
| + instr->hydrogen()->can_convert_undefined_to_nan(),
|
| instr->hydrogen()->deoptimize_on_minus_zero(),
|
| instr->environment(),
|
| mode);
|
|
|