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

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: fix x87 usage of bleeding_edge commits 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
« src/ia32/lithium-codegen-ia32.cc ('K') | « 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 393 matching lines...) Expand 10 before | Expand all | Expand 10 after
488 Register::ToAllocationIndex(reg)); 499 Register::ToAllocationIndex(reg));
489 } 500 }
490 501
491 502
492 LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) { 503 LUnallocated* LChunkBuilder::ToUnallocated(XMMRegister reg) {
493 return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER, 504 return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
494 XMMRegister::ToAllocationIndex(reg)); 505 XMMRegister::ToAllocationIndex(reg));
495 } 506 }
496 507
497 508
498 LUnallocated* LChunkBuilder::ToUnallocated(X87TopOfStackRegister reg) {
499 return new(zone()) LUnallocated(LUnallocated::FIXED_DOUBLE_REGISTER,
500 X87TopOfStackRegister::ToAllocationIndex(reg));
501 }
502
503
504 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) { 509 LOperand* LChunkBuilder::UseFixed(HValue* value, Register fixed_register) {
505 return Use(value, ToUnallocated(fixed_register)); 510 return Use(value, ToUnallocated(fixed_register));
506 } 511 }
507 512
508 513
509 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) { 514 LOperand* LChunkBuilder::UseFixedDouble(HValue* value, XMMRegister reg) {
510 return Use(value, ToUnallocated(reg)); 515 return Use(value, ToUnallocated(reg));
511 } 516 }
512 517
513 518
514 LOperand* LChunkBuilder::UseX87TopOfStack(HValue* value) {
515 return Use(value, ToUnallocated(x87tos));
516 }
517
518
519 LOperand* LChunkBuilder::UseRegister(HValue* value) { 519 LOperand* LChunkBuilder::UseRegister(HValue* value) {
520 return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER)); 520 return Use(value, new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER));
521 } 521 }
522 522
523 523
524 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) { 524 LOperand* LChunkBuilder::UseRegisterAtStart(HValue* value) {
525 return Use(value, 525 return Use(value,
526 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER, 526 new(zone()) LUnallocated(LUnallocated::MUST_HAVE_REGISTER,
527 LUnallocated::USED_AT_START)); 527 LUnallocated::USED_AT_START));
528 } 528 }
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
636 636
637 637
638 template<int I, int T> 638 template<int I, int T>
639 LInstruction* LChunkBuilder::DefineFixedDouble( 639 LInstruction* LChunkBuilder::DefineFixedDouble(
640 LTemplateInstruction<1, I, T>* instr, 640 LTemplateInstruction<1, I, T>* instr,
641 XMMRegister reg) { 641 XMMRegister reg) {
642 return Define(instr, ToUnallocated(reg)); 642 return Define(instr, ToUnallocated(reg));
643 } 643 }
644 644
645 645
646 template<int I, int T>
647 LInstruction* LChunkBuilder::DefineX87TOS(
648 LTemplateInstruction<1, I, T>* instr) {
649 return Define(instr, ToUnallocated(x87tos));
650 }
651
652
653 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) { 646 LInstruction* LChunkBuilder::AssignEnvironment(LInstruction* instr) {
654 HEnvironment* hydrogen_env = current_block_->last_environment(); 647 HEnvironment* hydrogen_env = current_block_->last_environment();
655 int argument_index_accumulator = 0; 648 int argument_index_accumulator = 0;
656 instr->set_environment(CreateEnvironment(hydrogen_env, 649 instr->set_environment(CreateEnvironment(hydrogen_env,
657 &argument_index_accumulator)); 650 &argument_index_accumulator));
658 return instr; 651 return instr;
659 } 652 }
660 653
661 654
662 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr, 655 LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
(...skipping 908 matching lines...) Expand 10 before | Expand all | Expand 10 after
1571 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1564 if (instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1572 temp = TempRegister(); 1565 temp = TempRegister();
1573 } 1566 }
1574 LMulI* mul = new(zone()) LMulI(left, right, temp); 1567 LMulI* mul = new(zone()) LMulI(left, right, temp);
1575 if (instr->CheckFlag(HValue::kCanOverflow) || 1568 if (instr->CheckFlag(HValue::kCanOverflow) ||
1576 instr->CheckFlag(HValue::kBailoutOnMinusZero)) { 1569 instr->CheckFlag(HValue::kBailoutOnMinusZero)) {
1577 AssignEnvironment(mul); 1570 AssignEnvironment(mul);
1578 } 1571 }
1579 return DefineSameAsFirst(mul); 1572 return DefineSameAsFirst(mul);
1580 } else if (instr->representation().IsDouble()) { 1573 } else if (instr->representation().IsDouble()) {
1581 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 1574 return DoArithmeticD(Token::MUL, instr);
1582 return DoArithmeticD(Token::MUL, instr);
1583 }
1584 ASSERT(instr->right()->IsConstant() &&
1585 static_cast<HConstant*>(instr->right())->DoubleValue() == -1);
1586 // TODO(olivf) This is currently just a hack to support the UnaryOp Minus
1587 // Stub. This will go away once we can use more than one X87 register,
1588 // thus fully support binary instructions without SSE2.
1589 LOperand* left = UseX87TopOfStack(instr->left());
1590 LNegateNoSSE2D* result = new(zone()) LNegateNoSSE2D(left);
1591 return DefineX87TOS(result);
1592 } else { 1575 } else {
1593 ASSERT(instr->representation().IsSmiOrTagged()); 1576 ASSERT(instr->representation().IsSmiOrTagged());
1594 return DoArithmeticT(Token::MUL, instr); 1577 return DoArithmeticT(Token::MUL, instr);
1595 } 1578 }
1596 } 1579 }
1597 1580
1598 1581
1599 LInstruction* LChunkBuilder::DoSub(HSub* instr) { 1582 LInstruction* LChunkBuilder::DoSub(HSub* instr) {
1600 if (instr->representation().IsInteger32()) { 1583 if (instr->representation().IsInteger32()) {
1601 ASSERT(instr->left()->representation().IsInteger32()); 1584 ASSERT(instr->left()->representation().IsInteger32());
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
1931 // building a stack frame. 1914 // building a stack frame.
1932 if (from.IsTagged()) { 1915 if (from.IsTagged()) {
1933 if (to.IsDouble()) { 1916 if (to.IsDouble()) {
1934 info()->MarkAsDeferredCalling(); 1917 info()->MarkAsDeferredCalling();
1935 LOperand* value = UseRegister(instr->value()); 1918 LOperand* value = UseRegister(instr->value());
1936 // Temp register only necessary for minus zero check. 1919 // Temp register only necessary for minus zero check.
1937 LOperand* temp = instr->deoptimize_on_minus_zero() 1920 LOperand* temp = instr->deoptimize_on_minus_zero()
1938 ? TempRegister() 1921 ? TempRegister()
1939 : NULL; 1922 : NULL;
1940 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp); 1923 LNumberUntagD* res = new(zone()) LNumberUntagD(value, temp);
1941 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 1924 return AssignEnvironment(DefineAsRegister(res));
1942 return AssignEnvironment(DefineAsRegister(res));
1943 } else {
1944 return AssignEnvironment(DefineX87TOS(res));
1945 }
1946 } else if (to.IsSmi()) { 1925 } else if (to.IsSmi()) {
1947 HValue* val = instr->value(); 1926 HValue* val = instr->value();
1948 LOperand* value = UseRegister(val); 1927 LOperand* value = UseRegister(val);
1949 if (val->type().IsSmi()) { 1928 if (val->type().IsSmi()) {
1950 return DefineSameAsFirst(new(zone()) LDummyUse(value)); 1929 return DefineSameAsFirst(new(zone()) LDummyUse(value));
1951 } 1930 }
1952 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value))); 1931 return AssignEnvironment(DefineSameAsFirst(new(zone()) LCheckSmi(value)));
1953 } else { 1932 } else {
1954 ASSERT(to.IsInteger32()); 1933 ASSERT(to.IsInteger32());
1955 if (instr->value()->type().IsSmi()) { 1934 if (instr->value()->type().IsSmi()) {
(...skipping 14 matching lines...) Expand all
1970 LTaggedToINoSSE2* res = 1949 LTaggedToINoSSE2* res =
1971 new(zone()) LTaggedToINoSSE2(value, TempRegister(), 1950 new(zone()) LTaggedToINoSSE2(value, TempRegister(),
1972 TempRegister(), TempRegister()); 1951 TempRegister(), TempRegister());
1973 return AssignEnvironment(DefineFixed(res, ecx)); 1952 return AssignEnvironment(DefineFixed(res, ecx));
1974 } 1953 }
1975 } 1954 }
1976 } 1955 }
1977 } else if (from.IsDouble()) { 1956 } else if (from.IsDouble()) {
1978 if (to.IsTagged()) { 1957 if (to.IsTagged()) {
1979 info()->MarkAsDeferredCalling(); 1958 info()->MarkAsDeferredCalling();
1980 LOperand* value = CpuFeatures::IsSupported(SSE2) 1959 LOperand* value = UseRegisterAtStart(instr->value());
1981 ? UseRegisterAtStart(instr->value())
1982 : UseAtStart(instr->value());
1983 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL; 1960 LOperand* temp = FLAG_inline_new ? TempRegister() : NULL;
1984 1961
1985 // Make sure that temp and result_temp are different registers. 1962 // Make sure that temp and result_temp are different registers.
1986 LUnallocated* result_temp = TempRegister(); 1963 LUnallocated* result_temp = TempRegister();
1987 LNumberTagD* result = new(zone()) LNumberTagD(value, temp); 1964 LNumberTagD* result = new(zone()) LNumberTagD(value, temp);
1988 return AssignPointerMap(Define(result, result_temp)); 1965 return AssignPointerMap(Define(result, result_temp));
1989 } else if (to.IsSmi()) { 1966 } else if (to.IsSmi()) {
1990 LOperand* value = UseRegister(instr->value()); 1967 LOperand* value = UseRegister(instr->value());
1991 return AssignEnvironment( 1968 return AssignEnvironment(
1992 DefineAsRegister(new(zone()) LDoubleToSmi(value))); 1969 DefineAsRegister(new(zone()) LDoubleToSmi(value)));
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2134 2111
2135 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) { 2112 LInstruction* LChunkBuilder::DoConstant(HConstant* instr) {
2136 Representation r = instr->representation(); 2113 Representation r = instr->representation();
2137 if (r.IsSmi()) { 2114 if (r.IsSmi()) {
2138 return DefineAsRegister(new(zone()) LConstantS); 2115 return DefineAsRegister(new(zone()) LConstantS);
2139 } else if (r.IsInteger32()) { 2116 } else if (r.IsInteger32()) {
2140 return DefineAsRegister(new(zone()) LConstantI); 2117 return DefineAsRegister(new(zone()) LConstantI);
2141 } else if (r.IsDouble()) { 2118 } else if (r.IsDouble()) {
2142 double value = instr->DoubleValue(); 2119 double value = instr->DoubleValue();
2143 bool value_is_zero = BitCast<uint64_t, double>(value) == 0; 2120 bool value_is_zero = BitCast<uint64_t, double>(value) == 0;
2144 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2121 LOperand* temp = value_is_zero ? NULL : TempRegister();
2145 LOperand* temp = value_is_zero ? NULL : TempRegister(); 2122 return DefineAsRegister(new(zone()) LConstantD(temp));
2146 return DefineAsRegister(new(zone()) LConstantD(temp));
2147 } else {
2148 return DefineX87TOS(new(zone()) LConstantD(NULL));
2149 }
2150 } else if (r.IsTagged()) { 2123 } else if (r.IsTagged()) {
2151 return DefineAsRegister(new(zone()) LConstantT); 2124 return DefineAsRegister(new(zone()) LConstantT);
2152 } else { 2125 } else {
2153 UNREACHABLE(); 2126 UNREACHABLE();
2154 return NULL; 2127 return NULL;
2155 } 2128 }
2156 } 2129 }
2157 2130
2158 2131
2159 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) { 2132 LInstruction* LChunkBuilder::DoLoadGlobalCell(HLoadGlobalCell* instr) {
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 2304
2332 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) { 2305 LInstruction* LChunkBuilder::DoStoreKeyed(HStoreKeyed* instr) {
2333 if (!instr->is_external()) { 2306 if (!instr->is_external()) {
2334 ASSERT(instr->elements()->representation().IsTagged()); 2307 ASSERT(instr->elements()->representation().IsTagged());
2335 ASSERT(instr->key()->representation().IsInteger32() || 2308 ASSERT(instr->key()->representation().IsInteger32() ||
2336 instr->key()->representation().IsSmi()); 2309 instr->key()->representation().IsSmi());
2337 2310
2338 if (instr->value()->representation().IsDouble()) { 2311 if (instr->value()->representation().IsDouble()) {
2339 LOperand* object = UseRegisterAtStart(instr->elements()); 2312 LOperand* object = UseRegisterAtStart(instr->elements());
2340 LOperand* val = NULL; 2313 LOperand* val = NULL;
2341 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2314 val = UseRegisterAtStart(instr->value());
2342 val = UseRegisterAtStart(instr->value());
2343 } else if (!instr->IsConstantHoleStore()) {
2344 val = UseX87TopOfStack(instr->value());
2345 }
2346 LOperand* key = UseRegisterOrConstantAtStart(instr->key()); 2315 LOperand* key = UseRegisterOrConstantAtStart(instr->key());
2347 return new(zone()) LStoreKeyed(object, key, val); 2316 return new(zone()) LStoreKeyed(object, key, val);
2348 } else { 2317 } else {
2349 ASSERT(instr->value()->representation().IsSmiOrTagged()); 2318 ASSERT(instr->value()->representation().IsSmiOrTagged());
2350 bool needs_write_barrier = instr->NeedsWriteBarrier(); 2319 bool needs_write_barrier = instr->NeedsWriteBarrier();
2351 2320
2352 LOperand* obj = UseRegister(instr->elements()); 2321 LOperand* obj = UseRegister(instr->elements());
2353 LOperand* val; 2322 LOperand* val;
2354 LOperand* key; 2323 LOperand* key;
2355 if (needs_write_barrier) { 2324 if (needs_write_barrier) {
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
2465 2434
2466 LOperand* val; 2435 LOperand* val;
2467 if (needs_write_barrier) { 2436 if (needs_write_barrier) {
2468 val = UseTempRegister(instr->value()); 2437 val = UseTempRegister(instr->value());
2469 } else if (can_be_constant) { 2438 } else if (can_be_constant) {
2470 val = UseRegisterOrConstant(instr->value()); 2439 val = UseRegisterOrConstant(instr->value());
2471 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) { 2440 } else if (FLAG_track_fields && instr->field_representation().IsSmi()) {
2472 val = UseTempRegister(instr->value()); 2441 val = UseTempRegister(instr->value());
2473 } else if (FLAG_track_double_fields && 2442 } else if (FLAG_track_double_fields &&
2474 instr->field_representation().IsDouble()) { 2443 instr->field_representation().IsDouble()) {
2475 if (CpuFeatures::IsSafeForSnapshot(SSE2)) { 2444 val = UseRegisterAtStart(instr->value());
2476 val = UseRegisterAtStart(instr->value());
2477 } else {
2478 val = UseX87TopOfStack(instr->value());
2479 }
2480 } else { 2445 } else {
2481 val = UseRegister(instr->value()); 2446 val = UseRegister(instr->value());
2482 } 2447 }
2483 2448
2484 // We only need a scratch register if we have a write barrier or we 2449 // We only need a scratch register if we have a write barrier or we
2485 // have a store into the properties array (not in-object-property). 2450 // have a store into the properties array (not in-object-property).
2486 LOperand* temp = (!is_in_object || needs_write_barrier || 2451 LOperand* temp = (!is_in_object || needs_write_barrier ||
2487 needs_write_barrier_for_map) ? TempRegister() : NULL; 2452 needs_write_barrier_for_map) ? TempRegister() : NULL;
2488 2453
2489 // We need a temporary register for write barrier of the map field. 2454 // We need a temporary register for write barrier of the map field.
(...skipping 314 matching lines...) Expand 10 before | Expand all | Expand 10 after
2804 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) { 2769 LInstruction* LChunkBuilder::DoLoadFieldByIndex(HLoadFieldByIndex* instr) {
2805 LOperand* object = UseRegister(instr->object()); 2770 LOperand* object = UseRegister(instr->object());
2806 LOperand* index = UseTempRegister(instr->index()); 2771 LOperand* index = UseTempRegister(instr->index());
2807 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index)); 2772 return DefineSameAsFirst(new(zone()) LLoadFieldByIndex(object, index));
2808 } 2773 }
2809 2774
2810 2775
2811 } } // namespace v8::internal 2776 } } // namespace v8::internal
2812 2777
2813 #endif // V8_TARGET_ARCH_IA32 2778 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« src/ia32/lithium-codegen-ia32.cc ('K') | « src/ia32/lithium-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698