12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef CPU_X86_VM_NATIVEINST_X86_HPP
26 #define CPU_X86_VM_NATIVEINST_X86_HPP
27
28 #include "asm/assembler.hpp"
29 #include "memory/allocation.hpp"
30 #include "runtime/icache.hpp"
31 #include "runtime/os.hpp"
32
33 // We have interfaces for the following instructions:
34 // - NativeInstruction
35 // - - NativeCall
36 // - - NativeMovConstReg
37 // - - NativeMovConstRegPatching
38 // - - NativeMovRegMem
39 // - - NativeMovRegMemPatching
40 // - - NativeJump
41 // - - NativeFarJump
42 // - - NativeIllegalOpCode
43 // - - NativeGeneralJump
44 // - - NativeReturn
45 // - - NativeReturnX (return with argument)
46 // - - NativePushConst
47 // - - NativeTstRegMem
48
49 // The base class for different kinds of native instruction abstractions.
50 // Provides the primitive operations to manipulate code relative to this.
51
661 };
662 };
663
664 // return instruction that does pop values of the stack
665 class NativeReturnX: public NativeInstruction {
666 public:
667 enum Intel_specific_constants {
668 instruction_code = 0xC2,
669 instruction_size = 2,
670 instruction_offset = 0,
671 next_instruction_offset = 2
672 };
673 };
674
675 // Simple test vs memory
676 class NativeTstRegMem: public NativeInstruction {
677 public:
678 enum Intel_specific_constants {
679 instruction_rex_prefix_mask = 0xF0,
680 instruction_rex_prefix = Assembler::REX,
681 instruction_code_memXregl = 0x85,
682 modrm_mask = 0x38, // select reg from the ModRM byte
683 modrm_reg = 0x00 // rax
684 };
685 };
686
687 inline bool NativeInstruction::is_illegal() { return (short)int_at(0) == (short)NativeIllegalInstruction::instruction_code; }
688 inline bool NativeInstruction::is_call() { return ubyte_at(0) == NativeCall::instruction_code; }
689 inline bool NativeInstruction::is_call_reg() { return ubyte_at(0) == NativeCallReg::instruction_code ||
690 (ubyte_at(1) == NativeCallReg::instruction_code &&
691 (ubyte_at(0) == Assembler::REX || ubyte_at(0) == Assembler::REX_B)); }
692 inline bool NativeInstruction::is_return() { return ubyte_at(0) == NativeReturn::instruction_code ||
693 ubyte_at(0) == NativeReturnX::instruction_code; }
694 inline bool NativeInstruction::is_jump() { return ubyte_at(0) == NativeJump::instruction_code ||
695 ubyte_at(0) == 0xEB; /* short jump */ }
696 inline bool NativeInstruction::is_jump_reg() {
697 int pos = 0;
698 if (ubyte_at(0) == Assembler::REX_B) pos = 1;
699 return ubyte_at(pos) == 0xFF && (ubyte_at(pos + 1) & 0xF0) == 0xE0;
700 }
701 inline bool NativeInstruction::is_far_jump() { return is_mov_literal64(); }
702 inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
703 (ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
704 inline bool NativeInstruction::is_safepoint_poll() {
705 #ifdef AMD64
706 // Try decoding a near safepoint first:
707 if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
708 ubyte_at(1) == 0x05) { // 00 rax 101
709 address fault = addr_at(6) + int_at(2);
710 NOT_JVMCI(assert(!Assembler::is_polling_page_far(), "unexpected poll encoding");)
711 return os::is_poll_address(fault);
712 }
713 // Now try decoding a far safepoint:
714 // two cases, depending on the choice of the base register in the address.
715 if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
716 ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
717 (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
718 (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
719 (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg)) {
720 NOT_JVMCI(assert(Assembler::is_polling_page_far(), "unexpected poll encoding");)
721 return true;
722 }
723 return false;
724 #else
725 return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
|
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 #ifndef CPU_X86_VM_NATIVEINST_X86_HPP
26 #define CPU_X86_VM_NATIVEINST_X86_HPP
27
28 #include "asm/assembler.hpp"
29 #include "memory/allocation.hpp"
30 #include "runtime/icache.hpp"
31 #include "runtime/os.hpp"
32 #include "runtime/safepointMechanism.hpp"
33
34 // We have interfaces for the following instructions:
35 // - NativeInstruction
36 // - - NativeCall
37 // - - NativeMovConstReg
38 // - - NativeMovConstRegPatching
39 // - - NativeMovRegMem
40 // - - NativeMovRegMemPatching
41 // - - NativeJump
42 // - - NativeFarJump
43 // - - NativeIllegalOpCode
44 // - - NativeGeneralJump
45 // - - NativeReturn
46 // - - NativeReturnX (return with argument)
47 // - - NativePushConst
48 // - - NativeTstRegMem
49
50 // The base class for different kinds of native instruction abstractions.
51 // Provides the primitive operations to manipulate code relative to this.
52
662 };
663 };
664
665 // return instruction that does pop values of the stack
666 class NativeReturnX: public NativeInstruction {
667 public:
668 enum Intel_specific_constants {
669 instruction_code = 0xC2,
670 instruction_size = 2,
671 instruction_offset = 0,
672 next_instruction_offset = 2
673 };
674 };
675
676 // Simple test vs memory
677 class NativeTstRegMem: public NativeInstruction {
678 public:
679 enum Intel_specific_constants {
680 instruction_rex_prefix_mask = 0xF0,
681 instruction_rex_prefix = Assembler::REX,
682 instruction_rex_b_prefix = Assembler::REX_B,
683 instruction_code_memXregl = 0x85,
684 modrm_mask = 0x38, // select reg from the ModRM byte
685 modrm_reg = 0x00 // rax
686 };
687 };
688
689 inline bool NativeInstruction::is_illegal() { return (short)int_at(0) == (short)NativeIllegalInstruction::instruction_code; }
690 inline bool NativeInstruction::is_call() { return ubyte_at(0) == NativeCall::instruction_code; }
691 inline bool NativeInstruction::is_call_reg() { return ubyte_at(0) == NativeCallReg::instruction_code ||
692 (ubyte_at(1) == NativeCallReg::instruction_code &&
693 (ubyte_at(0) == Assembler::REX || ubyte_at(0) == Assembler::REX_B)); }
694 inline bool NativeInstruction::is_return() { return ubyte_at(0) == NativeReturn::instruction_code ||
695 ubyte_at(0) == NativeReturnX::instruction_code; }
696 inline bool NativeInstruction::is_jump() { return ubyte_at(0) == NativeJump::instruction_code ||
697 ubyte_at(0) == 0xEB; /* short jump */ }
698 inline bool NativeInstruction::is_jump_reg() {
699 int pos = 0;
700 if (ubyte_at(0) == Assembler::REX_B) pos = 1;
701 return ubyte_at(pos) == 0xFF && (ubyte_at(pos + 1) & 0xF0) == 0xE0;
702 }
703 inline bool NativeInstruction::is_far_jump() { return is_mov_literal64(); }
704 inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
705 (ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
706 inline bool NativeInstruction::is_safepoint_poll() {
707 #ifdef AMD64
708 if (SafepointMechanism::uses_thread_local_poll()) {
709 // We know that the poll must have a REX_B prefix since we enforce its source to be
710 // a rex-register and the destination to be rax.
711 const bool has_rex_prefix = ubyte_at(0) == NativeTstRegMem::instruction_rex_b_prefix;
712 const bool is_test_opcode = ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl;
713 const bool is_rax_target = (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg;
714 if (has_rex_prefix && is_test_opcode && is_rax_target) {
715 return true;
716 }
717 }
718 // Try decoding a near safepoint first:
719 if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
720 ubyte_at(1) == 0x05) { // 00 rax 101
721 address fault = addr_at(6) + int_at(2);
722 NOT_JVMCI(assert(!Assembler::is_polling_page_far(), "unexpected poll encoding");)
723 return os::is_poll_address(fault);
724 }
725 // Now try decoding a far safepoint:
726 // two cases, depending on the choice of the base register in the address.
727 if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
728 ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
729 (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
730 (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
731 (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg)) {
732 NOT_JVMCI(assert(Assembler::is_polling_page_far(), "unexpected poll encoding");)
733 return true;
734 }
735 return false;
736 #else
737 return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
|