| 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_X64. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_X64. |
| 6 #if defined(TARGET_ARCH_X64) | 6 #if defined(TARGET_ARCH_X64) |
| 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 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 try_index(), | 193 try_index(), |
| 194 kConditionTypeErrorRuntimeEntry); | 194 kConditionTypeErrorRuntimeEntry); |
| 195 // We should never return here. | 195 // We should never return here. |
| 196 __ int3(); | 196 __ int3(); |
| 197 | 197 |
| 198 __ Bind(&done); | 198 __ Bind(&done); |
| 199 ASSERT(obj == result); | 199 ASSERT(obj == result); |
| 200 } | 200 } |
| 201 | 201 |
| 202 | 202 |
| 203 static Condition TokenKindToSmiCondition(Token::Kind kind) { |
| 204 switch (kind) { |
| 205 case Token::kEQ: return EQUAL; |
| 206 case Token::kNE: return NOT_EQUAL; |
| 207 case Token::kLT: return LESS; |
| 208 case Token::kGT: return GREATER; |
| 209 case Token::kLTE: return LESS_EQUAL; |
| 210 case Token::kGTE: return GREATER_EQUAL; |
| 211 default: |
| 212 UNREACHABLE(); |
| 213 return OVERFLOW; |
| 214 } |
| 215 } |
| 216 |
| 217 |
| 203 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { | 218 LocationSummary* EqualityCompareComp::MakeLocationSummary() const { |
| 204 const intptr_t kNumInputs = 2; | 219 const intptr_t kNumInputs = 2; |
| 205 if (receiver_class_id() != kObject) { | 220 if (receiver_class_id() != kObject) { |
| 206 ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble)); | 221 ASSERT((receiver_class_id() == kSmi) || (receiver_class_id() == kDouble)); |
| 207 // No temporary register needed for double comparison. | 222 // No temporary register needed for double comparison. |
| 208 const intptr_t kNumTemps = (receiver_class_id() == kSmi) ? 1 : 0; | 223 const intptr_t kNumTemps = (receiver_class_id() == kSmi) ? 1 : 0; |
| 209 LocationSummary* locs = new LocationSummary(kNumInputs, | 224 LocationSummary* locs = new LocationSummary(kNumInputs, |
| 210 kNumTemps, | 225 kNumTemps, |
| 211 LocationSummary::kNoCall); | 226 LocationSummary::kNoCall); |
| 212 locs->set_in(0, Location::RequiresRegister()); | 227 locs->set_in(0, Location::RequiresRegister()); |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 252 kDeoptSmiCompareSmi, | 267 kDeoptSmiCompareSmi, |
| 253 left, | 268 left, |
| 254 right); | 269 right); |
| 255 __ movq(temp, left); | 270 __ movq(temp, left); |
| 256 __ orq(temp, right); | 271 __ orq(temp, right); |
| 257 __ testq(temp, Immediate(kSmiTagMask)); | 272 __ testq(temp, Immediate(kSmiTagMask)); |
| 258 __ j(NOT_ZERO, deopt); | 273 __ j(NOT_ZERO, deopt); |
| 259 __ cmpq(left, right); | 274 __ cmpq(left, right); |
| 260 Register result = comp->locs()->out().reg(); | 275 Register result = comp->locs()->out().reg(); |
| 261 Label load_true, done; | 276 Label load_true, done; |
| 262 __ j(EQUAL, &load_true, Assembler::kNearJump); | 277 __ j(TokenKindToSmiCondition(comp->kind()), &load_true, Assembler::kNearJump); |
| 263 __ LoadObject(result, compiler->bool_false()); | 278 __ LoadObject(result, compiler->bool_false()); |
| 264 __ jmp(&done, Assembler::kNearJump); | 279 __ jmp(&done, Assembler::kNearJump); |
| 265 __ Bind(&load_true); | 280 __ Bind(&load_true); |
| 266 __ LoadObject(result, compiler->bool_true()); | 281 __ LoadObject(result, compiler->bool_true()); |
| 267 __ Bind(&done); | 282 __ Bind(&done); |
| 268 } | 283 } |
| 269 | 284 |
| 270 | 285 |
| 271 // TODO(srdjan): Add support for mixed Smi/Double equality | 286 // TODO(srdjan): Add support for mixed Smi/Double equality |
| 272 // (see LoadDoubleOrSmiToXmm). | 287 // (see LoadDoubleOrSmiToXmm). |
| 273 static void EmitDoubleEqualityCompare(FlowGraphCompiler* compiler, | 288 static void EmitDoubleEqualityCompare(FlowGraphCompiler* compiler, |
| 274 EqualityCompareComp* comp) { | 289 EqualityCompareComp* comp) { |
| 275 Register left = comp->locs()->in(0).reg(); | 290 Register left = comp->locs()->in(0).reg(); |
| 276 Register right = comp->locs()->in(1).reg(); | 291 Register right = comp->locs()->in(1).reg(); |
| 277 Label* deopt = compiler->AddDeoptStub(comp->cid(), | 292 Label* deopt = compiler->AddDeoptStub(comp->cid(), |
| 278 comp->token_pos(), | 293 comp->token_pos(), |
| 279 comp->try_index(), | 294 comp->try_index(), |
| 280 kDeoptDoubleCompareDouble, | 295 kDeoptDoubleCompareDouble, |
| 281 left, | 296 left, |
| 282 right); | 297 right); |
| 283 __ CompareClassId(left, kDouble); | 298 __ CompareClassId(left, kDouble); |
| 284 __ j(NOT_EQUAL, deopt); | 299 __ j(NOT_EQUAL, deopt); |
| 285 __ CompareClassId(right, kDouble); | 300 __ CompareClassId(right, kDouble); |
| 286 __ j(NOT_EQUAL, deopt); | 301 __ j(NOT_EQUAL, deopt); |
| 287 __ movsd(XMM0, FieldAddress(left, Double::value_offset())); | 302 __ movsd(XMM0, FieldAddress(left, Double::value_offset())); |
| 288 __ movsd(XMM1, FieldAddress(right, Double::value_offset())); | 303 __ movsd(XMM1, FieldAddress(right, Double::value_offset())); |
| 289 compiler->EmitDoubleCompareBool( | 304 compiler->EmitDoubleCompareBool(TokenKindToSmiCondition(comp->kind()), |
| 290 EQUAL, XMM0, XMM1, comp->locs()->out().reg()); | 305 XMM0, XMM1, |
| 306 comp->locs()->out().reg()); |
| 291 } | 307 } |
| 292 | 308 |
| 293 | 309 |
| 294 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, | 310 static void EmitEqualityAsInstanceCall(FlowGraphCompiler* compiler, |
| 295 EqualityCompareComp* comp) { | 311 EqualityCompareComp* comp) { |
| 296 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, | 312 compiler->AddCurrentDescriptor(PcDescriptors::kDeopt, |
| 297 comp->cid(), | 313 comp->cid(), |
| 298 comp->token_pos(), | 314 comp->token_pos(), |
| 299 comp->try_index()); | 315 comp->try_index()); |
| 300 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); | 316 const String& operator_name = String::ZoneHandle(String::NewSymbol("==")); |
| 301 const int kNumberOfArguments = 2; | 317 const int kNumberOfArguments = 2; |
| 302 const Array& kNoArgumentNames = Array::Handle(); | 318 const Array& kNoArgumentNames = Array::Handle(); |
| 303 const int kNumArgumentsChecked = 2; | 319 const int kNumArgumentsChecked = 2; |
| 304 | 320 |
| 305 compiler->GenerateInstanceCall(comp->cid(), | 321 compiler->GenerateInstanceCall(comp->cid(), |
| 306 comp->token_pos(), | 322 comp->token_pos(), |
| 307 comp->try_index(), | 323 comp->try_index(), |
| 308 operator_name, | 324 operator_name, |
| 309 kNumberOfArguments, | 325 kNumberOfArguments, |
| 310 kNoArgumentNames, | 326 kNoArgumentNames, |
| 311 kNumArgumentsChecked); | 327 kNumArgumentsChecked); |
| 312 ASSERT(comp->locs()->out().reg() == RAX); | 328 ASSERT(comp->locs()->out().reg() == RAX); |
| 329 if (comp->kind() == Token::kNE) { |
| 330 Label done, false_label; |
| 331 __ CompareObject(RAX, compiler->bool_true()); |
| 332 __ j(EQUAL, &false_label, Assembler::kNearJump); |
| 333 __ LoadObject(RAX, compiler->bool_true()); |
| 334 __ jmp(&done, Assembler::kNearJump); |
| 335 __ Bind(&false_label); |
| 336 __ LoadObject(RAX, compiler->bool_false()); |
| 337 __ Bind(&done); |
| 338 } |
| 313 } | 339 } |
| 314 | 340 |
| 315 | 341 |
| 316 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, | 342 static void EmitEqualityAsPolymorphicCall(FlowGraphCompiler* compiler, |
| 317 const ICData& orig_ic_data, | 343 const ICData& orig_ic_data, |
| 318 const LocationSummary& locs, | 344 const LocationSummary& locs, |
| 319 BranchInstr* branch, | 345 BranchInstr* branch, |
| 320 Token::Kind kind, | 346 Token::Kind kind, |
| 321 intptr_t cid, | 347 intptr_t cid, |
| 322 intptr_t token_pos, | 348 intptr_t token_pos, |
| 323 intptr_t try_index) { | 349 intptr_t try_index) { |
| 350 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
| 324 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); | 351 const ICData& ic_data = ICData::Handle(orig_ic_data.AsUnaryClassChecks()); |
| 325 ASSERT(ic_data.NumberOfChecks() > 0); | 352 ASSERT(ic_data.NumberOfChecks() > 0); |
| 326 ASSERT(ic_data.num_args_tested() == 1); | 353 ASSERT(ic_data.num_args_tested() == 1); |
| 327 Label* deopt = compiler->AddDeoptStub(cid, | 354 Label* deopt = compiler->AddDeoptStub(cid, |
| 328 token_pos, | 355 token_pos, |
| 329 try_index, | 356 try_index, |
| 330 kDeoptEquality); | 357 kDeoptEquality); |
| 331 Register left = locs.in(0).reg(); | 358 Register left = locs.in(0).reg(); |
| 332 Register right = locs.in(1).reg(); | 359 Register right = locs.in(1).reg(); |
| 333 __ testq(left, Immediate(kSmiTagMask)); | 360 __ testq(left, Immediate(kSmiTagMask)); |
| 334 Register temp = locs.temp(0).reg(); | 361 Register temp = locs.temp(0).reg(); |
| 335 if (ic_data.GetReceiverClassIdAt(0) == kSmi) { | 362 if (ic_data.GetReceiverClassIdAt(0) == kSmi) { |
| 336 Label done, load_class_id; | 363 Label done, load_class_id; |
| 337 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); | 364 __ j(NOT_ZERO, &load_class_id, Assembler::kNearJump); |
| 338 __ movq(temp, Immediate(kSmi)); | 365 __ movq(temp, Immediate(kSmi)); |
| 339 __ jmp(&done, Assembler::kNearJump); | 366 __ jmp(&done, Assembler::kNearJump); |
| 340 __ Bind(&load_class_id); | 367 __ Bind(&load_class_id); |
| 341 __ LoadClassId(temp, left); | 368 __ LoadClassId(temp, left); |
| 342 __ Bind(&done); | 369 __ Bind(&done); |
| 343 } else { | 370 } else { |
| 344 __ j(ZERO, deopt); // Smi deopts. | 371 __ j(ZERO, deopt); // Smi deopts. |
| 345 __ LoadClassId(temp, left); | 372 __ LoadClassId(temp, left); |
| 346 } | 373 } |
| 347 Condition cond = (kind == Token::kEQ) ? EQUAL : NOT_EQUAL; | 374 Condition cond = TokenKindToSmiCondition(kind); |
| 348 Label done; | 375 Label done; |
| 349 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { | 376 for (intptr_t i = 0; i < ic_data.NumberOfChecks(); i++) { |
| 350 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmi) || (i == 0)); | 377 ASSERT((ic_data.GetReceiverClassIdAt(i) != kSmi) || (i == 0)); |
| 351 Label next_test; | 378 Label next_test; |
| 352 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); | 379 __ cmpq(temp, Immediate(ic_data.GetReceiverClassIdAt(i))); |
| 353 __ j(NOT_EQUAL, &next_test, Assembler::kNearJump); | 380 __ j(NOT_EQUAL, &next_test, Assembler::kNearJump); |
| 354 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); | 381 const Function& target = Function::ZoneHandle(ic_data.GetTargetAt(i)); |
| 355 ObjectStore* object_store = Isolate::Current()->object_store(); | 382 ObjectStore* object_store = Isolate::Current()->object_store(); |
| 356 if (target.owner() == object_store->object_class()) { | 383 if (target.owner() == object_store->object_class()) { |
| 357 // Object.== is same as ===. | 384 // Object.== is same as ===. |
| (...skipping 13 matching lines...) Expand all Loading... |
| 371 } | 398 } |
| 372 } else { | 399 } else { |
| 373 const int kNumberOfArguments = 2; | 400 const int kNumberOfArguments = 2; |
| 374 const Array& kNoArgumentNames = Array::Handle(); | 401 const Array& kNoArgumentNames = Array::Handle(); |
| 375 compiler->GenerateStaticCall(cid, | 402 compiler->GenerateStaticCall(cid, |
| 376 token_pos, | 403 token_pos, |
| 377 try_index, | 404 try_index, |
| 378 target, | 405 target, |
| 379 kNumberOfArguments, | 406 kNumberOfArguments, |
| 380 kNoArgumentNames); | 407 kNoArgumentNames); |
| 381 if (branch != NULL) { | 408 if (branch == NULL) { |
| 409 if (kind == Token::kNE) { |
| 410 Label false_label; |
| 411 __ CompareObject(RAX, compiler->bool_true()); |
| 412 __ j(EQUAL, &false_label, Assembler::kNearJump); |
| 413 __ LoadObject(RAX, compiler->bool_true()); |
| 414 __ jmp(&done, Assembler::kNearJump); |
| 415 __ Bind(&false_label); |
| 416 __ LoadObject(RAX, compiler->bool_false()); |
| 417 __ jmp(&done); |
| 418 } |
| 419 } else { |
| 382 __ CompareObject(RAX, compiler->bool_true()); | 420 __ CompareObject(RAX, compiler->bool_true()); |
| 383 branch->EmitBranchOnCondition(compiler, cond); | 421 branch->EmitBranchOnCondition(compiler, cond); |
| 384 } | 422 } |
| 385 } | 423 } |
| 386 __ jmp(&done); | 424 __ jmp(&done); |
| 387 __ Bind(&next_test); | 425 __ Bind(&next_test); |
| 388 } | 426 } |
| 389 // Fall through leads to deoptimization | 427 // Fall through leads to deoptimization |
| 390 __ jmp(deopt); | 428 __ jmp(deopt); |
| 391 __ Bind(&done); | 429 __ Bind(&done); |
| 392 } | 430 } |
| 393 | 431 |
| 394 | 432 |
| 395 // First test if receiver is NULL, in which case === is applied. | 433 // First test if receiver is NULL, in which case === is applied. |
| 396 // If type feedback was provided (lists of <class-id, target>), do a | 434 // If type feedback was provided (lists of <class-id, target>), do a |
| 397 // type by type check (either === or static call to the operator. | 435 // type by type check (either === or static call to the operator. |
| 398 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, | 436 static void EmitGenericEqualityCompare(FlowGraphCompiler* compiler, |
| 399 const LocationSummary& locs, | 437 const LocationSummary& locs, |
| 400 Token::Kind kind, | 438 Token::Kind kind, |
| 401 BranchInstr* branch, | 439 BranchInstr* branch, |
| 402 const ICData& ic_data, | 440 const ICData& ic_data, |
| 403 intptr_t cid, | 441 intptr_t cid, |
| 404 intptr_t token_pos, | 442 intptr_t token_pos, |
| 405 intptr_t try_index) { | 443 intptr_t try_index) { |
| 444 ASSERT((kind == Token::kEQ) || (kind == Token::kNE)); |
| 406 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); | 445 ASSERT(!ic_data.IsNull() && (ic_data.NumberOfChecks() > 0)); |
| 407 Register left = locs.in(0).reg(); | 446 Register left = locs.in(0).reg(); |
| 408 Register right = locs.in(1).reg(); | 447 Register right = locs.in(1).reg(); |
| 409 const Immediate raw_null = | 448 const Immediate raw_null = |
| 410 Immediate(reinterpret_cast<intptr_t>(Object::null())); | 449 Immediate(reinterpret_cast<intptr_t>(Object::null())); |
| 411 Label done, non_null_compare; | 450 Label done, non_null_compare; |
| 412 __ cmpq(left, raw_null); | 451 __ cmpq(left, raw_null); |
| 413 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); | 452 __ j(NOT_EQUAL, &non_null_compare, Assembler::kNearJump); |
| 414 // Comparison with NULL is "===". | 453 // Comparison with NULL is "===". |
| 415 __ cmpq(left, right); | 454 __ cmpq(left, right); |
| 416 Condition cond = (kind == Token::kEQ) ? EQUAL : NOT_EQUAL; | 455 Condition cond = TokenKindToSmiCondition(kind); |
| 417 if (branch != NULL) { | 456 if (branch != NULL) { |
| 418 branch->EmitBranchOnCondition(compiler, cond); | 457 branch->EmitBranchOnCondition(compiler, cond); |
| 419 } else { | 458 } else { |
| 420 Register result = locs.out().reg(); | 459 Register result = locs.out().reg(); |
| 421 Label load_true; | 460 Label load_true; |
| 422 __ j(cond, &load_true, Assembler::kNearJump); | 461 __ j(cond, &load_true, Assembler::kNearJump); |
| 423 __ LoadObject(result, compiler->bool_false()); | 462 __ LoadObject(result, compiler->bool_false()); |
| 424 __ jmp(&done); | 463 __ jmp(&done); |
| 425 __ Bind(&load_true); | 464 __ Bind(&load_true); |
| 426 __ LoadObject(result, compiler->bool_true()); | 465 __ LoadObject(result, compiler->bool_true()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 438 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { | 477 void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
| 439 if (receiver_class_id() == kSmi) { | 478 if (receiver_class_id() == kSmi) { |
| 440 EmitSmiEqualityCompare(compiler, this); | 479 EmitSmiEqualityCompare(compiler, this); |
| 441 return; | 480 return; |
| 442 } | 481 } |
| 443 if (receiver_class_id() == kDouble) { | 482 if (receiver_class_id() == kDouble) { |
| 444 EmitDoubleEqualityCompare(compiler, this); | 483 EmitDoubleEqualityCompare(compiler, this); |
| 445 return; | 484 return; |
| 446 } | 485 } |
| 447 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { | 486 if (HasICData() && (ic_data()->NumberOfChecks() > 0)) { |
| 448 EmitGenericEqualityCompare(compiler, *locs(), Token::kEQ, NULL, | 487 EmitGenericEqualityCompare(compiler, *locs(), kind(), NULL, |
| 449 *ic_data(), cid(), token_pos(), try_index()); | 488 *ic_data(), cid(), token_pos(), try_index()); |
| 450 } else { | 489 } else { |
| 451 Register left = locs()->in(0).reg(); | 490 Register left = locs()->in(0).reg(); |
| 452 Register right = locs()->in(1).reg(); | 491 Register right = locs()->in(1).reg(); |
| 453 __ pushq(left); | 492 __ pushq(left); |
| 454 __ pushq(right); | 493 __ pushq(right); |
| 455 EmitEqualityAsInstanceCall(compiler, this); | 494 EmitEqualityAsInstanceCall(compiler, this); |
| 456 } | 495 } |
| 457 } | 496 } |
| 458 | 497 |
| 459 | 498 |
| 460 LocationSummary* RelationalOpComp::MakeLocationSummary() const { | 499 LocationSummary* RelationalOpComp::MakeLocationSummary() const { |
| 461 if (operands_class_id() == kSmi || operands_class_id() == kDouble) { | 500 if (operands_class_id() == kSmi || operands_class_id() == kDouble) { |
| 462 const intptr_t kNumInputs = 2; | 501 const intptr_t kNumInputs = 2; |
| 463 const intptr_t kNumTemps = 1; | 502 const intptr_t kNumTemps = 1; |
| 464 LocationSummary* summary = new LocationSummary(kNumInputs, | 503 LocationSummary* summary = new LocationSummary(kNumInputs, |
| 465 kNumTemps, | 504 kNumTemps, |
| 466 LocationSummary::kCall); | 505 LocationSummary::kCall); |
| 467 summary->set_in(0, Location::RequiresRegister()); | 506 summary->set_in(0, Location::RequiresRegister()); |
| 468 summary->set_in(1, Location::RequiresRegister()); | 507 summary->set_in(1, Location::RequiresRegister()); |
| 469 summary->set_out(Location::RequiresRegister()); | 508 summary->set_out(Location::RequiresRegister()); |
| 470 summary->set_temp(0, Location::RequiresRegister()); | 509 summary->set_temp(0, Location::RequiresRegister()); |
| 471 return summary; | 510 return summary; |
| 472 } | 511 } |
| 473 ASSERT(operands_class_id() == kObject); | 512 ASSERT(operands_class_id() == kObject); |
| 474 return MakeCallSummary(); | 513 return MakeCallSummary(); |
| 475 } | 514 } |
| 476 | 515 |
| 477 | 516 |
| 478 static Condition TokenKindToSmiCondition(Token::Kind kind) { | |
| 479 switch (kind) { | |
| 480 case Token::kEQ: return EQUAL; | |
| 481 case Token::kNE: return NOT_EQUAL; | |
| 482 case Token::kLT: return LESS; | |
| 483 case Token::kGT: return GREATER; | |
| 484 case Token::kLTE: return LESS_EQUAL; | |
| 485 case Token::kGTE: return GREATER_EQUAL; | |
| 486 default: | |
| 487 UNREACHABLE(); | |
| 488 return OVERFLOW; | |
| 489 } | |
| 490 } | |
| 491 | |
| 492 | |
| 493 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, | 517 static void EmitSmiComparisonOp(FlowGraphCompiler* compiler, |
| 494 const LocationSummary& locs, | 518 const LocationSummary& locs, |
| 495 Token::Kind kind, | 519 Token::Kind kind, |
| 496 BranchInstr* branch, | 520 BranchInstr* branch, |
| 497 intptr_t cid, | 521 intptr_t cid, |
| 498 intptr_t token_pos, | 522 intptr_t token_pos, |
| 499 intptr_t try_index) { | 523 intptr_t try_index) { |
| 500 Register left = locs.in(0).reg(); | 524 Register left = locs.in(0).reg(); |
| 501 Register right = locs.in(1).reg(); | 525 Register right = locs.in(1).reg(); |
| 502 Register temp = locs.temp(0).reg(); | 526 Register temp = locs.temp(0).reg(); |
| (...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2146 ASSERT(locs()->out().reg() == RAX); | 2170 ASSERT(locs()->out().reg() == RAX); |
| 2147 __ CompareObject(locs()->out().reg(), compiler->bool_true()); | 2171 __ CompareObject(locs()->out().reg(), compiler->bool_true()); |
| 2148 EmitBranchOnCondition(compiler, branch_condition); | 2172 EmitBranchOnCondition(compiler, branch_condition); |
| 2149 } | 2173 } |
| 2150 | 2174 |
| 2151 } // namespace dart | 2175 } // namespace dart |
| 2152 | 2176 |
| 2153 #undef __ | 2177 #undef __ |
| 2154 | 2178 |
| 2155 #endif // defined TARGET_ARCH_X64 | 2179 #endif // defined TARGET_ARCH_X64 |
| OLD | NEW |