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 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2697 LOperand* index = UseTempRegister(instr->index()); | 2659 LOperand* index = UseTempRegister(instr->index()); |
2698 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); | 2660 LLoadFieldByIndex* load = new(zone()) LLoadFieldByIndex(object, index); |
2699 LInstruction* result = DefineSameAsFirst(load); | 2661 LInstruction* result = DefineSameAsFirst(load); |
2700 return AssignPointerMap(result); | 2662 return AssignPointerMap(result); |
2701 } | 2663 } |
2702 | 2664 |
2703 | 2665 |
2704 } } // namespace v8::internal | 2666 } } // namespace v8::internal |
2705 | 2667 |
2706 #endif // V8_TARGET_ARCH_IA32 | 2668 #endif // V8_TARGET_ARCH_IA32 |
OLD | NEW |