| OLD | NEW |
| 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 3880 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3891 EmitIntegerMathAbs(instr); | 3891 EmitIntegerMathAbs(instr); |
| 3892 __ bind(deferred->exit()); | 3892 __ bind(deferred->exit()); |
| 3893 } | 3893 } |
| 3894 } | 3894 } |
| 3895 | 3895 |
| 3896 | 3896 |
| 3897 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { | 3897 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { |
| 3898 CpuFeatures::Scope scope(VFP2); | 3898 CpuFeatures::Scope scope(VFP2); |
| 3899 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3899 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 3900 Register result = ToRegister(instr->result()); | 3900 Register result = ToRegister(instr->result()); |
| 3901 Register scratch = scratch0(); | 3901 Register input_high = scratch0(); |
| 3902 Label done, exact; |
| 3902 | 3903 |
| 3903 __ EmitVFPTruncate(kRoundToMinusInf, | 3904 __ vmov(input_high, input.high()); |
| 3904 result, | 3905 __ TryInt32Floor(result, input, input_high, double_scratch0(), &done, &exact); |
| 3905 input, | 3906 DeoptimizeIf(al, instr->environment()); |
| 3906 scratch, | |
| 3907 double_scratch0()); | |
| 3908 DeoptimizeIf(ne, instr->environment()); | |
| 3909 | 3907 |
| 3908 __ bind(&exact); |
| 3910 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3909 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3911 // Test for -0. | 3910 // Test for -0. |
| 3912 Label done; | |
| 3913 __ cmp(result, Operand::Zero()); | 3911 __ cmp(result, Operand::Zero()); |
| 3914 __ b(ne, &done); | 3912 __ b(ne, &done); |
| 3915 __ vmov(scratch, input.high()); | 3913 __ cmp(input_high, Operand::Zero()); |
| 3916 __ tst(scratch, Operand(HeapNumber::kSignMask)); | 3914 DeoptimizeIf(mi, instr->environment()); |
| 3917 DeoptimizeIf(ne, instr->environment()); | |
| 3918 __ bind(&done); | |
| 3919 } | 3915 } |
| 3916 __ bind(&done); |
| 3920 } | 3917 } |
| 3921 | 3918 |
| 3922 | 3919 |
| 3923 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { | 3920 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { |
| 3924 CpuFeatures::Scope scope(VFP2); | 3921 CpuFeatures::Scope scope(VFP2); |
| 3925 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3922 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 3926 Register result = ToRegister(instr->result()); | 3923 Register result = ToRegister(instr->result()); |
| 3927 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); | 3924 DwVfpRegister double_scratch1 = ToDoubleRegister(instr->temp()); |
| 3928 Register scratch = scratch0(); | 3925 DwVfpRegister input_plus_dot_five = double_scratch1; |
| 3929 Label done, check_sign_on_zero; | 3926 Register input_high = scratch0(); |
| 3927 DwVfpRegister dot_five = double_scratch0(); |
| 3928 Label convert, done; |
| 3930 | 3929 |
| 3931 // Extract exponent bits. | 3930 __ Vmov(dot_five, 0.5, scratch0()); |
| 3932 __ vmov(result, input.high()); | 3931 __ vabs(double_scratch1, input); |
| 3933 __ ubfx(scratch, | 3932 __ VFPCompareAndSetFlags(double_scratch1, dot_five); |
| 3934 result, | 3933 // If input is in [-0.5, -0], the result is -0. |
| 3935 HeapNumber::kExponentShift, | 3934 // If input is in [+0, +0.5[, the result is +0. |
| 3936 HeapNumber::kExponentBits); | 3935 // If the input is +0.5, the result is 1. |
| 3936 __ b(hi, &convert); // Out of [-0.5, +0.5]. |
| 3937 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3938 __ vmov(input_high, input.high()); |
| 3939 __ cmp(input_high, Operand::Zero()); |
| 3940 DeoptimizeIf(mi, instr->environment()); // [-0.5, -0]. |
| 3941 } |
| 3942 __ VFPCompareAndSetFlags(input, dot_five); |
| 3943 __ mov(result, Operand(1), LeaveCC, eq); // +0.5. |
| 3944 // Remaining cases: [+0, +0.5[ or [-0.5, +0.5[, depending on |
| 3945 // flag kBailoutOnMinusZero. |
| 3946 __ mov(result, Operand::Zero(), LeaveCC, ne); |
| 3947 __ b(&done); |
| 3937 | 3948 |
| 3938 // If the number is in ]-0.5, +0.5[, the result is +/- 0. | 3949 __ bind(&convert); |
| 3939 __ cmp(scratch, Operand(HeapNumber::kExponentBias - 2)); | 3950 __ vadd(input_plus_dot_five, input, dot_five); |
| 3940 __ mov(result, Operand::Zero(), LeaveCC, le); | 3951 __ vmov(input_high, input_plus_dot_five.high()); |
| 3941 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3952 // Reuse dot_five (double_scratch0) as we no longer need this value. |
| 3942 __ b(le, &check_sign_on_zero); | 3953 __ TryInt32Floor(result, input_plus_dot_five, input_high, double_scratch0(), |
| 3943 } else { | 3954 &done, &done); |
| 3944 __ b(le, &done); | 3955 DeoptimizeIf(al, instr->environment()); |
| 3945 } | |
| 3946 | |
| 3947 // The following conversion will not work with numbers | |
| 3948 // outside of ]-2^32, 2^32[. | |
| 3949 __ cmp(scratch, Operand(HeapNumber::kExponentBias + 32)); | |
| 3950 DeoptimizeIf(ge, instr->environment()); | |
| 3951 | |
| 3952 __ Vmov(double_scratch0(), 0.5, scratch); | |
| 3953 __ vadd(double_scratch0(), input, double_scratch0()); | |
| 3954 | |
| 3955 // Save the original sign for later comparison. | |
| 3956 __ and_(scratch, result, Operand(HeapNumber::kSignMask)); | |
| 3957 | |
| 3958 // Check sign of the result: if the sign changed, the input | |
| 3959 // value was in ]0.5, 0[ and the result should be -0. | |
| 3960 __ vmov(result, double_scratch0().high()); | |
| 3961 __ eor(result, result, Operand(scratch), SetCC); | |
| 3962 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 3963 DeoptimizeIf(mi, instr->environment()); | |
| 3964 } else { | |
| 3965 __ mov(result, Operand::Zero(), LeaveCC, mi); | |
| 3966 __ b(mi, &done); | |
| 3967 } | |
| 3968 | |
| 3969 __ EmitVFPTruncate(kRoundToMinusInf, | |
| 3970 result, | |
| 3971 double_scratch0(), | |
| 3972 scratch, | |
| 3973 double_scratch1); | |
| 3974 DeoptimizeIf(ne, instr->environment()); | |
| 3975 | |
| 3976 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | |
| 3977 // Test for -0. | |
| 3978 __ cmp(result, Operand::Zero()); | |
| 3979 __ b(ne, &done); | |
| 3980 __ bind(&check_sign_on_zero); | |
| 3981 __ vmov(scratch, input.high()); | |
| 3982 __ tst(scratch, Operand(HeapNumber::kSignMask)); | |
| 3983 DeoptimizeIf(ne, instr->environment()); | |
| 3984 } | |
| 3985 __ bind(&done); | 3956 __ bind(&done); |
| 3986 } | 3957 } |
| 3987 | 3958 |
| 3988 | 3959 |
| 3989 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { | 3960 void LCodeGen::DoMathSqrt(LUnaryMathOperation* instr) { |
| 3990 CpuFeatures::Scope scope(VFP2); | 3961 CpuFeatures::Scope scope(VFP2); |
| 3991 DwVfpRegister input = ToDoubleRegister(instr->value()); | 3962 DwVfpRegister input = ToDoubleRegister(instr->value()); |
| 3992 DwVfpRegister result = ToDoubleRegister(instr->result()); | 3963 DwVfpRegister result = ToDoubleRegister(instr->result()); |
| 3993 __ vsqrt(result, input); | 3964 __ vsqrt(result, input); |
| 3994 } | 3965 } |
| (...skipping 1231 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5226 scratch2, | 5197 scratch2, |
| 5227 scratch3); | 5198 scratch3); |
| 5228 | 5199 |
| 5229 } else { | 5200 } else { |
| 5230 CpuFeatures::Scope scope(VFP3); | 5201 CpuFeatures::Scope scope(VFP3); |
| 5231 // Deoptimize if we don't have a heap number. | 5202 // Deoptimize if we don't have a heap number. |
| 5232 DeoptimizeIf(ne, instr->environment()); | 5203 DeoptimizeIf(ne, instr->environment()); |
| 5233 | 5204 |
| 5234 __ sub(ip, input_reg, Operand(kHeapObjectTag)); | 5205 __ sub(ip, input_reg, Operand(kHeapObjectTag)); |
| 5235 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); | 5206 __ vldr(double_scratch, ip, HeapNumber::kValueOffset); |
| 5236 __ EmitVFPTruncate(kRoundToZero, | 5207 __ TryDoubleToInt32Exact(input_reg, double_scratch, double_scratch2); |
| 5237 input_reg, | |
| 5238 double_scratch, | |
| 5239 scratch1, | |
| 5240 double_scratch2, | |
| 5241 kCheckForInexactConversion); | |
| 5242 DeoptimizeIf(ne, instr->environment()); | 5208 DeoptimizeIf(ne, instr->environment()); |
| 5243 | 5209 |
| 5244 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 5210 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 5245 __ cmp(input_reg, Operand::Zero()); | 5211 __ cmp(input_reg, Operand::Zero()); |
| 5246 __ b(ne, &done); | 5212 __ b(ne, &done); |
| 5247 __ vmov(scratch1, double_scratch.high()); | 5213 __ vmov(scratch1, double_scratch.high()); |
| 5248 __ tst(scratch1, Operand(HeapNumber::kSignMask)); | 5214 __ tst(scratch1, Operand(HeapNumber::kSignMask)); |
| 5249 DeoptimizeIf(ne, instr->environment()); | 5215 DeoptimizeIf(ne, instr->environment()); |
| 5250 } | 5216 } |
| 5251 } | 5217 } |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5327 | 5293 |
| 5328 if (instr->truncating()) { | 5294 if (instr->truncating()) { |
| 5329 Register scratch3 = ToRegister(instr->temp2()); | 5295 Register scratch3 = ToRegister(instr->temp2()); |
| 5330 __ EmitECMATruncate(result_reg, | 5296 __ EmitECMATruncate(result_reg, |
| 5331 double_input, | 5297 double_input, |
| 5332 double_scratch, | 5298 double_scratch, |
| 5333 scratch1, | 5299 scratch1, |
| 5334 scratch2, | 5300 scratch2, |
| 5335 scratch3); | 5301 scratch3); |
| 5336 } else { | 5302 } else { |
| 5337 __ EmitVFPTruncate(kRoundToMinusInf, | 5303 __ TryDoubleToInt32Exact(result_reg, double_input, double_scratch); |
| 5338 result_reg, | 5304 // Deoptimize if the input wasn't a int32 (inside a double). |
| 5339 double_input, | |
| 5340 scratch1, | |
| 5341 double_scratch, | |
| 5342 kCheckForInexactConversion); | |
| 5343 | |
| 5344 // Deoptimize if we had a vfp invalid exception, | |
| 5345 // including inexact operation. | |
| 5346 DeoptimizeIf(ne, instr->environment()); | 5305 DeoptimizeIf(ne, instr->environment()); |
| 5347 } | 5306 } |
| 5348 __ bind(&done); | 5307 __ bind(&done); |
| 5349 } | 5308 } |
| 5350 | 5309 |
| 5351 | 5310 |
| 5352 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { | 5311 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { |
| 5353 LOperand* input = instr->value(); | 5312 LOperand* input = instr->value(); |
| 5354 __ tst(ToRegister(input), Operand(kSmiTagMask)); | 5313 __ tst(ToRegister(input), Operand(kSmiTagMask)); |
| 5355 DeoptimizeIf(ne, instr->environment()); | 5314 DeoptimizeIf(ne, instr->environment()); |
| (...skipping 1013 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6369 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); | 6328 __ sub(scratch, result, Operand(index, LSL, kPointerSizeLog2 - kSmiTagSize)); |
| 6370 __ ldr(result, FieldMemOperand(scratch, | 6329 __ ldr(result, FieldMemOperand(scratch, |
| 6371 FixedArray::kHeaderSize - kPointerSize)); | 6330 FixedArray::kHeaderSize - kPointerSize)); |
| 6372 __ bind(&done); | 6331 __ bind(&done); |
| 6373 } | 6332 } |
| 6374 | 6333 |
| 6375 | 6334 |
| 6376 #undef __ | 6335 #undef __ |
| 6377 | 6336 |
| 6378 } } // namespace v8::internal | 6337 } } // namespace v8::internal |
| OLD | NEW |