| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "v8.h" | 5 #include "v8.h" |
| 6 | 6 |
| 7 #if V8_TARGET_ARCH_IA32 | 7 #if V8_TARGET_ARCH_IA32 |
| 8 | 8 |
| 9 #include "lithium-allocator-inl.h" | 9 #include "lithium-allocator-inl.h" |
| 10 #include "ia32/lithium-ia32.h" | 10 #include "ia32/lithium-ia32.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 53 for (int i = 0; i < InputCount(); i++) { | 53 for (int i = 0; i < InputCount(); i++) { |
| 54 LOperand* op = InputAt(i); | 54 LOperand* op = InputAt(i); |
| 55 if (op != NULL && op->IsDoubleRegister()) { | 55 if (op != NULL && op->IsDoubleRegister()) { |
| 56 return true; | 56 return true; |
| 57 } | 57 } |
| 58 } | 58 } |
| 59 return false; | 59 return false; |
| 60 } | 60 } |
| 61 | 61 |
| 62 | 62 |
| 63 bool LInstruction::IsDoubleInput(X87Register reg, LCodeGen* cgen) { | |
| 64 for (int i = 0; i < InputCount(); i++) { | |
| 65 LOperand* op = InputAt(i); | |
| 66 if (op != NULL && op->IsDoubleRegister()) { | |
| 67 if (cgen->ToX87Register(op).is(reg)) return true; | |
| 68 } | |
| 69 } | |
| 70 return false; | |
| 71 } | |
| 72 | |
| 73 | |
| 74 void LInstruction::PrintTo(StringStream* stream) { | 63 void LInstruction::PrintTo(StringStream* stream) { |
| 75 stream->Add("%s ", this->Mnemonic()); | 64 stream->Add("%s ", this->Mnemonic()); |
| 76 | 65 |
| 77 PrintOutputOperandTo(stream); | 66 PrintOutputOperandTo(stream); |
| 78 | 67 |
| 79 PrintDataTo(stream); | 68 PrintDataTo(stream); |
| 80 | 69 |
| 81 if (HasEnvironment()) { | 70 if (HasEnvironment()) { |
| 82 stream->Add(" "); | 71 stream->Add(" "); |
| 83 environment()->PrintTo(stream); | 72 environment()->PrintTo(stream); |
| (...skipping 849 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 933 ASSERT(fixed == 0 || used_at_start == 0); | 922 ASSERT(fixed == 0 || used_at_start == 0); |
| 934 } | 923 } |
| 935 #endif | 924 #endif |
| 936 | 925 |
| 937 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { | 926 if (FLAG_stress_pointer_maps && !instr->HasPointerMap()) { |
| 938 instr = AssignPointerMap(instr); | 927 instr = AssignPointerMap(instr); |
| 939 } | 928 } |
| 940 if (FLAG_stress_environments && !instr->HasEnvironment()) { | 929 if (FLAG_stress_environments && !instr->HasEnvironment()) { |
| 941 instr = AssignEnvironment(instr); | 930 instr = AssignEnvironment(instr); |
| 942 } | 931 } |
| 943 if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && instr->IsGoto() && | |
| 944 LGoto::cast(instr)->jumps_to_join()) { | |
| 945 // TODO(olivf) Since phis of spilled values are joined as registers | |
| 946 // (not in the stack slot), we need to allow the goto gaps to keep one | |
| 947 // x87 register alive. To ensure all other values are still spilled, we | |
| 948 // insert a fpu register barrier right before. | |
| 949 LClobberDoubles* clobber = new(zone()) LClobberDoubles(isolate()); | |
| 950 clobber->set_hydrogen_value(current); | |
| 951 chunk_->AddInstruction(clobber, current_block_); | |
| 952 } | |
| 953 chunk_->AddInstruction(instr, current_block_); | 932 chunk_->AddInstruction(instr, current_block_); |
| 954 | 933 |
| 955 if (instr->IsCall()) { | 934 if (instr->IsCall()) { |
| 956 HValue* hydrogen_value_for_lazy_bailout = current; | 935 HValue* hydrogen_value_for_lazy_bailout = current; |
| 957 LInstruction* instruction_needing_environment = NULL; | 936 LInstruction* instruction_needing_environment = NULL; |
| 958 if (current->HasObservableSideEffects()) { | 937 if (current->HasObservableSideEffects()) { |
| 959 HSimulate* sim = HSimulate::cast(current->next()); | 938 HSimulate* sim = HSimulate::cast(current->next()); |
| 960 instruction_needing_environment = instr; | 939 instruction_needing_environment = instr; |
| 961 sim->ReplayEnvironment(current_block_->last_environment()); | 940 sim->ReplayEnvironment(current_block_->last_environment()); |
| 962 hydrogen_value_for_lazy_bailout = sim; | 941 hydrogen_value_for_lazy_bailout = sim; |
| (...skipping 948 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1911 } | 1890 } |
| 1912 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); | 1891 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); |
| 1913 } else { | 1892 } else { |
| 1914 ASSERT(to.IsInteger32()); | 1893 ASSERT(to.IsInteger32()); |
| 1915 if (val->type().IsSmi() || val->representation().IsSmi()) { | 1894 if (val->type().IsSmi() || val->representation().IsSmi()) { |
| 1916 LOperand* value = UseRegister(val); | 1895 LOperand* value = UseRegister(val); |
| 1917 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); | 1896 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); |
| 1918 } else { | 1897 } else { |
| 1919 LOperand* value = UseRegister(val); | 1898 LOperand* value = UseRegister(val); |
| 1920 bool truncating = instr->CanTruncateToInt32(); | 1899 bool truncating = instr->CanTruncateToInt32(); |
| 1921 LOperand* xmm_temp = | 1900 LOperand* xmm_temp = !truncating ? FixedTemp(xmm1) : NULL; |
| 1922 (CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && !truncating) | |
| 1923 ? FixedTemp(xmm1) : NULL; | |
| 1924 LInstruction* result = | 1901 LInstruction* result = |
| 1925 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); | 1902 DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp)); |
| 1926 if (!val->representation().IsSmi()) result = AssignEnvironment(result); | 1903 if (!val->representation().IsSmi()) result = AssignEnvironment(result); |
| 1927 return result; | 1904 return result; |
| 1928 } | 1905 } |
| 1929 } | 1906 } |
| 1930 } else if (from.IsDouble()) { | 1907 } else if (from.IsDouble()) { |
| 1931 if (to.IsTagged()) { | 1908 if (to.IsTagged()) { |
| 1932 info()->MarkAsDeferredCalling(); | 1909 info()->MarkAsDeferredCalling(); |
| 1933 LOperand* value = UseRegisterAtStart(val); | 1910 LOperand* value = UseRegisterAtStart(val); |
| 1934 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; | 1911 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; |
| 1935 LUnallocated* result_temp = TempRegister(); | 1912 LUnallocated* result_temp = TempRegister(); |
| 1936 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); | 1913 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); |
| 1937 return AssignPointerMap(Define(result, result_temp)); | 1914 return AssignPointerMap(Define(result, result_temp)); |
| 1938 } else if (to.IsSmi()) { | 1915 } else if (to.IsSmi()) { |
| 1939 LOperand* value = UseRegister(val); | 1916 LOperand* value = UseRegister(val); |
| 1940 return AssignEnvironment( | 1917 return AssignEnvironment( |
| 1941 DefineAsRegister(new(zone()) LDoubleToSmi(value))); | 1918 DefineAsRegister(new(zone()) LDoubleToSmi(value))); |
| 1942 } else { | 1919 } else { |
| 1943 ASSERT(to.IsInteger32()); | 1920 ASSERT(to.IsInteger32()); |
| 1944 bool truncating = instr->CanTruncateToInt32(); | 1921 bool truncating = instr->CanTruncateToInt32(); |
| 1945 bool needs_temp = | 1922 bool needs_temp = !truncating; |
| 1946 CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && !truncating; | |
| 1947 LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val); | 1923 LOperand* value = needs_temp ? UseTempRegister(val) : UseRegister(val); |
| 1948 LOperand* temp = needs_temp ? TempRegister() : NULL; | 1924 LOperand* temp = needs_temp ? TempRegister() : NULL; |
| 1949 LInstruction* result = | 1925 LInstruction* result = |
| 1950 DefineAsRegister(new(zone()) LDoubleToI(value, temp)); | 1926 DefineAsRegister(new(zone()) LDoubleToI(value, temp)); |
| 1951 if (!truncating) result = AssignEnvironment(result); | 1927 if (!truncating) result = AssignEnvironment(result); |
| 1952 return result; | 1928 return result; |
| 1953 } | 1929 } |
| 1954 } else if (from.IsInteger32()) { | 1930 } else if (from.IsInteger32()) { |
| 1955 info()->MarkAsDeferredCalling(); | 1931 info()->MarkAsDeferredCalling(); |
| 1956 if (to.IsTagged()) { | 1932 if (to.IsTagged()) { |
| 1957 if (!instr->CheckFlag(HValue::kCanOverflow)) { | 1933 if (!instr->CheckFlag(HValue::kCanOverflow)) { |
| 1958 LOperand* value = UseRegister(val); | 1934 LOperand* value = UseRegister(val); |
| 1959 return DefineSameAsFirst(new(zone()) LSmiTag(value)); | 1935 return DefineSameAsFirst(new(zone()) LSmiTag(value)); |
| 1960 } else if (val->CheckFlag(HInstruction::kUint32)) { | 1936 } else if (val->CheckFlag(HInstruction::kUint32)) { |
| 1961 LOperand* value = UseRegister(val); | 1937 LOperand* value = UseRegister(val); |
| 1962 LOperand* temp1 = TempRegister(); | 1938 LOperand* temp1 = TempRegister(); |
| 1963 LOperand* temp2 = | 1939 LOperand* temp2 = FixedTemp(xmm1); |
| 1964 CpuFeatures::IsSupported(SSE2) ? FixedTemp(xmm1) : NULL; | |
| 1965 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2); | 1940 LNumberTagU* result = new(zone()) LNumberTagU(value, temp1, temp2); |
| 1966 return AssignPointerMap(DefineSameAsFirst(result)); | 1941 return AssignPointerMap(DefineSameAsFirst(result)); |
| 1967 } else { | 1942 } else { |
| 1968 LOperand* value = UseRegister(val); | 1943 LOperand* value = UseRegister(val); |
| 1969 LOperand* temp = TempRegister(); | 1944 LOperand* temp = TempRegister(); |
| 1970 LNumberTagI* result = new(zone()) LNumberTagI(value, temp); | 1945 LNumberTagI* result = new(zone()) LNumberTagI(value, temp); |
| 1971 return AssignPointerMap(DefineSameAsFirst(result)); | 1946 return AssignPointerMap(DefineSameAsFirst(result)); |
| 1972 } | 1947 } |
| 1973 } else if (to.IsSmi()) { | 1948 } else if (to.IsSmi()) { |
| 1974 LOperand* value = UseRegister(val); | 1949 LOperand* value = UseRegister(val); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2042 HValue* value = instr->value(); | 2017 HValue* value = instr->value(); |
| 2043 Representation input_rep = value->representation(); | 2018 Representation input_rep = value->representation(); |
| 2044 if (input_rep.IsDouble()) { | 2019 if (input_rep.IsDouble()) { |
| 2045 LOperand* reg = UseRegister(value); | 2020 LOperand* reg = UseRegister(value); |
| 2046 return DefineFixed(new(zone()) LClampDToUint8(reg), eax); | 2021 return DefineFixed(new(zone()) LClampDToUint8(reg), eax); |
| 2047 } else if (input_rep.IsInteger32()) { | 2022 } else if (input_rep.IsInteger32()) { |
| 2048 LOperand* reg = UseFixed(value, eax); | 2023 LOperand* reg = UseFixed(value, eax); |
| 2049 return DefineFixed(new(zone()) LClampIToUint8(reg), eax); | 2024 return DefineFixed(new(zone()) LClampIToUint8(reg), eax); |
| 2050 } else { | 2025 } else { |
| 2051 ASSERT(input_rep.IsSmiOrTagged()); | 2026 ASSERT(input_rep.IsSmiOrTagged()); |
| 2052 if (CpuFeatures::IsSupported(SSE2)) { | 2027 LOperand* reg = UseFixed(value, eax); |
| 2053 LOperand* reg = UseFixed(value, eax); | 2028 // Register allocator doesn't (yet) support allocation of double |
| 2054 // Register allocator doesn't (yet) support allocation of double | 2029 // temps. Reserve xmm1 explicitly. |
| 2055 // temps. Reserve xmm1 explicitly. | 2030 LOperand* temp = FixedTemp(xmm1); |
| 2056 LOperand* temp = FixedTemp(xmm1); | 2031 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, temp); |
| 2057 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, temp); | 2032 return AssignEnvironment(DefineFixed(result, eax)); |
| 2058 return AssignEnvironment(DefineFixed(result, eax)); | |
| 2059 } else { | |
| 2060 LOperand* value = UseRegister(instr->value()); | |
| 2061 LClampTToUint8NoSSE2* res = | |
| 2062 new(zone()) LClampTToUint8NoSSE2(value, TempRegister(), | |
| 2063 TempRegister(), TempRegister()); | |
| 2064 return AssignEnvironment(DefineFixed(res, ecx)); | |
| 2065 } | |
| 2066 } | 2033 } |
| 2067 } | 2034 } |
| 2068 | 2035 |
| 2069 | 2036 |
| 2070 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { | 2037 LInstruction* LChunkBuilder::DoDoubleBits(HDoubleBits* instr) { |
| 2071 HValue* value = instr->value(); | 2038 HValue* value = instr->value(); |
| 2072 ASSERT(value->representation().IsDouble()); | 2039 ASSERT(value->representation().IsDouble()); |
| 2073 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); | 2040 return DefineAsRegister(new(zone()) LDoubleBits(UseRegister(value))); |
| 2074 } | 2041 } |
| 2075 | 2042 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2251 elements_kind == EXTERNAL_INT8_ELEMENTS || | 2218 elements_kind == EXTERNAL_INT8_ELEMENTS || |
| 2252 elements_kind == EXTERNAL_UINT8_ELEMENTS || | 2219 elements_kind == EXTERNAL_UINT8_ELEMENTS || |
| 2253 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || | 2220 elements_kind == EXTERNAL_UINT8_CLAMPED_ELEMENTS || |
| 2254 elements_kind == UINT8_ELEMENTS || | 2221 elements_kind == UINT8_ELEMENTS || |
| 2255 elements_kind == INT8_ELEMENTS || | 2222 elements_kind == INT8_ELEMENTS || |
| 2256 elements_kind == UINT8_CLAMPED_ELEMENTS; | 2223 elements_kind == UINT8_CLAMPED_ELEMENTS; |
| 2257 if (val_is_fixed_register) { | 2224 if (val_is_fixed_register) { |
| 2258 return UseFixed(instr->value(), eax); | 2225 return UseFixed(instr->value(), eax); |
| 2259 } | 2226 } |
| 2260 | 2227 |
| 2261 if (!CpuFeatures::IsSafeForSnapshot(isolate(), SSE2) && | |
| 2262 IsDoubleOrFloatElementsKind(elements_kind)) { | |
| 2263 return UseRegisterAtStart(instr->value()); | |
| 2264 } | |
| 2265 | |
| 2266 return UseRegister(instr->value()); | 2228 return UseRegister(instr->value()); |
| 2267 } | 2229 } |
| 2268 | 2230 |
| 2269 | 2231 |
| 2270 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { | 2232 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { |
| 2271 if (!instr->is_typed_elements()) { | 2233 if (!instr->is_typed_elements()) { |
| 2272 ASSERT(instr->elements()->representation().IsTagged()); | 2234 ASSERT(instr->elements()->representation().IsTagged()); |
| 2273 ASSERT(instr->key()->representation().IsInteger32() || | 2235 ASSERT(instr->key()->representation().IsInteger32() || |
| 2274 instr->key()->representation().IsSmi()); | 2236 instr->key()->representation().IsSmi()); |
| 2275 | 2237 |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2705 LOperand* index = UseTempRegister(instr->index()); | 2667 LOperand* index = UseTempRegister(instr->index()); |
| 2706 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); | 2668 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); |
| 2707 LInstruction* result = DefineSameAsFirst(load); | 2669 LInstruction* result = DefineSameAsFirst(load); |
| 2708 return AssignPointerMap(result); | 2670 return AssignPointerMap(result); |
| 2709 } | 2671 } |
| 2710 | 2672 |
| 2711 | 2673 |
| 2712 } } // namespace v8::internal | 2674 } } // namespace v8::internal |
| 2713 | 2675 |
| 2714 #endif // V8_TARGET_ARCH_IA32 | 2676 #endif // V8_TARGET_ARCH_IA32 |
| OLD | NEW |