| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
| 6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
| 7 | 7 |
| 8 #include "vm/intermediate_language.h" | 8 #include "vm/intermediate_language.h" |
| 9 | 9 |
| 10 #include "lib/error.h" | 10 #include "lib/error.h" |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 LocationSummary* locs = | 273 LocationSummary* locs = |
| 274 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); | 274 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kCall); |
| 275 locs->set_in(0, Location::RegisterLocation(ECX)); | 275 locs->set_in(0, Location::RegisterLocation(ECX)); |
| 276 locs->set_in(1, Location::RegisterLocation(EDX)); | 276 locs->set_in(1, Location::RegisterLocation(EDX)); |
| 277 locs->set_out(Location::RegisterLocation(EAX)); | 277 locs->set_out(Location::RegisterLocation(EAX)); |
| 278 return locs; | 278 return locs; |
| 279 } | 279 } |
| 280 | 280 |
| 281 | 281 |
| 282 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, | 282 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, |
| 283 EqualityCompareComp* comp) { | 283 intptr_t deopt_id, |
| 284 intptr_t token_pos, |
| 285 intptr_t try_index, |
| 286 Token::Kind kind, |
| 287 const LocationSummary& locs) { |
| 284 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 288 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 285 comp->deopt_id(), | 289 deopt_id, |
| 286 comp->token_pos(), | 290 token_pos, |
| 287 comp->try_index()); | 291 try_index); |
| 288 const String& operator_name = String::ZoneHandle(Symbols::New("==")); | 292 const String& operator_name = String::ZoneHandle(Symbols::New("==")); |
| 289 const int kNumberOfArguments = 2; | 293 const int kNumberOfArguments = 2; |
| 290 const Array& kNoArgumentNames = Array::Handle(); | 294 const Array& kNoArgumentNames = Array::Handle(); |
| 291 const int kNumArgumentsChecked = 2; | 295 const int kNumArgumentsChecked = 2; |
| 292 | 296 |
| 293 Label done, false_label, true_label; | 297 Label done, false_label, true_label; |
| 294 Register left = comp->locs()->in(0).reg(); | 298 Register left = locs.in(0).reg(); |
| 295 Register right = comp->locs()->in(1).reg(); | 299 Register right = locs.in(1).reg(); |
| 296 __ popl(right); | 300 __ popl(right); |
| 297 __ popl(left); | 301 __ popl(left); |
| 298 const Immediate raw_null = | 302 const Immediate raw_null = |
| 299 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 303 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 300 Label check_identity, instance_call; | 304 Label check_identity, instance_call; |
| 301 __ cmpl(right, raw_null); | 305 __ cmpl(right, raw_null); |
| 302 __ j(EQUAL, &check_identity, Assembler::kNearJump); | 306 __ j(EQUAL, &check_identity, Assembler::kNearJump); |
| 303 __ cmpl(left, raw_null); | 307 __ cmpl(left, raw_null); |
| 304 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); | 308 __ j(NOT_EQUAL, &instance_call, Assembler::kNearJump); |
| 305 | 309 |
| 306 __ Bind(&check_identity); | 310 __ Bind(&check_identity); |
| 307 __ cmpl(left, right); | 311 __ cmpl(left, right); |
| 308 __ j(EQUAL, &true_label); | 312 __ j(EQUAL, &true_label); |
| 309 if (comp->kind() == Token::kEQ) { | 313 if (kind == Token::kEQ) { |
| 310 __ LoadObject(EAX, compiler->bool_false()); | 314 __ LoadObject(EAX, compiler->bool_false()); |
| 311 __ jmp(&done); | 315 __ jmp(&done); |
| 312 __ Bind(&true_label); | 316 __ Bind(&true_label); |
| 313 __ LoadObject(EAX, compiler->bool_true()); | 317 __ LoadObject(EAX, compiler->bool_true()); |
| 314 __ jmp(&done); | 318 __ jmp(&done); |
| 315 } else { | 319 } else { |
| 316 ASSERT(comp->kind() == Token::kNE); | 320 ASSERT(kind == Token::kNE); |
| 317 __ jmp(&false_label); | 321 __ jmp(&false_label); |
| 318 } | 322 } |
| 319 | 323 |
| 320 __ Bind(&instance_call); | 324 __ Bind(&instance_call); |
| 321 __ pushl(left); | 325 __ pushl(left); |
| 322 __ pushl(right); | 326 __ pushl(right); |
| 323 compiler->GenerateInstanceCall(comp->deopt_id(), | 327 compiler->GenerateInstanceCall(deopt_id, |
| 324 comp->token_pos(), | 328 token_pos, |
| 325 comp->try_index(), | 329 try_index, |
| 326 operator_name, | 330 operator_name, |
| 327 kNumberOfArguments, | 331 kNumberOfArguments, |
| 328 kNoArgumentNames, | 332 kNoArgumentNames, |
| 329 kNumArgumentsChecked, | 333 kNumArgumentsChecked, |
| 330 comp->locs()->stack_bitmap()); | 334 locs.stack_bitmap()); |
| 331 ASSERT(comp->locs()->out().reg() == EAX); | 335 if (kind == Token::kNE) { |
| 332 if (comp->kind() == Token::kNE) { | |
| 333 // Negate the condition: true label returns false and vice versa. | 336 // Negate the condition: true label returns false and vice versa. |
| 334 __ CompareObject(EAX, compiler->bool_true()); | 337 __ CompareObject(EAX, compiler->bool_true()); |
| 335 __ j(EQUAL, &true_label, Assembler::kNearJump); | 338 __ j(EQUAL, &true_label, Assembler::kNearJump); |
| 336 __ Bind(&false_label); | 339 __ Bind(&false_label); |
| 337 __ LoadObject(EAX, compiler->bool_true()); | 340 __ LoadObject(EAX, compiler->bool_true()); |
| 338 __ jmp(&done, Assembler::kNearJump); | 341 __ jmp(&done, Assembler::kNearJump); |
| 339 __ Bind(&true_label); | 342 __ Bind(&true_label); |
| 340 __ LoadObject(EAX, compiler->bool_false()); | 343 __ LoadObject(EAX, compiler->bool_false()); |
| 341 } | 344 } |
| 342 __ Bind(&done); | 345 __ Bind(&done); |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 651 return; | 654 return; |
| 652 } | 655 } |
| 653 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 656 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 654 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), | 657 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, *ic_data(), |
| 655 deopt_id(), token_pos(), try_index()); | 658 deopt_id(), token_pos(), try_index()); |
| 656 } else { | 659 } else { |
| 657 Register left = locs()->in(0).reg(); | 660 Register left = locs()->in(0).reg(); |
| 658 Register right = locs()->in(1).reg(); | 661 Register right = locs()->in(1).reg(); |
| 659 __ pushl(left); | 662 __ pushl(left); |
| 660 __ pushl(right); | 663 __ pushl(right); |
| 661 EmitEqualityAsInstanceCall(compiler, this); | 664 EmitEqualityAsInstanceCall(compiler, |
| 665 deopt_id(), |
| 666 token_pos(), |
| 667 try_index(), |
| 668 kind(), |
| 669 *locs()); |
| 670 ASSERT(locs()->out().reg() == EAX); |
| 662 } | 671 } |
| 663 } | 672 } |
| 664 | 673 |
| 665 | 674 |
| 666 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 675 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 667 const intptr_t kNumInputs = 2; | 676 const intptr_t kNumInputs = 2; |
| 668 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) { | 677 if ((operands_class_id() == kSmiCid) || (operands_class_id() == kDoubleCid)) { |
| 669 const intptr_t kNumTemps = 1; | 678 const intptr_t kNumTemps = 1; |
| 670 LocationSummary* summary = | 679 LocationSummary* summary = |
| 671 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); | 680 new LocationSummary(kNumInputs, kNumTemps, LocationSummary::kNoCall); |
| (...skipping 1472 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2144 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), | 2153 EmitGenericEqualityCompare(compiler, *locs(), kind(), this, *ic_data(), |
| 2145 deopt_id(), token_pos(), try_index()); | 2154 deopt_id(), token_pos(), try_index()); |
| 2146 return; | 2155 return; |
| 2147 } | 2156 } |
| 2148 // Otherwise polymorphic dispatch? | 2157 // Otherwise polymorphic dispatch? |
| 2149 } | 2158 } |
| 2150 Register left = locs()->in(0).reg(); | 2159 Register left = locs()->in(0).reg(); |
| 2151 Register right = locs()->in(1).reg(); | 2160 Register right = locs()->in(1).reg(); |
| 2152 __ pushl(left); | 2161 __ pushl(left); |
| 2153 __ pushl(right); | 2162 __ pushl(right); |
| 2154 // Not equal is always split into '==' and negate, | 2163 if ((kind() == Token::kNE) || (kind() == Token::kEQ)) { |
| 2164 EmitEqualityAsInstanceCall(compiler, |
| 2165 deopt_id(), |
| 2166 token_pos(), |
| 2167 try_index(), |
| 2168 Token::kEQ, // kNE reverse occurs at branch. |
| 2169 *locs()); |
| 2170 } else { |
| 2171 const String& function_name = |
| 2172 String::ZoneHandle(Symbols::New(Token::Str(kind()))); |
| 2173 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 2174 deopt_id(), |
| 2175 token_pos(), |
| 2176 try_index()); |
| 2177 const intptr_t kNumArguments = 2; |
| 2178 const intptr_t kNumArgsChecked = 2; // Type-feedback. |
| 2179 compiler->GenerateInstanceCall(deopt_id(), |
| 2180 token_pos(), |
| 2181 try_index(), |
| 2182 function_name, |
| 2183 kNumArguments, |
| 2184 Array::ZoneHandle(), // No optional args. |
| 2185 kNumArgsChecked, |
| 2186 locs()->stack_bitmap()); |
| 2187 } |
| 2155 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; | 2188 Condition branch_condition = (kind() == Token::kNE) ? NOT_EQUAL : EQUAL; |
| 2156 Token::Kind call_kind = (kind() == Token::kNE) ? Token::kEQ : kind(); | |
| 2157 const String& function_name = | |
| 2158 String::ZoneHandle(Symbols::New(Token::Str(call_kind))); | |
| 2159 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | |
| 2160 deopt_id(), | |
| 2161 token_pos(), | |
| 2162 try_index()); | |
| 2163 const intptr_t kNumArguments = 2; | |
| 2164 const intptr_t kNumArgsChecked = 2; // Type-feedback. | |
| 2165 compiler->GenerateInstanceCall(deopt_id(), | |
| 2166 token_pos(), | |
| 2167 try_index(), | |
| 2168 function_name, | |
| 2169 kNumArguments, | |
| 2170 Array::ZoneHandle(), // No optional arguments. | |
| 2171 kNumArgsChecked, | |
| 2172 locs()->stack_bitmap()); | |
| 2173 __ CompareObject(EAX, compiler->bool_true()); | 2189 __ CompareObject(EAX, compiler->bool_true()); |
| 2174 EmitBranchOnCondition(compiler, branch_condition); | 2190 EmitBranchOnCondition(compiler, branch_condition); |
| 2175 } | 2191 } |
| 2176 | 2192 |
| 2177 } // namespace dart | 2193 } // namespace dart |
| 2178 | 2194 |
| 2179 #undef __ | 2195 #undef __ |
| 2180 | 2196 |
| 2181 #endif // defined TARGET_ARCH_X64 | 2197 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |