| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_X87 | 7 #if V8_TARGET_ARCH_X87 |
| 8 | 8 |
| 9 #include "src/base/bits.h" | 9 #include "src/base/bits.h" |
| 10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
| (...skipping 3957 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3968 __ fld(0); | 3968 __ fld(0); |
| 3969 __ fadd_d(Operand::StaticVariable(one_half)); | 3969 __ fadd_d(Operand::StaticVariable(one_half)); |
| 3970 // rc=11B, round toward zero. | 3970 // rc=11B, round toward zero. |
| 3971 __ X87SetRC(0x0c00); | 3971 __ X87SetRC(0x0c00); |
| 3972 __ sub(esp, Immediate(kPointerSize)); | 3972 __ sub(esp, Immediate(kPointerSize)); |
| 3973 // Clear exception bits. | 3973 // Clear exception bits. |
| 3974 __ fnclex(); | 3974 __ fnclex(); |
| 3975 __ fistp_s(MemOperand(esp, 0)); | 3975 __ fistp_s(MemOperand(esp, 0)); |
| 3976 // Check overflow. | 3976 // Check overflow. |
| 3977 __ X87CheckIA(); | 3977 __ X87CheckIA(); |
| 3978 __ RecordComment("D2I conversion overflow"); | |
| 3979 __ pop(result); | 3978 __ pop(result); |
| 3980 DeoptimizeIf(equal, instr); | 3979 DeoptimizeIf(equal, instr, "conversion overflow"); |
| 3981 __ fnclex(); | 3980 __ fnclex(); |
| 3982 // Restore round mode. | 3981 // Restore round mode. |
| 3983 __ X87SetRC(0x0000); | 3982 __ X87SetRC(0x0000); |
| 3984 __ jmp(&done); | 3983 __ jmp(&done); |
| 3985 | 3984 |
| 3986 __ bind(&below_one_half); | 3985 __ bind(&below_one_half); |
| 3987 __ fld_d(Operand::StaticVariable(minus_one_half)); | 3986 __ fld_d(Operand::StaticVariable(minus_one_half)); |
| 3988 __ fld(1); | 3987 __ fld(1); |
| 3989 __ FCmp(); | 3988 __ FCmp(); |
| 3990 __ j(carry, &below_minus_one_half); | 3989 __ j(carry, &below_minus_one_half); |
| 3991 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if | 3990 // We return 0 for the input range [+0, 0.5[, or [-0.5, 0.5[ if |
| 3992 // we can ignore the difference between a result of -0 and +0. | 3991 // we can ignore the difference between a result of -0 and +0. |
| 3993 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3992 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3994 // If the sign is positive, we return +0. | 3993 // If the sign is positive, we return +0. |
| 3995 __ fld(0); | 3994 __ fld(0); |
| 3996 __ FXamSign(); | 3995 __ FXamSign(); |
| 3997 __ RecordComment("Minus zero"); | 3996 DeoptimizeIf(not_zero, instr, "minus zero"); |
| 3998 DeoptimizeIf(not_zero, instr); | |
| 3999 } | 3997 } |
| 4000 __ Move(result, Immediate(0)); | 3998 __ Move(result, Immediate(0)); |
| 4001 __ jmp(&done); | 3999 __ jmp(&done); |
| 4002 | 4000 |
| 4003 __ bind(&below_minus_one_half); | 4001 __ bind(&below_minus_one_half); |
| 4004 __ fld(0); | 4002 __ fld(0); |
| 4005 __ fadd_d(Operand::StaticVariable(one_half)); | 4003 __ fadd_d(Operand::StaticVariable(one_half)); |
| 4006 // rc=01B, round down. | 4004 // rc=01B, round down. |
| 4007 __ X87SetRC(0x0400); | 4005 __ X87SetRC(0x0400); |
| 4008 __ sub(esp, Immediate(kPointerSize)); | 4006 __ sub(esp, Immediate(kPointerSize)); |
| 4009 // Clear exception bits. | 4007 // Clear exception bits. |
| 4010 __ fnclex(); | 4008 __ fnclex(); |
| 4011 __ fistp_s(MemOperand(esp, 0)); | 4009 __ fistp_s(MemOperand(esp, 0)); |
| 4012 // Check overflow. | 4010 // Check overflow. |
| 4013 __ X87CheckIA(); | 4011 __ X87CheckIA(); |
| 4014 __ RecordComment("D2I conversion overflow"); | |
| 4015 __ pop(result); | 4012 __ pop(result); |
| 4016 DeoptimizeIf(equal, instr); | 4013 DeoptimizeIf(equal, instr, "conversion overflow"); |
| 4017 __ fnclex(); | 4014 __ fnclex(); |
| 4018 // Restore round mode. | 4015 // Restore round mode. |
| 4019 __ X87SetRC(0x0000); | 4016 __ X87SetRC(0x0000); |
| 4020 | 4017 |
| 4021 __ bind(&done); | 4018 __ bind(&done); |
| 4022 } | 4019 } |
| 4023 | 4020 |
| 4024 | 4021 |
| 4025 void LCodeGen::DoMathFround(LMathFround* instr) { | 4022 void LCodeGen::DoMathFround(LMathFround* instr) { |
| 4026 X87Register input_reg = ToX87Register(instr->value()); | 4023 X87Register input_reg = ToX87Register(instr->value()); |
| (...skipping 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5179 __ jmp(done); | 5176 __ jmp(done); |
| 5180 | 5177 |
| 5181 __ bind(&check_bools); | 5178 __ bind(&check_bools); |
| 5182 __ cmp(input_reg, factory()->true_value()); | 5179 __ cmp(input_reg, factory()->true_value()); |
| 5183 __ j(not_equal, &check_false, Label::kNear); | 5180 __ j(not_equal, &check_false, Label::kNear); |
| 5184 __ Move(input_reg, Immediate(1)); | 5181 __ Move(input_reg, Immediate(1)); |
| 5185 __ jmp(done); | 5182 __ jmp(done); |
| 5186 | 5183 |
| 5187 __ bind(&check_false); | 5184 __ bind(&check_false); |
| 5188 __ cmp(input_reg, factory()->false_value()); | 5185 __ cmp(input_reg, factory()->false_value()); |
| 5189 __ RecordComment("Deferred TaggedToI: cannot truncate"); | 5186 DeoptimizeIf(not_equal, instr, "cannot truncate"); |
| 5190 DeoptimizeIf(not_equal, instr); | |
| 5191 __ Move(input_reg, Immediate(0)); | 5187 __ Move(input_reg, Immediate(0)); |
| 5192 } else { | 5188 } else { |
| 5193 // TODO(olivf) Converting a number on the fpu is actually quite slow. We | 5189 // TODO(olivf) Converting a number on the fpu is actually quite slow. We |
| 5194 // should first try a fast conversion and then bailout to this slow case. | 5190 // should first try a fast conversion and then bailout to this slow case. |
| 5195 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 5191 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 5196 isolate()->factory()->heap_number_map()); | 5192 isolate()->factory()->heap_number_map()); |
| 5197 __ RecordComment("Deferred TaggedToI: not a heap number"); | 5193 DeoptimizeIf(not_equal, instr, "not a heap number"); |
| 5198 DeoptimizeIf(not_equal, instr); | |
| 5199 | 5194 |
| 5200 __ sub(esp, Immediate(kPointerSize)); | 5195 __ sub(esp, Immediate(kPointerSize)); |
| 5201 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); | 5196 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 5202 | 5197 |
| 5203 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { | 5198 if (instr->hydrogen()->GetMinusZeroMode() == FAIL_ON_MINUS_ZERO) { |
| 5204 Label no_precision_lost, not_nan, zero_check; | 5199 Label no_precision_lost, not_nan, zero_check; |
| 5205 __ fld(0); | 5200 __ fld(0); |
| 5206 | 5201 |
| 5207 __ fist_s(MemOperand(esp, 0)); | 5202 __ fist_s(MemOperand(esp, 0)); |
| 5208 __ fild_s(MemOperand(esp, 0)); | 5203 __ fild_s(MemOperand(esp, 0)); |
| 5209 __ FCmp(); | 5204 __ FCmp(); |
| 5210 __ pop(input_reg); | 5205 __ pop(input_reg); |
| 5211 | 5206 |
| 5212 __ j(equal, &no_precision_lost, Label::kNear); | 5207 __ j(equal, &no_precision_lost, Label::kNear); |
| 5213 __ fstp(0); | 5208 __ fstp(0); |
| 5214 __ RecordComment("Deferred TaggedToI: lost precision"); | 5209 DeoptimizeIf(no_condition, instr, "lost precision"); |
| 5215 DeoptimizeIf(no_condition, instr); | |
| 5216 __ bind(&no_precision_lost); | 5210 __ bind(&no_precision_lost); |
| 5217 | 5211 |
| 5218 __ j(parity_odd, ¬_nan); | 5212 __ j(parity_odd, ¬_nan); |
| 5219 __ fstp(0); | 5213 __ fstp(0); |
| 5220 __ RecordComment("Deferred TaggedToI: NaN"); | 5214 DeoptimizeIf(no_condition, instr, "NaN"); |
| 5221 DeoptimizeIf(no_condition, instr); | |
| 5222 __ bind(¬_nan); | 5215 __ bind(¬_nan); |
| 5223 | 5216 |
| 5224 __ test(input_reg, Operand(input_reg)); | 5217 __ test(input_reg, Operand(input_reg)); |
| 5225 __ j(zero, &zero_check, Label::kNear); | 5218 __ j(zero, &zero_check, Label::kNear); |
| 5226 __ fstp(0); | 5219 __ fstp(0); |
| 5227 __ jmp(done); | 5220 __ jmp(done); |
| 5228 | 5221 |
| 5229 __ bind(&zero_check); | 5222 __ bind(&zero_check); |
| 5230 // To check for minus zero, we load the value again as float, and check | 5223 // To check for minus zero, we load the value again as float, and check |
| 5231 // if that is still 0. | 5224 // if that is still 0. |
| 5232 __ sub(esp, Immediate(kPointerSize)); | 5225 __ sub(esp, Immediate(kPointerSize)); |
| 5233 __ fstp_s(Operand(esp, 0)); | 5226 __ fstp_s(Operand(esp, 0)); |
| 5234 __ pop(input_reg); | 5227 __ pop(input_reg); |
| 5235 __ test(input_reg, Operand(input_reg)); | 5228 __ test(input_reg, Operand(input_reg)); |
| 5236 __ RecordComment("Deferred TaggedToI: minus zero"); | 5229 DeoptimizeIf(not_zero, instr, "minus zero"); |
| 5237 DeoptimizeIf(not_zero, instr); | |
| 5238 } else { | 5230 } else { |
| 5239 __ fist_s(MemOperand(esp, 0)); | 5231 __ fist_s(MemOperand(esp, 0)); |
| 5240 __ fild_s(MemOperand(esp, 0)); | 5232 __ fild_s(MemOperand(esp, 0)); |
| 5241 __ FCmp(); | 5233 __ FCmp(); |
| 5242 __ pop(input_reg); | 5234 __ pop(input_reg); |
| 5243 __ RecordComment("Deferred TaggedToI: lost precision"); | 5235 DeoptimizeIf(not_equal, instr, "lost precision"); |
| 5244 DeoptimizeIf(not_equal, instr); | 5236 DeoptimizeIf(parity_even, instr, "NaN"); |
| 5245 __ RecordComment("Deferred TaggedToI: NaN"); | |
| 5246 DeoptimizeIf(parity_even, instr); | |
| 5247 } | 5237 } |
| 5248 } | 5238 } |
| 5249 } | 5239 } |
| 5250 | 5240 |
| 5251 | 5241 |
| 5252 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { | 5242 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { |
| 5253 class DeferredTaggedToI FINAL : public LDeferredCode { | 5243 class DeferredTaggedToI FINAL : public LDeferredCode { |
| 5254 public: | 5244 public: |
| 5255 DeferredTaggedToI(LCodeGen* codegen, | 5245 DeferredTaggedToI(LCodeGen* codegen, |
| 5256 LTaggedToI* instr, | 5246 LTaggedToI* instr, |
| (...skipping 996 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6253 CallRuntime(Runtime::kPushBlockContext, 2, instr); | 6243 CallRuntime(Runtime::kPushBlockContext, 2, instr); |
| 6254 RecordSafepoint(Safepoint::kNoLazyDeopt); | 6244 RecordSafepoint(Safepoint::kNoLazyDeopt); |
| 6255 } | 6245 } |
| 6256 | 6246 |
| 6257 | 6247 |
| 6258 #undef __ | 6248 #undef __ |
| 6259 | 6249 |
| 6260 } } // namespace v8::internal | 6250 } } // namespace v8::internal |
| 6261 | 6251 |
| 6262 #endif // V8_TARGET_ARCH_X87 | 6252 #endif // V8_TARGET_ARCH_X87 |
| OLD | NEW |