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

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

Issue 214753002: Refactor the arithmetic instructions for x64 port (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Correct arithmetic_op_8 implementation and add a test case Created 6 years, 9 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') | test/cctest/test-assembler-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 449 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 pc_[0] = adr.buf_[0] | code << 3; 460 pc_[0] = adr.buf_[0] | code << 3;
461 461
462 // Emit the rest of the encoded operand. 462 // Emit the rest of the encoded operand.
463 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i]; 463 for (unsigned i = 1; i < length; i++) pc_[i] = adr.buf_[i];
464 pc_ += length; 464 pc_ += length;
465 } 465 }
466 466
467 467
468 // Assembler Instruction implementations. 468 // Assembler Instruction implementations.
469 469
470 void Assembler::arithmetic_op(byte opcode, Register reg, const Operand& op) { 470 void Assembler::arithmetic_op(byte opcode,
471 Register reg,
472 const Operand& op,
473 int size) {
471 EnsureSpace ensure_space(this); 474 EnsureSpace ensure_space(this);
472 emit_rex_64(reg, op); 475 emit_rex(reg, op, size);
473 emit(opcode); 476 emit(opcode);
474 emit_operand(reg, op); 477 emit_operand(reg, op);
475 } 478 }
476 479
477 480
478 void Assembler::arithmetic_op(byte opcode, Register reg, Register rm_reg) { 481 void Assembler::arithmetic_op(byte opcode,
482 Register reg,
483 Register rm_reg,
484 int size) {
479 EnsureSpace ensure_space(this); 485 EnsureSpace ensure_space(this);
480 ASSERT((opcode & 0xC6) == 2); 486 ASSERT((opcode & 0xC6) == 2);
481 if (rm_reg.low_bits() == 4) { // Forces SIB byte. 487 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
482 // Swap reg and rm_reg and change opcode operand order. 488 // Swap reg and rm_reg and change opcode operand order.
483 emit_rex_64(rm_reg, reg); 489 emit_rex(rm_reg, reg, size);
484 emit(opcode ^ 0x02); 490 emit(opcode ^ 0x02);
485 emit_modrm(rm_reg, reg); 491 emit_modrm(rm_reg, reg);
486 } else { 492 } else {
487 emit_rex_64(reg, rm_reg); 493 emit_rex(reg, rm_reg, size);
488 emit(opcode); 494 emit(opcode);
489 emit_modrm(reg, rm_reg); 495 emit_modrm(reg, rm_reg);
490 } 496 }
491 } 497 }
492 498
493 499
494 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) { 500 void Assembler::arithmetic_op_16(byte opcode, Register reg, Register rm_reg) {
495 EnsureSpace ensure_space(this); 501 EnsureSpace ensure_space(this);
496 ASSERT((opcode & 0xC6) == 2); 502 ASSERT((opcode & 0xC6) == 2);
497 if (rm_reg.low_bits() == 4) { // Forces SIB byte. 503 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
(...skipping 15 matching lines...) Expand all
513 Register reg, 519 Register reg,
514 const Operand& rm_reg) { 520 const Operand& rm_reg) {
515 EnsureSpace ensure_space(this); 521 EnsureSpace ensure_space(this);
516 emit(0x66); 522 emit(0x66);
517 emit_optional_rex_32(reg, rm_reg); 523 emit_optional_rex_32(reg, rm_reg);
518 emit(opcode); 524 emit(opcode);
519 emit_operand(reg, rm_reg); 525 emit_operand(reg, rm_reg);
520 } 526 }
521 527
522 528
523 void Assembler::arithmetic_op_32(byte opcode, Register reg, Register rm_reg) { 529 void Assembler::arithmetic_op_8(byte opcode, Register reg, const Operand& op) {
530 EnsureSpace ensure_space(this);
531 if (!reg.is_byte_register()) {
532 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
533 emit_rex_32(reg);
534 }
535 emit(opcode);
536 emit_operand(reg, op);
537 }
538
539
540 void Assembler::arithmetic_op_8(byte opcode, Register reg, Register rm_reg) {
524 EnsureSpace ensure_space(this); 541 EnsureSpace ensure_space(this);
525 ASSERT((opcode & 0xC6) == 2); 542 ASSERT((opcode & 0xC6) == 2);
526 if (rm_reg.low_bits() == 4) { // Forces SIB byte. 543 if (rm_reg.low_bits() == 4) { // Forces SIB byte.
527 // Swap reg and rm_reg and change opcode operand order. 544 // Swap reg and rm_reg and change opcode operand order.
528 emit_optional_rex_32(rm_reg, reg); 545 if (!rm_reg.is_byte_register() || !reg.is_byte_register()) {
529 emit(opcode ^ 0x02); // E.g. 0x03 -> 0x01 for ADD. 546 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
547 emit_rex_32(rm_reg, reg);
548 }
549 emit(opcode ^ 0x02);
530 emit_modrm(rm_reg, reg); 550 emit_modrm(rm_reg, reg);
531 } else { 551 } else {
532 emit_optional_rex_32(reg, rm_reg); 552 if (!reg.is_byte_register() || !rm_reg.is_byte_register()) {
553 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
554 emit_rex_32(reg, rm_reg);
555 }
533 emit(opcode); 556 emit(opcode);
534 emit_modrm(reg, rm_reg); 557 emit_modrm(reg, rm_reg);
535 } 558 }
536 } 559 }
537 560
538 561
539 void Assembler::arithmetic_op_32(byte opcode,
540 Register reg,
541 const Operand& rm_reg) {
542 EnsureSpace ensure_space(this);
543 emit_optional_rex_32(reg, rm_reg);
544 emit(opcode);
545 emit_operand(reg, rm_reg);
546 }
547
548
549 void Assembler::immediate_arithmetic_op(byte subcode, 562 void Assembler::immediate_arithmetic_op(byte subcode,
550 Register dst, 563 Register dst,
551 Immediate src) { 564 Immediate src,
565 int size) {
552 EnsureSpace ensure_space(this); 566 EnsureSpace ensure_space(this);
553 emit_rex_64(dst); 567 emit_rex(dst, size);
554 if (is_int8(src.value_)) { 568 if (is_int8(src.value_)) {
555 emit(0x83); 569 emit(0x83);
556 emit_modrm(subcode, dst); 570 emit_modrm(subcode, dst);
557 emit(src.value_); 571 emit(src.value_);
558 } else if (dst.is(rax)) { 572 } else if (dst.is(rax)) {
559 emit(0x05 | (subcode << 3)); 573 emit(0x05 | (subcode << 3));
560 emitl(src.value_); 574 emitl(src.value_);
561 } else { 575 } else {
562 emit(0x81); 576 emit(0x81);
563 emit_modrm(subcode, dst); 577 emit_modrm(subcode, dst);
564 emitl(src.value_); 578 emitl(src.value_);
565 } 579 }
566 } 580 }
567 581
568 void Assembler::immediate_arithmetic_op(byte subcode, 582 void Assembler::immediate_arithmetic_op(byte subcode,
569 const Operand& dst, 583 const Operand& dst,
570 Immediate src) { 584 Immediate src,
585 int size) {
571 EnsureSpace ensure_space(this); 586 EnsureSpace ensure_space(this);
572 emit_rex_64(dst); 587 emit_rex(dst, size);
573 if (is_int8(src.value_)) { 588 if (is_int8(src.value_)) {
574 emit(0x83); 589 emit(0x83);
575 emit_operand(subcode, dst); 590 emit_operand(subcode, dst);
576 emit(src.value_); 591 emit(src.value_);
577 } else { 592 } else {
578 emit(0x81); 593 emit(0x81);
579 emit_operand(subcode, dst); 594 emit_operand(subcode, dst);
580 emitl(src.value_); 595 emitl(src.value_);
581 } 596 }
582 } 597 }
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
614 emit_operand(subcode, dst); 629 emit_operand(subcode, dst);
615 emit(src.value_); 630 emit(src.value_);
616 } else { 631 } else {
617 emit(0x81); 632 emit(0x81);
618 emit_operand(subcode, dst); 633 emit_operand(subcode, dst);
619 emitw(src.value_); 634 emitw(src.value_);
620 } 635 }
621 } 636 }
622 637
623 638
624 void Assembler::immediate_arithmetic_op_32(byte subcode,
625 Register dst,
626 Immediate src) {
627 EnsureSpace ensure_space(this);
628 emit_optional_rex_32(dst);
629 if (is_int8(src.value_)) {
630 emit(0x83);
631 emit_modrm(subcode, dst);
632 emit(src.value_);
633 } else if (dst.is(rax)) {
634 emit(0x05 | (subcode << 3));
635 emitl(src.value_);
636 } else {
637 emit(0x81);
638 emit_modrm(subcode, dst);
639 emitl(src.value_);
640 }
641 }
642
643
644 void Assembler::immediate_arithmetic_op_32(byte subcode,
645 const Operand& dst,
646 Immediate src) {
647 EnsureSpace ensure_space(this);
648 emit_optional_rex_32(dst);
649 if (is_int8(src.value_)) {
650 emit(0x83);
651 emit_operand(subcode, dst);
652 emit(src.value_);
653 } else {
654 emit(0x81);
655 emit_operand(subcode, dst);
656 emitl(src.value_);
657 }
658 }
659
660
661 void Assembler::immediate_arithmetic_op_8(byte subcode, 639 void Assembler::immediate_arithmetic_op_8(byte subcode,
662 const Operand& dst, 640 const Operand& dst,
663 Immediate src) { 641 Immediate src) {
664 EnsureSpace ensure_space(this); 642 EnsureSpace ensure_space(this);
665 emit_optional_rex_32(dst); 643 emit_optional_rex_32(dst);
666 ASSERT(is_int8(src.value_) || is_uint8(src.value_)); 644 ASSERT(is_int8(src.value_) || is_uint8(src.value_));
667 emit(0x80); 645 emit(0x80);
668 emit_operand(subcode, dst); 646 emit_operand(subcode, dst);
669 emit(src.value_); 647 emit(src.value_);
670 } 648 }
671 649
672 650
673 void Assembler::immediate_arithmetic_op_8(byte subcode, 651 void Assembler::immediate_arithmetic_op_8(byte subcode,
674 Register dst, 652 Register dst,
675 Immediate src) { 653 Immediate src) {
676 EnsureSpace ensure_space(this); 654 EnsureSpace ensure_space(this);
677 if (!dst.is_byte_register()) { 655 if (!dst.is_byte_register()) {
678 // Use 64-bit mode byte registers. 656 // Register is not one of al, bl, cl, dl. Its encoding needs REX.
679 emit_rex_64(dst); 657 emit_rex_32(dst);
680 } 658 }
681 ASSERT(is_int8(src.value_) || is_uint8(src.value_)); 659 ASSERT(is_int8(src.value_) || is_uint8(src.value_));
682 emit(0x80); 660 emit(0x80);
683 emit_modrm(subcode, dst); 661 emit_modrm(subcode, dst);
684 emit(src.value_); 662 emit(src.value_);
685 } 663 }
686 664
687 665
688 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) { 666 void Assembler::shift(Register dst, Immediate shift_amount, int subcode) {
689 EnsureSpace ensure_space(this); 667 EnsureSpace ensure_space(this);
(...skipping 2354 matching lines...) Expand 10 before | Expand all | Expand 10 after
3044 3022
3045 3023
3046 bool RelocInfo::IsInConstantPool() { 3024 bool RelocInfo::IsInConstantPool() {
3047 return false; 3025 return false;
3048 } 3026 }
3049 3027
3050 3028
3051 } } // namespace v8::internal 3029 } } // namespace v8::internal
3052 3030
3053 #endif // V8_TARGET_ARCH_X64 3031 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/assembler-x64.h ('k') | test/cctest/test-assembler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698