| OLD | NEW |
| 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 324 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 | 335 |
| 336 ASSERT(!overflow()); | 336 ASSERT(!overflow()); |
| 337 } | 337 } |
| 338 | 338 |
| 339 | 339 |
| 340 void Assembler::emit_operand(int rm, const Operand& adr) { | 340 void Assembler::emit_operand(int rm, const Operand& adr) { |
| 341 ASSERT_EQ(rm & 0x07, rm); | 341 ASSERT_EQ(rm & 0x07, rm); |
| 342 const unsigned length = adr.len_; | 342 const unsigned length = adr.len_; |
| 343 ASSERT(length > 0); | 343 ASSERT(length > 0); |
| 344 | 344 |
| 345 // Emit updated ModRM byte containing the given register. | 345 // Emit updated ModR/M byte containing the given register. |
| 346 pc_[0] = (adr.buf_[0] & ~0x38) | (rm << 3); | 346 pc_[0] = (adr.buf_[0] & ~0x38) | (rm << 3); |
| 347 | 347 |
| 348 // Emit the rest of the encoded operand. | 348 // Emit the rest of the encoded operand. |
| 349 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; | 349 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; |
| 350 pc_ += length; | 350 pc_ += length; |
| 351 } | 351 } |
| 352 | 352 |
| 353 | 353 |
| 354 // Assembler Instruction implementations | 354 // Assembler Instruction implementations |
| 355 | 355 |
| 356 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { | 356 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { |
| 357 EnsureSpace ensure_space(this); | 357 EnsureSpace ensure_space(this); |
| 358 last_pc_ = pc_; | 358 last_pc_ = pc_; |
| 359 emit_rex_64(reg, op); | 359 emit_rex_64(reg, op); |
| 360 emit(opcode); | 360 emit(opcode); |
| 361 emit_operand(reg, op); | 361 emit_operand(reg, op); |
| 362 } | 362 } |
| 363 | 363 |
| 364 | 364 |
| 365 void Assembler::arithmetic_op(byte opcode, Register dst, Register src) { | 365 void Assembler::arithmetic_op(byte opcode, Register dst, Register src) { |
| 366 EnsureSpace ensure_space(this); | 366 EnsureSpace ensure_space(this); |
| 367 last_pc_ = pc_; | 367 last_pc_ = pc_; |
| 368 emit_rex_64(dst, src); | 368 emit_rex_64(dst, src); |
| 369 emit(opcode); | 369 emit(opcode); |
| 370 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); | 370 emit_modrm(dst, src); |
| 371 } | 371 } |
| 372 | 372 |
| 373 void Assembler::immediate_arithmetic_op(byte subcode, | 373 void Assembler::immediate_arithmetic_op(byte subcode, |
| 374 Register dst, | 374 Register dst, |
| 375 Immediate src) { | 375 Immediate src) { |
| 376 EnsureSpace ensure_space(this); | 376 EnsureSpace ensure_space(this); |
| 377 last_pc_ = pc_; | 377 last_pc_ = pc_; |
| 378 emit_rex_64(dst); | 378 emit_rex_64(dst); |
| 379 if (is_int8(src.value_)) { | 379 if (is_int8(src.value_)) { |
| 380 emit(0x83); | 380 emit(0x83); |
| 381 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7)); | 381 emit_modrm(subcode, dst); |
| 382 emit(src.value_); | 382 emit(src.value_); |
| 383 } else if (dst.is(rax)) { | 383 } else if (dst.is(rax)) { |
| 384 emit(0x05 | (subcode << 3)); | 384 emit(0x05 | (subcode << 3)); |
| 385 emitl(src.value_); | 385 emitl(src.value_); |
| 386 } else { | 386 } else { |
| 387 emit(0x81); | 387 emit(0x81); |
| 388 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7)); | 388 emit_modrm(subcode, dst); |
| 389 emitl(src.value_); | 389 emitl(src.value_); |
| 390 } | 390 } |
| 391 } | 391 } |
| 392 | 392 |
| 393 void Assembler::immediate_arithmetic_op(byte subcode, | 393 void Assembler::immediate_arithmetic_op(byte subcode, |
| 394 const Operand& dst, | 394 const Operand& dst, |
| 395 Immediate src) { | 395 Immediate src) { |
| 396 EnsureSpace ensure_space(this); | 396 EnsureSpace ensure_space(this); |
| 397 last_pc_ = pc_; | 397 last_pc_ = pc_; |
| 398 emit_rex_64(dst); | 398 emit_rex_64(dst); |
| 399 if (is_int8(src.value_)) { | 399 if (is_int8(src.value_)) { |
| 400 emit(0x83); | 400 emit(0x83); |
| 401 emit_operand(Register::toRegister(subcode), dst); | 401 emit_operand(Register::toRegister(subcode), dst); |
| 402 emit(src.value_); | 402 emit(src.value_); |
| 403 } else { | 403 } else { |
| 404 emit(0x81); | 404 emit(0x81); |
| 405 emit_operand(Register::toRegister(subcode), dst); | 405 emit_operand(Register::toRegister(subcode), dst); |
| 406 emitl(src.value_); | 406 emitl(src.value_); |
| 407 } | 407 } |
| 408 } | 408 } |
| 409 | 409 |
| 410 | 410 |
| 411 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) { | 411 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) { |
| 412 EnsureSpace ensure_space(this); | 412 EnsureSpace ensure_space(this); |
| 413 last_pc_ = pc_; | 413 last_pc_ = pc_; |
| 414 ASSERT(is_uint6(shift_amount.value_)); // illegal shift count | 414 ASSERT(is_uint6(shift_amount.value_)); // illegal shift count |
| 415 if (shift_amount.value_ == 1) { | 415 if (shift_amount.value_ == 1) { |
| 416 emit_rex_64(dst); | 416 emit_rex_64(dst); |
| 417 emit(0xD1); | 417 emit(0xD1); |
| 418 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7)); | 418 emit_modrm(subcode, dst); |
| 419 } else { | 419 } else { |
| 420 emit_rex_64(dst); | 420 emit_rex_64(dst); |
| 421 emit(0xC1); | 421 emit(0xC1); |
| 422 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7)); | 422 emit_modrm(subcode, dst); |
| 423 emit(shift_amount.value_); | 423 emit(shift_amount.value_); |
| 424 } | 424 } |
| 425 } | 425 } |
| 426 | 426 |
| 427 | 427 |
| 428 void Assembler::shift(Register dst, int subcode) { | 428 void Assembler::shift(Register dst, int subcode) { |
| 429 EnsureSpace ensure_space(this); | 429 EnsureSpace ensure_space(this); |
| 430 last_pc_ = pc_; | 430 last_pc_ = pc_; |
| 431 emit_rex_64(dst); | 431 emit_rex_64(dst); |
| 432 emit(0xD3); | 432 emit(0xD3); |
| 433 emit(0xC0 | (subcode << 3) | (dst.code() & 0x7)); | 433 emit_modrm(subcode, dst); |
| 434 } | 434 } |
| 435 | 435 |
| 436 | 436 |
| 437 void Assembler::bt(const Operand& dst, Register src) { | 437 void Assembler::bt(const Operand& dst, Register src) { |
| 438 EnsureSpace ensure_space(this); | 438 EnsureSpace ensure_space(this); |
| 439 last_pc_ = pc_; | 439 last_pc_ = pc_; |
| 440 emit_rex_64(src, dst); | 440 emit_rex_64(src, dst); |
| 441 emit(0x0F); | 441 emit(0x0F); |
| 442 emit(0xA3); | 442 emit(0xA3); |
| 443 emit_operand(src, dst); | 443 emit_operand(src, dst); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 472 emitl(current); | 472 emitl(current); |
| 473 L->link_to(current); | 473 L->link_to(current); |
| 474 } | 474 } |
| 475 } | 475 } |
| 476 | 476 |
| 477 | 477 |
| 478 void Assembler::call(Register adr) { | 478 void Assembler::call(Register adr) { |
| 479 EnsureSpace ensure_space(this); | 479 EnsureSpace ensure_space(this); |
| 480 last_pc_ = pc_; | 480 last_pc_ = pc_; |
| 481 // Opcode: FF /2 r64 | 481 // Opcode: FF /2 r64 |
| 482 if (!is_uint3(adr.code())) { | 482 if (adr.code() > 7) { |
| 483 emit_rex_64(adr); | 483 emit_rex_64(adr); |
| 484 } | 484 } |
| 485 emit(0xFF); | 485 emit(0xFF); |
| 486 emit(0xD0 | (adr.code() & 0x07)); | 486 emit_modrm(0x2, adr); |
| 487 } | 487 } |
| 488 | 488 |
| 489 | 489 |
| 490 void Assembler::cpuid() { | 490 void Assembler::cpuid() { |
| 491 ASSERT(CpuFeatures::IsEnabled(CpuFeatures::CPUID)); | 491 ASSERT(CpuFeatures::IsEnabled(CpuFeatures::CPUID)); |
| 492 EnsureSpace ensure_space(this); | 492 EnsureSpace ensure_space(this); |
| 493 last_pc_ = pc_; | 493 last_pc_ = pc_; |
| 494 emit(0x0F); | 494 emit(0x0F); |
| 495 emit(0xA2); | 495 emit(0xA2); |
| 496 } | 496 } |
| 497 | 497 |
| 498 | 498 |
| 499 void Assembler::cqo() { | 499 void Assembler::cqo() { |
| 500 EnsureSpace ensure_space(this); | 500 EnsureSpace ensure_space(this); |
| 501 last_pc_ = pc_; | 501 last_pc_ = pc_; |
| 502 emit_rex_64(); | 502 emit_rex_64(); |
| 503 emit(0x99); | 503 emit(0x99); |
| 504 } | 504 } |
| 505 | 505 |
| 506 | 506 |
| 507 void Assembler::dec(Register dst) { | 507 void Assembler::dec(Register dst) { |
| 508 EnsureSpace ensure_space(this); | 508 EnsureSpace ensure_space(this); |
| 509 last_pc_ = pc_; | 509 last_pc_ = pc_; |
| 510 emit_rex_64(dst); | 510 emit_rex_64(dst); |
| 511 emit(0xFF); | 511 emit(0xFF); |
| 512 emit(0xC8 | (dst.code() & 0x7)); | 512 emit_modrm(0x1, dst); |
| 513 } | 513 } |
| 514 | 514 |
| 515 | 515 |
| 516 void Assembler::dec(const Operand& dst) { | 516 void Assembler::dec(const Operand& dst) { |
| 517 EnsureSpace ensure_space(this); | 517 EnsureSpace ensure_space(this); |
| 518 last_pc_ = pc_; | 518 last_pc_ = pc_; |
| 519 emit_rex_64(dst); | 519 emit_rex_64(dst); |
| 520 emit(0xFF); | 520 emit(0xFF); |
| 521 emit_operand(1, dst); | 521 emit_operand(1, dst); |
| 522 } | 522 } |
| 523 | 523 |
| 524 | 524 |
| 525 void Assembler::enter(Immediate size) { | 525 void Assembler::enter(Immediate size) { |
| 526 EnsureSpace ensure_space(this); | 526 EnsureSpace ensure_space(this); |
| 527 last_pc_ = pc_; | 527 last_pc_ = pc_; |
| 528 emit(0xC8); | 528 emit(0xC8); |
| 529 emitw(size.value_); // 16 bit operand, always. | 529 emitw(size.value_); // 16 bit operand, always. |
| 530 emit(0); | 530 emit(0); |
| 531 } | 531 } |
| 532 | 532 |
| 533 | 533 |
| 534 void Assembler::hlt() { | 534 void Assembler::hlt() { |
| 535 EnsureSpace ensure_space(this); | 535 EnsureSpace ensure_space(this); |
| 536 last_pc_ = pc_; | 536 last_pc_ = pc_; |
| 537 emit(0xF4); | 537 emit(0xF4); |
| 538 } | 538 } |
| 539 | 539 |
| 540 | 540 |
| 541 void Assembler::idiv(Register src) { |
| 542 EnsureSpace ensure_space(this); |
| 543 last_pc_ = pc_; |
| 544 emit_rex_64(src); |
| 545 emit(0xF7); |
| 546 emit_modrm(0x7, src); |
| 547 } |
| 548 |
| 549 |
| 550 void Assembler::imul(Register dst, const Operand& src) { |
| 551 EnsureSpace ensure_space(this); |
| 552 last_pc_ = pc_; |
| 553 emit_rex_64(dst, src); |
| 554 emit(0x0F); |
| 555 emit(0xAF); |
| 556 emit_operand(dst, src); |
| 557 } |
| 558 |
| 559 |
| 560 void Assembler::imul(Register dst, Register src, Immediate imm) { |
| 561 EnsureSpace ensure_space(this); |
| 562 last_pc_ = pc_; |
| 563 emit_rex_64(dst, src); |
| 564 if (is_int8(imm.value_)) { |
| 565 emit(0x6B); |
| 566 emit_modrm(dst, src); |
| 567 emit(imm.value_); |
| 568 } else { |
| 569 emit(0x69); |
| 570 emit_modrm(dst, src); |
| 571 emitl(imm.value_); |
| 572 } |
| 573 } |
| 574 |
| 575 |
| 541 void Assembler::inc(Register dst) { | 576 void Assembler::inc(Register dst) { |
| 542 EnsureSpace ensure_space(this); | 577 EnsureSpace ensure_space(this); |
| 543 last_pc_ = pc_; | 578 last_pc_ = pc_; |
| 544 emit_rex_64(dst); | 579 emit_rex_64(dst); |
| 545 emit(0xFF); | 580 emit(0xFF); |
| 546 emit(0xC0 | (dst.code() & 0x7)); | 581 emit_modrm(0x0, dst); |
| 547 } | 582 } |
| 548 | 583 |
| 549 | 584 |
| 550 void Assembler::inc(const Operand& dst) { | 585 void Assembler::inc(const Operand& dst) { |
| 551 EnsureSpace ensure_space(this); | 586 EnsureSpace ensure_space(this); |
| 552 last_pc_ = pc_; | 587 last_pc_ = pc_; |
| 553 emit_rex_64(dst); | 588 emit_rex_64(dst); |
| 554 emit(0xFF); | 589 emit(0xFF); |
| 555 emit_operand(0, dst); | 590 emit_operand(0, dst); |
| 556 } | 591 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 627 emitl(current); | 662 emitl(current); |
| 628 L->link_to(current); | 663 L->link_to(current); |
| 629 } | 664 } |
| 630 } | 665 } |
| 631 | 666 |
| 632 | 667 |
| 633 void Assembler::jmp(Register target) { | 668 void Assembler::jmp(Register target) { |
| 634 EnsureSpace ensure_space(this); | 669 EnsureSpace ensure_space(this); |
| 635 last_pc_ = pc_; | 670 last_pc_ = pc_; |
| 636 // Opcode FF/4 r64 | 671 // Opcode FF/4 r64 |
| 637 if (!is_uint3(target.code())) { | 672 if (target.code() > 7) { |
| 638 emit_rex_64(target); | 673 emit_rex_64(target); |
| 639 } | 674 } |
| 640 emit(0xFF); | 675 emit(0xFF); |
| 641 emit(0xE0 | target.code() & 0x07); | 676 emit_modrm(0x4, target); |
| 642 } | 677 } |
| 643 | 678 |
| 644 | 679 |
| 645 void Assembler::lea(Register dst, const Operand& src) { | 680 void Assembler::lea(Register dst, const Operand& src) { |
| 646 EnsureSpace ensure_space(this); | 681 EnsureSpace ensure_space(this); |
| 647 last_pc_ = pc_; | 682 last_pc_ = pc_; |
| 648 emit_rex_64(dst, src); | 683 emit_rex_64(dst, src); |
| 649 emit(0x8D); | 684 emit(0x8D); |
| 650 emit_operand(dst, src); | 685 emit_operand(dst, src); |
| 651 } | 686 } |
| 652 | 687 |
| 653 | 688 |
| 654 void Assembler::leave() { | 689 void Assembler::leave() { |
| 655 EnsureSpace ensure_space(this); | 690 EnsureSpace ensure_space(this); |
| 656 last_pc_ = pc_; | 691 last_pc_ = pc_; |
| 657 emit(0xC9); | 692 emit(0xC9); |
| 658 } | 693 } |
| 659 | 694 |
| 660 | 695 |
| 696 void Assembler::movb(Register dst, const Operand& src) { |
| 697 EnsureSpace ensure_space(this); |
| 698 last_pc_ = pc_; |
| 699 emit_rex_32(dst, src); |
| 700 emit(0x8A); |
| 701 emit_operand(dst, src); |
| 702 } |
| 703 |
| 704 void Assembler::movb(Register dst, Immediate imm) { |
| 705 EnsureSpace ensure_space(this); |
| 706 last_pc_ = pc_; |
| 707 emit_rex_32(dst); |
| 708 emit(0xC6); |
| 709 emit_modrm(0x0, dst); |
| 710 emit(imm.value_); |
| 711 } |
| 712 |
| 713 void Assembler::movb(const Operand& dst, Register src) { |
| 714 EnsureSpace ensure_space(this); |
| 715 last_pc_ = pc_; |
| 716 emit_rex_32(src, dst); |
| 717 emit(0x88); |
| 718 emit_operand(src, dst); |
| 719 } |
| 720 |
| 661 void Assembler::movl(Register dst, const Operand& src) { | 721 void Assembler::movl(Register dst, const Operand& src) { |
| 662 EnsureSpace ensure_space(this); | 722 EnsureSpace ensure_space(this); |
| 663 last_pc_ = pc_; | 723 last_pc_ = pc_; |
| 664 emit_optional_rex_32(dst, src); | 724 emit_optional_rex_32(dst, src); |
| 665 emit(0x8B); | 725 emit(0x8B); |
| 666 emit_operand(dst, src); | 726 emit_operand(dst, src); |
| 667 } | 727 } |
| 668 | 728 |
| 669 | 729 |
| 670 void Assembler::movl(Register dst, Register src) { | 730 void Assembler::movl(Register dst, Register src) { |
| 671 EnsureSpace ensure_space(this); | 731 EnsureSpace ensure_space(this); |
| 672 last_pc_ = pc_; | 732 last_pc_ = pc_; |
| 673 emit_optional_rex_32(dst, src); | 733 emit_optional_rex_32(dst, src); |
| 674 emit(0x8B); | 734 emit(0x8B); |
| 675 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); | 735 emit_modrm(dst, src); |
| 676 } | 736 } |
| 677 | 737 |
| 678 | 738 |
| 679 void Assembler::movl(const Operand& dst, Register src) { | 739 void Assembler::movl(const Operand& dst, Register src) { |
| 680 EnsureSpace ensure_space(this); | 740 EnsureSpace ensure_space(this); |
| 681 last_pc_ = pc_; | 741 last_pc_ = pc_; |
| 682 emit_optional_rex_32(src, dst); | 742 emit_optional_rex_32(src, dst); |
| 683 emit(0x89); | 743 emit(0x89); |
| 684 emit_operand(src, dst); | 744 emit_operand(src, dst); |
| 685 } | 745 } |
| 686 | 746 |
| 687 | 747 |
| 688 void Assembler::movl(Register dst, Immediate value) { | 748 void Assembler::movl(Register dst, Immediate value) { |
| 689 EnsureSpace ensure_space(this); | 749 EnsureSpace ensure_space(this); |
| 690 last_pc_ = pc_; | 750 last_pc_ = pc_; |
| 691 emit_optional_rex_32(dst); | 751 emit_optional_rex_32(dst); |
| 692 emit(0xC7); | 752 emit(0xC7); |
| 693 emit(0xC0 | (dst.code() & 0x7)); | 753 emit_modrm(0x0, dst); |
| 694 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. | 754 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. |
| 695 } | 755 } |
| 696 | 756 |
| 697 | 757 |
| 698 void Assembler::movq(Register dst, const Operand& src) { | 758 void Assembler::movq(Register dst, const Operand& src) { |
| 699 EnsureSpace ensure_space(this); | 759 EnsureSpace ensure_space(this); |
| 700 last_pc_ = pc_; | 760 last_pc_ = pc_; |
| 701 emit_rex_64(dst, src); | 761 emit_rex_64(dst, src); |
| 702 emit(0x8B); | 762 emit(0x8B); |
| 703 emit_operand(dst, src); | 763 emit_operand(dst, src); |
| 704 } | 764 } |
| 705 | 765 |
| 706 | 766 |
| 707 void Assembler::movq(Register dst, Register src) { | 767 void Assembler::movq(Register dst, Register src) { |
| 708 EnsureSpace ensure_space(this); | 768 EnsureSpace ensure_space(this); |
| 709 last_pc_ = pc_; | 769 last_pc_ = pc_; |
| 710 emit_rex_64(dst, src); | 770 emit_rex_64(dst, src); |
| 711 emit(0x8B); | 771 emit(0x8B); |
| 712 emit(0xC0 | (dst.code() & 0x7) << 3 | (src.code() & 0x7)); | 772 emit_modrm(dst, src); |
| 713 } | 773 } |
| 714 | 774 |
| 715 | 775 |
| 716 void Assembler::movq(Register dst, Immediate value) { | 776 void Assembler::movq(Register dst, Immediate value) { |
| 717 EnsureSpace ensure_space(this); | 777 EnsureSpace ensure_space(this); |
| 718 last_pc_ = pc_; | 778 last_pc_ = pc_; |
| 719 emit_rex_64(dst); | 779 emit_rex_64(dst); |
| 720 emit(0xC7); | 780 emit(0xC7); |
| 721 emit(0xC0 | (dst.code() & 0x7)); | 781 emit_modrm(0x0, dst); |
| 722 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. | 782 emit(value); // Only 32-bit immediates are possible, not 8-bit immediates. |
| 723 } | 783 } |
| 724 | 784 |
| 725 | 785 |
| 726 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { | 786 void Assembler::movq(Register dst, int64_t value, RelocInfo::Mode rmode) { |
| 727 EnsureSpace ensure_space(this); | 787 EnsureSpace ensure_space(this); |
| 728 last_pc_ = pc_; | 788 last_pc_ = pc_; |
| 729 emit_rex_64(dst); | 789 emit_rex_64(dst); |
| 730 emit(0xB8 | (dst.code() & 0x7)); | 790 emit(0xB8 | (dst.code() & 0x7)); // Not a ModR/M byte. |
| 731 emitq(value, rmode); | 791 emitq(value, rmode); |
| 732 } | 792 } |
| 733 | 793 |
| 734 | 794 |
| 735 void Assembler::movq(const Operand& dst, Register src) { | 795 void Assembler::movq(const Operand& dst, Register src) { |
| 736 EnsureSpace ensure_space(this); | 796 EnsureSpace ensure_space(this); |
| 737 last_pc_ = pc_; | 797 last_pc_ = pc_; |
| 738 emit_rex_64(src, dst); | 798 emit_rex_64(src, dst); |
| 739 emit(0x89); | 799 emit(0x89); |
| 740 emit_operand(src, dst); | 800 emit_operand(src, dst); |
| 741 } | 801 } |
| 742 | 802 |
| 743 | 803 |
| 804 void Assembler::mul(Register src) { |
| 805 EnsureSpace ensure_space(this); |
| 806 last_pc_ = pc_; |
| 807 emit_rex_64(src); |
| 808 emit(0xF7); |
| 809 emit_modrm(0x4, src); |
| 810 } |
| 811 |
| 812 |
| 744 void Assembler::neg(Register dst) { | 813 void Assembler::neg(Register dst) { |
| 745 EnsureSpace ensure_space(this); | 814 EnsureSpace ensure_space(this); |
| 746 last_pc_ = pc_; | 815 last_pc_ = pc_; |
| 747 emit_rex_64(dst); | 816 emit_rex_64(dst); |
| 748 emit(0xF7); | 817 emit(0xF7); |
| 749 emit(0xC0 | (0x3 << 3) | (dst.code() & 0x7)); | 818 emit_modrm(0x3, dst); |
| 750 } | 819 } |
| 751 | 820 |
| 752 | 821 |
| 753 void Assembler::neg(const Operand& dst) { | 822 void Assembler::neg(const Operand& dst) { |
| 754 EnsureSpace ensure_space(this); | 823 EnsureSpace ensure_space(this); |
| 755 last_pc_ = pc_; | 824 last_pc_ = pc_; |
| 756 emit_rex_64(dst); | 825 emit_rex_64(dst); |
| 757 emit(0xF7); | 826 emit(0xF7); |
| 758 emit_operand(3, dst); | 827 emit_operand(3, dst); |
| 759 } | 828 } |
| 760 | 829 |
| 761 | 830 |
| 762 void Assembler::nop() { | 831 void Assembler::nop() { |
| 763 EnsureSpace ensure_space(this); | 832 EnsureSpace ensure_space(this); |
| 764 last_pc_ = pc_; | 833 last_pc_ = pc_; |
| 765 emit(0x90); | 834 emit(0x90); |
| 766 } | 835 } |
| 767 | 836 |
| 768 | 837 |
| 769 void Assembler::not_(Register dst) { | 838 void Assembler::not_(Register dst) { |
| 770 EnsureSpace ensure_space(this); | 839 EnsureSpace ensure_space(this); |
| 771 last_pc_ = pc_; | 840 last_pc_ = pc_; |
| 772 emit_rex_64(dst); | 841 emit_rex_64(dst); |
| 773 emit(0xF7); | 842 emit(0xF7); |
| 774 emit(0xC0 | (0x2 << 3) | (dst.code() & 0x7)); | 843 emit_modrm(0x2, dst); |
| 775 } | 844 } |
| 776 | 845 |
| 777 | 846 |
| 778 void Assembler::not_(const Operand& dst) { | 847 void Assembler::not_(const Operand& dst) { |
| 779 EnsureSpace ensure_space(this); | 848 EnsureSpace ensure_space(this); |
| 780 last_pc_ = pc_; | 849 last_pc_ = pc_; |
| 781 emit_rex_64(dst); | 850 emit_rex_64(dst); |
| 782 emit(0xF7); | 851 emit(0xF7); |
| 783 emit_operand(2, dst); | 852 emit_operand(2, dst); |
| 784 } | 853 } |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 emit(0x00); | 936 emit(0x00); |
| 868 emit(0x00); | 937 emit(0x00); |
| 869 return; | 938 return; |
| 870 } | 939 } |
| 871 } | 940 } |
| 872 | 941 |
| 873 | 942 |
| 874 void Assembler::pop(Register dst) { | 943 void Assembler::pop(Register dst) { |
| 875 EnsureSpace ensure_space(this); | 944 EnsureSpace ensure_space(this); |
| 876 last_pc_ = pc_; | 945 last_pc_ = pc_; |
| 877 if (dst.code() & 0x8) { | 946 if (dst.code() > 7) { |
| 878 emit_rex_64(dst); | 947 emit_rex_64(dst); |
| 879 } | 948 } |
| 880 emit(0x58 | (dst.code() & 0x7)); | 949 emit(0x58 | (dst.code() & 0x7)); |
| 881 } | 950 } |
| 882 | 951 |
| 883 | 952 |
| 884 void Assembler::pop(const Operand& dst) { | 953 void Assembler::pop(const Operand& dst) { |
| 885 EnsureSpace ensure_space(this); | 954 EnsureSpace ensure_space(this); |
| 886 last_pc_ = pc_; | 955 last_pc_ = pc_; |
| 887 emit_rex_64(dst); // Could be omitted in some cases. | 956 emit_rex_64(dst); // Could be omitted in some cases. |
| 888 emit(0x8F); | 957 emit(0x8F); |
| 889 emit_operand(0, dst); | 958 emit_operand(0, dst); |
| 890 } | 959 } |
| 891 | 960 |
| 892 | 961 |
| 893 void Assembler::popfq() { | 962 void Assembler::popfq() { |
| 894 EnsureSpace ensure_space(this); | 963 EnsureSpace ensure_space(this); |
| 895 last_pc_ = pc_; | 964 last_pc_ = pc_; |
| 896 emit(0x9D); | 965 emit(0x9D); |
| 897 } | 966 } |
| 898 | 967 |
| 899 | 968 |
| 900 void Assembler::push(Register src) { | 969 void Assembler::push(Register src) { |
| 901 EnsureSpace ensure_space(this); | 970 EnsureSpace ensure_space(this); |
| 902 last_pc_ = pc_; | 971 last_pc_ = pc_; |
| 903 if (src.code() & 0x8) { | 972 if (src.code() > 7) { |
| 904 emit_rex_64(src); | 973 emit_rex_64(src); |
| 905 } | 974 } |
| 906 emit(0x50 | (src.code() & 0x7)); | 975 emit(0x50 | (src.code() & 0x7)); |
| 907 } | 976 } |
| 908 | 977 |
| 909 | 978 |
| 910 void Assembler::push(const Operand& src) { | 979 void Assembler::push(const Operand& src) { |
| 911 EnsureSpace ensure_space(this); | 980 EnsureSpace ensure_space(this); |
| 912 last_pc_ = pc_; | 981 last_pc_ = pc_; |
| 913 emit_rex_64(src); // Could be omitted in some cases. | 982 emit_rex_64(src); // Could be omitted in some cases. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 936 } | 1005 } |
| 937 | 1006 |
| 938 | 1007 |
| 939 void Assembler::rcl(Register dst, uint8_t imm8) { | 1008 void Assembler::rcl(Register dst, uint8_t imm8) { |
| 940 EnsureSpace ensure_space(this); | 1009 EnsureSpace ensure_space(this); |
| 941 last_pc_ = pc_; | 1010 last_pc_ = pc_; |
| 942 ASSERT(is_uint6(imm8)); // illegal shift count | 1011 ASSERT(is_uint6(imm8)); // illegal shift count |
| 943 if (imm8 == 1) { | 1012 if (imm8 == 1) { |
| 944 emit_rex_64(dst); | 1013 emit_rex_64(dst); |
| 945 emit(0xD1); | 1014 emit(0xD1); |
| 946 emit(0xD0 | (dst.code() & 0x7)); | 1015 emit_modrm(0x2, dst); |
| 947 } else { | 1016 } else { |
| 948 emit_rex_64(dst); | 1017 emit_rex_64(dst); |
| 949 emit(0xC1); | 1018 emit(0xC1); |
| 950 emit(0xD0 | (dst.code() & 0x7)); | 1019 emit_modrm(0x2, dst); |
| 951 emit(imm8); | 1020 emit(imm8); |
| 952 } | 1021 } |
| 953 } | 1022 } |
| 954 | 1023 |
| 955 | 1024 |
| 956 void Assembler::ret(int imm16) { | 1025 void Assembler::ret(int imm16) { |
| 957 EnsureSpace ensure_space(this); | 1026 EnsureSpace ensure_space(this); |
| 958 last_pc_ = pc_; | 1027 last_pc_ = pc_; |
| 959 ASSERT(is_uint16(imm16)); | 1028 ASSERT(is_uint16(imm16)); |
| 960 if (imm16 == 0) { | 1029 if (imm16 == 0) { |
| 961 emit(0xC3); | 1030 emit(0xC3); |
| 962 } else { | 1031 } else { |
| 963 emit(0xC2); | 1032 emit(0xC2); |
| 964 emit(imm16 & 0xFF); | 1033 emit(imm16 & 0xFF); |
| 965 emit((imm16 >> 8) & 0xFF); | 1034 emit((imm16 >> 8) & 0xFF); |
| 966 } | 1035 } |
| 967 } | 1036 } |
| 968 | 1037 |
| 969 | 1038 |
| 1039 void Assembler::shld(Register dst, Register src) { |
| 1040 EnsureSpace ensure_space(this); |
| 1041 last_pc_ = pc_; |
| 1042 emit_rex_64(src, dst); |
| 1043 emit(0x0F); |
| 1044 emit(0xA5); |
| 1045 emit_modrm(src, dst); |
| 1046 } |
| 1047 |
| 1048 |
| 1049 void Assembler::shrd(Register dst, Register src) { |
| 1050 EnsureSpace ensure_space(this); |
| 1051 last_pc_ = pc_; |
| 1052 emit_rex_64(src, dst); |
| 1053 emit(0x0F); |
| 1054 emit(0xAD); |
| 1055 emit_modrm(src, dst); |
| 1056 } |
| 1057 |
| 1058 |
| 970 void Assembler::xchg(Register dst, Register src) { | 1059 void Assembler::xchg(Register dst, Register src) { |
| 971 EnsureSpace ensure_space(this); | 1060 EnsureSpace ensure_space(this); |
| 972 last_pc_ = pc_; | 1061 last_pc_ = pc_; |
| 973 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding | 1062 if (src.is(rax) || dst.is(rax)) { // Single-byte encoding |
| 974 Register other = src.is(rax) ? dst : src; | 1063 Register other = src.is(rax) ? dst : src; |
| 975 emit_rex_64(other); | 1064 emit_rex_64(other); |
| 976 emit(0x90 | (other.code() & 0x7)); | 1065 emit(0x90 | (other.code() & 0x7)); |
| 977 } else { | 1066 } else { |
| 978 emit_rex_64(src, dst); | 1067 emit_rex_64(src, dst); |
| 979 emit(0x87); | 1068 emit(0x87); |
| 980 emit(0xC0 | (src.code() & 0x7) << 3 | (dst.code() & 0x7)); | 1069 emit_modrm(src, dst); |
| 981 } | 1070 } |
| 982 } | 1071 } |
| 983 | 1072 |
| 984 | 1073 |
| 985 void Assembler::testb(Register reg, Immediate mask) { | 1074 void Assembler::testb(Register reg, Immediate mask) { |
| 986 EnsureSpace ensure_space(this); | 1075 EnsureSpace ensure_space(this); |
| 987 last_pc_ = pc_; | 1076 last_pc_ = pc_; |
| 988 if (reg.is(rax)) { | 1077 if (reg.is(rax)) { |
| 989 emit(0xA8); | 1078 emit(0xA8); |
| 990 emit(mask); | 1079 emit(mask); |
| 991 } else { | 1080 } else { |
| 992 if (reg.code() & 0x8) { | 1081 if (reg.code() > 3) { |
| 993 emit_rex_32(rax, reg); | 1082 // Register is not one of al, bl, cl, dl. Its encoding needs REX. |
| 1083 emit_rex_32(reg); |
| 994 } | 1084 } |
| 995 emit(0xF6); | 1085 emit(0xF6); |
| 996 emit(0xC0 | (reg.code() & 0x3)); | 1086 emit_modrm(0x0, reg); |
| 997 emit(mask.value_); // Low byte emitted. | 1087 emit(mask.value_); // Low byte emitted. |
| 998 } | 1088 } |
| 999 } | 1089 } |
| 1000 | 1090 |
| 1001 | 1091 |
| 1002 void Assembler::testb(const Operand& op, Immediate mask) { | 1092 void Assembler::testb(const Operand& op, Immediate mask) { |
| 1003 EnsureSpace ensure_space(this); | 1093 EnsureSpace ensure_space(this); |
| 1004 last_pc_ = pc_; | 1094 last_pc_ = pc_; |
| 1005 emit_optional_rex_32(rax, op); | 1095 emit_optional_rex_32(rax, op); |
| 1006 emit(0xF6); | 1096 emit(0xF6); |
| 1007 emit_operand(rax, op); // Operation code 0 | 1097 emit_operand(rax, op); // Operation code 0 |
| 1008 emit(mask.value_); // Low byte emitted. | 1098 emit(mask.value_); // Low byte emitted. |
| 1009 } | 1099 } |
| 1010 | 1100 |
| 1011 | 1101 |
| 1012 void Assembler::testl(Register reg, Immediate mask) { | 1102 void Assembler::testl(Register reg, Immediate mask) { |
| 1013 EnsureSpace ensure_space(this); | 1103 EnsureSpace ensure_space(this); |
| 1014 last_pc_ = pc_; | 1104 last_pc_ = pc_; |
| 1015 if (reg.is(rax)) { | 1105 if (reg.is(rax)) { |
| 1016 emit(0xA9); | 1106 emit(0xA9); |
| 1017 emit(mask); | 1107 emit(mask); |
| 1018 } else { | 1108 } else { |
| 1019 emit_optional_rex_32(rax, reg); | 1109 emit_optional_rex_32(rax, reg); |
| 1020 emit(0xF7); | 1110 emit(0xF7); |
| 1021 emit(0xC0 | (reg.code() & 0x3)); | 1111 emit_modrm(0x0, reg); |
| 1022 emit(mask); | 1112 emit(mask); |
| 1023 } | 1113 } |
| 1024 } | 1114 } |
| 1025 | 1115 |
| 1026 | 1116 |
| 1027 void Assembler::testl(const Operand& op, Immediate mask) { | 1117 void Assembler::testl(const Operand& op, Immediate mask) { |
| 1028 EnsureSpace ensure_space(this); | 1118 EnsureSpace ensure_space(this); |
| 1029 last_pc_ = pc_; | 1119 last_pc_ = pc_; |
| 1030 emit_optional_rex_32(rax, op); | 1120 emit_optional_rex_32(rax, op); |
| 1031 emit(0xF7); | 1121 emit(0xF7); |
| 1032 emit_operand(rax, op); // Operation code 0 | 1122 emit_operand(rax, op); // Operation code 0 |
| 1033 emit(mask); | 1123 emit(mask); |
| 1034 } | 1124 } |
| 1035 | 1125 |
| 1036 | 1126 |
| 1127 void Assembler::testq(const Operand& op, Register reg) { |
| 1128 EnsureSpace ensure_space(this); |
| 1129 last_pc_ = pc_; |
| 1130 emit_rex_64(reg, op); |
| 1131 emit(0x85); |
| 1132 emit_operand(reg, op); |
| 1133 } |
| 1134 |
| 1135 |
| 1136 void Assembler::testq(Register dst, Register src) { |
| 1137 EnsureSpace ensure_space(this); |
| 1138 last_pc_ = pc_; |
| 1139 emit_rex_64(dst, src); |
| 1140 emit(0x85); |
| 1141 emit_modrm(dst, src); |
| 1142 } |
| 1143 |
| 1144 |
| 1037 // Relocation information implementations | 1145 // Relocation information implementations |
| 1038 | 1146 |
| 1039 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { | 1147 void Assembler::RecordRelocInfo(RelocInfo::Mode rmode, intptr_t data) { |
| 1040 ASSERT(rmode != RelocInfo::NONE); | 1148 ASSERT(rmode != RelocInfo::NONE); |
| 1041 // Don't record external references unless the heap will be serialized. | 1149 // Don't record external references unless the heap will be serialized. |
| 1042 if (rmode == RelocInfo::EXTERNAL_REFERENCE && | 1150 if (rmode == RelocInfo::EXTERNAL_REFERENCE && |
| 1043 !Serializer::enabled() && | 1151 !Serializer::enabled() && |
| 1044 !FLAG_debug_code) { | 1152 !FLAG_debug_code) { |
| 1045 return; | 1153 return; |
| 1046 } | 1154 } |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1374 UNIMPLEMENTED(); | 1482 UNIMPLEMENTED(); |
| 1375 return NULL; | 1483 return NULL; |
| 1376 } | 1484 } |
| 1377 | 1485 |
| 1378 byte* JavaScriptFrame::GetCallerStackPointer() const { | 1486 byte* JavaScriptFrame::GetCallerStackPointer() const { |
| 1379 UNIMPLEMENTED(); | 1487 UNIMPLEMENTED(); |
| 1380 return NULL; | 1488 return NULL; |
| 1381 } | 1489 } |
| 1382 | 1490 |
| 1383 } } // namespace v8::internal | 1491 } } // namespace v8::internal |
| OLD | NEW |