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

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

Issue 542105: Fix a bug in the short-circuit logical operations in the toplevel... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Fix a bug in the short-circuit logical operations in the toplevel... Created 10 years, 11 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 | « no previous file | src/x64/fast-codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 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 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 switch (location_) { 207 switch (location_) {
208 case kAccumulator: 208 case kAccumulator:
209 if (!reg.is(result_register())) __ mov(result_register(), reg); 209 if (!reg.is(result_register())) __ mov(result_register(), reg);
210 break; 210 break;
211 case kStack: 211 case kStack:
212 __ push(reg); 212 __ push(reg);
213 break; 213 break;
214 } 214 }
215 break; 215 break;
216 216
217 case Expression::kValueTest:
218 case Expression::kTestValue:
219 // Push an extra copy of the value in case it's needed.
220 __ push(reg);
221 // Fall through.
222
223 case Expression::kTest: 217 case Expression::kTest:
224 // For simplicity we always test the accumulator register. 218 // For simplicity we always test the accumulator register.
225 if (!reg.is(result_register())) __ mov(result_register(), reg); 219 if (!reg.is(result_register())) __ mov(result_register(), reg);
226 DoTest(context); 220 DoTest(context);
227 break; 221 break;
222
223 case Expression::kValueTest:
224 case Expression::kTestValue:
225 if (!reg.is(result_register())) __ mov(result_register(), reg);
226 switch (location_) {
227 case kAccumulator:
228 break;
229 case kStack:
230 __ push(result_register());
231 break;
232 }
233 DoTest(context);
234 break;
228 } 235 }
229 } 236 }
230 237
231 238
232 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) { 239 void FastCodeGenerator::Apply(Expression::Context context, Slot* slot) {
233 switch (context) { 240 switch (context) {
234 case Expression::kUninitialized: 241 case Expression::kUninitialized:
235 UNREACHABLE(); 242 UNREACHABLE();
236 case Expression::kEffect: 243 case Expression::kEffect:
237 // Nothing to do. 244 // Nothing to do.
238 break; 245 break;
239 case Expression::kValue: { 246 case Expression::kValue: {
240 MemOperand slot_operand = EmitSlotSearch(slot, result_register()); 247 MemOperand slot_operand = EmitSlotSearch(slot, result_register());
241 switch (location_) { 248 switch (location_) {
242 case kAccumulator: 249 case kAccumulator:
243 __ mov(result_register(), slot_operand); 250 __ mov(result_register(), slot_operand);
244 break; 251 break;
245 case kStack: 252 case kStack:
246 // Memory operands can be pushed directly. 253 // Memory operands can be pushed directly.
247 __ push(slot_operand); 254 __ push(slot_operand);
248 break; 255 break;
249 } 256 }
250 break; 257 break;
251 } 258 }
252 259
253 case Expression::kTest: 260 case Expression::kTest:
261 // For simplicity we always test the accumulator register.
254 Move(result_register(), slot); 262 Move(result_register(), slot);
255 DoTest(context); 263 DoTest(context);
256 break; 264 break;
257 265
258 case Expression::kValueTest: 266 case Expression::kValueTest:
259 case Expression::kTestValue: 267 case Expression::kTestValue:
260 Move(result_register(), slot); 268 Move(result_register(), slot);
261 __ push(result_register()); 269 switch (location_) {
270 case kAccumulator:
271 break;
272 case kStack:
273 __ push(result_register());
274 break;
275 }
262 DoTest(context); 276 DoTest(context);
263 break; 277 break;
264 } 278 }
265 } 279 }
266 280
267 281
268 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) { 282 void FastCodeGenerator::Apply(Expression::Context context, Literal* lit) {
269 switch (context) { 283 switch (context) {
270 case Expression::kUninitialized: 284 case Expression::kUninitialized:
271 UNREACHABLE(); 285 UNREACHABLE();
272 case Expression::kEffect: 286 case Expression::kEffect:
273 // Nothing to do. 287 // Nothing to do.
274 break; 288 break;
275 case Expression::kValue: 289 case Expression::kValue:
276 switch (location_) { 290 switch (location_) {
277 case kAccumulator: 291 case kAccumulator:
278 __ mov(result_register(), lit->handle()); 292 __ mov(result_register(), lit->handle());
279 break; 293 break;
280 case kStack: 294 case kStack:
281 // Immediates can be pushed directly. 295 // Immediates can be pushed directly.
282 __ push(Immediate(lit->handle())); 296 __ push(Immediate(lit->handle()));
283 break; 297 break;
284 } 298 }
285 break; 299 break;
286 300
287 case Expression::kTest: 301 case Expression::kTest:
302 // For simplicity we always test the accumulator register.
288 __ mov(result_register(), lit->handle()); 303 __ mov(result_register(), lit->handle());
289 DoTest(context); 304 DoTest(context);
290 break; 305 break;
291 306
292 case Expression::kValueTest: 307 case Expression::kValueTest:
293 case Expression::kTestValue: 308 case Expression::kTestValue:
294 __ mov(result_register(), lit->handle()); 309 __ mov(result_register(), lit->handle());
295 __ push(result_register()); 310 switch (location_) {
311 case kAccumulator:
312 break;
313 case kStack:
314 __ push(result_register());
315 break;
316 }
296 DoTest(context); 317 DoTest(context);
297 break; 318 break;
298 } 319 }
299 } 320 }
300 321
301 322
302 void FastCodeGenerator::ApplyTOS(Expression::Context context) { 323 void FastCodeGenerator::ApplyTOS(Expression::Context context) {
303 switch (context) { 324 switch (context) {
304 case Expression::kUninitialized: 325 case Expression::kUninitialized:
305 UNREACHABLE(); 326 UNREACHABLE();
306 327
307 case Expression::kEffect: 328 case Expression::kEffect:
308 __ Drop(1); 329 __ Drop(1);
309 break; 330 break;
310 331
311 case Expression::kValue: 332 case Expression::kValue:
312 switch (location_) { 333 switch (location_) {
313 case kAccumulator: 334 case kAccumulator:
314 __ pop(result_register()); 335 __ pop(result_register());
315 break; 336 break;
316 case kStack: 337 case kStack:
317 break; 338 break;
318 } 339 }
319 break; 340 break;
320 341
321 case Expression::kTest: 342 case Expression::kTest:
343 // For simplicity we always test the accumulator register.
322 __ pop(result_register()); 344 __ pop(result_register());
323 DoTest(context); 345 DoTest(context);
324 break; 346 break;
325 347
326 case Expression::kValueTest: 348 case Expression::kValueTest:
327 case Expression::kTestValue: 349 case Expression::kTestValue:
328 __ mov(result_register(), Operand(esp, 0)); 350 switch (location_) {
351 case kAccumulator:
352 __ pop(result_register());
353 break;
354 case kStack:
355 __ mov(result_register(), Operand(esp, 0));
356 break;
357 }
329 DoTest(context); 358 DoTest(context);
330 break; 359 break;
331 } 360 }
332 } 361 }
333 362
334 363
335 void FastCodeGenerator::DropAndApply(int count, 364 void FastCodeGenerator::DropAndApply(int count,
336 Expression::Context context, 365 Expression::Context context,
337 Register reg) { 366 Register reg) {
338 ASSERT(count > 0); 367 ASSERT(count > 0);
(...skipping 13 matching lines...) Expand all
352 if (!reg.is(result_register())) __ mov(result_register(), reg); 381 if (!reg.is(result_register())) __ mov(result_register(), reg);
353 break; 382 break;
354 case kStack: 383 case kStack:
355 if (count > 1) __ Drop(count - 1); 384 if (count > 1) __ Drop(count - 1);
356 __ mov(Operand(esp, 0), reg); 385 __ mov(Operand(esp, 0), reg);
357 break; 386 break;
358 } 387 }
359 break; 388 break;
360 389
361 case Expression::kTest: 390 case Expression::kTest:
391 // For simplicity we always test the accumulator register.
362 __ Drop(count); 392 __ Drop(count);
363 if (!reg.is(result_register())) __ mov(result_register(), reg); 393 if (!reg.is(result_register())) __ mov(result_register(), reg);
364 DoTest(context); 394 DoTest(context);
365 break; 395 break;
366 396
367 case Expression::kValueTest: 397 case Expression::kValueTest:
368 case Expression::kTestValue: 398 case Expression::kTestValue:
369 if (count > 1) __ Drop(count - 1); 399 switch (location_) {
370 if (!reg.is(result_register())) __ mov(result_register(), reg); 400 case kAccumulator:
371 __ mov(Operand(esp, 0), result_register()); 401 __ Drop(count);
402 if (!reg.is(result_register())) __ mov(result_register(), reg);
403 break;
404 case kStack:
405 if (count > 1) __ Drop(count - 1);
406 __ mov(result_register(), reg);
407 __ mov(Operand(esp, 0), result_register());
408 break;
409 }
372 DoTest(context); 410 DoTest(context);
373 break; 411 break;
374 } 412 }
375 } 413 }
376 414
377 415
378 void FastCodeGenerator::Apply(Expression::Context context, 416 void FastCodeGenerator::Apply(Expression::Context context,
379 Label* materialize_true, 417 Label* materialize_true,
380 Label* materialize_false) { 418 Label* materialize_false) {
381 switch (context) { 419 switch (context) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
433 __ push(Immediate(Factory::false_value())); 471 __ push(Immediate(Factory::false_value()));
434 break; 472 break;
435 } 473 }
436 __ jmp(false_label_); 474 __ jmp(false_label_);
437 break; 475 break;
438 } 476 }
439 } 477 }
440 478
441 479
442 void FastCodeGenerator::DoTest(Expression::Context context) { 480 void FastCodeGenerator::DoTest(Expression::Context context) {
443 // The value to test is in the accumulator, and duplicated on the stack if 481 // The value to test is in the accumulator. If the value might be needed
444 // necessary (for value/test and test/value contexts). 482 // on the stack (value/test and test/value contexts with a stack location
483 // desired), then the value is already duplicated on the stack.
445 ASSERT_NE(NULL, true_label_); 484 ASSERT_NE(NULL, true_label_);
446 ASSERT_NE(NULL, false_label_); 485 ASSERT_NE(NULL, false_label_);
447 486
448 // If there is a value on the stack, use a discard label for the 487 // In value/test and test/value expression contexts with stack as the
449 // value-is-unneeded branch in the inlined part of the test. 488 // desired location, there is already an extra value on the stack. Use a
489 // label to discard it if unneeded.
450 Label discard; 490 Label discard;
451 Label* if_true = 491 Label* if_true = true_label_;
452 (context == Expression::kTestValue) ? &discard : true_label_; 492 Label* if_false = false_label_;
453 Label* if_false = 493 switch (context) {
454 (context == Expression::kValueTest) ? &discard : false_label_; 494 case Expression::kUninitialized:
495 case Expression::kEffect:
496 case Expression::kValue:
497 UNREACHABLE();
498 case Expression::kTest:
499 break;
500 case Expression::kValueTest:
501 switch (location_) {
502 case kAccumulator:
503 break;
504 case kStack:
505 if_false = &discard;
506 break;
507 }
508 break;
509 case Expression::kTestValue:
510 switch (location_) {
511 case kAccumulator:
512 break;
513 case kStack:
514 if_true = &discard;
515 break;
516 }
517 break;
518 }
455 519
456 // Emit the inlined tests assumed by the stub. 520 // Emit the inlined tests assumed by the stub.
457 __ cmp(result_register(), Factory::undefined_value()); 521 __ cmp(result_register(), Factory::undefined_value());
458 __ j(equal, if_false); 522 __ j(equal, if_false);
459 __ cmp(result_register(), Factory::true_value()); 523 __ cmp(result_register(), Factory::true_value());
460 __ j(equal, if_true); 524 __ j(equal, if_true);
461 __ cmp(result_register(), Factory::false_value()); 525 __ cmp(result_register(), Factory::false_value());
462 __ j(equal, if_false); 526 __ j(equal, if_false);
463 ASSERT_EQ(0, kSmiTag); 527 ASSERT_EQ(0, kSmiTag);
464 __ test(result_register(), Operand(result_register())); 528 __ test(result_register(), Operand(result_register()));
465 __ j(zero, if_false); 529 __ j(zero, if_false);
466 __ test(result_register(), Immediate(kSmiTagMask)); 530 __ test(result_register(), Immediate(kSmiTagMask));
467 __ j(zero, if_true); 531 __ j(zero, if_true);
468 532
533 // Save a copy of the value if it may be needed and isn't already saved.
534 switch (context) {
535 case Expression::kUninitialized:
536 case Expression::kEffect:
537 case Expression::kValue:
538 UNREACHABLE();
539 case Expression::kTest:
540 break;
541 case Expression::kValueTest:
542 switch (location_) {
543 case kAccumulator:
544 __ push(result_register());
545 break;
546 case kStack:
547 break;
548 }
549 break;
550 case Expression::kTestValue:
551 switch (location_) {
552 case kAccumulator:
553 __ push(result_register());
554 break;
555 case kStack:
556 break;
557 }
558 break;
559 }
560
469 // Call the ToBoolean stub for all other cases. 561 // Call the ToBoolean stub for all other cases.
470 ToBooleanStub stub; 562 ToBooleanStub stub;
471 __ push(result_register()); 563 __ push(result_register());
472 __ CallStub(&stub); 564 __ CallStub(&stub);
473 __ test(eax, Operand(eax)); 565 __ test(eax, Operand(eax));
474 566
475 // The stub returns nonzero for true. Complete based on the context. 567 // The stub returns nonzero for true. Complete based on the context.
476 switch (context) { 568 switch (context) {
477 case Expression::kUninitialized: 569 case Expression::kUninitialized:
478 case Expression::kEffect: 570 case Expression::kEffect:
(...skipping 1232 matching lines...) Expand 10 before | Expand all | Expand 10 after
1711 __ add(Operand(edx), Immediate(masm_->CodeObject())); 1803 __ add(Operand(edx), Immediate(masm_->CodeObject()));
1712 __ mov(Operand(esp, 0), edx); 1804 __ mov(Operand(esp, 0), edx);
1713 // And return. 1805 // And return.
1714 __ ret(0); 1806 __ ret(0);
1715 } 1807 }
1716 1808
1717 1809
1718 #undef __ 1810 #undef __
1719 1811
1720 } } // namespace v8::internal 1812 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « no previous file | src/x64/fast-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698