Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(593)

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 202083002: [ia32/x64] Smaller instruction to check NaN (Closed) Base URL: git://github.com/v8/v8.git@master
Patch Set: only NaN related code remains Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 2222 matching lines...) Expand 10 before | Expand all | Expand 10 after
2233 __ ucomisd(xmm_scratch, value); 2233 __ ucomisd(xmm_scratch, value);
2234 EmitFalseBranch(instr, not_equal); 2234 EmitFalseBranch(instr, not_equal);
2235 __ movmskpd(kScratchRegister, value); 2235 __ movmskpd(kScratchRegister, value);
2236 __ testl(kScratchRegister, Immediate(1)); 2236 __ testl(kScratchRegister, Immediate(1));
2237 EmitBranch(instr, not_zero); 2237 EmitBranch(instr, not_zero);
2238 } else { 2238 } else {
2239 Register value = ToRegister(instr->value()); 2239 Register value = ToRegister(instr->value());
2240 Handle<Map> map = masm()->isolate()->factory()->heap_number_map(); 2240 Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
2241 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK); 2241 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2242 __ cmpl(FieldOperand(value, HeapNumber::kExponentOffset), 2242 __ cmpl(FieldOperand(value, HeapNumber::kExponentOffset),
2243 Immediate(0x80000000)); 2243 Immediate(0x1));
2244 EmitFalseBranch(instr, not_equal); 2244 EmitFalseBranch(instr, no_overflow);
2245 __ cmpl(FieldOperand(value, HeapNumber::kMantissaOffset), 2245 __ cmpl(FieldOperand(value, HeapNumber::kMantissaOffset),
2246 Immediate(0x00000000)); 2246 Immediate(0x00000000));
2247 EmitBranch(instr, equal); 2247 EmitBranch(instr, equal);
2248 } 2248 }
2249 } 2249 }
2250 2250
2251 2251
2252 Condition LCodeGen::EmitIsObject(Register input, 2252 Condition LCodeGen::EmitIsObject(Register input,
2253 Label* is_not_object, 2253 Label* is_not_object,
2254 Label* is_object) { 2254 Label* is_object) {
(...skipping 1294 matching lines...) Expand 10 before | Expand all | Expand 10 after
3549 if (CpuFeatures::IsSupported(SSE4_1)) { 3549 if (CpuFeatures::IsSupported(SSE4_1)) {
3550 CpuFeatureScope scope(masm(), SSE4_1); 3550 CpuFeatureScope scope(masm(), SSE4_1);
3551 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3551 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3552 // Deoptimize if minus zero. 3552 // Deoptimize if minus zero.
3553 __ movq(output_reg, input_reg); 3553 __ movq(output_reg, input_reg);
3554 __ subq(output_reg, Immediate(1)); 3554 __ subq(output_reg, Immediate(1));
3555 DeoptimizeIf(overflow, instr->environment()); 3555 DeoptimizeIf(overflow, instr->environment());
3556 } 3556 }
3557 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); 3557 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
3558 __ cvttsd2si(output_reg, xmm_scratch); 3558 __ cvttsd2si(output_reg, xmm_scratch);
3559 __ cmpl(output_reg, Immediate(0x80000000)); 3559 __ cmpl(output_reg, Immediate(0x1));
3560 DeoptimizeIf(equal, instr->environment()); 3560 DeoptimizeIf(overflow, instr->environment());
3561 } else { 3561 } else {
3562 Label negative_sign, done; 3562 Label negative_sign, done;
3563 // Deoptimize on unordered. 3563 // Deoptimize on unordered.
3564 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 3564 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
3565 __ ucomisd(input_reg, xmm_scratch); 3565 __ ucomisd(input_reg, xmm_scratch);
3566 DeoptimizeIf(parity_even, instr->environment()); 3566 DeoptimizeIf(parity_even, instr->environment());
3567 __ j(below, &negative_sign, Label::kNear); 3567 __ j(below, &negative_sign, Label::kNear);
3568 3568
3569 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3569 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3570 // Check for negative zero. 3570 // Check for negative zero.
3571 Label positive_sign; 3571 Label positive_sign;
3572 __ j(above, &positive_sign, Label::kNear); 3572 __ j(above, &positive_sign, Label::kNear);
3573 __ movmskpd(output_reg, input_reg); 3573 __ movmskpd(output_reg, input_reg);
3574 __ testq(output_reg, Immediate(1)); 3574 __ testq(output_reg, Immediate(1));
3575 DeoptimizeIf(not_zero, instr->environment()); 3575 DeoptimizeIf(not_zero, instr->environment());
3576 __ Set(output_reg, 0); 3576 __ Set(output_reg, 0);
3577 __ jmp(&done, Label::kNear); 3577 __ jmp(&done, Label::kNear);
3578 __ bind(&positive_sign); 3578 __ bind(&positive_sign);
3579 } 3579 }
3580 3580
3581 // Use truncating instruction (OK because input is positive). 3581 // Use truncating instruction (OK because input is positive).
3582 __ cvttsd2si(output_reg, input_reg); 3582 __ cvttsd2si(output_reg, input_reg);
3583 // Overflow is signalled with minint. 3583 // Overflow is signalled with minint.
3584 __ cmpl(output_reg, Immediate(0x80000000)); 3584 __ cmpl(output_reg, Immediate(0x1));
3585 DeoptimizeIf(equal, instr->environment()); 3585 DeoptimizeIf(overflow, instr->environment());
3586 __ jmp(&done, Label::kNear); 3586 __ jmp(&done, Label::kNear);
3587 3587
3588 // Non-zero negative reaches here. 3588 // Non-zero negative reaches here.
3589 __ bind(&negative_sign); 3589 __ bind(&negative_sign);
3590 // Truncate, then compare and compensate. 3590 // Truncate, then compare and compensate.
3591 __ cvttsd2si(output_reg, input_reg); 3591 __ cvttsd2si(output_reg, input_reg);
3592 __ Cvtlsi2sd(xmm_scratch, output_reg); 3592 __ Cvtlsi2sd(xmm_scratch, output_reg);
3593 __ ucomisd(input_reg, xmm_scratch); 3593 __ ucomisd(input_reg, xmm_scratch);
3594 __ j(equal, &done, Label::kNear); 3594 __ j(equal, &done, Label::kNear);
3595 __ subl(output_reg, Immediate(1)); 3595 __ subl(output_reg, Immediate(1));
(...skipping 16 matching lines...) Expand all
3612 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3612 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
3613 __ movq(kScratchRegister, one_half); 3613 __ movq(kScratchRegister, one_half);
3614 __ movq(xmm_scratch, kScratchRegister); 3614 __ movq(xmm_scratch, kScratchRegister);
3615 __ ucomisd(xmm_scratch, input_reg); 3615 __ ucomisd(xmm_scratch, input_reg);
3616 __ j(above, &below_one_half, Label::kNear); 3616 __ j(above, &below_one_half, Label::kNear);
3617 3617
3618 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). 3618 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x).
3619 __ addsd(xmm_scratch, input_reg); 3619 __ addsd(xmm_scratch, input_reg);
3620 __ cvttsd2si(output_reg, xmm_scratch); 3620 __ cvttsd2si(output_reg, xmm_scratch);
3621 // Overflow is signalled with minint. 3621 // Overflow is signalled with minint.
3622 __ cmpl(output_reg, Immediate(0x80000000)); 3622 __ cmpl(output_reg, Immediate(0x1));
3623 __ RecordComment("D2I conversion overflow"); 3623 __ RecordComment("D2I conversion overflow");
3624 DeoptimizeIf(equal, instr->environment()); 3624 DeoptimizeIf(overflow, instr->environment());
3625 __ jmp(&done, dist); 3625 __ jmp(&done, dist);
3626 3626
3627 __ bind(&below_one_half); 3627 __ bind(&below_one_half);
3628 __ movq(kScratchRegister, minus_one_half); 3628 __ movq(kScratchRegister, minus_one_half);
3629 __ movq(xmm_scratch, kScratchRegister); 3629 __ movq(xmm_scratch, kScratchRegister);
3630 __ ucomisd(xmm_scratch, input_reg); 3630 __ ucomisd(xmm_scratch, input_reg);
3631 __ j(below_equal, &round_to_zero, Label::kNear); 3631 __ j(below_equal, &round_to_zero, Label::kNear);
3632 3632
3633 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then 3633 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then
3634 // compare and compensate. 3634 // compare and compensate.
3635 __ movq(input_temp, input_reg); // Do not alter input_reg. 3635 __ movq(input_temp, input_reg); // Do not alter input_reg.
3636 __ subsd(input_temp, xmm_scratch); 3636 __ subsd(input_temp, xmm_scratch);
3637 __ cvttsd2si(output_reg, input_temp); 3637 __ cvttsd2si(output_reg, input_temp);
3638 // Catch minint due to overflow, and to prevent overflow when compensating. 3638 // Catch minint due to overflow, and to prevent overflow when compensating.
3639 __ cmpl(output_reg, Immediate(0x80000000)); 3639 __ cmpl(output_reg, Immediate(0x1));
3640 __ RecordComment("D2I conversion overflow"); 3640 __ RecordComment("D2I conversion overflow");
3641 DeoptimizeIf(equal, instr->environment()); 3641 DeoptimizeIf(overflow, instr->environment());
3642 3642
3643 __ Cvtlsi2sd(xmm_scratch, output_reg); 3643 __ Cvtlsi2sd(xmm_scratch, output_reg);
3644 __ ucomisd(xmm_scratch, input_temp); 3644 __ ucomisd(xmm_scratch, input_temp);
3645 __ j(equal, &done, dist); 3645 __ j(equal, &done, dist);
3646 __ subl(output_reg, Immediate(1)); 3646 __ subl(output_reg, Immediate(1));
3647 // No overflow because we already ruled out minint. 3647 // No overflow because we already ruled out minint.
3648 __ jmp(&done, dist); 3648 __ jmp(&done, dist);
3649 3649
3650 __ bind(&round_to_zero); 3650 __ bind(&round_to_zero);
3651 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if 3651 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if
(...skipping 1012 matching lines...) Expand 10 before | Expand all | Expand 10 after
4664 __ movp(reg, kScratchRegister); 4664 __ movp(reg, kScratchRegister);
4665 } 4665 }
4666 4666
4667 4667
4668 void LCodeGen::DoSmiTag(LSmiTag* instr) { 4668 void LCodeGen::DoSmiTag(LSmiTag* instr) {
4669 HChange* hchange = instr->hydrogen(); 4669 HChange* hchange = instr->hydrogen();
4670 Register input = ToRegister(instr->value()); 4670 Register input = ToRegister(instr->value());
4671 Register output = ToRegister(instr->result()); 4671 Register output = ToRegister(instr->result());
4672 if (hchange->CheckFlag(HValue::kCanOverflow) && 4672 if (hchange->CheckFlag(HValue::kCanOverflow) &&
4673 hchange->value()->CheckFlag(HValue::kUint32)) { 4673 hchange->value()->CheckFlag(HValue::kUint32)) {
4674 __ testl(input, Immediate(0x80000000)); 4674 __ testl(input, input);
4675 DeoptimizeIf(not_zero, instr->environment()); 4675 DeoptimizeIf(sign, instr->environment());
4676 } 4676 }
4677 __ Integer32ToSmi(output, input); 4677 __ Integer32ToSmi(output, input);
4678 if (hchange->CheckFlag(HValue::kCanOverflow) && 4678 if (hchange->CheckFlag(HValue::kCanOverflow) &&
4679 !hchange->value()->CheckFlag(HValue::kUint32)) { 4679 !hchange->value()->CheckFlag(HValue::kUint32)) {
4680 DeoptimizeIf(overflow, instr->environment()); 4680 DeoptimizeIf(overflow, instr->environment());
4681 } 4681 }
4682 } 4682 }
4683 4683
4684 4684
4685 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 4685 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
(...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after
5060 5060
5061 // Check for heap number 5061 // Check for heap number
5062 __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5062 __ Cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
5063 factory()->heap_number_map()); 5063 factory()->heap_number_map());
5064 __ j(equal, &heap_number, Label::kNear); 5064 __ j(equal, &heap_number, Label::kNear);
5065 5065
5066 // Check for undefined. Undefined is converted to zero for clamping 5066 // Check for undefined. Undefined is converted to zero for clamping
5067 // conversions. 5067 // conversions.
5068 __ Cmp(input_reg, factory()->undefined_value()); 5068 __ Cmp(input_reg, factory()->undefined_value());
5069 DeoptimizeIf(not_equal, instr->environment()); 5069 DeoptimizeIf(not_equal, instr->environment());
5070 __ movp(input_reg, Immediate(0)); 5070 __ xorl(input_reg, input_reg);
5071 __ jmp(&done, Label::kNear); 5071 __ jmp(&done, Label::kNear);
5072 5072
5073 // Heap number 5073 // Heap number
5074 __ bind(&heap_number); 5074 __ bind(&heap_number);
5075 __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); 5075 __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset));
5076 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); 5076 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg);
5077 __ jmp(&done, Label::kNear); 5077 __ jmp(&done, Label::kNear);
5078 5078
5079 // smi 5079 // smi
5080 __ bind(&is_smi); 5080 __ bind(&is_smi);
(...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after
5642 FixedArray::kHeaderSize - kPointerSize)); 5642 FixedArray::kHeaderSize - kPointerSize));
5643 __ bind(&done); 5643 __ bind(&done);
5644 } 5644 }
5645 5645
5646 5646
5647 #undef __ 5647 #undef __
5648 5648
5649 } } // namespace v8::internal 5649 } } // namespace v8::internal
5650 5650
5651 #endif // V8_TARGET_ARCH_X64 5651 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/full-codegen-x64.cc ('k') | src/x64/macro-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698