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 |