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

Side by Side Diff: src/x64/assembler-x64.cc

Issue 119078: Add multiplication and division to x64 assembler. Add emit_modrm() function. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/x64/assembler-x64.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2009 the V8 project authors. All rights reserved. 1 // Copyright 2009 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 324 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698