| 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 |