| OLD | NEW |
| 1 // Copyright 2011 the V8 project authors. All rights reserved. | 1 // Copyright 2011 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 1044 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 double v = instr->value(); | 1055 double v = instr->value(); |
| 1056 // Use xor to produce +0.0 in a fast and compact way, but avoid to | 1056 // Use xor to produce +0.0 in a fast and compact way, but avoid to |
| 1057 // do so if the constant is -0.0. | 1057 // do so if the constant is -0.0. |
| 1058 if (BitCast<uint64_t, double>(v) == 0) { | 1058 if (BitCast<uint64_t, double>(v) == 0) { |
| 1059 __ xorpd(res, res); | 1059 __ xorpd(res, res); |
| 1060 } else { | 1060 } else { |
| 1061 Register temp = ToRegister(instr->TempAt(0)); | 1061 Register temp = ToRegister(instr->TempAt(0)); |
| 1062 uint64_t int_val = BitCast<uint64_t, double>(v); | 1062 uint64_t int_val = BitCast<uint64_t, double>(v); |
| 1063 int32_t lower = static_cast<int32_t>(int_val); | 1063 int32_t lower = static_cast<int32_t>(int_val); |
| 1064 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); | 1064 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); |
| 1065 if (CpuFeatures::IsSupported(SSE4_1)) { | 1065 if (isolate()->cpu_features()->IsSupported(SSE4_1)) { |
| 1066 CpuFeatures::Scope scope(SSE4_1); | 1066 CpuFeatures::Scope scope(SSE4_1); |
| 1067 if (lower != 0) { | 1067 if (lower != 0) { |
| 1068 __ Set(temp, Immediate(lower)); | 1068 __ Set(temp, Immediate(lower)); |
| 1069 __ movd(res, Operand(temp)); | 1069 __ movd(res, Operand(temp)); |
| 1070 __ Set(temp, Immediate(upper)); | 1070 __ Set(temp, Immediate(upper)); |
| 1071 __ pinsrd(res, Operand(temp), 1); | 1071 __ pinsrd(res, Operand(temp), 1); |
| 1072 } else { | 1072 } else { |
| 1073 __ xorpd(res, res); | 1073 __ xorpd(res, res); |
| 1074 __ Set(temp, Immediate(upper)); | 1074 __ Set(temp, Immediate(upper)); |
| 1075 __ pinsrd(res, Operand(temp), 1); | 1075 __ pinsrd(res, Operand(temp), 1); |
| (...skipping 949 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2025 __ push(eax); | 2025 __ push(eax); |
| 2026 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); | 2026 __ mov(esi, Operand(ebp, StandardFrameConstants::kContextOffset)); |
| 2027 __ CallRuntime(Runtime::kTraceExit, 1); | 2027 __ CallRuntime(Runtime::kTraceExit, 1); |
| 2028 } | 2028 } |
| 2029 __ mov(esp, ebp); | 2029 __ mov(esp, ebp); |
| 2030 __ pop(ebp); | 2030 __ pop(ebp); |
| 2031 __ Ret((ParameterCount() + 1) * kPointerSize, ecx); | 2031 __ Ret((ParameterCount() + 1) * kPointerSize, ecx); |
| 2032 } | 2032 } |
| 2033 | 2033 |
| 2034 | 2034 |
| 2035 void LCodeGen::DoLoadGlobalCell(LLoadGlobalCell* instr) { | 2035 void LCodeGen::DoLoadGlobal(LLoadGlobal* instr) { |
| 2036 Register result = ToRegister(instr->result()); | 2036 Register result = ToRegister(instr->result()); |
| 2037 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); | 2037 __ mov(result, Operand::Cell(instr->hydrogen()->cell())); |
| 2038 if (instr->hydrogen()->check_hole_value()) { | 2038 if (instr->hydrogen()->check_hole_value()) { |
| 2039 __ cmp(result, factory()->the_hole_value()); | 2039 __ cmp(result, factory()->the_hole_value()); |
| 2040 DeoptimizeIf(equal, instr->environment()); | 2040 DeoptimizeIf(equal, instr->environment()); |
| 2041 } | 2041 } |
| 2042 } | 2042 } |
| 2043 | 2043 |
| 2044 | 2044 |
| 2045 void LCodeGen::DoLoadGlobalGeneric(LLoadGlobalGeneric* instr) { | 2045 void LCodeGen::DoStoreGlobal(LStoreGlobal* instr) { |
| 2046 ASSERT(ToRegister(instr->context()).is(esi)); | |
| 2047 ASSERT(ToRegister(instr->global_object()).is(eax)); | |
| 2048 ASSERT(ToRegister(instr->result()).is(eax)); | |
| 2049 | |
| 2050 __ mov(ecx, instr->name()); | |
| 2051 RelocInfo::Mode mode = instr->for_typeof() ? RelocInfo::CODE_TARGET : | |
| 2052 RelocInfo::CODE_TARGET_CONTEXT; | |
| 2053 Handle<Code> ic = isolate()->builtins()->LoadIC_Initialize(); | |
| 2054 CallCode(ic, mode, instr); | |
| 2055 } | |
| 2056 | |
| 2057 | |
| 2058 void LCodeGen::DoStoreGlobalCell(LStoreGlobalCell* instr) { | |
| 2059 Register value = ToRegister(instr->InputAt(0)); | 2046 Register value = ToRegister(instr->InputAt(0)); |
| 2060 Operand cell_operand = Operand::Cell(instr->hydrogen()->cell()); | 2047 Operand cell_operand = Operand::Cell(instr->hydrogen()->cell()); |
| 2061 | 2048 |
| 2062 // If the cell we are storing to contains the hole it could have | 2049 // If the cell we are storing to contains the hole it could have |
| 2063 // been deleted from the property dictionary. In that case, we need | 2050 // been deleted from the property dictionary. In that case, we need |
| 2064 // to update the property details in the property dictionary to mark | 2051 // to update the property details in the property dictionary to mark |
| 2065 // it as no longer deleted. We deoptimize in that case. | 2052 // it as no longer deleted. We deoptimize in that case. |
| 2066 if (instr->hydrogen()->check_hole_value()) { | 2053 if (instr->hydrogen()->check_hole_value()) { |
| 2067 __ cmp(cell_operand, factory()->the_hole_value()); | 2054 __ cmp(cell_operand, factory()->the_hole_value()); |
| 2068 DeoptimizeIf(equal, instr->environment()); | 2055 DeoptimizeIf(equal, instr->environment()); |
| 2069 } | 2056 } |
| 2070 | 2057 |
| 2071 // Store the value. | 2058 // Store the value. |
| 2072 __ mov(cell_operand, value); | 2059 __ mov(cell_operand, value); |
| 2073 } | 2060 } |
| 2074 | 2061 |
| 2075 | 2062 |
| 2076 void LCodeGen::DoStoreGlobalGeneric(LStoreGlobalGeneric* instr) { | |
| 2077 ASSERT(ToRegister(instr->context()).is(esi)); | |
| 2078 ASSERT(ToRegister(instr->global_object()).is(edx)); | |
| 2079 ASSERT(ToRegister(instr->value()).is(eax)); | |
| 2080 | |
| 2081 __ mov(ecx, instr->name()); | |
| 2082 Handle<Code> ic = isolate()->builtins()->StoreIC_Initialize(); | |
| 2083 CallCode(ic, RelocInfo::CODE_TARGET_CONTEXT, instr); | |
| 2084 } | |
| 2085 | |
| 2086 | |
| 2087 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { | 2063 void LCodeGen::DoLoadContextSlot(LLoadContextSlot* instr) { |
| 2088 Register context = ToRegister(instr->context()); | 2064 Register context = ToRegister(instr->context()); |
| 2089 Register result = ToRegister(instr->result()); | 2065 Register result = ToRegister(instr->result()); |
| 2090 __ mov(result, ContextOperand(context, instr->slot_index())); | 2066 __ mov(result, ContextOperand(context, instr->slot_index())); |
| 2091 } | 2067 } |
| 2092 | 2068 |
| 2093 | 2069 |
| 2094 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { | 2070 void LCodeGen::DoStoreContextSlot(LStoreContextSlot* instr) { |
| 2095 Register context = ToRegister(instr->context()); | 2071 Register context = ToRegister(instr->context()); |
| 2096 Register value = ToRegister(instr->value()); | 2072 Register value = ToRegister(instr->value()); |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2321 __ movsx_w(result, Operand(external_pointer, key, times_2, 0)); | 2297 __ movsx_w(result, Operand(external_pointer, key, times_2, 0)); |
| 2322 break; | 2298 break; |
| 2323 case kExternalUnsignedShortArray: | 2299 case kExternalUnsignedShortArray: |
| 2324 __ movzx_w(result, Operand(external_pointer, key, times_2, 0)); | 2300 __ movzx_w(result, Operand(external_pointer, key, times_2, 0)); |
| 2325 break; | 2301 break; |
| 2326 case kExternalIntArray: | 2302 case kExternalIntArray: |
| 2327 __ mov(result, Operand(external_pointer, key, times_4, 0)); | 2303 __ mov(result, Operand(external_pointer, key, times_4, 0)); |
| 2328 break; | 2304 break; |
| 2329 case kExternalUnsignedIntArray: | 2305 case kExternalUnsignedIntArray: |
| 2330 __ mov(result, Operand(external_pointer, key, times_4, 0)); | 2306 __ mov(result, Operand(external_pointer, key, times_4, 0)); |
| 2331 __ test(result, Operand(result)); | 2307 __ test(Operand(result), Immediate(0x80000000)); |
| 2332 // TODO(danno): we could be more clever here, perhaps having a special | 2308 // TODO(danno): we could be more clever here, perhaps having a special |
| 2333 // version of the stub that detects if the overflow case actually | 2309 // version of the stub that detects if the overflow case actually |
| 2334 // happens, and generate code that returns a double rather than int. | 2310 // happens, and generate code that returns a double rather than int. |
| 2335 DeoptimizeIf(negative, instr->environment()); | 2311 DeoptimizeIf(not_zero, instr->environment()); |
| 2336 break; | 2312 break; |
| 2337 case kExternalFloatArray: | 2313 case kExternalFloatArray: |
| 2338 UNREACHABLE(); | 2314 UNREACHABLE(); |
| 2339 break; | 2315 break; |
| 2340 } | 2316 } |
| 2341 } | 2317 } |
| 2342 } | 2318 } |
| 2343 | 2319 |
| 2344 | 2320 |
| 2345 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { | 2321 void LCodeGen::DoLoadKeyedGeneric(LLoadKeyedGeneric* instr) { |
| (...skipping 1098 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3444 if (instr->truncating()) { | 3420 if (instr->truncating()) { |
| 3445 __ j(equal, &heap_number); | 3421 __ j(equal, &heap_number); |
| 3446 // Check for undefined. Undefined is converted to zero for truncating | 3422 // Check for undefined. Undefined is converted to zero for truncating |
| 3447 // conversions. | 3423 // conversions. |
| 3448 __ cmp(input_reg, factory()->undefined_value()); | 3424 __ cmp(input_reg, factory()->undefined_value()); |
| 3449 DeoptimizeIf(not_equal, instr->environment()); | 3425 DeoptimizeIf(not_equal, instr->environment()); |
| 3450 __ mov(input_reg, 0); | 3426 __ mov(input_reg, 0); |
| 3451 __ jmp(&done); | 3427 __ jmp(&done); |
| 3452 | 3428 |
| 3453 __ bind(&heap_number); | 3429 __ bind(&heap_number); |
| 3454 if (CpuFeatures::IsSupported(SSE3)) { | 3430 if (isolate()->cpu_features()->IsSupported(SSE3)) { |
| 3455 CpuFeatures::Scope scope(SSE3); | 3431 CpuFeatures::Scope scope(SSE3); |
| 3456 NearLabel convert; | 3432 NearLabel convert; |
| 3457 // Use more powerful conversion when sse3 is available. | 3433 // Use more powerful conversion when sse3 is available. |
| 3458 // Load x87 register with heap number. | 3434 // Load x87 register with heap number. |
| 3459 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); | 3435 __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset)); |
| 3460 // Get exponent alone and check for too-big exponent. | 3436 // Get exponent alone and check for too-big exponent. |
| 3461 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); | 3437 __ mov(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset)); |
| 3462 __ and_(input_reg, HeapNumber::kExponentMask); | 3438 __ and_(input_reg, HeapNumber::kExponentMask); |
| 3463 const uint32_t kTooBigExponent = | 3439 const uint32_t kTooBigExponent = |
| 3464 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; | 3440 (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift; |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3554 ASSERT(result->IsRegister()); | 3530 ASSERT(result->IsRegister()); |
| 3555 | 3531 |
| 3556 XMMRegister input_reg = ToDoubleRegister(input); | 3532 XMMRegister input_reg = ToDoubleRegister(input); |
| 3557 Register result_reg = ToRegister(result); | 3533 Register result_reg = ToRegister(result); |
| 3558 | 3534 |
| 3559 if (instr->truncating()) { | 3535 if (instr->truncating()) { |
| 3560 // Performs a truncating conversion of a floating point number as used by | 3536 // Performs a truncating conversion of a floating point number as used by |
| 3561 // the JS bitwise operations. | 3537 // the JS bitwise operations. |
| 3562 __ cvttsd2si(result_reg, Operand(input_reg)); | 3538 __ cvttsd2si(result_reg, Operand(input_reg)); |
| 3563 __ cmp(result_reg, 0x80000000u); | 3539 __ cmp(result_reg, 0x80000000u); |
| 3564 if (CpuFeatures::IsSupported(SSE3)) { | 3540 if (isolate()->cpu_features()->IsSupported(SSE3)) { |
| 3565 // This will deoptimize if the exponent of the input in out of range. | 3541 // This will deoptimize if the exponent of the input in out of range. |
| 3566 CpuFeatures::Scope scope(SSE3); | 3542 CpuFeatures::Scope scope(SSE3); |
| 3567 NearLabel convert, done; | 3543 NearLabel convert, done; |
| 3568 __ j(not_equal, &done); | 3544 __ j(not_equal, &done); |
| 3569 __ sub(Operand(esp), Immediate(kDoubleSize)); | 3545 __ sub(Operand(esp), Immediate(kDoubleSize)); |
| 3570 __ movdbl(Operand(esp, 0), input_reg); | 3546 __ movdbl(Operand(esp, 0), input_reg); |
| 3571 // Get exponent alone and check for too-big exponent. | 3547 // Get exponent alone and check for too-big exponent. |
| 3572 __ mov(result_reg, Operand(esp, sizeof(int32_t))); | 3548 __ mov(result_reg, Operand(esp, sizeof(int32_t))); |
| 3573 __ and_(result_reg, HeapNumber::kExponentMask); | 3549 __ and_(result_reg, HeapNumber::kExponentMask); |
| 3574 const uint32_t kTooBigExponent = | 3550 const uint32_t kTooBigExponent = |
| (...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4127 ASSERT(osr_pc_offset_ == -1); | 4103 ASSERT(osr_pc_offset_ == -1); |
| 4128 osr_pc_offset_ = masm()->pc_offset(); | 4104 osr_pc_offset_ = masm()->pc_offset(); |
| 4129 } | 4105 } |
| 4130 | 4106 |
| 4131 | 4107 |
| 4132 #undef __ | 4108 #undef __ |
| 4133 | 4109 |
| 4134 } } // namespace v8::internal | 4110 } } // namespace v8::internal |
| 4135 | 4111 |
| 4136 #endif // V8_TARGET_ARCH_IA32 | 4112 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |