| 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 1978 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1989 } else { | 1989 } else { |
| 1990 __ xorps(res, res); | 1990 __ xorps(res, res); |
| 1991 __ Set(temp, Immediate(upper)); | 1991 __ Set(temp, Immediate(upper)); |
| 1992 __ pinsrd(res, Operand(temp), 1); | 1992 __ pinsrd(res, Operand(temp), 1); |
| 1993 } | 1993 } |
| 1994 } else { | 1994 } else { |
| 1995 __ Set(temp, Immediate(upper)); | 1995 __ Set(temp, Immediate(upper)); |
| 1996 __ movd(res, Operand(temp)); | 1996 __ movd(res, Operand(temp)); |
| 1997 __ psllq(res, 32); | 1997 __ psllq(res, 32); |
| 1998 if (lower != 0) { | 1998 if (lower != 0) { |
| 1999 XMMRegister xmm_scratch = double_scratch0(); |
| 1999 __ Set(temp, Immediate(lower)); | 2000 __ Set(temp, Immediate(lower)); |
| 2000 __ movd(xmm0, Operand(temp)); | 2001 __ movd(xmm_scratch, Operand(temp)); |
| 2001 __ por(res, xmm0); | 2002 __ por(res, xmm_scratch); |
| 2002 } | 2003 } |
| 2003 } | 2004 } |
| 2004 } | 2005 } |
| 2005 } | 2006 } |
| 2006 } | 2007 } |
| 2007 | 2008 |
| 2008 | 2009 |
| 2009 void LCodeGen::DoConstantE(LConstantE* instr) { | 2010 void LCodeGen::DoConstantE(LConstantE* instr) { |
| 2010 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); | 2011 __ lea(ToRegister(instr->result()), Operand::StaticVariable(instr->value())); |
| 2011 } | 2012 } |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2200 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; | 2201 Condition condition = (operation == HMathMinMax::kMathMin) ? below : above; |
| 2201 XMMRegister left_reg = ToDoubleRegister(left); | 2202 XMMRegister left_reg = ToDoubleRegister(left); |
| 2202 XMMRegister right_reg = ToDoubleRegister(right); | 2203 XMMRegister right_reg = ToDoubleRegister(right); |
| 2203 __ ucomisd(left_reg, right_reg); | 2204 __ ucomisd(left_reg, right_reg); |
| 2204 __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. | 2205 __ j(parity_even, &check_nan_left, Label::kNear); // At least one NaN. |
| 2205 __ j(equal, &check_zero, Label::kNear); // left == right. | 2206 __ j(equal, &check_zero, Label::kNear); // left == right. |
| 2206 __ j(condition, &return_left, Label::kNear); | 2207 __ j(condition, &return_left, Label::kNear); |
| 2207 __ jmp(&return_right, Label::kNear); | 2208 __ jmp(&return_right, Label::kNear); |
| 2208 | 2209 |
| 2209 __ bind(&check_zero); | 2210 __ bind(&check_zero); |
| 2210 XMMRegister xmm_scratch = xmm0; | 2211 XMMRegister xmm_scratch = double_scratch0(); |
| 2211 __ xorps(xmm_scratch, xmm_scratch); | 2212 __ xorps(xmm_scratch, xmm_scratch); |
| 2212 __ ucomisd(left_reg, xmm_scratch); | 2213 __ ucomisd(left_reg, xmm_scratch); |
| 2213 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. | 2214 __ j(not_equal, &return_left, Label::kNear); // left == right != 0. |
| 2214 // At this point, both left and right are either 0 or -0. | 2215 // At this point, both left and right are either 0 or -0. |
| 2215 if (operation == HMathMinMax::kMathMin) { | 2216 if (operation == HMathMinMax::kMathMin) { |
| 2216 __ orpd(left_reg, right_reg); | 2217 __ orpd(left_reg, right_reg); |
| 2217 } else { | 2218 } else { |
| 2218 // Since we operate on +0 and/or -0, addsd and andsd have the same effect. | 2219 // Since we operate on +0 and/or -0, addsd and andsd have the same effect. |
| 2219 __ addsd(left_reg, right_reg); | 2220 __ addsd(left_reg, right_reg); |
| 2220 } | 2221 } |
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 void LCodeGen::DoBranch(LBranch* instr) { | 2371 void LCodeGen::DoBranch(LBranch* instr) { |
| 2371 Representation r = instr->hydrogen()->value()->representation(); | 2372 Representation r = instr->hydrogen()->value()->representation(); |
| 2372 if (r.IsSmiOrInteger32()) { | 2373 if (r.IsSmiOrInteger32()) { |
| 2373 Register reg = ToRegister(instr->value()); | 2374 Register reg = ToRegister(instr->value()); |
| 2374 __ test(reg, Operand(reg)); | 2375 __ test(reg, Operand(reg)); |
| 2375 EmitBranch(instr, not_zero); | 2376 EmitBranch(instr, not_zero); |
| 2376 } else if (r.IsDouble()) { | 2377 } else if (r.IsDouble()) { |
| 2377 ASSERT(!info()->IsStub()); | 2378 ASSERT(!info()->IsStub()); |
| 2378 CpuFeatureScope scope(masm(), SSE2); | 2379 CpuFeatureScope scope(masm(), SSE2); |
| 2379 XMMRegister reg = ToDoubleRegister(instr->value()); | 2380 XMMRegister reg = ToDoubleRegister(instr->value()); |
| 2380 __ xorps(xmm0, xmm0); | 2381 XMMRegister xmm_scratch = double_scratch0(); |
| 2381 __ ucomisd(reg, xmm0); | 2382 __ xorps(xmm_scratch, xmm_scratch); |
| 2383 __ ucomisd(reg, xmm_scratch); |
| 2382 EmitBranch(instr, not_equal); | 2384 EmitBranch(instr, not_equal); |
| 2383 } else { | 2385 } else { |
| 2384 ASSERT(r.IsTagged()); | 2386 ASSERT(r.IsTagged()); |
| 2385 Register reg = ToRegister(instr->value()); | 2387 Register reg = ToRegister(instr->value()); |
| 2386 HType type = instr->hydrogen()->value()->type(); | 2388 HType type = instr->hydrogen()->value()->type(); |
| 2387 if (type.IsBoolean()) { | 2389 if (type.IsBoolean()) { |
| 2388 ASSERT(!info()->IsStub()); | 2390 ASSERT(!info()->IsStub()); |
| 2389 __ cmp(reg, factory()->true_value()); | 2391 __ cmp(reg, factory()->true_value()); |
| 2390 EmitBranch(instr, equal); | 2392 EmitBranch(instr, equal); |
| 2391 } else if (type.IsSmi()) { | 2393 } else if (type.IsSmi()) { |
| 2392 ASSERT(!info()->IsStub()); | 2394 ASSERT(!info()->IsStub()); |
| 2393 __ test(reg, Operand(reg)); | 2395 __ test(reg, Operand(reg)); |
| 2394 EmitBranch(instr, not_equal); | 2396 EmitBranch(instr, not_equal); |
| 2395 } else if (type.IsJSArray()) { | 2397 } else if (type.IsJSArray()) { |
| 2396 ASSERT(!info()->IsStub()); | 2398 ASSERT(!info()->IsStub()); |
| 2397 EmitBranch(instr, no_condition); | 2399 EmitBranch(instr, no_condition); |
| 2398 } else if (type.IsHeapNumber()) { | 2400 } else if (type.IsHeapNumber()) { |
| 2399 ASSERT(!info()->IsStub()); | 2401 ASSERT(!info()->IsStub()); |
| 2400 CpuFeatureScope scope(masm(), SSE2); | 2402 CpuFeatureScope scope(masm(), SSE2); |
| 2401 __ xorps(xmm0, xmm0); | 2403 XMMRegister xmm_scratch = double_scratch0(); |
| 2402 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); | 2404 __ xorps(xmm_scratch, xmm_scratch); |
| 2405 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); |
| 2403 EmitBranch(instr, not_equal); | 2406 EmitBranch(instr, not_equal); |
| 2404 } else if (type.IsString()) { | 2407 } else if (type.IsString()) { |
| 2405 ASSERT(!info()->IsStub()); | 2408 ASSERT(!info()->IsStub()); |
| 2406 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); | 2409 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); |
| 2407 EmitBranch(instr, not_equal); | 2410 EmitBranch(instr, not_equal); |
| 2408 } else { | 2411 } else { |
| 2409 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); | 2412 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); |
| 2410 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); | 2413 if (expected.IsEmpty()) expected = ToBooleanStub::Types::Generic(); |
| 2411 | 2414 |
| 2412 if (expected.Contains(ToBooleanStub::UNDEFINED)) { | 2415 if (expected.Contains(ToBooleanStub::UNDEFINED)) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2477 } | 2480 } |
| 2478 | 2481 |
| 2479 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { | 2482 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { |
| 2480 // heap number -> false iff +0, -0, or NaN. | 2483 // heap number -> false iff +0, -0, or NaN. |
| 2481 Label not_heap_number; | 2484 Label not_heap_number; |
| 2482 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), | 2485 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), |
| 2483 factory()->heap_number_map()); | 2486 factory()->heap_number_map()); |
| 2484 __ j(not_equal, ¬_heap_number, Label::kNear); | 2487 __ j(not_equal, ¬_heap_number, Label::kNear); |
| 2485 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 2488 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 2486 CpuFeatureScope scope(masm(), SSE2); | 2489 CpuFeatureScope scope(masm(), SSE2); |
| 2487 __ xorps(xmm0, xmm0); | 2490 XMMRegister xmm_scratch = double_scratch0(); |
| 2488 __ ucomisd(xmm0, FieldOperand(reg, HeapNumber::kValueOffset)); | 2491 __ xorps(xmm_scratch, xmm_scratch); |
| 2492 __ ucomisd(xmm_scratch, FieldOperand(reg, HeapNumber::kValueOffset)); |
| 2489 } else { | 2493 } else { |
| 2490 __ fldz(); | 2494 __ fldz(); |
| 2491 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 2495 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
| 2492 __ FCmp(); | 2496 __ FCmp(); |
| 2493 } | 2497 } |
| 2494 __ j(zero, instr->FalseLabel(chunk_)); | 2498 __ j(zero, instr->FalseLabel(chunk_)); |
| 2495 __ jmp(instr->TrueLabel(chunk_)); | 2499 __ jmp(instr->TrueLabel(chunk_)); |
| 2496 __ bind(¬_heap_number); | 2500 __ bind(¬_heap_number); |
| 2497 } | 2501 } |
| 2498 | 2502 |
| (...skipping 1419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3918 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } | 3922 virtual LInstruction* instr() V8_OVERRIDE { return instr_; } |
| 3919 private: | 3923 private: |
| 3920 LMathAbs* instr_; | 3924 LMathAbs* instr_; |
| 3921 }; | 3925 }; |
| 3922 | 3926 |
| 3923 ASSERT(instr->value()->Equals(instr->result())); | 3927 ASSERT(instr->value()->Equals(instr->result())); |
| 3924 Representation r = instr->hydrogen()->value()->representation(); | 3928 Representation r = instr->hydrogen()->value()->representation(); |
| 3925 | 3929 |
| 3926 CpuFeatureScope scope(masm(), SSE2); | 3930 CpuFeatureScope scope(masm(), SSE2); |
| 3927 if (r.IsDouble()) { | 3931 if (r.IsDouble()) { |
| 3928 XMMRegister scratch = xmm0; | 3932 XMMRegister scratch = double_scratch0(); |
| 3929 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3933 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3930 __ xorps(scratch, scratch); | 3934 __ xorps(scratch, scratch); |
| 3931 __ subsd(scratch, input_reg); | 3935 __ subsd(scratch, input_reg); |
| 3932 __ pand(input_reg, scratch); | 3936 __ pand(input_reg, scratch); |
| 3933 } else if (r.IsSmiOrInteger32()) { | 3937 } else if (r.IsSmiOrInteger32()) { |
| 3934 EmitIntegerMathAbs(instr); | 3938 EmitIntegerMathAbs(instr); |
| 3935 } else { // Tagged case. | 3939 } else { // Tagged case. |
| 3936 DeferredMathAbsTaggedHeapNumber* deferred = | 3940 DeferredMathAbsTaggedHeapNumber* deferred = |
| 3937 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_); | 3941 new(zone()) DeferredMathAbsTaggedHeapNumber(this, instr, x87_stack_); |
| 3938 Register input_reg = ToRegister(instr->value()); | 3942 Register input_reg = ToRegister(instr->value()); |
| 3939 // Smi check. | 3943 // Smi check. |
| 3940 __ JumpIfNotSmi(input_reg, deferred->entry()); | 3944 __ JumpIfNotSmi(input_reg, deferred->entry()); |
| 3941 EmitIntegerMathAbs(instr); | 3945 EmitIntegerMathAbs(instr); |
| 3942 __ bind(deferred->exit()); | 3946 __ bind(deferred->exit()); |
| 3943 } | 3947 } |
| 3944 } | 3948 } |
| 3945 | 3949 |
| 3946 | 3950 |
| 3947 void LCodeGen::DoMathFloor(LMathFloor* instr) { | 3951 void LCodeGen::DoMathFloor(LMathFloor* instr) { |
| 3948 CpuFeatureScope scope(masm(), SSE2); | 3952 CpuFeatureScope scope(masm(), SSE2); |
| 3949 XMMRegister xmm_scratch = xmm0; | 3953 XMMRegister xmm_scratch = double_scratch0(); |
| 3950 Register output_reg = ToRegister(instr->result()); | 3954 Register output_reg = ToRegister(instr->result()); |
| 3951 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3955 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 3952 | 3956 |
| 3953 if (CpuFeatures::IsSupported(SSE4_1)) { | 3957 if (CpuFeatures::IsSupported(SSE4_1)) { |
| 3954 CpuFeatureScope scope(masm(), SSE4_1); | 3958 CpuFeatureScope scope(masm(), SSE4_1); |
| 3955 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { | 3959 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { |
| 3956 // Deoptimize on negative zero. | 3960 // Deoptimize on negative zero. |
| 3957 Label non_zero; | 3961 Label non_zero; |
| 3958 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. | 3962 __ xorps(xmm_scratch, xmm_scratch); // Zero the register. |
| 3959 __ ucomisd(input_reg, xmm_scratch); | 3963 __ ucomisd(input_reg, xmm_scratch); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4007 | 4011 |
| 4008 __ bind(&done); | 4012 __ bind(&done); |
| 4009 } | 4013 } |
| 4010 } | 4014 } |
| 4011 | 4015 |
| 4012 | 4016 |
| 4013 void LCodeGen::DoMathRound(LMathRound* instr) { | 4017 void LCodeGen::DoMathRound(LMathRound* instr) { |
| 4014 CpuFeatureScope scope(masm(), SSE2); | 4018 CpuFeatureScope scope(masm(), SSE2); |
| 4015 Register output_reg = ToRegister(instr->result()); | 4019 Register output_reg = ToRegister(instr->result()); |
| 4016 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4020 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 4017 XMMRegister xmm_scratch = xmm0; | 4021 XMMRegister xmm_scratch = double_scratch0(); |
| 4018 XMMRegister input_temp = ToDoubleRegister(instr->temp()); | 4022 XMMRegister input_temp = ToDoubleRegister(instr->temp()); |
| 4019 ExternalReference one_half = ExternalReference::address_of_one_half(); | 4023 ExternalReference one_half = ExternalReference::address_of_one_half(); |
| 4020 ExternalReference minus_one_half = | 4024 ExternalReference minus_one_half = |
| 4021 ExternalReference::address_of_minus_one_half(); | 4025 ExternalReference::address_of_minus_one_half(); |
| 4022 | 4026 |
| 4023 Label done, round_to_zero, below_one_half, do_not_compensate; | 4027 Label done, round_to_zero, below_one_half, do_not_compensate; |
| 4024 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); | 4028 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); |
| 4025 __ ucomisd(xmm_scratch, input_reg); | 4029 __ ucomisd(xmm_scratch, input_reg); |
| 4026 __ j(above, &below_one_half); | 4030 __ j(above, &below_one_half); |
| 4027 | 4031 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4074 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { | 4078 void LCodeGen::DoMathSqrt(LMathSqrt* instr) { |
| 4075 CpuFeatureScope scope(masm(), SSE2); | 4079 CpuFeatureScope scope(masm(), SSE2); |
| 4076 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4080 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 4077 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); | 4081 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); |
| 4078 __ sqrtsd(input_reg, input_reg); | 4082 __ sqrtsd(input_reg, input_reg); |
| 4079 } | 4083 } |
| 4080 | 4084 |
| 4081 | 4085 |
| 4082 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { | 4086 void LCodeGen::DoMathPowHalf(LMathPowHalf* instr) { |
| 4083 CpuFeatureScope scope(masm(), SSE2); | 4087 CpuFeatureScope scope(masm(), SSE2); |
| 4084 XMMRegister xmm_scratch = xmm0; | 4088 XMMRegister xmm_scratch = double_scratch0(); |
| 4085 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4089 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 4086 Register scratch = ToRegister(instr->temp()); | 4090 Register scratch = ToRegister(instr->temp()); |
| 4087 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); | 4091 ASSERT(ToDoubleRegister(instr->result()).is(input_reg)); |
| 4088 | 4092 |
| 4089 // Note that according to ECMA-262 15.8.2.13: | 4093 // Note that according to ECMA-262 15.8.2.13: |
| 4090 // Math.pow(-Infinity, 0.5) == Infinity | 4094 // Math.pow(-Infinity, 0.5) == Infinity |
| 4091 // Math.sqrt(-Infinity) == NaN | 4095 // Math.sqrt(-Infinity) == NaN |
| 4092 Label done, sqrt; | 4096 Label done, sqrt; |
| 4093 // Check base for -Infinity. According to IEEE-754, single-precision | 4097 // Check base for -Infinity. According to IEEE-754, single-precision |
| 4094 // -Infinity has the highest 9 bits set and the lowest 23 bits cleared. | 4098 // -Infinity has the highest 9 bits set and the lowest 23 bits cleared. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4193 // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF) | 4197 // Random bit pattern = (state[0] << 14) + (state[1] & 0x3FFFF) |
| 4194 Register random = state0; | 4198 Register random = state0; |
| 4195 __ shl(random, 14); | 4199 __ shl(random, 14); |
| 4196 __ and_(state1, Immediate(0x3FFFF)); | 4200 __ and_(state1, Immediate(0x3FFFF)); |
| 4197 __ add(random, state1); | 4201 __ add(random, state1); |
| 4198 | 4202 |
| 4199 // Convert 32 random bits in random to 0.(32 random bits) in a double | 4203 // Convert 32 random bits in random to 0.(32 random bits) in a double |
| 4200 // by computing: | 4204 // by computing: |
| 4201 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). | 4205 // ( 1.(20 0s)(32 random bits) x 2^20 ) - (1.0 x 2^20)). |
| 4202 XMMRegister result = ToDoubleRegister(instr->result()); | 4206 XMMRegister result = ToDoubleRegister(instr->result()); |
| 4203 // We use xmm0 as fixed scratch register here. | 4207 XMMRegister scratch4 = double_scratch0(); |
| 4204 XMMRegister scratch4 = xmm0; | |
| 4205 __ mov(scratch3, Immediate(0x49800000)); // 1.0 x 2^20 as single. | 4208 __ mov(scratch3, Immediate(0x49800000)); // 1.0 x 2^20 as single. |
| 4206 __ movd(scratch4, scratch3); | 4209 __ movd(scratch4, scratch3); |
| 4207 __ movd(result, random); | 4210 __ movd(result, random); |
| 4208 __ cvtss2sd(scratch4, scratch4); | 4211 __ cvtss2sd(scratch4, scratch4); |
| 4209 __ xorps(result, scratch4); | 4212 __ xorps(result, scratch4); |
| 4210 __ subsd(result, scratch4); | 4213 __ subsd(result, scratch4); |
| 4211 } | 4214 } |
| 4212 | 4215 |
| 4213 | 4216 |
| 4214 void LCodeGen::DoMathLog(LMathLog* instr) { | 4217 void LCodeGen::DoMathLog(LMathLog* instr) { |
| 4215 CpuFeatureScope scope(masm(), SSE2); | 4218 CpuFeatureScope scope(masm(), SSE2); |
| 4216 ASSERT(instr->value()->Equals(instr->result())); | 4219 ASSERT(instr->value()->Equals(instr->result())); |
| 4217 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4220 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
| 4221 XMMRegister xmm_scratch = double_scratch0(); |
| 4218 Label positive, done, zero; | 4222 Label positive, done, zero; |
| 4219 __ xorps(xmm0, xmm0); | 4223 __ xorps(xmm_scratch, xmm_scratch); |
| 4220 __ ucomisd(input_reg, xmm0); | 4224 __ ucomisd(input_reg, xmm_scratch); |
| 4221 __ j(above, &positive, Label::kNear); | 4225 __ j(above, &positive, Label::kNear); |
| 4222 __ j(equal, &zero, Label::kNear); | 4226 __ j(equal, &zero, Label::kNear); |
| 4223 ExternalReference nan = | 4227 ExternalReference nan = |
| 4224 ExternalReference::address_of_canonical_non_hole_nan(); | 4228 ExternalReference::address_of_canonical_non_hole_nan(); |
| 4225 __ movdbl(input_reg, Operand::StaticVariable(nan)); | 4229 __ movdbl(input_reg, Operand::StaticVariable(nan)); |
| 4226 __ jmp(&done, Label::kNear); | 4230 __ jmp(&done, Label::kNear); |
| 4227 __ bind(&zero); | 4231 __ bind(&zero); |
| 4228 __ push(Immediate(0xFFF00000)); | 4232 __ push(Immediate(0xFFF00000)); |
| 4229 __ push(Immediate(0)); | 4233 __ push(Immediate(0)); |
| 4230 __ movdbl(input_reg, Operand(esp, 0)); | 4234 __ movdbl(input_reg, Operand(esp, 0)); |
| 4231 __ add(Operand(esp), Immediate(kDoubleSize)); | 4235 __ add(Operand(esp), Immediate(kDoubleSize)); |
| 4232 __ jmp(&done, Label::kNear); | 4236 __ jmp(&done, Label::kNear); |
| 4233 __ bind(&positive); | 4237 __ bind(&positive); |
| 4234 __ fldln2(); | 4238 __ fldln2(); |
| 4235 __ sub(Operand(esp), Immediate(kDoubleSize)); | 4239 __ sub(Operand(esp), Immediate(kDoubleSize)); |
| 4236 __ movdbl(Operand(esp, 0), input_reg); | 4240 __ movdbl(Operand(esp, 0), input_reg); |
| 4237 __ fld_d(Operand(esp, 0)); | 4241 __ fld_d(Operand(esp, 0)); |
| 4238 __ fyl2x(); | 4242 __ fyl2x(); |
| 4239 __ fstp_d(Operand(esp, 0)); | 4243 __ fstp_d(Operand(esp, 0)); |
| 4240 __ movdbl(input_reg, Operand(esp, 0)); | 4244 __ movdbl(input_reg, Operand(esp, 0)); |
| 4241 __ add(Operand(esp), Immediate(kDoubleSize)); | 4245 __ add(Operand(esp), Immediate(kDoubleSize)); |
| 4242 __ bind(&done); | 4246 __ bind(&done); |
| 4243 } | 4247 } |
| 4244 | 4248 |
| 4245 | 4249 |
| 4246 void LCodeGen::DoMathExp(LMathExp* instr) { | 4250 void LCodeGen::DoMathExp(LMathExp* instr) { |
| 4247 CpuFeatureScope scope(masm(), SSE2); | 4251 CpuFeatureScope scope(masm(), SSE2); |
| 4248 XMMRegister input = ToDoubleRegister(instr->value()); | 4252 XMMRegister input = ToDoubleRegister(instr->value()); |
| 4249 XMMRegister result = ToDoubleRegister(instr->result()); | 4253 XMMRegister result = ToDoubleRegister(instr->result()); |
| 4254 XMMRegister temp0 = double_scratch0(); |
| 4250 Register temp1 = ToRegister(instr->temp1()); | 4255 Register temp1 = ToRegister(instr->temp1()); |
| 4251 Register temp2 = ToRegister(instr->temp2()); | 4256 Register temp2 = ToRegister(instr->temp2()); |
| 4252 | 4257 |
| 4253 MathExpGenerator::EmitMathExp(masm(), input, result, xmm0, temp1, temp2); | 4258 MathExpGenerator::EmitMathExp(masm(), input, result, temp0, temp1, temp2); |
| 4254 } | 4259 } |
| 4255 | 4260 |
| 4256 | 4261 |
| 4257 void LCodeGen::DoMathTan(LMathTan* instr) { | 4262 void LCodeGen::DoMathTan(LMathTan* instr) { |
| 4258 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); | 4263 ASSERT(ToDoubleRegister(instr->result()).is(xmm1)); |
| 4259 // Set the context register to a GC-safe fake value. Clobbering it is | 4264 // Set the context register to a GC-safe fake value. Clobbering it is |
| 4260 // OK because this instruction is marked as a call. | 4265 // OK because this instruction is marked as a call. |
| 4261 __ Set(esi, Immediate(0)); | 4266 __ Set(esi, Immediate(0)); |
| 4262 TranscendentalCacheStub stub(TranscendentalCache::TAN, | 4267 TranscendentalCacheStub stub(TranscendentalCache::TAN, |
| 4263 TranscendentalCacheStub::UNTAGGED); | 4268 TranscendentalCacheStub::UNTAGGED); |
| (...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4624 Operand operand(BuildFastArrayOperand( | 4629 Operand operand(BuildFastArrayOperand( |
| 4625 instr->elements(), | 4630 instr->elements(), |
| 4626 key, | 4631 key, |
| 4627 instr->hydrogen()->key()->representation(), | 4632 instr->hydrogen()->key()->representation(), |
| 4628 elements_kind, | 4633 elements_kind, |
| 4629 0, | 4634 0, |
| 4630 instr->additional_index())); | 4635 instr->additional_index())); |
| 4631 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { | 4636 if (elements_kind == EXTERNAL_FLOAT_ELEMENTS) { |
| 4632 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4637 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 4633 CpuFeatureScope scope(masm(), SSE2); | 4638 CpuFeatureScope scope(masm(), SSE2); |
| 4634 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); | 4639 XMMRegister xmm_scratch = double_scratch0(); |
| 4635 __ movss(operand, xmm0); | 4640 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); |
| 4641 __ movss(operand, xmm_scratch); |
| 4636 } else { | 4642 } else { |
| 4637 __ fld(0); | 4643 __ fld(0); |
| 4638 __ fstp_s(operand); | 4644 __ fstp_s(operand); |
| 4639 } | 4645 } |
| 4640 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4646 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
| 4641 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4647 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 4642 CpuFeatureScope scope(masm(), SSE2); | 4648 CpuFeatureScope scope(masm(), SSE2); |
| 4643 __ movdbl(operand, ToDoubleRegister(instr->value())); | 4649 __ movdbl(operand, ToDoubleRegister(instr->value())); |
| 4644 } else { | 4650 } else { |
| 4645 X87Mov(operand, ToX87Register(instr->value())); | 4651 X87Mov(operand, ToX87Register(instr->value())); |
| (...skipping 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5088 __ bind(deferred->exit()); | 5094 __ bind(deferred->exit()); |
| 5089 } | 5095 } |
| 5090 | 5096 |
| 5091 | 5097 |
| 5092 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, | 5098 void LCodeGen::DoDeferredNumberTagI(LInstruction* instr, |
| 5093 LOperand* value, | 5099 LOperand* value, |
| 5094 IntegerSignedness signedness) { | 5100 IntegerSignedness signedness) { |
| 5095 Label slow; | 5101 Label slow; |
| 5096 Register reg = ToRegister(value); | 5102 Register reg = ToRegister(value); |
| 5097 Register tmp = reg.is(eax) ? ecx : eax; | 5103 Register tmp = reg.is(eax) ? ecx : eax; |
| 5104 XMMRegister xmm_scratch = double_scratch0(); |
| 5098 | 5105 |
| 5099 // Preserve the value of all registers. | 5106 // Preserve the value of all registers. |
| 5100 PushSafepointRegistersScope scope(this); | 5107 PushSafepointRegistersScope scope(this); |
| 5101 | 5108 |
| 5102 Label done; | 5109 Label done; |
| 5103 | 5110 |
| 5104 if (signedness == SIGNED_INT32) { | 5111 if (signedness == SIGNED_INT32) { |
| 5105 // There was overflow, so bits 30 and 31 of the original integer | 5112 // There was overflow, so bits 30 and 31 of the original integer |
| 5106 // disagree. Try to allocate a heap number in new space and store | 5113 // disagree. Try to allocate a heap number in new space and store |
| 5107 // the value in there. If that fails, call the runtime system. | 5114 // the value in there. If that fails, call the runtime system. |
| 5108 __ SmiUntag(reg); | 5115 __ SmiUntag(reg); |
| 5109 __ xor_(reg, 0x80000000); | 5116 __ xor_(reg, 0x80000000); |
| 5110 if (CpuFeatures::IsSupported(SSE2)) { | 5117 if (CpuFeatures::IsSupported(SSE2)) { |
| 5111 CpuFeatureScope feature_scope(masm(), SSE2); | 5118 CpuFeatureScope feature_scope(masm(), SSE2); |
| 5112 __ Cvtsi2sd(xmm0, Operand(reg)); | 5119 __ Cvtsi2sd(xmm_scratch, Operand(reg)); |
| 5113 } else { | 5120 } else { |
| 5114 __ push(reg); | 5121 __ push(reg); |
| 5115 __ fild_s(Operand(esp, 0)); | 5122 __ fild_s(Operand(esp, 0)); |
| 5116 __ pop(reg); | 5123 __ pop(reg); |
| 5117 } | 5124 } |
| 5118 } else { | 5125 } else { |
| 5119 if (CpuFeatures::IsSupported(SSE2)) { | 5126 if (CpuFeatures::IsSupported(SSE2)) { |
| 5120 CpuFeatureScope feature_scope(masm(), SSE2); | 5127 CpuFeatureScope feature_scope(masm(), SSE2); |
| 5121 __ LoadUint32(xmm0, reg, | 5128 __ LoadUint32(xmm_scratch, reg, |
| 5122 ToDoubleRegister(LNumberTagU::cast(instr)->temp())); | 5129 ToDoubleRegister(LNumberTagU::cast(instr)->temp())); |
| 5123 } else { | 5130 } else { |
| 5124 // There's no fild variant for unsigned values, so zero-extend to a 64-bit | 5131 // There's no fild variant for unsigned values, so zero-extend to a 64-bit |
| 5125 // int manually. | 5132 // int manually. |
| 5126 __ push(Immediate(0)); | 5133 __ push(Immediate(0)); |
| 5127 __ push(reg); | 5134 __ push(reg); |
| 5128 __ fild_d(Operand(esp, 0)); | 5135 __ fild_d(Operand(esp, 0)); |
| 5129 __ pop(reg); | 5136 __ pop(reg); |
| 5130 __ pop(reg); | 5137 __ pop(reg); |
| 5131 } | 5138 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 5147 // the environment's HContext or HInlinedContext value. | 5154 // the environment's HContext or HInlinedContext value. |
| 5148 // They only call Runtime::kAllocateHeapNumber. | 5155 // They only call Runtime::kAllocateHeapNumber. |
| 5149 // The corresponding HChange instructions are added in a phase that does | 5156 // The corresponding HChange instructions are added in a phase that does |
| 5150 // not have easy access to the local context. | 5157 // not have easy access to the local context. |
| 5151 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 5158 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 5152 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 5159 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
| 5153 RecordSafepointWithRegisters( | 5160 RecordSafepointWithRegisters( |
| 5154 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 5161 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
| 5155 if (!reg.is(eax)) __ mov(reg, eax); | 5162 if (!reg.is(eax)) __ mov(reg, eax); |
| 5156 | 5163 |
| 5157 // Done. Put the value in xmm0 into the value of the allocated heap | 5164 // Done. Put the value in xmm_scratch into the value of the allocated heap |
| 5158 // number. | 5165 // number. |
| 5159 __ bind(&done); | 5166 __ bind(&done); |
| 5160 if (CpuFeatures::IsSupported(SSE2)) { | 5167 if (CpuFeatures::IsSupported(SSE2)) { |
| 5161 CpuFeatureScope feature_scope(masm(), SSE2); | 5168 CpuFeatureScope feature_scope(masm(), SSE2); |
| 5162 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm0); | 5169 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch); |
| 5163 } else { | 5170 } else { |
| 5164 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 5171 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
| 5165 } | 5172 } |
| 5166 __ StoreToSafepointRegisterSlot(reg, reg); | 5173 __ StoreToSafepointRegisterSlot(reg, reg); |
| 5167 } | 5174 } |
| 5168 | 5175 |
| 5169 | 5176 |
| 5170 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 5177 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
| 5171 class DeferredNumberTagD V8_FINAL : public LDeferredCode { | 5178 class DeferredNumberTagD V8_FINAL : public LDeferredCode { |
| 5172 public: | 5179 public: |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5342 if (can_convert_undefined_to_nan) { | 5349 if (can_convert_undefined_to_nan) { |
| 5343 __ j(not_equal, &convert, Label::kNear); | 5350 __ j(not_equal, &convert, Label::kNear); |
| 5344 } else { | 5351 } else { |
| 5345 DeoptimizeIf(not_equal, env); | 5352 DeoptimizeIf(not_equal, env); |
| 5346 } | 5353 } |
| 5347 | 5354 |
| 5348 // Heap number to XMM conversion. | 5355 // Heap number to XMM conversion. |
| 5349 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 5356 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 5350 | 5357 |
| 5351 if (deoptimize_on_minus_zero) { | 5358 if (deoptimize_on_minus_zero) { |
| 5352 XMMRegister xmm_scratch = xmm0; | 5359 XMMRegister xmm_scratch = double_scratch0(); |
| 5353 __ xorps(xmm_scratch, xmm_scratch); | 5360 __ xorps(xmm_scratch, xmm_scratch); |
| 5354 __ ucomisd(result_reg, xmm_scratch); | 5361 __ ucomisd(result_reg, xmm_scratch); |
| 5355 __ j(not_zero, &done, Label::kNear); | 5362 __ j(not_zero, &done, Label::kNear); |
| 5356 __ movmskpd(temp_reg, result_reg); | 5363 __ movmskpd(temp_reg, result_reg); |
| 5357 __ test_b(temp_reg, 1); | 5364 __ test_b(temp_reg, 1); |
| 5358 DeoptimizeIf(not_zero, env); | 5365 DeoptimizeIf(not_zero, env); |
| 5359 } | 5366 } |
| 5360 __ jmp(&done, Label::kNear); | 5367 __ jmp(&done, Label::kNear); |
| 5361 | 5368 |
| 5362 if (can_convert_undefined_to_nan) { | 5369 if (can_convert_undefined_to_nan) { |
| (...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5508 } else { | 5515 } else { |
| 5509 X87Register input_reg = ToX87Register(input); | 5516 X87Register input_reg = ToX87Register(input); |
| 5510 X87Fxch(input_reg); | 5517 X87Fxch(input_reg); |
| 5511 __ TruncateX87TOSToI(result_reg); | 5518 __ TruncateX87TOSToI(result_reg); |
| 5512 } | 5519 } |
| 5513 } else { | 5520 } else { |
| 5514 Label bailout, done; | 5521 Label bailout, done; |
| 5515 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 5522 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 5516 CpuFeatureScope scope(masm(), SSE2); | 5523 CpuFeatureScope scope(masm(), SSE2); |
| 5517 XMMRegister input_reg = ToDoubleRegister(input); | 5524 XMMRegister input_reg = ToDoubleRegister(input); |
| 5518 __ DoubleToI(result_reg, input_reg, xmm0, | 5525 XMMRegister xmm_scratch = double_scratch0(); |
| 5526 __ DoubleToI(result_reg, input_reg, xmm_scratch, |
| 5519 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); | 5527 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); |
| 5520 } else { | 5528 } else { |
| 5521 X87Register input_reg = ToX87Register(input); | 5529 X87Register input_reg = ToX87Register(input); |
| 5522 X87Fxch(input_reg); | 5530 X87Fxch(input_reg); |
| 5523 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), | 5531 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), |
| 5524 &bailout, Label::kNear); | 5532 &bailout, Label::kNear); |
| 5525 } | 5533 } |
| 5526 __ jmp(&done, Label::kNear); | 5534 __ jmp(&done, Label::kNear); |
| 5527 __ bind(&bailout); | 5535 __ bind(&bailout); |
| 5528 DeoptimizeIf(no_condition, instr->environment()); | 5536 DeoptimizeIf(no_condition, instr->environment()); |
| 5529 __ bind(&done); | 5537 __ bind(&done); |
| 5530 } | 5538 } |
| 5531 } | 5539 } |
| 5532 | 5540 |
| 5533 | 5541 |
| 5534 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { | 5542 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { |
| 5535 LOperand* input = instr->value(); | 5543 LOperand* input = instr->value(); |
| 5536 ASSERT(input->IsDoubleRegister()); | 5544 ASSERT(input->IsDoubleRegister()); |
| 5537 LOperand* result = instr->result(); | 5545 LOperand* result = instr->result(); |
| 5538 ASSERT(result->IsRegister()); | 5546 ASSERT(result->IsRegister()); |
| 5539 Register result_reg = ToRegister(result); | 5547 Register result_reg = ToRegister(result); |
| 5540 | 5548 |
| 5541 Label bailout, done; | 5549 Label bailout, done; |
| 5542 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 5550 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
| 5543 CpuFeatureScope scope(masm(), SSE2); | 5551 CpuFeatureScope scope(masm(), SSE2); |
| 5544 XMMRegister input_reg = ToDoubleRegister(input); | 5552 XMMRegister input_reg = ToDoubleRegister(input); |
| 5545 __ DoubleToI(result_reg, input_reg, xmm0, | 5553 XMMRegister xmm_scratch = double_scratch0(); |
| 5554 __ DoubleToI(result_reg, input_reg, xmm_scratch, |
| 5546 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); | 5555 instr->hydrogen()->GetMinusZeroMode(), &bailout, Label::kNear); |
| 5547 } else { | 5556 } else { |
| 5548 X87Register input_reg = ToX87Register(input); | 5557 X87Register input_reg = ToX87Register(input); |
| 5549 X87Fxch(input_reg); | 5558 X87Fxch(input_reg); |
| 5550 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), | 5559 __ X87TOSToI(result_reg, instr->hydrogen()->GetMinusZeroMode(), |
| 5551 &bailout, Label::kNear); | 5560 &bailout, Label::kNear); |
| 5552 } | 5561 } |
| 5553 __ jmp(&done, Label::kNear); | 5562 __ jmp(&done, Label::kNear); |
| 5554 __ bind(&bailout); | 5563 __ bind(&bailout); |
| 5555 DeoptimizeIf(no_condition, instr->environment()); | 5564 DeoptimizeIf(no_condition, instr->environment()); |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5699 DeoptimizeIf(not_equal, instr->environment()); | 5708 DeoptimizeIf(not_equal, instr->environment()); |
| 5700 } | 5709 } |
| 5701 | 5710 |
| 5702 __ bind(&success); | 5711 __ bind(&success); |
| 5703 } | 5712 } |
| 5704 | 5713 |
| 5705 | 5714 |
| 5706 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { | 5715 void LCodeGen::DoClampDToUint8(LClampDToUint8* instr) { |
| 5707 CpuFeatureScope scope(masm(), SSE2); | 5716 CpuFeatureScope scope(masm(), SSE2); |
| 5708 XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); | 5717 XMMRegister value_reg = ToDoubleRegister(instr->unclamped()); |
| 5718 XMMRegister xmm_scratch = double_scratch0(); |
| 5709 Register result_reg = ToRegister(instr->result()); | 5719 Register result_reg = ToRegister(instr->result()); |
| 5710 __ ClampDoubleToUint8(value_reg, xmm0, result_reg); | 5720 __ ClampDoubleToUint8(value_reg, xmm_scratch, result_reg); |
| 5711 } | 5721 } |
| 5712 | 5722 |
| 5713 | 5723 |
| 5714 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { | 5724 void LCodeGen::DoClampIToUint8(LClampIToUint8* instr) { |
| 5715 ASSERT(instr->unclamped()->Equals(instr->result())); | 5725 ASSERT(instr->unclamped()->Equals(instr->result())); |
| 5716 Register value_reg = ToRegister(instr->result()); | 5726 Register value_reg = ToRegister(instr->result()); |
| 5717 __ ClampUint8(value_reg); | 5727 __ ClampUint8(value_reg); |
| 5718 } | 5728 } |
| 5719 | 5729 |
| 5720 | 5730 |
| 5721 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { | 5731 void LCodeGen::DoClampTToUint8(LClampTToUint8* instr) { |
| 5722 CpuFeatureScope scope(masm(), SSE2); | 5732 CpuFeatureScope scope(masm(), SSE2); |
| 5723 | 5733 |
| 5724 ASSERT(instr->unclamped()->Equals(instr->result())); | 5734 ASSERT(instr->unclamped()->Equals(instr->result())); |
| 5725 Register input_reg = ToRegister(instr->unclamped()); | 5735 Register input_reg = ToRegister(instr->unclamped()); |
| 5736 XMMRegister xmm_scratch = double_scratch0(); |
| 5726 Label is_smi, done, heap_number; | 5737 Label is_smi, done, heap_number; |
| 5727 | 5738 |
| 5728 __ JumpIfSmi(input_reg, &is_smi); | 5739 __ JumpIfSmi(input_reg, &is_smi); |
| 5729 | 5740 |
| 5730 // Check for heap number | 5741 // Check for heap number |
| 5731 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 5742 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
| 5732 factory()->heap_number_map()); | 5743 factory()->heap_number_map()); |
| 5733 __ j(equal, &heap_number, Label::kNear); | 5744 __ j(equal, &heap_number, Label::kNear); |
| 5734 | 5745 |
| 5735 // Check for undefined. Undefined is converted to zero for clamping | 5746 // Check for undefined. Undefined is converted to zero for clamping |
| 5736 // conversions. | 5747 // conversions. |
| 5737 __ cmp(input_reg, factory()->undefined_value()); | 5748 __ cmp(input_reg, factory()->undefined_value()); |
| 5738 DeoptimizeIf(not_equal, instr->environment()); | 5749 DeoptimizeIf(not_equal, instr->environment()); |
| 5739 __ mov(input_reg, 0); | 5750 __ mov(input_reg, 0); |
| 5740 __ jmp(&done, Label::kNear); | 5751 __ jmp(&done, Label::kNear); |
| 5741 | 5752 |
| 5742 // Heap number | 5753 // Heap number |
| 5743 __ bind(&heap_number); | 5754 __ bind(&heap_number); |
| 5744 __ movdbl(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 5755 __ movdbl(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 5745 __ ClampDoubleToUint8(xmm0, xmm1, input_reg); | 5756 __ ClampDoubleToUint8(xmm_scratch, xmm1, input_reg); |
| 5746 __ jmp(&done, Label::kNear); | 5757 __ jmp(&done, Label::kNear); |
| 5747 | 5758 |
| 5748 // smi | 5759 // smi |
| 5749 __ bind(&is_smi); | 5760 __ bind(&is_smi); |
| 5750 __ SmiUntag(input_reg); | 5761 __ SmiUntag(input_reg); |
| 5751 __ ClampUint8(input_reg); | 5762 __ ClampUint8(input_reg); |
| 5752 __ bind(&done); | 5763 __ bind(&done); |
| 5753 } | 5764 } |
| 5754 | 5765 |
| 5755 | 5766 |
| (...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6384 FixedArray::kHeaderSize - kPointerSize)); | 6395 FixedArray::kHeaderSize - kPointerSize)); |
| 6385 __ bind(&done); | 6396 __ bind(&done); |
| 6386 } | 6397 } |
| 6387 | 6398 |
| 6388 | 6399 |
| 6389 #undef __ | 6400 #undef __ |
| 6390 | 6401 |
| 6391 } } // namespace v8::internal | 6402 } } // namespace v8::internal |
| 6392 | 6403 |
| 6393 #endif // V8_TARGET_ARCH_IA32 | 6404 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |