OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/code-generator.h" | 5 #include "src/compiler/code-generator.h" |
6 | 6 |
7 #include "src/ast/scopes.h" | 7 #include "src/ast/scopes.h" |
8 #include "src/compiler/code-generator-impl.h" | 8 #include "src/compiler/code-generator-impl.h" |
9 #include "src/compiler/gap-resolver.h" | 9 #include "src/compiler/gap-resolver.h" |
10 #include "src/compiler/node-matchers.h" | 10 #include "src/compiler/node-matchers.h" |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 auto index1 = i.InputRegister(1); \ | 379 auto index1 = i.InputRegister(1); \ |
380 auto index2 = i.InputUint32(2); \ | 380 auto index2 = i.InputUint32(2); \ |
381 OutOfLineCode* ool; \ | 381 OutOfLineCode* ool; \ |
382 if (instr->InputAt(3)->IsRegister()) { \ | 382 if (instr->InputAt(3)->IsRegister()) { \ |
383 auto length = i.InputRegister(3); \ | 383 auto length = i.InputRegister(3); \ |
384 DCHECK_EQ(0, index2); \ | 384 DCHECK_EQ(0, index2); \ |
385 __ cmpl(index1, length); \ | 385 __ cmpl(index1, length); \ |
386 ool = new (zone()) OutOfLineLoadNaN(this, result); \ | 386 ool = new (zone()) OutOfLineLoadNaN(this, result); \ |
387 } else { \ | 387 } else { \ |
388 auto length = i.InputUint32(3); \ | 388 auto length = i.InputUint32(3); \ |
| 389 RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode(); \ |
389 DCHECK_LE(index2, length); \ | 390 DCHECK_LE(index2, length); \ |
390 __ cmpl(index1, Immediate(length - index2)); \ | 391 __ cmpl(index1, Immediate(length - index2, rmode)); \ |
391 class OutOfLineLoadFloat final : public OutOfLineCode { \ | 392 class OutOfLineLoadFloat final : public OutOfLineCode { \ |
392 public: \ | 393 public: \ |
393 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ | 394 OutOfLineLoadFloat(CodeGenerator* gen, XMMRegister result, \ |
394 Register buffer, Register index1, int32_t index2, \ | 395 Register buffer, Register index1, int32_t index2, \ |
395 int32_t length) \ | 396 int32_t length, RelocInfo::Mode rmode) \ |
396 : OutOfLineCode(gen), \ | 397 : OutOfLineCode(gen), \ |
397 result_(result), \ | 398 result_(result), \ |
398 buffer_(buffer), \ | 399 buffer_(buffer), \ |
399 index1_(index1), \ | 400 index1_(index1), \ |
400 index2_(index2), \ | 401 index2_(index2), \ |
401 length_(length) {} \ | 402 length_(length), \ |
| 403 rmode_(rmode) {} \ |
402 \ | 404 \ |
403 void Generate() final { \ | 405 void Generate() final { \ |
404 __ leal(kScratchRegister, Operand(index1_, index2_)); \ | 406 __ leal(kScratchRegister, Operand(index1_, index2_)); \ |
405 __ Pcmpeqd(result_, result_); \ | 407 __ Pcmpeqd(result_, result_); \ |
406 __ cmpl(kScratchRegister, Immediate(length_)); \ | 408 __ cmpl(kScratchRegister, Immediate(length_, rmode_)); \ |
407 __ j(above_equal, exit()); \ | 409 __ j(above_equal, exit()); \ |
408 __ asm_instr(result_, \ | 410 __ asm_instr(result_, \ |
409 Operand(buffer_, kScratchRegister, times_1, 0)); \ | 411 Operand(buffer_, kScratchRegister, times_1, 0)); \ |
410 } \ | 412 } \ |
411 \ | 413 \ |
412 private: \ | 414 private: \ |
413 XMMRegister const result_; \ | 415 XMMRegister const result_; \ |
414 Register const buffer_; \ | 416 Register const buffer_; \ |
415 Register const index1_; \ | 417 Register const index1_; \ |
416 int32_t const index2_; \ | 418 int32_t const index2_; \ |
417 int32_t const length_; \ | 419 int32_t const length_; \ |
| 420 RelocInfo::Mode rmode_; \ |
418 }; \ | 421 }; \ |
419 ool = new (zone()) \ | 422 ool = new (zone()) OutOfLineLoadFloat(this, result, buffer, index1, \ |
420 OutOfLineLoadFloat(this, result, buffer, index1, index2, length); \ | 423 index2, length, rmode); \ |
421 } \ | 424 } \ |
422 __ j(above_equal, ool->entry()); \ | 425 __ j(above_equal, ool->entry()); \ |
423 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ | 426 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ |
424 __ bind(ool->exit()); \ | 427 __ bind(ool->exit()); \ |
425 } while (false) | 428 } while (false) |
426 | 429 |
427 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ | 430 #define ASSEMBLE_CHECKED_LOAD_INTEGER(asm_instr) \ |
428 do { \ | 431 do { \ |
429 auto result = i.OutputRegister(); \ | 432 auto result = i.OutputRegister(); \ |
430 auto buffer = i.InputRegister(0); \ | 433 auto buffer = i.InputRegister(0); \ |
431 auto index1 = i.InputRegister(1); \ | 434 auto index1 = i.InputRegister(1); \ |
432 auto index2 = i.InputUint32(2); \ | 435 auto index2 = i.InputUint32(2); \ |
433 OutOfLineCode* ool; \ | 436 OutOfLineCode* ool; \ |
434 if (instr->InputAt(3)->IsRegister()) { \ | 437 if (instr->InputAt(3)->IsRegister()) { \ |
435 auto length = i.InputRegister(3); \ | 438 auto length = i.InputRegister(3); \ |
436 DCHECK_EQ(0, index2); \ | 439 DCHECK_EQ(0, index2); \ |
437 __ cmpl(index1, length); \ | 440 __ cmpl(index1, length); \ |
438 ool = new (zone()) OutOfLineLoadZero(this, result); \ | 441 ool = new (zone()) OutOfLineLoadZero(this, result); \ |
439 } else { \ | 442 } else { \ |
440 auto length = i.InputUint32(3); \ | 443 auto length = i.InputUint32(3); \ |
| 444 RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode(); \ |
441 DCHECK_LE(index2, length); \ | 445 DCHECK_LE(index2, length); \ |
442 __ cmpl(index1, Immediate(length - index2)); \ | 446 __ cmpl(index1, Immediate(length - index2, rmode)); \ |
443 class OutOfLineLoadInteger final : public OutOfLineCode { \ | 447 class OutOfLineLoadInteger final : public OutOfLineCode { \ |
444 public: \ | 448 public: \ |
445 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ | 449 OutOfLineLoadInteger(CodeGenerator* gen, Register result, \ |
446 Register buffer, Register index1, int32_t index2, \ | 450 Register buffer, Register index1, int32_t index2, \ |
447 int32_t length) \ | 451 int32_t length, RelocInfo::Mode rmode) \ |
448 : OutOfLineCode(gen), \ | 452 : OutOfLineCode(gen), \ |
449 result_(result), \ | 453 result_(result), \ |
450 buffer_(buffer), \ | 454 buffer_(buffer), \ |
451 index1_(index1), \ | 455 index1_(index1), \ |
452 index2_(index2), \ | 456 index2_(index2), \ |
453 length_(length) {} \ | 457 length_(length), \ |
| 458 rmode_(rmode) {} \ |
454 \ | 459 \ |
455 void Generate() final { \ | 460 void Generate() final { \ |
456 Label oob; \ | 461 Label oob; \ |
457 __ leal(kScratchRegister, Operand(index1_, index2_)); \ | 462 __ leal(kScratchRegister, Operand(index1_, index2_)); \ |
458 __ cmpl(kScratchRegister, Immediate(length_)); \ | 463 __ cmpl(kScratchRegister, Immediate(length_, rmode_)); \ |
459 __ j(above_equal, &oob, Label::kNear); \ | 464 __ j(above_equal, &oob, Label::kNear); \ |
460 __ asm_instr(result_, \ | 465 __ asm_instr(result_, \ |
461 Operand(buffer_, kScratchRegister, times_1, 0)); \ | 466 Operand(buffer_, kScratchRegister, times_1, 0)); \ |
462 __ jmp(exit()); \ | 467 __ jmp(exit()); \ |
463 __ bind(&oob); \ | 468 __ bind(&oob); \ |
464 __ xorl(result_, result_); \ | 469 __ xorl(result_, result_); \ |
465 } \ | 470 } \ |
466 \ | 471 \ |
467 private: \ | 472 private: \ |
468 Register const result_; \ | 473 Register const result_; \ |
469 Register const buffer_; \ | 474 Register const buffer_; \ |
470 Register const index1_; \ | 475 Register const index1_; \ |
471 int32_t const index2_; \ | 476 int32_t const index2_; \ |
472 int32_t const length_; \ | 477 int32_t const length_; \ |
| 478 RelocInfo::Mode const rmode_; \ |
473 }; \ | 479 }; \ |
474 ool = new (zone()) \ | 480 ool = new (zone()) OutOfLineLoadInteger(this, result, buffer, index1, \ |
475 OutOfLineLoadInteger(this, result, buffer, index1, index2, length); \ | 481 index2, length, rmode); \ |
476 } \ | 482 } \ |
477 __ j(above_equal, ool->entry()); \ | 483 __ j(above_equal, ool->entry()); \ |
478 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ | 484 __ asm_instr(result, Operand(buffer, index1, times_1, index2)); \ |
479 __ bind(ool->exit()); \ | 485 __ bind(ool->exit()); \ |
480 } while (false) | 486 } while (false) |
481 | 487 |
482 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ | 488 #define ASSEMBLE_CHECKED_STORE_FLOAT(asm_instr) \ |
483 do { \ | 489 do { \ |
484 auto buffer = i.InputRegister(0); \ | 490 auto buffer = i.InputRegister(0); \ |
485 auto index1 = i.InputRegister(1); \ | 491 auto index1 = i.InputRegister(1); \ |
486 auto index2 = i.InputUint32(2); \ | 492 auto index2 = i.InputUint32(2); \ |
487 auto value = i.InputDoubleRegister(4); \ | 493 auto value = i.InputDoubleRegister(4); \ |
488 if (instr->InputAt(3)->IsRegister()) { \ | 494 if (instr->InputAt(3)->IsRegister()) { \ |
489 auto length = i.InputRegister(3); \ | 495 auto length = i.InputRegister(3); \ |
490 DCHECK_EQ(0, index2); \ | 496 DCHECK_EQ(0, index2); \ |
491 Label done; \ | 497 Label done; \ |
492 __ cmpl(index1, length); \ | 498 __ cmpl(index1, length); \ |
493 __ j(above_equal, &done, Label::kNear); \ | 499 __ j(above_equal, &done, Label::kNear); \ |
494 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 500 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
495 __ bind(&done); \ | 501 __ bind(&done); \ |
496 } else { \ | 502 } else { \ |
497 auto length = i.InputUint32(3); \ | 503 auto length = i.InputUint32(3); \ |
| 504 RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode(); \ |
498 DCHECK_LE(index2, length); \ | 505 DCHECK_LE(index2, length); \ |
499 __ cmpl(index1, Immediate(length - index2)); \ | 506 __ cmpl(index1, Immediate(length - index2, rmode)); \ |
500 class OutOfLineStoreFloat final : public OutOfLineCode { \ | 507 class OutOfLineStoreFloat final : public OutOfLineCode { \ |
501 public: \ | 508 public: \ |
502 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \ | 509 OutOfLineStoreFloat(CodeGenerator* gen, Register buffer, \ |
503 Register index1, int32_t index2, int32_t length, \ | 510 Register index1, int32_t index2, int32_t length, \ |
504 XMMRegister value) \ | 511 XMMRegister value, RelocInfo::Mode rmode) \ |
505 : OutOfLineCode(gen), \ | 512 : OutOfLineCode(gen), \ |
506 buffer_(buffer), \ | 513 buffer_(buffer), \ |
507 index1_(index1), \ | 514 index1_(index1), \ |
508 index2_(index2), \ | 515 index2_(index2), \ |
509 length_(length), \ | 516 length_(length), \ |
510 value_(value) {} \ | 517 value_(value), \ |
| 518 rmode_(rmode) {} \ |
511 \ | 519 \ |
512 void Generate() final { \ | 520 void Generate() final { \ |
513 __ leal(kScratchRegister, Operand(index1_, index2_)); \ | 521 __ leal(kScratchRegister, Operand(index1_, index2_)); \ |
514 __ cmpl(kScratchRegister, Immediate(length_)); \ | 522 __ cmpl(kScratchRegister, Immediate(length_, rmode_)); \ |
515 __ j(above_equal, exit()); \ | 523 __ j(above_equal, exit()); \ |
516 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ | 524 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ |
517 value_); \ | 525 value_); \ |
518 } \ | 526 } \ |
519 \ | 527 \ |
520 private: \ | 528 private: \ |
521 Register const buffer_; \ | 529 Register const buffer_; \ |
522 Register const index1_; \ | 530 Register const index1_; \ |
523 int32_t const index2_; \ | 531 int32_t const index2_; \ |
524 int32_t const length_; \ | 532 int32_t const length_; \ |
525 XMMRegister const value_; \ | 533 XMMRegister const value_; \ |
| 534 RelocInfo::Mode rmode_; \ |
526 }; \ | 535 }; \ |
527 auto ool = new (zone()) \ | 536 auto ool = new (zone()) OutOfLineStoreFloat( \ |
528 OutOfLineStoreFloat(this, buffer, index1, index2, length, value); \ | 537 this, buffer, index1, index2, length, value, rmode); \ |
529 __ j(above_equal, ool->entry()); \ | 538 __ j(above_equal, ool->entry()); \ |
530 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 539 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
531 __ bind(ool->exit()); \ | 540 __ bind(ool->exit()); \ |
532 } \ | 541 } \ |
533 } while (false) | 542 } while (false) |
534 | 543 |
535 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \ | 544 #define ASSEMBLE_CHECKED_STORE_INTEGER_IMPL(asm_instr, Value) \ |
536 do { \ | 545 do { \ |
537 auto buffer = i.InputRegister(0); \ | 546 auto buffer = i.InputRegister(0); \ |
538 auto index1 = i.InputRegister(1); \ | 547 auto index1 = i.InputRegister(1); \ |
539 auto index2 = i.InputUint32(2); \ | 548 auto index2 = i.InputUint32(2); \ |
540 if (instr->InputAt(3)->IsRegister()) { \ | 549 if (instr->InputAt(3)->IsRegister()) { \ |
541 auto length = i.InputRegister(3); \ | 550 auto length = i.InputRegister(3); \ |
542 DCHECK_EQ(0, index2); \ | 551 DCHECK_EQ(0, index2); \ |
543 Label done; \ | 552 Label done; \ |
544 __ cmpl(index1, length); \ | 553 __ cmpl(index1, length); \ |
545 __ j(above_equal, &done, Label::kNear); \ | 554 __ j(above_equal, &done, Label::kNear); \ |
546 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 555 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
547 __ bind(&done); \ | 556 __ bind(&done); \ |
548 } else { \ | 557 } else { \ |
549 auto length = i.InputUint32(3); \ | 558 auto length = i.InputUint32(3); \ |
| 559 RelocInfo::Mode rmode = i.ToConstant(instr->InputAt(3)).rmode(); \ |
550 DCHECK_LE(index2, length); \ | 560 DCHECK_LE(index2, length); \ |
551 __ cmpl(index1, Immediate(length - index2)); \ | 561 __ cmpl(index1, Immediate(length - index2, rmode)); \ |
552 class OutOfLineStoreInteger final : public OutOfLineCode { \ | 562 class OutOfLineStoreInteger final : public OutOfLineCode { \ |
553 public: \ | 563 public: \ |
554 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \ | 564 OutOfLineStoreInteger(CodeGenerator* gen, Register buffer, \ |
555 Register index1, int32_t index2, int32_t length, \ | 565 Register index1, int32_t index2, int32_t length, \ |
556 Value value) \ | 566 Value value, RelocInfo::Mode rmode) \ |
557 : OutOfLineCode(gen), \ | 567 : OutOfLineCode(gen), \ |
558 buffer_(buffer), \ | 568 buffer_(buffer), \ |
559 index1_(index1), \ | 569 index1_(index1), \ |
560 index2_(index2), \ | 570 index2_(index2), \ |
561 length_(length), \ | 571 length_(length), \ |
562 value_(value) {} \ | 572 value_(value), \ |
| 573 rmode_(rmode) {} \ |
563 \ | 574 \ |
564 void Generate() final { \ | 575 void Generate() final { \ |
565 __ leal(kScratchRegister, Operand(index1_, index2_)); \ | 576 __ leal(kScratchRegister, Operand(index1_, index2_)); \ |
566 __ cmpl(kScratchRegister, Immediate(length_)); \ | 577 __ cmpl(kScratchRegister, Immediate(length_, rmode_)); \ |
567 __ j(above_equal, exit()); \ | 578 __ j(above_equal, exit()); \ |
568 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ | 579 __ asm_instr(Operand(buffer_, kScratchRegister, times_1, 0), \ |
569 value_); \ | 580 value_); \ |
570 } \ | 581 } \ |
571 \ | 582 \ |
572 private: \ | 583 private: \ |
573 Register const buffer_; \ | 584 Register const buffer_; \ |
574 Register const index1_; \ | 585 Register const index1_; \ |
575 int32_t const index2_; \ | 586 int32_t const index2_; \ |
576 int32_t const length_; \ | 587 int32_t const length_; \ |
577 Value const value_; \ | 588 Value const value_; \ |
| 589 RelocInfo::Mode rmode_; \ |
578 }; \ | 590 }; \ |
579 auto ool = new (zone()) \ | 591 auto ool = new (zone()) OutOfLineStoreInteger( \ |
580 OutOfLineStoreInteger(this, buffer, index1, index2, length, value); \ | 592 this, buffer, index1, index2, length, value, rmode); \ |
581 __ j(above_equal, ool->entry()); \ | 593 __ j(above_equal, ool->entry()); \ |
582 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ | 594 __ asm_instr(Operand(buffer, index1, times_1, index2), value); \ |
583 __ bind(ool->exit()); \ | 595 __ bind(ool->exit()); \ |
584 } \ | 596 } \ |
585 } while (false) | 597 } while (false) |
586 | 598 |
587 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ | 599 #define ASSEMBLE_CHECKED_STORE_INTEGER(asm_instr) \ |
588 do { \ | 600 do { \ |
589 if (instr->InputAt(4)->IsRegister()) { \ | 601 if (instr->InputAt(4)->IsRegister()) { \ |
590 Register value = i.InputRegister(4); \ | 602 Register value = i.InputRegister(4); \ |
(...skipping 1756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2347 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; | 2359 int padding_size = last_lazy_deopt_pc_ + space_needed - current_pc; |
2348 __ Nop(padding_size); | 2360 __ Nop(padding_size); |
2349 } | 2361 } |
2350 } | 2362 } |
2351 | 2363 |
2352 #undef __ | 2364 #undef __ |
2353 | 2365 |
2354 } // namespace compiler | 2366 } // namespace compiler |
2355 } // namespace internal | 2367 } // namespace internal |
2356 } // namespace v8 | 2368 } // namespace v8 |
OLD | NEW |