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

Side by Side Diff: src/ia32/lithium-codegen-ia32.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/ia32/full-codegen-ia32.cc ('k') | src/ia32/macro-assembler-ia32.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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 2615 matching lines...) Expand 10 before | Expand all | Expand 10 after
2626 __ ucomisd(xmm_scratch, value); 2626 __ ucomisd(xmm_scratch, value);
2627 EmitFalseBranch(instr, not_equal); 2627 EmitFalseBranch(instr, not_equal);
2628 __ movmskpd(scratch, value); 2628 __ movmskpd(scratch, value);
2629 __ test(scratch, Immediate(1)); 2629 __ test(scratch, Immediate(1));
2630 EmitBranch(instr, not_zero); 2630 EmitBranch(instr, not_zero);
2631 } else { 2631 } else {
2632 Register value = ToRegister(instr->value()); 2632 Register value = ToRegister(instr->value());
2633 Handle<Map> map = masm()->isolate()->factory()->heap_number_map(); 2633 Handle<Map> map = masm()->isolate()->factory()->heap_number_map();
2634 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK); 2634 __ CheckMap(value, map, instr->FalseLabel(chunk()), DO_SMI_CHECK);
2635 __ cmp(FieldOperand(value, HeapNumber::kExponentOffset), 2635 __ cmp(FieldOperand(value, HeapNumber::kExponentOffset),
2636 Immediate(0x80000000)); 2636 Immediate(0x1));
2637 EmitFalseBranch(instr, not_equal); 2637 EmitFalseBranch(instr, no_overflow);
2638 __ cmp(FieldOperand(value, HeapNumber::kMantissaOffset), 2638 __ cmp(FieldOperand(value, HeapNumber::kMantissaOffset),
2639 Immediate(0x00000000)); 2639 Immediate(0x00000000));
2640 EmitBranch(instr, equal); 2640 EmitBranch(instr, equal);
2641 } 2641 }
2642 } 2642 }
2643 2643
2644 2644
2645 Condition LCodeGen::EmitIsObject(Register input, 2645 Condition LCodeGen::EmitIsObject(Register input,
2646 Register temp1, 2646 Register temp1,
2647 Label* is_not_object, 2647 Label* is_not_object,
(...skipping 1279 matching lines...) Expand 10 before | Expand all | Expand 10 after
3927 __ ucomisd(input_reg, xmm_scratch); 3927 __ ucomisd(input_reg, xmm_scratch);
3928 __ j(not_equal, &non_zero, Label::kNear); 3928 __ j(not_equal, &non_zero, Label::kNear);
3929 __ movmskpd(output_reg, input_reg); 3929 __ movmskpd(output_reg, input_reg);
3930 __ test(output_reg, Immediate(1)); 3930 __ test(output_reg, Immediate(1));
3931 DeoptimizeIf(not_zero, instr->environment()); 3931 DeoptimizeIf(not_zero, instr->environment());
3932 __ bind(&non_zero); 3932 __ bind(&non_zero);
3933 } 3933 }
3934 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown); 3934 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
3935 __ cvttsd2si(output_reg, Operand(xmm_scratch)); 3935 __ cvttsd2si(output_reg, Operand(xmm_scratch));
3936 // Overflow is signalled with minint. 3936 // Overflow is signalled with minint.
3937 __ cmp(output_reg, 0x80000000u); 3937 __ cmp(output_reg, 0x1);
3938 DeoptimizeIf(equal, instr->environment()); 3938 DeoptimizeIf(overflow, instr->environment());
3939 } else { 3939 } else {
3940 Label negative_sign, done; 3940 Label negative_sign, done;
3941 // Deoptimize on unordered. 3941 // Deoptimize on unordered.
3942 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. 3942 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
3943 __ ucomisd(input_reg, xmm_scratch); 3943 __ ucomisd(input_reg, xmm_scratch);
3944 DeoptimizeIf(parity_even, instr->environment()); 3944 DeoptimizeIf(parity_even, instr->environment());
3945 __ j(below, &negative_sign, Label::kNear); 3945 __ j(below, &negative_sign, Label::kNear);
3946 3946
3947 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 3947 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
3948 // Check for negative zero. 3948 // Check for negative zero.
3949 Label positive_sign; 3949 Label positive_sign;
3950 __ j(above, &positive_sign, Label::kNear); 3950 __ j(above, &positive_sign, Label::kNear);
3951 __ movmskpd(output_reg, input_reg); 3951 __ movmskpd(output_reg, input_reg);
3952 __ test(output_reg, Immediate(1)); 3952 __ test(output_reg, Immediate(1));
3953 DeoptimizeIf(not_zero, instr->environment()); 3953 DeoptimizeIf(not_zero, instr->environment());
3954 __ Set(output_reg, Immediate(0)); 3954 __ Set(output_reg, Immediate(0));
3955 __ jmp(&done, Label::kNear); 3955 __ jmp(&done, Label::kNear);
3956 __ bind(&positive_sign); 3956 __ bind(&positive_sign);
3957 } 3957 }
3958 3958
3959 // Use truncating instruction (OK because input is positive). 3959 // Use truncating instruction (OK because input is positive).
3960 __ cvttsd2si(output_reg, Operand(input_reg)); 3960 __ cvttsd2si(output_reg, Operand(input_reg));
3961 // Overflow is signalled with minint. 3961 // Overflow is signalled with minint.
3962 __ cmp(output_reg, 0x80000000u); 3962 __ cmp(output_reg, 0x1);
3963 DeoptimizeIf(equal, instr->environment()); 3963 DeoptimizeIf(overflow, instr->environment());
3964 __ jmp(&done, Label::kNear); 3964 __ jmp(&done, Label::kNear);
3965 3965
3966 // Non-zero negative reaches here. 3966 // Non-zero negative reaches here.
3967 __ bind(&negative_sign); 3967 __ bind(&negative_sign);
3968 // Truncate, then compare and compensate. 3968 // Truncate, then compare and compensate.
3969 __ cvttsd2si(output_reg, Operand(input_reg)); 3969 __ cvttsd2si(output_reg, Operand(input_reg));
3970 __ Cvtsi2sd(xmm_scratch, output_reg); 3970 __ Cvtsi2sd(xmm_scratch, output_reg);
3971 __ ucomisd(input_reg, xmm_scratch); 3971 __ ucomisd(input_reg, xmm_scratch);
3972 __ j(equal, &done, Label::kNear); 3972 __ j(equal, &done, Label::kNear);
3973 __ sub(output_reg, Immediate(1)); 3973 __ sub(output_reg, Immediate(1));
(...skipping 18 matching lines...) Expand all
3992 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear; 3992 Label::Distance dist = DeoptEveryNTimes() ? Label::kFar : Label::kNear;
3993 3993
3994 __ movsd(xmm_scratch, Operand::StaticVariable(one_half)); 3994 __ movsd(xmm_scratch, Operand::StaticVariable(one_half));
3995 __ ucomisd(xmm_scratch, input_reg); 3995 __ ucomisd(xmm_scratch, input_reg);
3996 __ j(above, &below_one_half, Label::kNear); 3996 __ j(above, &below_one_half, Label::kNear);
3997 3997
3998 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). 3998 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x).
3999 __ addsd(xmm_scratch, input_reg); 3999 __ addsd(xmm_scratch, input_reg);
4000 __ cvttsd2si(output_reg, Operand(xmm_scratch)); 4000 __ cvttsd2si(output_reg, Operand(xmm_scratch));
4001 // Overflow is signalled with minint. 4001 // Overflow is signalled with minint.
4002 __ cmp(output_reg, 0x80000000u); 4002 __ cmp(output_reg, 0x1);
4003 __ RecordComment("D2I conversion overflow"); 4003 __ RecordComment("D2I conversion overflow");
4004 DeoptimizeIf(equal, instr->environment()); 4004 DeoptimizeIf(overflow, instr->environment());
4005 __ jmp(&done, dist); 4005 __ jmp(&done, dist);
4006 4006
4007 __ bind(&below_one_half); 4007 __ bind(&below_one_half);
4008 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half)); 4008 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half));
4009 __ ucomisd(xmm_scratch, input_reg); 4009 __ ucomisd(xmm_scratch, input_reg);
4010 __ j(below_equal, &round_to_zero, Label::kNear); 4010 __ j(below_equal, &round_to_zero, Label::kNear);
4011 4011
4012 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then 4012 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then
4013 // compare and compensate. 4013 // compare and compensate.
4014 __ movaps(input_temp, input_reg); // Do not alter input_reg. 4014 __ movaps(input_temp, input_reg); // Do not alter input_reg.
4015 __ subsd(input_temp, xmm_scratch); 4015 __ subsd(input_temp, xmm_scratch);
4016 __ cvttsd2si(output_reg, Operand(input_temp)); 4016 __ cvttsd2si(output_reg, Operand(input_temp));
4017 // Catch minint due to overflow, and to prevent overflow when compensating. 4017 // Catch minint due to overflow, and to prevent overflow when compensating.
4018 __ cmp(output_reg, 0x80000000u); 4018 __ cmp(output_reg, 0x1);
4019 __ RecordComment("D2I conversion overflow"); 4019 __ RecordComment("D2I conversion overflow");
4020 DeoptimizeIf(equal, instr->environment()); 4020 DeoptimizeIf(overflow, instr->environment());
4021 4021
4022 __ Cvtsi2sd(xmm_scratch, output_reg); 4022 __ Cvtsi2sd(xmm_scratch, output_reg);
4023 __ ucomisd(xmm_scratch, input_temp); 4023 __ ucomisd(xmm_scratch, input_temp);
4024 __ j(equal, &done, dist); 4024 __ j(equal, &done, dist);
4025 __ sub(output_reg, Immediate(1)); 4025 __ sub(output_reg, Immediate(1));
4026 // No overflow because we already ruled out minint. 4026 // No overflow because we already ruled out minint.
4027 __ jmp(&done, dist); 4027 __ jmp(&done, dist);
4028 4028
4029 __ bind(&round_to_zero); 4029 __ bind(&round_to_zero);
4030 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if 4030 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if
(...skipping 2304 matching lines...) Expand 10 before | Expand all | Expand 10 after
6335 FixedArray::kHeaderSize - kPointerSize)); 6335 FixedArray::kHeaderSize - kPointerSize));
6336 __ bind(&done); 6336 __ bind(&done);
6337 } 6337 }
6338 6338
6339 6339
6340 #undef __ 6340 #undef __
6341 6341
6342 } } // namespace v8::internal 6342 } } // namespace v8::internal
6343 6343
6344 #endif // V8_TARGET_ARCH_IA32 6344 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/full-codegen-ia32.cc ('k') | src/ia32/macro-assembler-ia32.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698