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

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

Issue 18041003: Implement X87 stack tracking and x87 multiplication (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: rebase Created 7 years, 5 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') | no next file » | 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 for (int i = 0; i < InputCount(); i++) { 75 for (int i = 0; i < InputCount(); i++) {
76 LOperand* op = InputAt(i); 76 LOperand* op = InputAt(i);
77 if (op != NULL && op->IsDoubleRegister()) { 77 if (op != NULL && op->IsDoubleRegister()) {
78 return true; 78 return true;
79 } 79 }
80 } 80 }
81 return false; 81 return false;
82 } 82 }
83 83
84 84
85 bool LInstruction::IsDoubleInput(X87Register reg, LCodeGen* cgen) {
86 for (int i = 0; i < InputCount(); i++) {
87 LOperand* op = InputAt(i);
88 if (op != NULL && op->IsDoubleRegister()) {
89 if (cgen->ToX87Register(op).is(reg)) return true;
90 }
91 }
92 return false;
93 }
94
95
85 void LInstruction::PrintTo(StringStream* stream) { 96 void LInstruction::PrintTo(StringStream* stream) {
86 stream->Add("%s ", this->Mnemonic()); 97 stream->Add("%s ", this->Mnemonic());
87 98
88 PrintOutputOperandTo(stream); 99 PrintOutputOperandTo(stream);
89 100
90 PrintDataTo(stream); 101 PrintDataTo(stream);
91 102
92 if (HasEnvironment()) { 103 if (HasEnvironment()) {
93 stream->Add(" "); 104 stream->Add(" ");
94 environment()->PrintTo(stream); 105 environment()->PrintTo(stream);
(...skipping 392 matching lines...) Expand 10 before | Expand all | Expand 10 after
487 Register::ToAllocationIndex(reg)); 498 Register::ToAllocationIndex(reg));
488 } 499 }
489 500
490 501
491 LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) { 502 LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) {
492 return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, 503 return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
493 XMMRegister::ToAllocationIndex(reg)); 504 XMMRegister::ToAllocationIndex(reg));
494 } 505 }
495 506
496 507
497 LUnallocated* LChunkBuilder::ToUnallocated(X87TopOfStackRegister reg) {
498 return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
499 X87TopOfStackRegister::ToAllocationIndex(reg));
500 }
501
502
503 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) { 508 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
504 return Use(value, ToUnallocated(fixed_register)); 509 return Use(value, ToUnallocated(fixed_register));
505 } 510 }
506 511
507 512
508 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) { 513 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) {
509 return Use(value, ToUnallocated(reg)); 514 return Use(value, ToUnallocated(reg));
510 } 515 }
511 516
512 517
513 LOperand* LChunkBuilder::UseX87TopOfStack(HValue* value) {
514 return Use(value, ToUnallocated(x87tos));
515 }
516
517
518 LOperand* LChunkBuilder::UseRegister(HValue* value) { 518 LOperand* LChunkBuilder::UseRegister(HValue* value) {
519 return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); 519 return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
520 } 520 }
521 521
522 522
523 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) { 523 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
524 return Use(value, 524 return Use(value,
525 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER, 525 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER,
526 LUnallocated::USED_AT_START)); 526 LUnallocated::USED_AT_START));
527 } 527 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
635 635
636 636
637 template<int I, int T> 637 template<int I, int T>
638 LInstruction* LChunkBuilder::DefineFixedDouble( 638 LInstruction* LChunkBuilder::DefineFixedDouble(
639 LTemplateInstruction<1, I, T>* instr, 639 LTemplateInstruction<1, I, T>* instr,
640 XMMRegister reg) { 640 XMMRegister reg) {
641 return Define(instr, ToUnallocated(reg)); 641 return Define(instr, ToUnallocated(reg));
642 } 642 }
643 643
644 644
645 template<int I, int T>
646 LInstruction* LChunkBuilder::DefineX87TOS(
647 LTemplateInstruction<1, I, T>* instr) {
648 return Define(instr, ToUnallocated(x87tos));
649 }
650
651
652 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 645 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
653 HEnvironment* hydrogen_env = current_block_->last_environment(); 646 HEnvironment* hydrogen_env = current_block_->last_environment();
654 int argument_index_accumulator = 0; 647 int argument_index_accumulator = 0;
655 instr->set_environment(CreateEnvironment(hydrogen_env, 648 instr->set_environment(CreateEnvironment(hydrogen_env,
656 &argument_index_accumulator)); 649 &argument_index_accumulator));
657 return instr; 650 return instr;
658 } 651 }
659 652
660 653
661 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, 654 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after
1570 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1563 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1571 temp = TempRegister(); 1564 temp = TempRegister();
1572 } 1565 }
1573 LMulI* mul = new(zone()) LMulI(left, right, temp); 1566 LMulI* mul = new(zone()) LMulI(left, right, temp);
1574 if (instr->CheckFlag(HValue::kCanOverflow) || 1567 if (instr->CheckFlag(HValue::kCanOverflow) ||
1575 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1568 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1576 AssignEnvironment(mul); 1569 AssignEnvironment(mul);
1577 } 1570 }
1578 return DefineSameAsFirst(mul); 1571 return DefineSameAsFirst(mul);
1579 } else if (instr->representation().IsDouble()) { 1572 } else if (instr->representation().IsDouble()) {
1580 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 1573 return DoArithmeticD(Token::MUL, instr);
1581 return DoArithmeticD(Token::MUL, instr);
1582 }
1583 ASSERT(instr->right()->IsConstant() &&
1584 static_cast<HConstant*>(instr->right())->DoubleValue() == -1);
1585 // TODO(olivf) This is currently just a hack to support the UnaryOp Minus
1586 // Stub. This will go away once we can use more than one X87 register,
1587 // thus fully support binary instructions without SSE2.
1588 LOperand* left = UseX87TopOfStack(instr->left());
1589 LNegateNoSSE2D* result = new(zone()) LNegateNoSSE2D(left);
1590 return DefineX87TOS(result);
1591 } else { 1574 } else {
1592 ASSERT(instr->representation().IsSmiOrTagged()); 1575 ASSERT(instr->representation().IsSmiOrTagged());
1593 return DoArithmeticT(Token::MUL, instr); 1576 return DoArithmeticT(Token::MUL, instr);
1594 } 1577 }
1595 } 1578 }
1596 1579
1597 1580
1598 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1581 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1599 if (instr->representation().IsInteger32()) { 1582 if (instr->representation().IsInteger32()) {
1600 ASSERT(instr->left()->representation().IsInteger32()); 1583 ASSERT(instr->left()->representation().IsInteger32());
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1930 // building a stack frame. 1913 // building a stack frame.
1931 if (from.IsTagged()) { 1914 if (from.IsTagged()) {
1932 if (to.IsDouble()) { 1915 if (to.IsDouble()) {
1933 info()->MarkAsDeferredCalling(); 1916 info()->MarkAsDeferredCalling();
1934 LOperand* value = UseRegister(instr->value()); 1917 LOperand* value = UseRegister(instr->value());
1935 // Temp register only necessary for minus zero check. 1918 // Temp register only necessary for minus zero check.
1936 LOperand* temp = instr->deoptimize_on_minus_zero() 1919 LOperand* temp = instr->deoptimize_on_minus_zero()
1937 ? TempRegister() 1920 ? TempRegister()
1938 : NULL; 1921 : NULL;
1939 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); 1922 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
1940 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 1923 return AssignEnvironment(DefineAsRegister(res));
1941 return AssignEnvironment(DefineAsRegister(res));
1942 } else {
1943 return AssignEnvironment(DefineX87TOS(res));
1944 }
1945 } else if (to.IsSmi()) { 1924 } else if (to.IsSmi()) {
1946 HValue* val = instr->value(); 1925 HValue* val = instr->value();
1947 LOperand* value = UseRegister(val); 1926 LOperand* value = UseRegister(val);
1948 if (val->type().IsSmi()) { 1927 if (val->type().IsSmi()) {
1949 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1928 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1950 } 1929 }
1951 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); 1930 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
1952 } else { 1931 } else {
1953 ASSERT(to.IsInteger32()); 1932 ASSERT(to.IsInteger32());
1954 if (instr->value()->type().IsSmi()) { 1933 if (instr->value()->type().IsSmi()) {
(...skipping 14 matching lines...) Expand all
1969 LTaggedToINoSSE2* res = 1948 LTaggedToINoSSE2* res =
1970 new(zone()) LTaggedToINoSSE2(value, TempRegister(), 1949 new(zone()) LTaggedToINoSSE2(value, TempRegister(),
1971 TempRegister(), TempRegister()); 1950 TempRegister(), TempRegister());
1972 return AssignEnvironment(DefineFixed(res, ecx)); 1951 return AssignEnvironment(DefineFixed(res, ecx));
1973 } 1952 }
1974 } 1953 }
1975 } 1954 }
1976 } else if (from.IsDouble()) { 1955 } else if (from.IsDouble()) {
1977 if (to.IsTagged()) { 1956 if (to.IsTagged()) {
1978 info()->MarkAsDeferredCalling(); 1957 info()->MarkAsDeferredCalling();
1979 LOperand* value = CpuFeatures::IsSupported(SSE2) 1958 LOperand* value = UseRegisterAtStart(instr->value());
1980 ? UseRegisterAtStart(instr->value())
1981 : UseAtStart(instr->value());
1982 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; 1959 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL;
1983 1960
1984 // Make sure that temp and result_temp are different registers. 1961 // Make sure that temp and result_temp are different registers.
1985 LUnallocated* result_temp = TempRegister(); 1962 LUnallocated* result_temp = TempRegister();
1986 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); 1963 LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
1987 return AssignPointerMap(Define(result, result_temp)); 1964 return AssignPointerMap(Define(result, result_temp));
1988 } else if (to.IsSmi()) { 1965 } else if (to.IsSmi()) {
1989 LOperand* value = UseRegister(instr->value()); 1966 LOperand* value = UseRegister(instr->value());
1990 return AssignEnvironment( 1967 return AssignEnvironment(
1991 DefineAsRegister(new(zone()) LDoubleToSmi(value))); 1968 DefineAsRegister(new(zone()) LDoubleToSmi(value)));
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2133 2110
2134 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 2111 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2135 Representation r = instr->representation(); 2112 Representation r = instr->representation();
2136 if (r.IsSmi()) { 2113 if (r.IsSmi()) {
2137 return DefineAsRegister(new(zone()) LConstantS); 2114 return DefineAsRegister(new(zone()) LConstantS);
2138 } else if (r.IsInteger32()) { 2115 } else if (r.IsInteger32()) {
2139 return DefineAsRegister(new(zone()) LConstantI); 2116 return DefineAsRegister(new(zone()) LConstantI);
2140 } else if (r.IsDouble()) { 2117 } else if (r.IsDouble()) {
2141 double value = instr->DoubleValue(); 2118 double value = instr->DoubleValue();
2142 bool value_is_zero = BitCast<uint64_t, double>(value) == 0; 2119 bool value_is_zero = BitCast<uint64_t, double>(value) == 0;
2143 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2120 LOperand* temp = value_is_zero ? NULL : TempRegister();
2144 LOperand* temp = value_is_zero ? NULL : TempRegister(); 2121 return DefineAsRegister(new(zone()) LConstantD(temp));
2145 return DefineAsRegister(new(zone()) LConstantD(temp));
2146 } else {
2147 return DefineX87TOS(new(zone()) LConstantD(NULL));
2148 }
2149 } else if (r.IsTagged()) { 2122 } else if (r.IsTagged()) {
2150 return DefineAsRegister(new(zone()) LConstantT); 2123 return DefineAsRegister(new(zone()) LConstantT);
2151 } else { 2124 } else {
2152 UNREACHABLE(); 2125 UNREACHABLE();
2153 return NULL; 2126 return NULL;
2154 } 2127 }
2155 } 2128 }
2156 2129
2157 2130
2158 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { 2131 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2330 2303
2331 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { 2304 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2332 if (!instr->is_external()) { 2305 if (!instr->is_external()) {
2333 ASSERT(instr->elements()->representation().IsTagged()); 2306 ASSERT(instr->elements()->representation().IsTagged());
2334 ASSERT(instr->key()->representation().IsInteger32() || 2307 ASSERT(instr->key()->representation().IsInteger32() ||
2335 instr->key()->representation().IsSmi()); 2308 instr->key()->representation().IsSmi());
2336 2309
2337 if (instr->value()->representation().IsDouble()) { 2310 if (instr->value()->representation().IsDouble()) {
2338 LOperand* object = UseRegisterAtStart(instr->elements()); 2311 LOperand* object = UseRegisterAtStart(instr->elements());
2339 LOperand* val = NULL; 2312 LOperand* val = NULL;
2340 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2313 val = UseRegisterAtStart(instr->value());
2341 val = UseRegisterAtStart(instr->value());
2342 } else if (!instr->IsConstantHoleStore()) {
2343 val = UseX87TopOfStack(instr->value());
2344 }
2345 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2314 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2346 return new(zone()) LStoreKeyed(object, key, val); 2315 return new(zone()) LStoreKeyed(object, key, val);
2347 } else { 2316 } else {
2348 ASSERT(instr->value()->representation().IsSmiOrTagged()); 2317 ASSERT(instr->value()->representation().IsSmiOrTagged());
2349 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2318 bool needs_write_barrier = instr->NeedsWriteBarrier();
2350 2319
2351 LOperand* obj = UseRegister(instr->elements()); 2320 LOperand* obj = UseRegister(instr->elements());
2352 LOperand* val; 2321 LOperand* val;
2353 LOperand* key; 2322 LOperand* key;
2354 if (needs_write_barrier) { 2323 if (needs_write_barrier) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2464 2433
2465 LOperand* val; 2434 LOperand* val;
2466 if (needs_write_barrier) { 2435 if (needs_write_barrier) {
2467 val = UseTempRegister(instr->value()); 2436 val = UseTempRegister(instr->value());
2468 } else if (can_be_constant) { 2437 } else if (can_be_constant) {
2469 val = UseRegisterOrConstant(instr->value()); 2438 val = UseRegisterOrConstant(instr->value());
2470 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) { 2439 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) {
2471 val = UseTempRegister(instr->value()); 2440 val = UseTempRegister(instr->value());
2472 } else if (FLAG_track_double_fields && 2441 } else if (FLAG_track_double_fields &&
2473 instr->field_representation().IsDouble()) { 2442 instr->field_representation().IsDouble()) {
2474 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2443 val = UseRegisterAtStart(instr->value());
2475 val = UseRegisterAtStart(instr->value());
2476 } else {
2477 val = UseX87TopOfStack(instr->value());
2478 }
2479 } else { 2444 } else {
2480 val = UseRegister(instr->value()); 2445 val = UseRegister(instr->value());
2481 } 2446 }
2482 2447
2483 // We only need a scratch register if we have a write barrier or we 2448 // We only need a scratch register if we have a write barrier or we
2484 // have a store into the properties array (not in-object-property). 2449 // have a store into the properties array (not in-object-property).
2485 LOperand* temp = (!is_in_object || needs_write_barrier || 2450 LOperand* temp = (!is_in_object || needs_write_barrier ||
2486 needs_write_barrier_for_map) ? TempRegister() : NULL; 2451 needs_write_barrier_for_map) ? TempRegister() : NULL;
2487 2452
2488 // We need a temporary register for write barrier of the map field. 2453 // We need a temporary register for write barrier of the map field.
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
2785 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2750 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2786 LOperand* object = UseRegister(instr->object()); 2751 LOperand* object = UseRegister(instr->object());
2787 LOperand* index = UseTempRegister(instr->index()); 2752 LOperand* index = UseTempRegister(instr->index());
2788 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); 2753 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
2789 } 2754 }
2790 2755
2791 2756
2792 } } // namespace v8::internal 2757 } } // namespace v8::internal
2793 2758
2794 #endif // V8_TARGET_ARCH_IA32 2759 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698