Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(55)

Side by Side Diff: src/ia32/lithium-ia32.cc

Issue 13426006: Improvements for x87 stack handling (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Last comments Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
84 operand->IsUsedAtStart()); 84 operand->IsUsedAtStart());
85 } 85 }
86 for (TempIterator it(this); !it.Done(); it.Advance()) { 86 for (TempIterator it(this); !it.Done(); it.Advance()) {
87 LUnallocated* operand = LUnallocated::cast(it.Current()); 87 LUnallocated* operand = LUnallocated::cast(it.Current());
88 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy()); 88 ASSERT(operand->HasFixedPolicy() ||!operand->HasRegisterPolicy());
89 } 89 }
90 } 90 }
91 #endif 91 #endif
92 92
93 93
94 bool LInstruction::HasDoubleRegisterResult() {
95 return HasResult() && result()->IsDoubleRegister();
96 }
97
98
99 bool LInstruction::HasDoubleRegisterInput() {
100 for (int i = 0; i < InputCount(); i++) {
101 LOperand* op = InputAt(i);
102 if (op->IsDoubleRegister()) {
103 return true;
104 }
105 }
106 return false;
107 }
108
109
94 void LInstruction::PrintTo(StringStream* stream) { 110 void LInstruction::PrintTo(StringStream* stream) {
95 stream->Add("%s ", this->Mnemonic()); 111 stream->Add("%s ", this->Mnemonic());
96 112
97 PrintOutputOperandTo(stream); 113 PrintOutputOperandTo(stream);
98 114
99 PrintDataTo(stream); 115 PrintDataTo(stream);
100 116
101 if (HasEnvironment()) { 117 if (HasEnvironment()) {
102 stream->Add(" "); 118 stream->Add(" ");
103 environment()->PrintTo(stream); 119 environment()->PrintTo(stream);
(...skipping 431 matching lines...) Expand 10 before | Expand all | Expand 10 after
535 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) { 551 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
536 return Use(value, ToUnallocated(fixed_register)); 552 return Use(value, ToUnallocated(fixed_register));
537 } 553 }
538 554
539 555
540 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) { 556 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) {
541 return Use(value, ToUnallocated(reg)); 557 return Use(value, ToUnallocated(reg));
542 } 558 }
543 559
544 560
561 LOperand* LChunkBuilder::UseX87TopOfStack(HValue* value) {
562 return Use(value, ToUnallocated(x87tos));
563 }
564
565
545 LOperand* LChunkBuilder::UseRegister(HValue* value) { 566 LOperand* LChunkBuilder::UseRegister(HValue* value) {
546 return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); 567 return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
547 } 568 }
548 569
549 570
550 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) { 571 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
551 return Use(value, 572 return Use(value,
552 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER, 573 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER,
553 LUnallocated::USED_AT_START)); 574 LUnallocated::USED_AT_START));
554 } 575 }
(...skipping 1299 matching lines...) Expand 10 before | Expand all | Expand 10 after
1854 // building a stack frame. 1875 // building a stack frame.
1855 if (from.IsTagged()) { 1876 if (from.IsTagged()) {
1856 if (to.IsDouble()) { 1877 if (to.IsDouble()) {
1857 info()->MarkAsDeferredCalling(); 1878 info()->MarkAsDeferredCalling();
1858 LOperand* value = UseRegister(instr->value()); 1879 LOperand* value = UseRegister(instr->value());
1859 // Temp register only necessary for minus zero check. 1880 // Temp register only necessary for minus zero check.
1860 LOperand* temp = instr->deoptimize_on_minus_zero() 1881 LOperand* temp = instr->deoptimize_on_minus_zero()
1861 ? TempRegister() 1882 ? TempRegister()
1862 : NULL; 1883 : NULL;
1863 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); 1884 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
1864 return AssignEnvironment(DefineAsRegister(res)); 1885 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
1886 return AssignEnvironment(DefineAsRegister(res));
1887 } else {
1888 return AssignEnvironment(DefineX87TOS(res));
1889 }
1865 } else { 1890 } else {
1866 ASSERT(to.IsInteger32()); 1891 ASSERT(to.IsInteger32());
1867 LOperand* value = UseRegister(instr->value());
1868 if (instr->value()->type().IsSmi()) { 1892 if (instr->value()->type().IsSmi()) {
1893 LOperand* value = UseRegister(instr->value());
1869 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false)); 1894 return DefineSameAsFirst(new(zone()) LSmiUntag(value, false));
1870 } else { 1895 } else {
1871 bool truncating = instr->CanTruncateToInt32(); 1896 bool truncating = instr->CanTruncateToInt32();
1872 LOperand* xmm_temp = 1897 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
1873 (truncating && CpuFeatures::IsSupported(SSE3)) 1898 LOperand* value = UseRegister(instr->value());
1874 ? NULL 1899 LOperand* xmm_temp =
1875 : FixedTemp(xmm1); 1900 (truncating && CpuFeatures::IsSupported(SSE3))
1876 LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp); 1901 ? NULL
1877 return AssignEnvironment(DefineSameAsFirst(res)); 1902 : FixedTemp(xmm1);
1903 LTaggedToI* res = new(zone()) LTaggedToI(value, xmm_temp);
1904 return AssignEnvironment(DefineSameAsFirst(res));
1905 } else {
1906 LOperand* value = UseFixed(instr->value(), ecx);
1907 LTaggedToINoSSE2* res =
1908 new(zone()) LTaggedToINoSSE2(value, TempRegister(),
1909 TempRegister(), TempRegister());
1910 return AssignEnvironment(DefineFixed(res, ecx));
1911 }
1878 } 1912 }
1879 } 1913 }
1880 } else if (from.IsDouble()) { 1914 } else if (from.IsDouble()) {
1881 if (to.IsTagged()) { 1915 if (to.IsTagged()) {
1882 info()->MarkAsDeferredCalling(); 1916 info()->MarkAsDeferredCalling();
1883 LOperand* value = CpuFeatures::IsSupported(SSE2) 1917 LOperand* value = CpuFeatures::IsSupported(SSE2)
1884 ? UseRegisterAtStart(instr->value()) 1918 ? UseRegisterAtStart(instr->value())
1885 : UseAtStart(instr->value()); 1919 : UseAtStart(instr->value());
1886 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; 1920 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL;
1887 1921
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1985 HValue* value = instr->value(); 2019 HValue* value = instr->value();
1986 Representation input_rep = value->representation(); 2020 Representation input_rep = value->representation();
1987 if (input_rep.IsDouble()) { 2021 if (input_rep.IsDouble()) {
1988 LOperand* reg = UseRegister(value); 2022 LOperand* reg = UseRegister(value);
1989 return DefineFixed(new(zone()) LClampDToUint8(reg), eax); 2023 return DefineFixed(new(zone()) LClampDToUint8(reg), eax);
1990 } else if (input_rep.IsInteger32()) { 2024 } else if (input_rep.IsInteger32()) {
1991 LOperand* reg = UseFixed(value, eax); 2025 LOperand* reg = UseFixed(value, eax);
1992 return DefineFixed(new(zone()) LClampIToUint8(reg), eax); 2026 return DefineFixed(new(zone()) LClampIToUint8(reg), eax);
1993 } else { 2027 } else {
1994 ASSERT(input_rep.IsTagged()); 2028 ASSERT(input_rep.IsTagged());
1995 LOperand* reg = UseFixed(value, eax); 2029 if (CpuFeatures::IsSupported(SSE2)) {
1996 // Register allocator doesn't (yet) support allocation of double 2030 LOperand* reg = UseFixed(value, eax);
1997 // temps. Reserve xmm1 explicitly. 2031 // Register allocator doesn't (yet) support allocation of double
1998 LOperand* temp = FixedTemp(xmm1); 2032 // temps. Reserve xmm1 explicitly.
1999 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, temp); 2033 LOperand* temp = FixedTemp(xmm1);
2000 return AssignEnvironment(DefineFixed(result, eax)); 2034 LClampTToUint8* result = new(zone()) LClampTToUint8(reg, temp);
2035 return AssignEnvironment(DefineFixed(result, eax));
2036 } else {
2037 LOperand* value = UseRegister(instr->value());
2038 LClampTToUint8NoSSE2* res =
2039 new(zone()) LClampTToUint8NoSSE2(value, TempRegister(),
2040 TempRegister(), TempRegister());
2041 return AssignEnvironment(DefineFixed(res, ecx));
2042 }
2001 } 2043 }
2002 } 2044 }
2003 2045
2004 2046
2005 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) { 2047 LInstruction* LChunkBuilder::DoReturn(HReturn* instr) {
2006 LOperand* context = info()->IsStub() 2048 LOperand* context = info()->IsStub()
2007 ? UseFixed(instr->context(), esi) 2049 ? UseFixed(instr->context(), esi)
2008 : NULL; 2050 : NULL;
2009 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count()); 2051 LOperand* parameter_count = UseRegisterOrConstant(instr->parameter_count());
2010 return new(zone()) LReturn(UseFixed(instr->value(), eax), context, 2052 return new(zone()) LReturn(UseFixed(instr->value(), eax), context,
2011 parameter_count); 2053 parameter_count);
2012 } 2054 }
2013 2055
2014 2056
2015 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 2057 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2016 Representation r = instr->representation(); 2058 Representation r = instr->representation();
2017 if (r.IsInteger32()) { 2059 if (r.IsInteger32()) {
2018 return DefineAsRegister(new(zone()) LConstantI); 2060 return DefineAsRegister(new(zone()) LConstantI);
2019 } else if (r.IsDouble()) { 2061 } else if (r.IsDouble()) {
2020 double value = instr->DoubleValue(); 2062 double value = instr->DoubleValue();
2021 LOperand* temp = (BitCast<uint64_t, double>(value) != 0) 2063 bool value_is_zero = BitCast<uint64_t, double>(value) == 0;
2022 ? TempRegister() 2064 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
2023 : NULL; 2065 LOperand* temp = value_is_zero ? NULL : TempRegister();
2024 return DefineAsRegister(new(zone()) LConstantD(temp)); 2066 return DefineAsRegister(new(zone()) LConstantD(temp));
2067 } else {
2068 return DefineX87TOS(new(zone()) LConstantD(NULL));
2069 }
2025 } else if (r.IsTagged()) { 2070 } else if (r.IsTagged()) {
2026 return DefineAsRegister(new(zone()) LConstantT); 2071 return DefineAsRegister(new(zone()) LConstantT);
2027 } else { 2072 } else {
2028 UNREACHABLE(); 2073 UNREACHABLE();
2029 return NULL; 2074 return NULL;
2030 } 2075 }
2031 } 2076 }
2032 2077
2033 2078
2034 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { 2079 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after
2183 LOperand* context = UseFixed(instr->context(), esi); 2228 LOperand* context = UseFixed(instr->context(), esi);
2184 LOperand* object = UseFixed(instr->object(), edx); 2229 LOperand* object = UseFixed(instr->object(), edx);
2185 LOperand* key = UseFixed(instr->key(), ecx); 2230 LOperand* key = UseFixed(instr->key(), ecx);
2186 2231
2187 LLoadKeyedGeneric* result = 2232 LLoadKeyedGeneric* result =
2188 new(zone()) LLoadKeyedGeneric(context, object, key); 2233 new(zone()) LLoadKeyedGeneric(context, object, key);
2189 return MarkAsCall(DefineFixed(result, eax), instr); 2234 return MarkAsCall(DefineFixed(result, eax), instr);
2190 } 2235 }
2191 2236
2192 2237
2238 LOperand* LChunkBuilder::GetStoreKeyedValueOperand(HStoreKeyed* instr) {
2239 ElementsKind elements_kind = instr->elements_kind();
2240
2241 // Determine if we need a byte register in this case for the value.
2242 bool val_is_fixed_register =
2243 elements_kind == EXTERNAL_BYTE_ELEMENTS ||
2244 elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
2245 elements_kind == EXTERNAL_PIXEL_ELEMENTS;
2246 if (val_is_fixed_register) {
2247 return UseFixed(instr->value(), eax);
2248 }
2249
2250 if (!CpuFeatures::IsSafeForSnapshot(SSE2) &&
2251 IsDoubleOrFloatElementsKind(elements_kind)) {
2252 return UseRegisterAtStart(instr->value());
2253 }
2254
2255 return UseRegister(instr->value());
2256 }
2257
2258
2193 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { 2259 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2194 if (!instr->is_external()) { 2260 if (!instr->is_external()) {
2195 ASSERT(instr->elements()->representation().IsTagged()); 2261 ASSERT(instr->elements()->representation().IsTagged());
2196 ASSERT(instr->key()->representation().IsInteger32() || 2262 ASSERT(instr->key()->representation().IsInteger32() ||
2197 instr->key()->representation().IsTagged()); 2263 instr->key()->representation().IsTagged());
2198 2264
2199 if (instr->value()->representation().IsDouble()) { 2265 if (instr->value()->representation().IsDouble()) {
2200 LOperand* object = UseRegisterAtStart(instr->elements()); 2266 LOperand* object = UseRegisterAtStart(instr->elements());
2201 LOperand* val = UseTempRegister(instr->value()); 2267 LOperand* val = NULL;
2268 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
2269 val = UseRegisterAtStart(instr->value());
2270 } else if (!instr->IsConstantHoleStore()) {
2271 val = UseX87TopOfStack(instr->value());
2272 }
2202 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2273 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2203 2274
2204 return new(zone()) LStoreKeyed(object, key, val); 2275 return new(zone()) LStoreKeyed(object, key, val);
2205 } else { 2276 } else {
2206 ASSERT(instr->value()->representation().IsTagged()); 2277 ASSERT(instr->value()->representation().IsTagged());
2207 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2278 bool needs_write_barrier = instr->NeedsWriteBarrier();
2208 2279
2209 LOperand* obj = UseRegister(instr->elements()); 2280 LOperand* obj = UseRegister(instr->elements());
2210 LOperand* val = needs_write_barrier 2281 LOperand* val = needs_write_barrier
2211 ? UseTempRegister(instr->value()) 2282 ? UseTempRegister(instr->value())
2212 : UseRegisterAtStart(instr->value()); 2283 : UseRegisterAtStart(instr->value());
2213 LOperand* key = needs_write_barrier 2284 LOperand* key = needs_write_barrier
2214 ? UseTempRegister(instr->key()) 2285 ? UseTempRegister(instr->key())
2215 : UseRegisterOrConstantAtStart(instr->key()); 2286 : UseRegisterOrConstantAtStart(instr->key());
2216 return new(zone()) LStoreKeyed(obj, key, val); 2287 return new(zone()) LStoreKeyed(obj, key, val);
2217 } 2288 }
2218 } 2289 }
2219 2290
2220 ElementsKind elements_kind = instr->elements_kind(); 2291 ElementsKind elements_kind = instr->elements_kind();
2221 ASSERT( 2292 ASSERT(
2222 (instr->value()->representation().IsInteger32() && 2293 (instr->value()->representation().IsInteger32() &&
2223 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) && 2294 (elements_kind != EXTERNAL_FLOAT_ELEMENTS) &&
2224 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) || 2295 (elements_kind != EXTERNAL_DOUBLE_ELEMENTS)) ||
2225 (instr->value()->representation().IsDouble() && 2296 (instr->value()->representation().IsDouble() &&
2226 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) || 2297 ((elements_kind == EXTERNAL_FLOAT_ELEMENTS) ||
2227 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS)))); 2298 (elements_kind == EXTERNAL_DOUBLE_ELEMENTS))));
2228 ASSERT(instr->elements()->representation().IsExternal()); 2299 ASSERT(instr->elements()->representation().IsExternal());
2229 2300
2230 LOperand* external_pointer = UseRegister(instr->elements()); 2301 LOperand* external_pointer = UseRegister(instr->elements());
2231 // Determine if we need a byte register in this case for the value. 2302 LOperand* val = GetStoreKeyedValueOperand(instr);
2232 bool val_is_fixed_register =
2233 elements_kind == EXTERNAL_BYTE_ELEMENTS ||
2234 elements_kind == EXTERNAL_UNSIGNED_BYTE_ELEMENTS ||
2235 elements_kind == EXTERNAL_PIXEL_ELEMENTS;
2236
2237 LOperand* val = val_is_fixed_register
2238 ? UseFixed(instr->value(), eax)
2239 : UseRegister(instr->value());
2240 bool clobbers_key = ExternalArrayOpRequiresTemp( 2303 bool clobbers_key = ExternalArrayOpRequiresTemp(
2241 instr->key()->representation(), elements_kind); 2304 instr->key()->representation(), elements_kind);
2242 LOperand* key = clobbers_key 2305 LOperand* key = clobbers_key
2243 ? UseTempRegister(instr->key()) 2306 ? UseTempRegister(instr->key())
2244 : UseRegisterOrConstantAtStart(instr->key()); 2307 : UseRegisterOrConstantAtStart(instr->key());
2245 return new(zone()) LStoreKeyed(external_pointer, 2308 return new(zone()) LStoreKeyed(external_pointer,
2246 key, 2309 key,
2247 val); 2310 val);
2248 } 2311 }
2249 2312
(...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after
2648 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2711 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2649 LOperand* object = UseRegister(instr->object()); 2712 LOperand* object = UseRegister(instr->object());
2650 LOperand* index = UseTempRegister(instr->index()); 2713 LOperand* index = UseTempRegister(instr->index());
2651 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); 2714 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
2652 } 2715 }
2653 2716
2654 2717
2655 } } // namespace v8::internal 2718 } } // namespace v8::internal
2656 2719
2657 #endif // V8_TARGET_ARCH_IA32 2720 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | src/ia32/macro-assembler-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698