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

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

Issue 20455: Move implementation of comparisons with constant smis to use... (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/toiger/
Patch Set: '' Created 11 years, 10 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/codegen-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 2006-2008 the V8 project authors. All rights reserved. 1 // Copyright 2006-2008 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 1311 matching lines...) Expand 10 before | Expand all | Expand 10 after
1322 ASSERT(right_side.is_valid()); 1322 ASSERT(right_side.is_valid());
1323 __ cmp(left_side.reg(), Operand(right_side.reg())); 1323 __ cmp(left_side.reg(), Operand(right_side.reg()));
1324 } else { 1324 } else {
1325 __ cmp(Operand(left_side.reg()), Immediate(right_side.handle())); 1325 __ cmp(Operand(left_side.reg()), Immediate(right_side.handle()));
1326 } 1326 }
1327 left_side.Unuse(); 1327 left_side.Unuse();
1328 right_side.Unuse(); 1328 right_side.Unuse();
1329 dest->Split(cc); 1329 dest->Split(cc);
1330 } 1330 }
1331 } else { // Neither side is a constant Smi, normal comparison operation. 1331 } else { // Neither side is a constant Smi, normal comparison operation.
1332 // If either side is a non-smi constant, skip the smi check.
1333 bool known_non_smi =
1334 left_side.is_constant() && !left_side.handle()->IsSmi() ||
1335 right_side.is_constant() && !right_side.handle()->IsSmi();
1332 left_side.ToRegister(); 1336 left_side.ToRegister();
1333 right_side.ToRegister(); 1337 right_side.ToRegister();
1334 ASSERT(left_side.is_valid());
1335 ASSERT(right_side.is_valid());
1336 // Check for the smi case.
1337 JumpTarget is_smi(this); 1338 JumpTarget is_smi(this);
1338 Result temp = allocator_->Allocate(); 1339 if (!known_non_smi) {
1339 ASSERT(temp.is_valid()); 1340 // Check for the smi case.
1340 __ mov(temp.reg(), left_side.reg()); 1341 Result temp = allocator_->Allocate();
1341 __ or_(temp.reg(), Operand(right_side.reg())); 1342 ASSERT(temp.is_valid());
1342 __ test(temp.reg(), Immediate(kSmiTagMask)); 1343 __ mov(temp.reg(), left_side.reg());
1343 temp.Unuse(); 1344 __ or_(temp.reg(), Operand(right_side.reg()));
1344 is_smi.Branch(zero, &left_side, &right_side, taken); 1345 __ test(temp.reg(), Immediate(kSmiTagMask));
1345 1346 temp.Unuse();
1347 is_smi.Branch(zero, &left_side, &right_side, taken);
1348 }
1346 // When non-smi, call out to the compare stub. "parameters" setup by 1349 // When non-smi, call out to the compare stub. "parameters" setup by
1347 // calling code in edx and eax and "result" is returned in the flags. 1350 // calling code in edx and eax and "result" is returned in the flags.
1348 if (!left_side.reg().is(eax)) { 1351 if (!left_side.reg().is(eax)) {
1349 right_side.ToRegister(eax); 1352 right_side.ToRegister(eax);
1350 left_side.ToRegister(edx); 1353 left_side.ToRegister(edx);
1351 } else if (!right_side.reg().is(edx)) { 1354 } else if (!right_side.reg().is(edx)) {
1352 left_side.ToRegister(edx); 1355 left_side.ToRegister(edx);
1353 right_side.ToRegister(eax); 1356 right_side.ToRegister(eax);
1354 } else { 1357 } else {
1355 frame_->Spill(eax); // Can be multiply referenced, even now. 1358 frame_->Spill(eax); // Can be multiply referenced, even now.
1356 frame_->Spill(edx); 1359 frame_->Spill(edx);
1357 __ xchg(eax, edx); 1360 __ xchg(eax, edx);
1358 // If left_side and right_side become real (non-dummy) arguments 1361 // If left_side and right_side become real (non-dummy) arguments
1359 // to CallStub, they need to be swapped in this case. 1362 // to CallStub, they need to be swapped in this case.
1360 } 1363 }
1361 CompareStub stub(cc, strict); 1364 CompareStub stub(cc, strict);
1362 Result answer = frame_->CallStub(&stub, &right_side, &left_side, 0); 1365 Result answer = frame_->CallStub(&stub, &right_side, &left_side, 0);
1363 if (cc == equal) { 1366 if (cc == equal) {
1364 __ test(answer.reg(), Operand(answer.reg())); 1367 __ test(answer.reg(), Operand(answer.reg()));
1365 } else { 1368 } else {
1366 __ cmp(answer.reg(), 0); 1369 __ cmp(answer.reg(), 0);
1367 } 1370 }
1368 answer.Unuse(); 1371 answer.Unuse();
1369 dest->true_target()->Branch(cc); 1372 if (known_non_smi) {
1370 dest->false_target()->Jump(); 1373 dest->Split(cc);
1371 1374 } else {
1372 is_smi.Bind(&left_side, &right_side); 1375 dest->true_target()->Branch(cc);
1373 left_side.ToRegister(); 1376 dest->false_target()->Jump();
1374 right_side.ToRegister(); 1377 is_smi.Bind(&left_side, &right_side);
1375 __ cmp(left_side.reg(), Operand(right_side.reg())); 1378 left_side.ToRegister();
1376 right_side.Unuse(); 1379 right_side.ToRegister();
1377 left_side.Unuse(); 1380 __ cmp(left_side.reg(), Operand(right_side.reg()));
1378 dest->Split(cc); 1381 right_side.Unuse();
1382 left_side.Unuse();
1383 dest->Split(cc);
1384 }
1379 } 1385 }
1380 } 1386 }
1381 1387
1382 1388
1383 void CodeGenerator::SmiComparison(Condition cc,
1384 Handle<Object> smi_value,
1385 bool strict) {
1386 // Strict only makes sense for equality comparisons.
1387 ASSERT(!strict || cc == equal);
1388 ASSERT(is_intn(Smi::cast(*smi_value)->value(), kMaxSmiInlinedBits));
1389
1390 JumpTarget is_smi(this);
1391 Result comparee = frame_->Pop();
1392 comparee.ToRegister();
1393 // Check whether the other operand is a smi.
1394 __ test(comparee.reg(), Immediate(kSmiTagMask));
1395 is_smi.Branch(zero, &comparee, taken);
1396
1397 // Setup and call the compare stub, which expects arguments in edx
1398 // and eax.
1399 CompareStub stub(cc, strict);
1400 comparee.ToRegister(edx);
1401 Result value = allocator_->Allocate(eax);
1402 ASSERT(value.is_valid());
1403 __ Set(value.reg(), Immediate(smi_value));
1404 Result result = frame_->CallStub(&stub, &comparee, &value, 0);
1405 __ cmp(result.reg(), 0);
1406 result.Unuse();
1407 destination()->true_target()->Branch(cc);
1408 destination()->false_target()->Jump();
1409
1410 is_smi.Bind(&comparee);
1411 comparee.ToRegister();
1412 // Test smi equality and comparison by signed int comparison.
1413 __ cmp(Operand(comparee.reg()), Immediate(smi_value));
1414 comparee.Unuse();
1415 destination()->Split(cc);
1416 }
1417
1418
1419 class CallFunctionStub: public CodeStub { 1389 class CallFunctionStub: public CodeStub {
1420 public: 1390 public:
1421 explicit CallFunctionStub(int argc) : argc_(argc) { } 1391 explicit CallFunctionStub(int argc) : argc_(argc) { }
1422 1392
1423 void Generate(MacroAssembler* masm); 1393 void Generate(MacroAssembler* masm);
1424 1394
1425 private: 1395 private:
1426 int argc_; 1396 int argc_;
1427 1397
1428 #ifdef DEBUG 1398 #ifdef DEBUG
(...skipping 3306 matching lines...) Expand 10 before | Expand all | Expand 10 after
4735 Result answer = frame_->CallStub(&stub, 2); 4705 Result answer = frame_->CallStub(&stub, 2);
4736 answer.ToRegister(); 4706 answer.ToRegister();
4737 __ test(answer.reg(), Operand(answer.reg())); 4707 __ test(answer.reg(), Operand(answer.reg()));
4738 answer.Unuse(); 4708 answer.Unuse();
4739 destination()->Split(zero); 4709 destination()->Split(zero);
4740 return; 4710 return;
4741 } 4711 }
4742 default: 4712 default:
4743 UNREACHABLE(); 4713 UNREACHABLE();
4744 } 4714 }
4745 4715 Load(left);
4746 // Optimize for the case where (at least) one of the expressions 4716 Load(right);
4747 // is a literal small integer. 4717 Comparison(cc, strict, destination());
4748 if (IsInlineSmi(left->AsLiteral())) {
4749 Load(right);
4750 SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(), strict);
4751 } else if (IsInlineSmi(right->AsLiteral())) {
4752 Load(left);
4753 SmiComparison(cc, right->AsLiteral()->handle(), strict);
4754 } else {
4755 Load(left);
4756 Load(right);
4757 Comparison(cc, strict, destination());
4758 }
4759 } 4718 }
4760 4719
4761 4720
4762 #ifdef DEBUG 4721 #ifdef DEBUG
4763 bool CodeGenerator::HasValidEntryRegisters() { 4722 bool CodeGenerator::HasValidEntryRegisters() {
4764 return (allocator()->count(eax) == frame()->register_count(eax)) 4723 return (allocator()->count(eax) == frame()->register_count(eax))
4765 && (allocator()->count(ebx) == frame()->register_count(ebx)) 4724 && (allocator()->count(ebx) == frame()->register_count(ebx))
4766 && (allocator()->count(ecx) == frame()->register_count(ecx)) 4725 && (allocator()->count(ecx) == frame()->register_count(ecx))
4767 && (allocator()->count(edx) == frame()->register_count(edx)) 4726 && (allocator()->count(edx) == frame()->register_count(edx))
4768 && (allocator()->count(edi) == frame()->register_count(edi)); 4727 && (allocator()->count(edi) == frame()->register_count(edi));
(...skipping 1798 matching lines...) Expand 10 before | Expand all | Expand 10 after
6567 6526
6568 // Slow-case: Go through the JavaScript implementation. 6527 // Slow-case: Go through the JavaScript implementation.
6569 __ bind(&slow); 6528 __ bind(&slow);
6570 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION); 6529 __ InvokeBuiltin(Builtins::INSTANCE_OF, JUMP_FUNCTION);
6571 } 6530 }
6572 6531
6573 6532
6574 #undef __ 6533 #undef __
6575 6534
6576 } } // namespace v8::internal 6535 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/codegen-ia32.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698