| 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 |