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 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
250 } | 250 } |
251 } | 251 } |
252 | 252 |
253 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { | 253 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { |
254 Comment(";;; Save clobbered callee double registers"); | 254 Comment(";;; Save clobbered callee double registers"); |
255 CpuFeatureScope scope(masm(), SSE2); | 255 CpuFeatureScope scope(masm(), SSE2); |
256 int count = 0; | 256 int count = 0; |
257 BitVector* doubles = chunk()->allocated_double_registers(); | 257 BitVector* doubles = chunk()->allocated_double_registers(); |
258 BitVector::Iterator save_iterator(doubles); | 258 BitVector::Iterator save_iterator(doubles); |
259 while (!save_iterator.Done()) { | 259 while (!save_iterator.Done()) { |
260 __ movdbl(MemOperand(esp, count * kDoubleSize), | 260 __ movsd(MemOperand(esp, count * kDoubleSize), |
261 XMMRegister::FromAllocationIndex(save_iterator.Current())); | 261 XMMRegister::FromAllocationIndex(save_iterator.Current())); |
262 save_iterator.Advance(); | 262 save_iterator.Advance(); |
263 count++; | 263 count++; |
264 } | 264 } |
265 } | 265 } |
266 } | 266 } |
267 | 267 |
268 // Possibly allocate a local context. | 268 // Possibly allocate a local context. |
269 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; | 269 int heap_slots = info_->num_heap_slots() - Context::MIN_CONTEXT_SLOTS; |
270 if (heap_slots > 0) { | 270 if (heap_slots > 0) { |
(...skipping 1955 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2226 break; | 2226 break; |
2227 case Token::DIV: | 2227 case Token::DIV: |
2228 __ divsd(left, right); | 2228 __ divsd(left, right); |
2229 // Don't delete this mov. It may improve performance on some CPUs, | 2229 // Don't delete this mov. It may improve performance on some CPUs, |
2230 // when there is a mulsd depending on the result | 2230 // when there is a mulsd depending on the result |
2231 __ movaps(left, left); | 2231 __ movaps(left, left); |
2232 break; | 2232 break; |
2233 case Token::MOD: { | 2233 case Token::MOD: { |
2234 // Pass two doubles as arguments on the stack. | 2234 // Pass two doubles as arguments on the stack. |
2235 __ PrepareCallCFunction(4, eax); | 2235 __ PrepareCallCFunction(4, eax); |
2236 __ movdbl(Operand(esp, 0 * kDoubleSize), left); | 2236 __ movsd(Operand(esp, 0 * kDoubleSize), left); |
2237 __ movdbl(Operand(esp, 1 * kDoubleSize), right); | 2237 __ movsd(Operand(esp, 1 * kDoubleSize), right); |
2238 __ CallCFunction( | 2238 __ CallCFunction( |
2239 ExternalReference::double_fp_operation(Token::MOD, isolate()), | 2239 ExternalReference::double_fp_operation(Token::MOD, isolate()), |
2240 4); | 2240 4); |
2241 | 2241 |
2242 // Return value is in st(0) on ia32. | 2242 // Return value is in st(0) on ia32. |
2243 // Store it into the result register. | 2243 // Store it into the result register. |
2244 __ sub(Operand(esp), Immediate(kDoubleSize)); | 2244 __ sub(Operand(esp), Immediate(kDoubleSize)); |
2245 __ fstp_d(Operand(esp, 0)); | 2245 __ fstp_d(Operand(esp, 0)); |
2246 __ movdbl(result, Operand(esp, 0)); | 2246 __ movsd(result, Operand(esp, 0)); |
2247 __ add(Operand(esp), Immediate(kDoubleSize)); | 2247 __ add(Operand(esp), Immediate(kDoubleSize)); |
2248 break; | 2248 break; |
2249 } | 2249 } |
2250 default: | 2250 default: |
2251 UNREACHABLE(); | 2251 UNREACHABLE(); |
2252 break; | 2252 break; |
2253 } | 2253 } |
2254 } else { | 2254 } else { |
2255 X87Register left = ToX87Register(instr->left()); | 2255 X87Register left = ToX87Register(instr->left()); |
2256 X87Register right = ToX87Register(instr->right()); | 2256 X87Register right = ToX87Register(instr->right()); |
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2610 __ fstp(0); | 2610 __ fstp(0); |
2611 EmitFalseBranch(instr, no_condition); | 2611 EmitFalseBranch(instr, no_condition); |
2612 __ bind(&ok); | 2612 __ bind(&ok); |
2613 } | 2613 } |
2614 | 2614 |
2615 | 2615 |
2616 __ sub(esp, Immediate(kDoubleSize)); | 2616 __ sub(esp, Immediate(kDoubleSize)); |
2617 if (use_sse2) { | 2617 if (use_sse2) { |
2618 CpuFeatureScope scope(masm(), SSE2); | 2618 CpuFeatureScope scope(masm(), SSE2); |
2619 XMMRegister input_reg = ToDoubleRegister(instr->object()); | 2619 XMMRegister input_reg = ToDoubleRegister(instr->object()); |
2620 __ movdbl(MemOperand(esp, 0), input_reg); | 2620 __ movsd(MemOperand(esp, 0), input_reg); |
2621 } else { | 2621 } else { |
2622 __ fstp_d(MemOperand(esp, 0)); | 2622 __ fstp_d(MemOperand(esp, 0)); |
2623 } | 2623 } |
2624 | 2624 |
2625 __ add(esp, Immediate(kDoubleSize)); | 2625 __ add(esp, Immediate(kDoubleSize)); |
2626 int offset = sizeof(kHoleNanUpper32); | 2626 int offset = sizeof(kHoleNanUpper32); |
2627 __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32)); | 2627 __ cmp(MemOperand(esp, -offset), Immediate(kHoleNanUpper32)); |
2628 EmitBranch(instr, equal); | 2628 EmitBranch(instr, equal); |
2629 } | 2629 } |
2630 | 2630 |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3072 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 3072 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
3073 __ CallRuntime(Runtime::kTraceExit, 1); | 3073 __ CallRuntime(Runtime::kTraceExit, 1); |
3074 } | 3074 } |
3075 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { | 3075 if (info()->saves_caller_doubles() && CpuFeatures::IsSupported(SSE2)) { |
3076 ASSERT(NeedsEagerFrame()); | 3076 ASSERT(NeedsEagerFrame()); |
3077 CpuFeatureScope scope(masm(), SSE2); | 3077 CpuFeatureScope scope(masm(), SSE2); |
3078 BitVector* doubles = chunk()->allocated_double_registers(); | 3078 BitVector* doubles = chunk()->allocated_double_registers(); |
3079 BitVector::Iterator save_iterator(doubles); | 3079 BitVector::Iterator save_iterator(doubles); |
3080 int count = 0; | 3080 int count = 0; |
3081 while (!save_iterator.Done()) { | 3081 while (!save_iterator.Done()) { |
3082 __ movdbl(XMMRegister::FromAllocationIndex(save_iterator.Current()), | 3082 __ movsd(XMMRegister::FromAllocationIndex(save_iterator.Current()), |
3083 MemOperand(esp, count * kDoubleSize)); | 3083 MemOperand(esp, count * kDoubleSize)); |
3084 save_iterator.Advance(); | 3084 save_iterator.Advance(); |
3085 count++; | 3085 count++; |
3086 } | 3086 } |
3087 } | 3087 } |
3088 if (dynamic_frame_alignment_) { | 3088 if (dynamic_frame_alignment_) { |
3089 // Fetch the state of the dynamic frame alignment. | 3089 // Fetch the state of the dynamic frame alignment. |
3090 __ mov(edx, Operand(ebp, | 3090 __ mov(edx, Operand(ebp, |
3091 JavaScriptFrameConstants::kDynamicAlignmentStateOffset)); | 3091 JavaScriptFrameConstants::kDynamicAlignmentStateOffset)); |
3092 } | 3092 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3240 } | 3240 } |
3241 return; | 3241 return; |
3242 } | 3242 } |
3243 | 3243 |
3244 Register object = ToRegister(instr->object()); | 3244 Register object = ToRegister(instr->object()); |
3245 if (FLAG_track_double_fields && | 3245 if (FLAG_track_double_fields && |
3246 instr->hydrogen()->representation().IsDouble()) { | 3246 instr->hydrogen()->representation().IsDouble()) { |
3247 if (CpuFeatures::IsSupported(SSE2)) { | 3247 if (CpuFeatures::IsSupported(SSE2)) { |
3248 CpuFeatureScope scope(masm(), SSE2); | 3248 CpuFeatureScope scope(masm(), SSE2); |
3249 XMMRegister result = ToDoubleRegister(instr->result()); | 3249 XMMRegister result = ToDoubleRegister(instr->result()); |
3250 __ movdbl(result, FieldOperand(object, offset)); | 3250 __ movsd(result, FieldOperand(object, offset)); |
3251 } else { | 3251 } else { |
3252 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); | 3252 X87Mov(ToX87Register(instr->result()), FieldOperand(object, offset)); |
3253 } | 3253 } |
3254 return; | 3254 return; |
3255 } | 3255 } |
3256 | 3256 |
3257 Register result = ToRegister(instr->result()); | 3257 Register result = ToRegister(instr->result()); |
3258 if (!access.IsInobject()) { | 3258 if (!access.IsInobject()) { |
3259 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); | 3259 __ mov(result, FieldOperand(object, JSObject::kPropertiesOffset)); |
3260 object = result; | 3260 object = result; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3394 CpuFeatureScope scope(masm(), SSE2); | 3394 CpuFeatureScope scope(masm(), SSE2); |
3395 XMMRegister result(ToDoubleRegister(instr->result())); | 3395 XMMRegister result(ToDoubleRegister(instr->result())); |
3396 __ movss(result, operand); | 3396 __ movss(result, operand); |
3397 __ cvtss2sd(result, result); | 3397 __ cvtss2sd(result, result); |
3398 } else { | 3398 } else { |
3399 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); | 3399 X87Mov(ToX87Register(instr->result()), operand, kX87FloatOperand); |
3400 } | 3400 } |
3401 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 3401 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
3402 if (CpuFeatures::IsSupported(SSE2)) { | 3402 if (CpuFeatures::IsSupported(SSE2)) { |
3403 CpuFeatureScope scope(masm(), SSE2); | 3403 CpuFeatureScope scope(masm(), SSE2); |
3404 __ movdbl(ToDoubleRegister(instr->result()), operand); | 3404 __ movsd(ToDoubleRegister(instr->result()), operand); |
3405 } else { | 3405 } else { |
3406 X87Mov(ToX87Register(instr->result()), operand); | 3406 X87Mov(ToX87Register(instr->result()), operand); |
3407 } | 3407 } |
3408 } else { | 3408 } else { |
3409 Register result(ToRegister(instr->result())); | 3409 Register result(ToRegister(instr->result())); |
3410 switch (elements_kind) { | 3410 switch (elements_kind) { |
3411 case EXTERNAL_BYTE_ELEMENTS: | 3411 case EXTERNAL_BYTE_ELEMENTS: |
3412 __ movsx_b(result, operand); | 3412 __ movsx_b(result, operand); |
3413 break; | 3413 break; |
3414 case EXTERNAL_PIXEL_ELEMENTS: | 3414 case EXTERNAL_PIXEL_ELEMENTS: |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3465 Operand double_load_operand = BuildFastArrayOperand( | 3465 Operand double_load_operand = BuildFastArrayOperand( |
3466 instr->elements(), | 3466 instr->elements(), |
3467 instr->key(), | 3467 instr->key(), |
3468 instr->hydrogen()->key()->representation(), | 3468 instr->hydrogen()->key()->representation(), |
3469 FAST_DOUBLE_ELEMENTS, | 3469 FAST_DOUBLE_ELEMENTS, |
3470 FixedDoubleArray::kHeaderSize - kHeapObjectTag, | 3470 FixedDoubleArray::kHeaderSize - kHeapObjectTag, |
3471 instr->additional_index()); | 3471 instr->additional_index()); |
3472 if (CpuFeatures::IsSupported(SSE2)) { | 3472 if (CpuFeatures::IsSupported(SSE2)) { |
3473 CpuFeatureScope scope(masm(), SSE2); | 3473 CpuFeatureScope scope(masm(), SSE2); |
3474 XMMRegister result = ToDoubleRegister(instr->result()); | 3474 XMMRegister result = ToDoubleRegister(instr->result()); |
3475 __ movdbl(result, double_load_operand); | 3475 __ movsd(result, double_load_operand); |
3476 } else { | 3476 } else { |
3477 X87Mov(ToX87Register(instr->result()), double_load_operand); | 3477 X87Mov(ToX87Register(instr->result()), double_load_operand); |
3478 } | 3478 } |
3479 } | 3479 } |
3480 | 3480 |
3481 | 3481 |
3482 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { | 3482 void LCodeGen::DoLoadKeyedFixedArray(LLoadKeyed* instr) { |
3483 Register result = ToRegister(instr->result()); | 3483 Register result = ToRegister(instr->result()); |
3484 | 3484 |
3485 // Load the result. | 3485 // Load the result. |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3988 CpuFeatureScope scope(masm(), SSE2); | 3988 CpuFeatureScope scope(masm(), SSE2); |
3989 Register output_reg = ToRegister(instr->result()); | 3989 Register output_reg = ToRegister(instr->result()); |
3990 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 3990 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
3991 XMMRegister xmm_scratch = double_scratch0(); | 3991 XMMRegister xmm_scratch = double_scratch0(); |
3992 XMMRegister input_temp = ToDoubleRegister(instr->temp()); | 3992 XMMRegister input_temp = ToDoubleRegister(instr->temp()); |
3993 ExternalReference one_half = ExternalReference::address_of_one_half(); | 3993 ExternalReference one_half = ExternalReference::address_of_one_half(); |
3994 ExternalReference minus_one_half = | 3994 ExternalReference minus_one_half = |
3995 ExternalReference::address_of_minus_one_half(); | 3995 ExternalReference::address_of_minus_one_half(); |
3996 | 3996 |
3997 Label done, round_to_zero, below_one_half, do_not_compensate; | 3997 Label done, round_to_zero, below_one_half, do_not_compensate; |
3998 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); | 3998 __ movsd(xmm_scratch, Operand::StaticVariable(one_half)); |
3999 __ ucomisd(xmm_scratch, input_reg); | 3999 __ ucomisd(xmm_scratch, input_reg); |
4000 __ j(above, &below_one_half); | 4000 __ j(above, &below_one_half); |
4001 | 4001 |
4002 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). | 4002 // CVTTSD2SI rounds towards zero, since 0.5 <= x, we use floor(0.5 + x). |
4003 __ addsd(xmm_scratch, input_reg); | 4003 __ addsd(xmm_scratch, input_reg); |
4004 __ cvttsd2si(output_reg, Operand(xmm_scratch)); | 4004 __ cvttsd2si(output_reg, Operand(xmm_scratch)); |
4005 // Overflow is signalled with minint. | 4005 // Overflow is signalled with minint. |
4006 __ cmp(output_reg, 0x80000000u); | 4006 __ cmp(output_reg, 0x80000000u); |
4007 __ RecordComment("D2I conversion overflow"); | 4007 __ RecordComment("D2I conversion overflow"); |
4008 DeoptimizeIf(equal, instr->environment()); | 4008 DeoptimizeIf(equal, instr->environment()); |
4009 __ jmp(&done); | 4009 __ jmp(&done); |
4010 | 4010 |
4011 __ bind(&below_one_half); | 4011 __ bind(&below_one_half); |
4012 __ movdbl(xmm_scratch, Operand::StaticVariable(minus_one_half)); | 4012 __ movsd(xmm_scratch, Operand::StaticVariable(minus_one_half)); |
4013 __ ucomisd(xmm_scratch, input_reg); | 4013 __ ucomisd(xmm_scratch, input_reg); |
4014 __ j(below_equal, &round_to_zero); | 4014 __ j(below_equal, &round_to_zero); |
4015 | 4015 |
4016 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then | 4016 // CVTTSD2SI rounds towards zero, we use ceil(x - (-0.5)) and then |
4017 // compare and compensate. | 4017 // compare and compensate. |
4018 __ movsd(input_temp, input_reg); // Do not alter input_reg. | 4018 __ movsd(input_temp, input_reg); // Do not alter input_reg. |
4019 __ subsd(input_temp, xmm_scratch); | 4019 __ subsd(input_temp, xmm_scratch); |
4020 __ cvttsd2si(output_reg, Operand(input_temp)); | 4020 __ cvttsd2si(output_reg, Operand(input_temp)); |
4021 // Catch minint due to overflow, and to prevent overflow when compensating. | 4021 // Catch minint due to overflow, and to prevent overflow when compensating. |
4022 __ cmp(output_reg, 0x80000000u); | 4022 __ cmp(output_reg, 0x80000000u); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4189 ASSERT(instr->value()->Equals(instr->result())); | 4189 ASSERT(instr->value()->Equals(instr->result())); |
4190 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 4190 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
4191 XMMRegister xmm_scratch = double_scratch0(); | 4191 XMMRegister xmm_scratch = double_scratch0(); |
4192 Label positive, done, zero; | 4192 Label positive, done, zero; |
4193 __ xorps(xmm_scratch, xmm_scratch); | 4193 __ xorps(xmm_scratch, xmm_scratch); |
4194 __ ucomisd(input_reg, xmm_scratch); | 4194 __ ucomisd(input_reg, xmm_scratch); |
4195 __ j(above, &positive, Label::kNear); | 4195 __ j(above, &positive, Label::kNear); |
4196 __ j(equal, &zero, Label::kNear); | 4196 __ j(equal, &zero, Label::kNear); |
4197 ExternalReference nan = | 4197 ExternalReference nan = |
4198 ExternalReference::address_of_canonical_non_hole_nan(); | 4198 ExternalReference::address_of_canonical_non_hole_nan(); |
4199 __ movdbl(input_reg, Operand::StaticVariable(nan)); | 4199 __ movsd(input_reg, Operand::StaticVariable(nan)); |
4200 __ jmp(&done, Label::kNear); | 4200 __ jmp(&done, Label::kNear); |
4201 __ bind(&zero); | 4201 __ bind(&zero); |
4202 __ push(Immediate(0xFFF00000)); | 4202 ExternalReference ninf = |
4203 __ push(Immediate(0)); | 4203 ExternalReference::address_of_negative_infinity(); |
4204 __ movdbl(input_reg, Operand(esp, 0)); | 4204 __ movsd(input_reg, Operand::StaticVariable(ninf)); |
4205 __ add(Operand(esp), Immediate(kDoubleSize)); | |
4206 __ jmp(&done, Label::kNear); | 4205 __ jmp(&done, Label::kNear); |
4207 __ bind(&positive); | 4206 __ bind(&positive); |
4208 __ fldln2(); | 4207 __ fldln2(); |
4209 __ sub(Operand(esp), Immediate(kDoubleSize)); | 4208 __ sub(Operand(esp), Immediate(kDoubleSize)); |
4210 __ movdbl(Operand(esp, 0), input_reg); | 4209 __ movsd(Operand(esp, 0), input_reg); |
4211 __ fld_d(Operand(esp, 0)); | 4210 __ fld_d(Operand(esp, 0)); |
4212 __ fyl2x(); | 4211 __ fyl2x(); |
4213 __ fstp_d(Operand(esp, 0)); | 4212 __ fstp_d(Operand(esp, 0)); |
4214 __ movdbl(input_reg, Operand(esp, 0)); | 4213 __ movsd(input_reg, Operand(esp, 0)); |
4215 __ add(Operand(esp), Immediate(kDoubleSize)); | 4214 __ add(Operand(esp), Immediate(kDoubleSize)); |
4216 __ bind(&done); | 4215 __ bind(&done); |
4217 } | 4216 } |
4218 | 4217 |
4219 | 4218 |
4220 void LCodeGen::DoMathExp(LMathExp* instr) { | 4219 void LCodeGen::DoMathExp(LMathExp* instr) { |
4221 CpuFeatureScope scope(masm(), SSE2); | 4220 CpuFeatureScope scope(masm(), SSE2); |
4222 XMMRegister input = ToDoubleRegister(instr->value()); | 4221 XMMRegister input = ToDoubleRegister(instr->value()); |
4223 XMMRegister result = ToDoubleRegister(instr->result()); | 4222 XMMRegister result = ToDoubleRegister(instr->result()); |
4224 XMMRegister temp0 = double_scratch0(); | 4223 XMMRegister temp0 = double_scratch0(); |
(...skipping 250 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4475 DeoptimizeIf(zero, instr->environment()); | 4474 DeoptimizeIf(zero, instr->environment()); |
4476 } | 4475 } |
4477 } | 4476 } |
4478 } else if (FLAG_track_double_fields && representation.IsDouble()) { | 4477 } else if (FLAG_track_double_fields && representation.IsDouble()) { |
4479 ASSERT(transition.is_null()); | 4478 ASSERT(transition.is_null()); |
4480 ASSERT(access.IsInobject()); | 4479 ASSERT(access.IsInobject()); |
4481 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); | 4480 ASSERT(!instr->hydrogen()->NeedsWriteBarrier()); |
4482 if (CpuFeatures::IsSupported(SSE2)) { | 4481 if (CpuFeatures::IsSupported(SSE2)) { |
4483 CpuFeatureScope scope(masm(), SSE2); | 4482 CpuFeatureScope scope(masm(), SSE2); |
4484 XMMRegister value = ToDoubleRegister(instr->value()); | 4483 XMMRegister value = ToDoubleRegister(instr->value()); |
4485 __ movdbl(FieldOperand(object, offset), value); | 4484 __ movsd(FieldOperand(object, offset), value); |
4486 } else { | 4485 } else { |
4487 X87Register value = ToX87Register(instr->value()); | 4486 X87Register value = ToX87Register(instr->value()); |
4488 X87Mov(FieldOperand(object, offset), value); | 4487 X87Mov(FieldOperand(object, offset), value); |
4489 } | 4488 } |
4490 return; | 4489 return; |
4491 } | 4490 } |
4492 | 4491 |
4493 if (!transition.is_null()) { | 4492 if (!transition.is_null()) { |
4494 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { | 4493 if (!instr->hydrogen()->NeedsWriteBarrierForMap()) { |
4495 __ mov(FieldOperand(object, HeapObject::kMapOffset), transition); | 4494 __ mov(FieldOperand(object, HeapObject::kMapOffset), transition); |
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4625 XMMRegister xmm_scratch = double_scratch0(); | 4624 XMMRegister xmm_scratch = double_scratch0(); |
4626 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); | 4625 __ cvtsd2ss(xmm_scratch, ToDoubleRegister(instr->value())); |
4627 __ movss(operand, xmm_scratch); | 4626 __ movss(operand, xmm_scratch); |
4628 } else { | 4627 } else { |
4629 __ fld(0); | 4628 __ fld(0); |
4630 __ fstp_s(operand); | 4629 __ fstp_s(operand); |
4631 } | 4630 } |
4632 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { | 4631 } else if (elements_kind == EXTERNAL_DOUBLE_ELEMENTS) { |
4633 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4632 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
4634 CpuFeatureScope scope(masm(), SSE2); | 4633 CpuFeatureScope scope(masm(), SSE2); |
4635 __ movdbl(operand, ToDoubleRegister(instr->value())); | 4634 __ movsd(operand, ToDoubleRegister(instr->value())); |
4636 } else { | 4635 } else { |
4637 X87Mov(operand, ToX87Register(instr->value())); | 4636 X87Mov(operand, ToX87Register(instr->value())); |
4638 } | 4637 } |
4639 } else { | 4638 } else { |
4640 Register value = ToRegister(instr->value()); | 4639 Register value = ToRegister(instr->value()); |
4641 switch (elements_kind) { | 4640 switch (elements_kind) { |
4642 case EXTERNAL_PIXEL_ELEMENTS: | 4641 case EXTERNAL_PIXEL_ELEMENTS: |
4643 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 4642 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
4644 case EXTERNAL_BYTE_ELEMENTS: | 4643 case EXTERNAL_BYTE_ELEMENTS: |
4645 __ mov_b(operand, value); | 4644 __ mov_b(operand, value); |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4683 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { | 4682 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { |
4684 CpuFeatureScope scope(masm(), SSE2); | 4683 CpuFeatureScope scope(masm(), SSE2); |
4685 XMMRegister value = ToDoubleRegister(instr->value()); | 4684 XMMRegister value = ToDoubleRegister(instr->value()); |
4686 | 4685 |
4687 if (instr->NeedsCanonicalization()) { | 4686 if (instr->NeedsCanonicalization()) { |
4688 Label have_value; | 4687 Label have_value; |
4689 | 4688 |
4690 __ ucomisd(value, value); | 4689 __ ucomisd(value, value); |
4691 __ j(parity_odd, &have_value); // NaN. | 4690 __ j(parity_odd, &have_value); // NaN. |
4692 | 4691 |
4693 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference)); | 4692 __ movsd(value, Operand::StaticVariable(canonical_nan_reference)); |
4694 __ bind(&have_value); | 4693 __ bind(&have_value); |
4695 } | 4694 } |
4696 | 4695 |
4697 __ movdbl(double_store_operand, value); | 4696 __ movsd(double_store_operand, value); |
4698 } else { | 4697 } else { |
4699 // Can't use SSE2 in the serializer | 4698 // Can't use SSE2 in the serializer |
4700 if (instr->hydrogen()->IsConstantHoleStore()) { | 4699 if (instr->hydrogen()->IsConstantHoleStore()) { |
4701 // This means we should store the (double) hole. No floating point | 4700 // This means we should store the (double) hole. No floating point |
4702 // registers required. | 4701 // registers required. |
4703 double nan_double = FixedDoubleArray::hole_nan_as_double(); | 4702 double nan_double = FixedDoubleArray::hole_nan_as_double(); |
4704 uint64_t int_val = BitCast<uint64_t, double>(nan_double); | 4703 uint64_t int_val = BitCast<uint64_t, double>(nan_double); |
4705 int32_t lower = static_cast<int32_t>(int_val); | 4704 int32_t lower = static_cast<int32_t>(int_val); |
4706 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); | 4705 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); |
4707 | 4706 |
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5153 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); | 5152 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber); |
5154 RecordSafepointWithRegisters( | 5153 RecordSafepointWithRegisters( |
5155 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); | 5154 instr->pointer_map(), 0, Safepoint::kNoLazyDeopt); |
5156 if (!reg.is(eax)) __ mov(reg, eax); | 5155 if (!reg.is(eax)) __ mov(reg, eax); |
5157 | 5156 |
5158 // Done. Put the value in xmm_scratch into the value of the allocated heap | 5157 // Done. Put the value in xmm_scratch into the value of the allocated heap |
5159 // number. | 5158 // number. |
5160 __ bind(&done); | 5159 __ bind(&done); |
5161 if (CpuFeatures::IsSupported(SSE2)) { | 5160 if (CpuFeatures::IsSupported(SSE2)) { |
5162 CpuFeatureScope feature_scope(masm(), SSE2); | 5161 CpuFeatureScope feature_scope(masm(), SSE2); |
5163 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch); | 5162 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), xmm_scratch); |
5164 } else { | 5163 } else { |
5165 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 5164 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
5166 } | 5165 } |
5167 __ StoreToSafepointRegisterSlot(reg, reg); | 5166 __ StoreToSafepointRegisterSlot(reg, reg); |
5168 } | 5167 } |
5169 | 5168 |
5170 | 5169 |
5171 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { | 5170 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { |
5172 class DeferredNumberTagD V8_FINAL : public LDeferredCode { | 5171 class DeferredNumberTagD V8_FINAL : public LDeferredCode { |
5173 public: | 5172 public: |
(...skipping 23 matching lines...) Expand all Loading... |
5197 if (FLAG_inline_new) { | 5196 if (FLAG_inline_new) { |
5198 Register tmp = ToRegister(instr->temp()); | 5197 Register tmp = ToRegister(instr->temp()); |
5199 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); | 5198 __ AllocateHeapNumber(reg, tmp, no_reg, deferred->entry()); |
5200 } else { | 5199 } else { |
5201 __ jmp(deferred->entry()); | 5200 __ jmp(deferred->entry()); |
5202 } | 5201 } |
5203 __ bind(deferred->exit()); | 5202 __ bind(deferred->exit()); |
5204 if (use_sse2) { | 5203 if (use_sse2) { |
5205 CpuFeatureScope scope(masm(), SSE2); | 5204 CpuFeatureScope scope(masm(), SSE2); |
5206 XMMRegister input_reg = ToDoubleRegister(instr->value()); | 5205 XMMRegister input_reg = ToDoubleRegister(instr->value()); |
5207 __ movdbl(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); | 5206 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg); |
5208 } else { | 5207 } else { |
5209 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); | 5208 __ fstp_d(FieldOperand(reg, HeapNumber::kValueOffset)); |
5210 } | 5209 } |
5211 } | 5210 } |
5212 | 5211 |
5213 | 5212 |
5214 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { | 5213 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { |
5215 // TODO(3095996): Get rid of this. For now, we need to make the | 5214 // TODO(3095996): Get rid of this. For now, we need to make the |
5216 // result register contain a valid pointer because it is already | 5215 // result register contain a valid pointer because it is already |
5217 // contained in the register pointer map. | 5216 // contained in the register pointer map. |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5340 // Heap number map check. | 5339 // Heap number map check. |
5341 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), | 5340 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), |
5342 factory()->heap_number_map()); | 5341 factory()->heap_number_map()); |
5343 if (can_convert_undefined_to_nan) { | 5342 if (can_convert_undefined_to_nan) { |
5344 __ j(not_equal, &convert, Label::kNear); | 5343 __ j(not_equal, &convert, Label::kNear); |
5345 } else { | 5344 } else { |
5346 DeoptimizeIf(not_equal, env); | 5345 DeoptimizeIf(not_equal, env); |
5347 } | 5346 } |
5348 | 5347 |
5349 // Heap number to XMM conversion. | 5348 // Heap number to XMM conversion. |
5350 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 5349 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
5351 | 5350 |
5352 if (deoptimize_on_minus_zero) { | 5351 if (deoptimize_on_minus_zero) { |
5353 XMMRegister xmm_scratch = double_scratch0(); | 5352 XMMRegister xmm_scratch = double_scratch0(); |
5354 __ xorps(xmm_scratch, xmm_scratch); | 5353 __ xorps(xmm_scratch, xmm_scratch); |
5355 __ ucomisd(result_reg, xmm_scratch); | 5354 __ ucomisd(result_reg, xmm_scratch); |
5356 __ j(not_zero, &done, Label::kNear); | 5355 __ j(not_zero, &done, Label::kNear); |
5357 __ movmskpd(temp_reg, result_reg); | 5356 __ movmskpd(temp_reg, result_reg); |
5358 __ test_b(temp_reg, 1); | 5357 __ test_b(temp_reg, 1); |
5359 DeoptimizeIf(not_zero, env); | 5358 DeoptimizeIf(not_zero, env); |
5360 } | 5359 } |
5361 __ jmp(&done, Label::kNear); | 5360 __ jmp(&done, Label::kNear); |
5362 | 5361 |
5363 if (can_convert_undefined_to_nan) { | 5362 if (can_convert_undefined_to_nan) { |
5364 __ bind(&convert); | 5363 __ bind(&convert); |
5365 | 5364 |
5366 // Convert undefined (and hole) to NaN. | 5365 // Convert undefined (and hole) to NaN. |
5367 __ cmp(input_reg, factory()->undefined_value()); | 5366 __ cmp(input_reg, factory()->undefined_value()); |
5368 DeoptimizeIf(not_equal, env); | 5367 DeoptimizeIf(not_equal, env); |
5369 | 5368 |
5370 ExternalReference nan = | 5369 ExternalReference nan = |
5371 ExternalReference::address_of_canonical_non_hole_nan(); | 5370 ExternalReference::address_of_canonical_non_hole_nan(); |
5372 __ movdbl(result_reg, Operand::StaticVariable(nan)); | 5371 __ movsd(result_reg, Operand::StaticVariable(nan)); |
5373 __ jmp(&done, Label::kNear); | 5372 __ jmp(&done, Label::kNear); |
5374 } | 5373 } |
5375 } else { | 5374 } else { |
5376 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); | 5375 ASSERT(mode == NUMBER_CANDIDATE_IS_SMI); |
5377 } | 5376 } |
5378 | 5377 |
5379 __ bind(&load_smi); | 5378 __ bind(&load_smi); |
5380 // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the | 5379 // Smi to XMM conversion. Clobbering a temp is faster than re-tagging the |
5381 // input register since we avoid dependencies. | 5380 // input register since we avoid dependencies. |
5382 __ mov(temp_reg, input_reg); | 5381 __ mov(temp_reg, input_reg); |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5751 | 5750 |
5752 // Check for undefined. Undefined is converted to zero for clamping | 5751 // Check for undefined. Undefined is converted to zero for clamping |
5753 // conversions. | 5752 // conversions. |
5754 __ cmp(input_reg, factory()->undefined_value()); | 5753 __ cmp(input_reg, factory()->undefined_value()); |
5755 DeoptimizeIf(not_equal, instr->environment()); | 5754 DeoptimizeIf(not_equal, instr->environment()); |
5756 __ mov(input_reg, 0); | 5755 __ mov(input_reg, 0); |
5757 __ jmp(&done, Label::kNear); | 5756 __ jmp(&done, Label::kNear); |
5758 | 5757 |
5759 // Heap number | 5758 // Heap number |
5760 __ bind(&heap_number); | 5759 __ bind(&heap_number); |
5761 __ movdbl(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); | 5760 __ movsd(xmm_scratch, FieldOperand(input_reg, HeapNumber::kValueOffset)); |
5762 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); | 5761 __ ClampDoubleToUint8(xmm_scratch, temp_xmm_reg, input_reg); |
5763 __ jmp(&done, Label::kNear); | 5762 __ jmp(&done, Label::kNear); |
5764 | 5763 |
5765 // smi | 5764 // smi |
5766 __ bind(&is_smi); | 5765 __ bind(&is_smi); |
5767 __ SmiUntag(input_reg); | 5766 __ SmiUntag(input_reg); |
5768 __ ClampUint8(input_reg); | 5767 __ ClampUint8(input_reg); |
5769 __ bind(&done); | 5768 __ bind(&done); |
5770 } | 5769 } |
5771 | 5770 |
(...skipping 628 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6400 FixedArray::kHeaderSize - kPointerSize)); | 6399 FixedArray::kHeaderSize - kPointerSize)); |
6401 __ bind(&done); | 6400 __ bind(&done); |
6402 } | 6401 } |
6403 | 6402 |
6404 | 6403 |
6405 #undef __ | 6404 #undef __ |
6406 | 6405 |
6407 } } // namespace v8::internal | 6406 } } // namespace v8::internal |
6408 | 6407 |
6409 #endif // V8_TARGET_ARCH_IA32 | 6408 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |