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

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

Issue 6049008: SSE2 truncating double-to-i. (Closed)
Patch Set: . Created 9 years, 11 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
OLDNEW
1 // Copyright 2010 the V8 project authors. All rights reserved. 1 // Copyright 2010 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 2226 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 DeoptimizeIf(equal, instr->environment()); 2237 DeoptimizeIf(equal, instr->environment());
2238 } 2238 }
2239 2239
2240 2240
2241 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2241 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2242 XMMRegister xmm_scratch = xmm0; 2242 XMMRegister xmm_scratch = xmm0;
2243 Register output_reg = ToRegister(instr->result()); 2243 Register output_reg = ToRegister(instr->result());
2244 XMMRegister input_reg = ToDoubleRegister(instr->input()); 2244 XMMRegister input_reg = ToDoubleRegister(instr->input());
2245 2245
2246 // xmm_scratch = 0.5 2246 // xmm_scratch = 0.5
2247 ExternalReference one_half = ExternalReference::address_of_one_half(); 2247 ExternalReference one_half = ExternalReference::address_of_one_half();
Erik Corry 2011/01/04 22:33:00 Here's how to load a constant into an XMM register
2248 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 2248 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
2249 2249
2250 // input = input + 0.5 2250 // input = input + 0.5
2251 __ addsd(input_reg, xmm_scratch); 2251 __ addsd(input_reg, xmm_scratch);
2252 2252
2253 // We need to return -0 for the input range [-0.5, 0[, otherwise 2253 // We need to return -0 for the input range [-0.5, 0[, otherwise
2254 // compute Math.floor(value + 0.5). 2254 // compute Math.floor(value + 0.5).
2255 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2255 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2256 __ ucomisd(input_reg, xmm_scratch); 2256 __ ucomisd(input_reg, xmm_scratch);
2257 DeoptimizeIf(below_equal, instr->environment()); 2257 DeoptimizeIf(below_equal, instr->environment());
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after
2878 __ add(Operand(esp), Immediate(kDoubleSize)); 2878 __ add(Operand(esp), Immediate(kDoubleSize));
2879 DeoptimizeIf(no_condition, instr->environment()); 2879 DeoptimizeIf(no_condition, instr->environment());
2880 __ bind(&convert); 2880 __ bind(&convert);
2881 // Do conversion, which cannot fail because we checked the exponent. 2881 // Do conversion, which cannot fail because we checked the exponent.
2882 __ fld_d(Operand(esp, 0)); 2882 __ fld_d(Operand(esp, 0));
2883 __ fisttp_d(Operand(esp, 0)); 2883 __ fisttp_d(Operand(esp, 0));
2884 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result. 2884 __ mov(result_reg, Operand(esp, 0)); // Low word of answer is the result.
2885 __ add(Operand(esp), Immediate(kDoubleSize)); 2885 __ add(Operand(esp), Immediate(kDoubleSize));
2886 __ bind(&done); 2886 __ bind(&done);
2887 } else { 2887 } else {
2888 // This will bail out if the input was not in the int32 range (or, 2888 NearLabel done;
2889 // unfortunately, if the input was 0x80000000). 2889 Register temp_reg = ToRegister(instr->temporary());
2890 DeoptimizeIf(equal, instr->environment()); 2890 XMMRegister xmm_scratch = xmm0;
2891
2892 __ j(not_equal, &done);
2893
2894 // Get high 32 bits of the input in temp_reg.
2895 __ pshufd(xmm_scratch, input_reg, 1);
2896 __ movd(Operand(temp_reg), xmm_scratch);
2897
2898 // Zero out the sign and the exponent in the input (by shifting
2899 // it to the left) and restore the implicit mantissa bit,
2900 // i.e. convert the input to unsigned int64 shifted left by
2901 // kExponentBits.
2902 __ mov(result_reg, 1);
2903 __ movd(xmm_scratch, Operand(result_reg));
2904 __ psllq(xmm_scratch, kDoubleSize * kBitsPerByte - 1);
Erik Corry 2011/01/04 22:33:00 It might be faster to load xmm_scratch using the t
2905 __ psllq(input_reg, HeapNumber::kExponentBits);
2906 __ por(input_reg, xmm_scratch);
2907
2908 // Restore high 32 bits of the input in result_reg.
2909 __ mov(result_reg, temp_reg);
2910
2911 // Prepare negation mask in temp_reg.
2912 __ sar(temp_reg, kBitsPerInt - 1);
2913
2914 // Extract the exponent from result_reg and subtract adjusted
2915 // bias from it. The adjustment is selected in a way such that
2916 // when the difference is zero, the answer is in the low 32 bits
2917 // of the input, otherwise a shift has to be performed.
2918 __ shr(result_reg, HeapNumber::kExponentShift);
2919 __ and_(result_reg,
2920 HeapNumber::kExponentMask >> HeapNumber::kExponentShift);
2921 __ sub(Operand(result_reg),
2922 Immediate(HeapNumber::kExponentBias +
2923 HeapNumber::kExponentBits +
2924 HeapNumber::kMantissaBits));
2925 // Don't handle big (or special) exponents.
Erik Corry 2011/01/04 22:33:00 Could you add a comment describing the range handl
2926 DeoptimizeIf(greater_equal, instr->environment());
2927
2928 // Get the amount to shift the input right in xmm_scratch.
2929 __ neg(result_reg);
2930 __ movd(xmm_scratch, Operand(result_reg));
2931
2932 // Shift the input right and extract low 32 bits.
2933 __ psrlq(input_reg, xmm_scratch);
2934 __ movd(Operand(result_reg), input_reg);
2935
2936 // Use the prepared mask in temp_reg to negate the result if necessary.
2937 __ xor_(result_reg, Operand(temp_reg));
2938 __ sub(result_reg, Operand(temp_reg));
Erik Corry 2011/01/04 22:33:00 ooh, nice!
2939 __ bind(&done);
2891 } 2940 }
2892 } else { 2941 } else {
2893 NearLabel done; 2942 NearLabel done;
2894 __ cvttsd2si(result_reg, Operand(input_reg)); 2943 __ cvttsd2si(result_reg, Operand(input_reg));
2895 __ cvtsi2sd(xmm0, Operand(result_reg)); 2944 __ cvtsi2sd(xmm0, Operand(result_reg));
2896 __ ucomisd(xmm0, input_reg); 2945 __ ucomisd(xmm0, input_reg);
2897 DeoptimizeIf(not_equal, instr->environment()); 2946 DeoptimizeIf(not_equal, instr->environment());
2898 DeoptimizeIf(parity_even, instr->environment()); // NaN. 2947 DeoptimizeIf(parity_even, instr->environment()); // NaN.
2899 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2948 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2900 // The integer converted back is equal to the original. We 2949 // The integer converted back is equal to the original. We
(...skipping 399 matching lines...) Expand 10 before | Expand all | Expand 10 after
3300 ASSERT(!environment->HasBeenRegistered()); 3349 ASSERT(!environment->HasBeenRegistered());
3301 RegisterEnvironmentForDeoptimization(environment); 3350 RegisterEnvironmentForDeoptimization(environment);
3302 ASSERT(osr_pc_offset_ == -1); 3351 ASSERT(osr_pc_offset_ == -1);
3303 osr_pc_offset_ = masm()->pc_offset(); 3352 osr_pc_offset_ = masm()->pc_offset();
3304 } 3353 }
3305 3354
3306 3355
3307 #undef __ 3356 #undef __
3308 3357
3309 } } // namespace v8::internal 3358 } } // namespace v8::internal
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698