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 |