annotate src/cpu/x86/vm/nativeInst_x86.hpp @ 3101:6ccb95c97e6d

IdealGraphVisualizer: Work around a problem with JSplitPane and the NetBeans editor: setDividerLocation() doesn't work when the split pane has not been layouted and painted yet. JSplitPane then initially uses a tiny width for the left editor component, which causes the editor to calculate invalid offsets and constantly throw exceptions, particularly on mouse events. Thus, defer adding the two components and setting the divider's location.
author Peter Hofer <peter.hofer@jku.at>
date Thu, 30 Jun 2011 12:17:27 +0200
parents b40d4fa697bf
children f79b652d4437 127b3692c168
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a61af66fc99e Initial load
duke
parents:
diff changeset
1 /*
2404
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
2 * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
a61af66fc99e Initial load
duke
parents:
diff changeset
4 *
a61af66fc99e Initial load
duke
parents:
diff changeset
5 * This code is free software; you can redistribute it and/or modify it
a61af66fc99e Initial load
duke
parents:
diff changeset
6 * under the terms of the GNU General Public License version 2 only, as
a61af66fc99e Initial load
duke
parents:
diff changeset
7 * published by the Free Software Foundation.
a61af66fc99e Initial load
duke
parents:
diff changeset
8 *
a61af66fc99e Initial load
duke
parents:
diff changeset
9 * This code is distributed in the hope that it will be useful, but WITHOUT
a61af66fc99e Initial load
duke
parents:
diff changeset
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
a61af66fc99e Initial load
duke
parents:
diff changeset
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a61af66fc99e Initial load
duke
parents:
diff changeset
12 * version 2 for more details (a copy is included in the LICENSE file that
a61af66fc99e Initial load
duke
parents:
diff changeset
13 * accompanied this code).
a61af66fc99e Initial load
duke
parents:
diff changeset
14 *
a61af66fc99e Initial load
duke
parents:
diff changeset
15 * You should have received a copy of the GNU General Public License version
a61af66fc99e Initial load
duke
parents:
diff changeset
16 * 2 along with this work; if not, write to the Free Software Foundation,
a61af66fc99e Initial load
duke
parents:
diff changeset
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
a61af66fc99e Initial load
duke
parents:
diff changeset
18 *
1552
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 314
diff changeset
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 314
diff changeset
20 * or visit www.oracle.com if you need additional information or have any
c18cbe5936b8 6941466: Oracle rebranding changes for Hotspot repositories
trims
parents: 314
diff changeset
21 * questions.
0
a61af66fc99e Initial load
duke
parents:
diff changeset
22 *
a61af66fc99e Initial load
duke
parents:
diff changeset
23 */
a61af66fc99e Initial load
duke
parents:
diff changeset
24
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
25 #ifndef CPU_X86_VM_NATIVEINST_X86_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
26 #define CPU_X86_VM_NATIVEINST_X86_HPP
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
27
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
28 #include "asm/assembler.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
29 #include "memory/allocation.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
30 #include "runtime/icache.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
31 #include "runtime/os.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
32 #include "utilities/top.hpp"
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
33
0
a61af66fc99e Initial load
duke
parents:
diff changeset
34 // We have interfaces for the following instructions:
a61af66fc99e Initial load
duke
parents:
diff changeset
35 // - NativeInstruction
a61af66fc99e Initial load
duke
parents:
diff changeset
36 // - - NativeCall
a61af66fc99e Initial load
duke
parents:
diff changeset
37 // - - NativeMovConstReg
a61af66fc99e Initial load
duke
parents:
diff changeset
38 // - - NativeMovConstRegPatching
a61af66fc99e Initial load
duke
parents:
diff changeset
39 // - - NativeMovRegMem
a61af66fc99e Initial load
duke
parents:
diff changeset
40 // - - NativeMovRegMemPatching
a61af66fc99e Initial load
duke
parents:
diff changeset
41 // - - NativeJump
a61af66fc99e Initial load
duke
parents:
diff changeset
42 // - - NativeIllegalOpCode
a61af66fc99e Initial load
duke
parents:
diff changeset
43 // - - NativeGeneralJump
a61af66fc99e Initial load
duke
parents:
diff changeset
44 // - - NativeReturn
a61af66fc99e Initial load
duke
parents:
diff changeset
45 // - - NativeReturnX (return with argument)
a61af66fc99e Initial load
duke
parents:
diff changeset
46 // - - NativePushConst
a61af66fc99e Initial load
duke
parents:
diff changeset
47 // - - NativeTstRegMem
a61af66fc99e Initial load
duke
parents:
diff changeset
48
a61af66fc99e Initial load
duke
parents:
diff changeset
49 // The base class for different kinds of native instruction abstractions.
a61af66fc99e Initial load
duke
parents:
diff changeset
50 // Provides the primitive operations to manipulate code relative to this.
a61af66fc99e Initial load
duke
parents:
diff changeset
51
a61af66fc99e Initial load
duke
parents:
diff changeset
52 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
a61af66fc99e Initial load
duke
parents:
diff changeset
53 friend class Relocation;
a61af66fc99e Initial load
duke
parents:
diff changeset
54
a61af66fc99e Initial load
duke
parents:
diff changeset
55 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
56 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
57 nop_instruction_code = 0x90,
a61af66fc99e Initial load
duke
parents:
diff changeset
58 nop_instruction_size = 1
a61af66fc99e Initial load
duke
parents:
diff changeset
59 };
a61af66fc99e Initial load
duke
parents:
diff changeset
60
a61af66fc99e Initial load
duke
parents:
diff changeset
61 bool is_nop() { return ubyte_at(0) == nop_instruction_code; }
116
018d5b58dd4f 6537506: Provide a mechanism for specifying Java-level USDT-like dtrace probes
kamg
parents: 0
diff changeset
62 bool is_dtrace_trap();
0
a61af66fc99e Initial load
duke
parents:
diff changeset
63 inline bool is_call();
a61af66fc99e Initial load
duke
parents:
diff changeset
64 inline bool is_illegal();
a61af66fc99e Initial load
duke
parents:
diff changeset
65 inline bool is_return();
a61af66fc99e Initial load
duke
parents:
diff changeset
66 inline bool is_jump();
a61af66fc99e Initial load
duke
parents:
diff changeset
67 inline bool is_cond_jump();
a61af66fc99e Initial load
duke
parents:
diff changeset
68 inline bool is_safepoint_poll();
a61af66fc99e Initial load
duke
parents:
diff changeset
69 inline bool is_mov_literal64();
a61af66fc99e Initial load
duke
parents:
diff changeset
70
a61af66fc99e Initial load
duke
parents:
diff changeset
71 protected:
a61af66fc99e Initial load
duke
parents:
diff changeset
72 address addr_at(int offset) const { return address(this) + offset; }
a61af66fc99e Initial load
duke
parents:
diff changeset
73
a61af66fc99e Initial load
duke
parents:
diff changeset
74 s_char sbyte_at(int offset) const { return *(s_char*) addr_at(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
75 u_char ubyte_at(int offset) const { return *(u_char*) addr_at(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
76
a61af66fc99e Initial load
duke
parents:
diff changeset
77 jint int_at(int offset) const { return *(jint*) addr_at(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
78
a61af66fc99e Initial load
duke
parents:
diff changeset
79 intptr_t ptr_at(int offset) const { return *(intptr_t*) addr_at(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
80
a61af66fc99e Initial load
duke
parents:
diff changeset
81 oop oop_at (int offset) const { return *(oop*) addr_at(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
82
a61af66fc99e Initial load
duke
parents:
diff changeset
83
a61af66fc99e Initial load
duke
parents:
diff changeset
84 void set_char_at(int offset, char c) { *addr_at(offset) = (u_char)c; wrote(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
85 void set_int_at(int offset, jint i) { *(jint*)addr_at(offset) = i; wrote(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
86 void set_ptr_at (int offset, intptr_t ptr) { *(intptr_t*) addr_at(offset) = ptr; wrote(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
87 void set_oop_at (int offset, oop o) { *(oop*) addr_at(offset) = o; wrote(offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
88
a61af66fc99e Initial load
duke
parents:
diff changeset
89 // This doesn't really do anything on Intel, but it is the place where
a61af66fc99e Initial load
duke
parents:
diff changeset
90 // cache invalidation belongs, generically:
a61af66fc99e Initial load
duke
parents:
diff changeset
91 void wrote(int offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
92
a61af66fc99e Initial load
duke
parents:
diff changeset
93 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
94
a61af66fc99e Initial load
duke
parents:
diff changeset
95 // unit test stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
96 static void test() {} // override for testing
a61af66fc99e Initial load
duke
parents:
diff changeset
97
a61af66fc99e Initial load
duke
parents:
diff changeset
98 inline friend NativeInstruction* nativeInstruction_at(address address);
a61af66fc99e Initial load
duke
parents:
diff changeset
99 };
a61af66fc99e Initial load
duke
parents:
diff changeset
100
a61af66fc99e Initial load
duke
parents:
diff changeset
101 inline NativeInstruction* nativeInstruction_at(address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
102 NativeInstruction* inst = (NativeInstruction*)address;
a61af66fc99e Initial load
duke
parents:
diff changeset
103 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
104 //inst->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
105 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
106 return inst;
a61af66fc99e Initial load
duke
parents:
diff changeset
107 }
a61af66fc99e Initial load
duke
parents:
diff changeset
108
a61af66fc99e Initial load
duke
parents:
diff changeset
109 inline NativeCall* nativeCall_at(address address);
a61af66fc99e Initial load
duke
parents:
diff changeset
110 // The NativeCall is an abstraction for accessing/manipulating native call imm32/rel32off
a61af66fc99e Initial load
duke
parents:
diff changeset
111 // instructions (used to manipulate inline caches, primitive & dll calls, etc.).
a61af66fc99e Initial load
duke
parents:
diff changeset
112
a61af66fc99e Initial load
duke
parents:
diff changeset
113 class NativeCall: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
114 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
115 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
116 instruction_code = 0xE8,
a61af66fc99e Initial load
duke
parents:
diff changeset
117 instruction_size = 5,
a61af66fc99e Initial load
duke
parents:
diff changeset
118 instruction_offset = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
119 displacement_offset = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
120 return_address_offset = 5
a61af66fc99e Initial load
duke
parents:
diff changeset
121 };
a61af66fc99e Initial load
duke
parents:
diff changeset
122
a61af66fc99e Initial load
duke
parents:
diff changeset
123 enum { cache_line_size = BytesPerWord }; // conservative estimate!
a61af66fc99e Initial load
duke
parents:
diff changeset
124
a61af66fc99e Initial load
duke
parents:
diff changeset
125 address instruction_address() const { return addr_at(instruction_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
126 address next_instruction_address() const { return addr_at(return_address_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
127 int displacement() const { return (jint) int_at(displacement_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
128 address displacement_address() const { return addr_at(displacement_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
129 address return_address() const { return addr_at(return_address_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
130 address destination() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
131 void set_destination(address dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
132 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
133 assert((labs((intptr_t) dest - (intptr_t) return_address()) &
a61af66fc99e Initial load
duke
parents:
diff changeset
134 0xFFFFFFFF00000000) == 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
135 "must be 32bit offset");
a61af66fc99e Initial load
duke
parents:
diff changeset
136 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
137 set_int_at(displacement_offset, dest - return_address());
a61af66fc99e Initial load
duke
parents:
diff changeset
138 }
a61af66fc99e Initial load
duke
parents:
diff changeset
139 void set_destination_mt_safe(address dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
140
a61af66fc99e Initial load
duke
parents:
diff changeset
141 void verify_alignment() { assert((intptr_t)addr_at(displacement_offset) % BytesPerInt == 0, "must be aligned"); }
a61af66fc99e Initial load
duke
parents:
diff changeset
142 void verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
143 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
144
a61af66fc99e Initial load
duke
parents:
diff changeset
145 // Creation
a61af66fc99e Initial load
duke
parents:
diff changeset
146 inline friend NativeCall* nativeCall_at(address address);
a61af66fc99e Initial load
duke
parents:
diff changeset
147 inline friend NativeCall* nativeCall_before(address return_address);
a61af66fc99e Initial load
duke
parents:
diff changeset
148
a61af66fc99e Initial load
duke
parents:
diff changeset
149 static bool is_call_at(address instr) {
a61af66fc99e Initial load
duke
parents:
diff changeset
150 return ((*instr) & 0xFF) == NativeCall::instruction_code;
a61af66fc99e Initial load
duke
parents:
diff changeset
151 }
a61af66fc99e Initial load
duke
parents:
diff changeset
152
a61af66fc99e Initial load
duke
parents:
diff changeset
153 static bool is_call_before(address return_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
154 return is_call_at(return_address - NativeCall::return_address_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
155 }
a61af66fc99e Initial load
duke
parents:
diff changeset
156
a61af66fc99e Initial load
duke
parents:
diff changeset
157 static bool is_call_to(address instr, address target) {
a61af66fc99e Initial load
duke
parents:
diff changeset
158 return nativeInstruction_at(instr)->is_call() &&
a61af66fc99e Initial load
duke
parents:
diff changeset
159 nativeCall_at(instr)->destination() == target;
a61af66fc99e Initial load
duke
parents:
diff changeset
160 }
a61af66fc99e Initial load
duke
parents:
diff changeset
161
a61af66fc99e Initial load
duke
parents:
diff changeset
162 // MT-safe patching of a call instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
163 static void insert(address code_pos, address entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
164
a61af66fc99e Initial load
duke
parents:
diff changeset
165 static void replace_mt_safe(address instr_addr, address code_buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
166 };
a61af66fc99e Initial load
duke
parents:
diff changeset
167
a61af66fc99e Initial load
duke
parents:
diff changeset
168 inline NativeCall* nativeCall_at(address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
169 NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
170 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
171 call->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
172 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
173 return call;
a61af66fc99e Initial load
duke
parents:
diff changeset
174 }
a61af66fc99e Initial load
duke
parents:
diff changeset
175
a61af66fc99e Initial load
duke
parents:
diff changeset
176 inline NativeCall* nativeCall_before(address return_address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
177 NativeCall* call = (NativeCall*)(return_address - NativeCall::return_address_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
178 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
179 call->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
180 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
181 return call;
a61af66fc99e Initial load
duke
parents:
diff changeset
182 }
a61af66fc99e Initial load
duke
parents:
diff changeset
183
a61af66fc99e Initial load
duke
parents:
diff changeset
184 // An interface for accessing/manipulating native mov reg, imm32 instructions.
a61af66fc99e Initial load
duke
parents:
diff changeset
185 // (used to manipulate inlined 32bit data dll calls, etc.)
a61af66fc99e Initial load
duke
parents:
diff changeset
186 class NativeMovConstReg: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
187 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
188 static const bool has_rex = true;
a61af66fc99e Initial load
duke
parents:
diff changeset
189 static const int rex_size = 1;
a61af66fc99e Initial load
duke
parents:
diff changeset
190 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
191 static const bool has_rex = false;
a61af66fc99e Initial load
duke
parents:
diff changeset
192 static const int rex_size = 0;
a61af66fc99e Initial load
duke
parents:
diff changeset
193 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
194 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
195 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
196 instruction_code = 0xB8,
a61af66fc99e Initial load
duke
parents:
diff changeset
197 instruction_size = 1 + rex_size + wordSize,
a61af66fc99e Initial load
duke
parents:
diff changeset
198 instruction_offset = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
199 data_offset = 1 + rex_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
200 next_instruction_offset = instruction_size,
a61af66fc99e Initial load
duke
parents:
diff changeset
201 register_mask = 0x07
a61af66fc99e Initial load
duke
parents:
diff changeset
202 };
a61af66fc99e Initial load
duke
parents:
diff changeset
203
a61af66fc99e Initial load
duke
parents:
diff changeset
204 address instruction_address() const { return addr_at(instruction_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
205 address next_instruction_address() const { return addr_at(next_instruction_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
206 intptr_t data() const { return ptr_at(data_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
207 void set_data(intptr_t x) { set_ptr_at(data_offset, x); }
a61af66fc99e Initial load
duke
parents:
diff changeset
208
a61af66fc99e Initial load
duke
parents:
diff changeset
209 void verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
210 void print();
a61af66fc99e Initial load
duke
parents:
diff changeset
211
a61af66fc99e Initial load
duke
parents:
diff changeset
212 // unit test stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
213 static void test() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
214
a61af66fc99e Initial load
duke
parents:
diff changeset
215 // Creation
a61af66fc99e Initial load
duke
parents:
diff changeset
216 inline friend NativeMovConstReg* nativeMovConstReg_at(address address);
a61af66fc99e Initial load
duke
parents:
diff changeset
217 inline friend NativeMovConstReg* nativeMovConstReg_before(address address);
a61af66fc99e Initial load
duke
parents:
diff changeset
218 };
a61af66fc99e Initial load
duke
parents:
diff changeset
219
a61af66fc99e Initial load
duke
parents:
diff changeset
220 inline NativeMovConstReg* nativeMovConstReg_at(address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
221 NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
222 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
223 test->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
224 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
225 return test;
a61af66fc99e Initial load
duke
parents:
diff changeset
226 }
a61af66fc99e Initial load
duke
parents:
diff changeset
227
a61af66fc99e Initial load
duke
parents:
diff changeset
228 inline NativeMovConstReg* nativeMovConstReg_before(address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
229 NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_size - NativeMovConstReg::instruction_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
230 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
231 test->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
232 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
233 return test;
a61af66fc99e Initial load
duke
parents:
diff changeset
234 }
a61af66fc99e Initial load
duke
parents:
diff changeset
235
a61af66fc99e Initial load
duke
parents:
diff changeset
236 class NativeMovConstRegPatching: public NativeMovConstReg {
a61af66fc99e Initial load
duke
parents:
diff changeset
237 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
238 friend NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
239 NativeMovConstRegPatching* test = (NativeMovConstRegPatching*)(address - instruction_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
240 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
241 test->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
242 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
243 return test;
a61af66fc99e Initial load
duke
parents:
diff changeset
244 }
a61af66fc99e Initial load
duke
parents:
diff changeset
245 };
a61af66fc99e Initial load
duke
parents:
diff changeset
246
a61af66fc99e Initial load
duke
parents:
diff changeset
247 // An interface for accessing/manipulating native moves of the form:
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
248 // mov[b/w/l/q] [reg + offset], reg (instruction_code_reg2mem)
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
249 // mov[b/w/l/q] reg, [reg+offset] (instruction_code_mem2reg
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
250 // mov[s/z]x[w/b/q] [reg + offset], reg
0
a61af66fc99e Initial load
duke
parents:
diff changeset
251 // fld_s [reg+offset]
a61af66fc99e Initial load
duke
parents:
diff changeset
252 // fld_d [reg+offset]
a61af66fc99e Initial load
duke
parents:
diff changeset
253 // fstp_s [reg + offset]
a61af66fc99e Initial load
duke
parents:
diff changeset
254 // fstp_d [reg + offset]
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
255 // mov_literal64 scratch,<pointer> ; mov[b/w/l/q] 0(scratch),reg | mov[b/w/l/q] reg,0(scratch)
0
a61af66fc99e Initial load
duke
parents:
diff changeset
256 //
a61af66fc99e Initial load
duke
parents:
diff changeset
257 // Warning: These routines must be able to handle any instruction sequences
a61af66fc99e Initial load
duke
parents:
diff changeset
258 // that are generated as a result of the load/store byte,word,long
a61af66fc99e Initial load
duke
parents:
diff changeset
259 // macros. For example: The load_unsigned_byte instruction generates
a61af66fc99e Initial load
duke
parents:
diff changeset
260 // an xor reg,reg inst prior to generating the movb instruction. This
a61af66fc99e Initial load
duke
parents:
diff changeset
261 // class must skip the xor instruction.
a61af66fc99e Initial load
duke
parents:
diff changeset
262
a61af66fc99e Initial load
duke
parents:
diff changeset
263 class NativeMovRegMem: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
264 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
265 enum Intel_specific_constants {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
266 instruction_prefix_wide_lo = Assembler::REX,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
267 instruction_prefix_wide_hi = Assembler::REX_WRXB,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
268 instruction_code_xor = 0x33,
a61af66fc99e Initial load
duke
parents:
diff changeset
269 instruction_extended_prefix = 0x0F,
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
270 instruction_code_mem2reg_movslq = 0x63,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
271 instruction_code_mem2reg_movzxb = 0xB6,
a61af66fc99e Initial load
duke
parents:
diff changeset
272 instruction_code_mem2reg_movsxb = 0xBE,
a61af66fc99e Initial load
duke
parents:
diff changeset
273 instruction_code_mem2reg_movzxw = 0xB7,
a61af66fc99e Initial load
duke
parents:
diff changeset
274 instruction_code_mem2reg_movsxw = 0xBF,
a61af66fc99e Initial load
duke
parents:
diff changeset
275 instruction_operandsize_prefix = 0x66,
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
276 instruction_code_reg2mem = 0x89,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
277 instruction_code_mem2reg = 0x8b,
0
a61af66fc99e Initial load
duke
parents:
diff changeset
278 instruction_code_reg2memb = 0x88,
a61af66fc99e Initial load
duke
parents:
diff changeset
279 instruction_code_mem2regb = 0x8a,
a61af66fc99e Initial load
duke
parents:
diff changeset
280 instruction_code_float_s = 0xd9,
a61af66fc99e Initial load
duke
parents:
diff changeset
281 instruction_code_float_d = 0xdd,
a61af66fc99e Initial load
duke
parents:
diff changeset
282 instruction_code_long_volatile = 0xdf,
a61af66fc99e Initial load
duke
parents:
diff changeset
283 instruction_code_xmm_ss_prefix = 0xf3,
a61af66fc99e Initial load
duke
parents:
diff changeset
284 instruction_code_xmm_sd_prefix = 0xf2,
a61af66fc99e Initial load
duke
parents:
diff changeset
285 instruction_code_xmm_code = 0x0f,
a61af66fc99e Initial load
duke
parents:
diff changeset
286 instruction_code_xmm_load = 0x10,
a61af66fc99e Initial load
duke
parents:
diff changeset
287 instruction_code_xmm_store = 0x11,
a61af66fc99e Initial load
duke
parents:
diff changeset
288 instruction_code_xmm_lpd = 0x12,
a61af66fc99e Initial load
duke
parents:
diff changeset
289
a61af66fc99e Initial load
duke
parents:
diff changeset
290 instruction_size = 4,
a61af66fc99e Initial load
duke
parents:
diff changeset
291 instruction_offset = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
292 data_offset = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
293 next_instruction_offset = 4
a61af66fc99e Initial load
duke
parents:
diff changeset
294 };
a61af66fc99e Initial load
duke
parents:
diff changeset
295
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
296 // helper
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
297 int instruction_start() const;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
298
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
299 address instruction_address() const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
300
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
301 address next_instruction_address() const;
0
a61af66fc99e Initial load
duke
parents:
diff changeset
302
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
303 int offset() const;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
305 void set_offset(int x);
0
a61af66fc99e Initial load
duke
parents:
diff changeset
306
a61af66fc99e Initial load
duke
parents:
diff changeset
307 void add_offset_in_bytes(int add_offset) { set_offset ( ( offset() + add_offset ) ); }
a61af66fc99e Initial load
duke
parents:
diff changeset
308
a61af66fc99e Initial load
duke
parents:
diff changeset
309 void verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
310 void print ();
a61af66fc99e Initial load
duke
parents:
diff changeset
311
a61af66fc99e Initial load
duke
parents:
diff changeset
312 // unit test stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
313 static void test() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
314
a61af66fc99e Initial load
duke
parents:
diff changeset
315 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
316 inline friend NativeMovRegMem* nativeMovRegMem_at (address address);
a61af66fc99e Initial load
duke
parents:
diff changeset
317 };
a61af66fc99e Initial load
duke
parents:
diff changeset
318
a61af66fc99e Initial load
duke
parents:
diff changeset
319 inline NativeMovRegMem* nativeMovRegMem_at (address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
320 NativeMovRegMem* test = (NativeMovRegMem*)(address - NativeMovRegMem::instruction_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
321 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
322 test->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
323 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
324 return test;
a61af66fc99e Initial load
duke
parents:
diff changeset
325 }
a61af66fc99e Initial load
duke
parents:
diff changeset
326
a61af66fc99e Initial load
duke
parents:
diff changeset
327 class NativeMovRegMemPatching: public NativeMovRegMem {
a61af66fc99e Initial load
duke
parents:
diff changeset
328 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
329 friend NativeMovRegMemPatching* nativeMovRegMemPatching_at (address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
330 NativeMovRegMemPatching* test = (NativeMovRegMemPatching*)(address - instruction_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
331 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
332 test->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
333 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
334 return test;
a61af66fc99e Initial load
duke
parents:
diff changeset
335 }
a61af66fc99e Initial load
duke
parents:
diff changeset
336 };
a61af66fc99e Initial load
duke
parents:
diff changeset
337
a61af66fc99e Initial load
duke
parents:
diff changeset
338
a61af66fc99e Initial load
duke
parents:
diff changeset
339
a61af66fc99e Initial load
duke
parents:
diff changeset
340 // An interface for accessing/manipulating native leal instruction of form:
a61af66fc99e Initial load
duke
parents:
diff changeset
341 // leal reg, [reg + offset]
a61af66fc99e Initial load
duke
parents:
diff changeset
342
a61af66fc99e Initial load
duke
parents:
diff changeset
343 class NativeLoadAddress: public NativeMovRegMem {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
344 #ifdef AMD64
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
345 static const bool has_rex = true;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
346 static const int rex_size = 1;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
347 #else
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
348 static const bool has_rex = false;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
349 static const int rex_size = 0;
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
350 #endif // AMD64
0
a61af66fc99e Initial load
duke
parents:
diff changeset
351 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
352 enum Intel_specific_constants {
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
353 instruction_prefix_wide = Assembler::REX_W,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
354 instruction_prefix_wide_extended = Assembler::REX_WB,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
355 lea_instruction_code = 0x8D,
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
356 mov64_instruction_code = 0xB8
0
a61af66fc99e Initial load
duke
parents:
diff changeset
357 };
a61af66fc99e Initial load
duke
parents:
diff changeset
358
a61af66fc99e Initial load
duke
parents:
diff changeset
359 void verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
360 void print ();
a61af66fc99e Initial load
duke
parents:
diff changeset
361
a61af66fc99e Initial load
duke
parents:
diff changeset
362 // unit test stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
363 static void test() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
364
a61af66fc99e Initial load
duke
parents:
diff changeset
365 private:
a61af66fc99e Initial load
duke
parents:
diff changeset
366 friend NativeLoadAddress* nativeLoadAddress_at (address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
367 NativeLoadAddress* test = (NativeLoadAddress*)(address - instruction_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
368 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
369 test->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
370 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
371 return test;
a61af66fc99e Initial load
duke
parents:
diff changeset
372 }
a61af66fc99e Initial load
duke
parents:
diff changeset
373 };
a61af66fc99e Initial load
duke
parents:
diff changeset
374
a61af66fc99e Initial load
duke
parents:
diff changeset
375 // jump rel32off
a61af66fc99e Initial load
duke
parents:
diff changeset
376
a61af66fc99e Initial load
duke
parents:
diff changeset
377 class NativeJump: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
378 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
379 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
380 instruction_code = 0xe9,
a61af66fc99e Initial load
duke
parents:
diff changeset
381 instruction_size = 5,
a61af66fc99e Initial load
duke
parents:
diff changeset
382 instruction_offset = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
383 data_offset = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
384 next_instruction_offset = 5
a61af66fc99e Initial load
duke
parents:
diff changeset
385 };
a61af66fc99e Initial load
duke
parents:
diff changeset
386
a61af66fc99e Initial load
duke
parents:
diff changeset
387 address instruction_address() const { return addr_at(instruction_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
388 address next_instruction_address() const { return addr_at(next_instruction_offset); }
a61af66fc99e Initial load
duke
parents:
diff changeset
389 address jump_destination() const {
a61af66fc99e Initial load
duke
parents:
diff changeset
390 address dest = (int_at(data_offset)+next_instruction_address());
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
391 // 32bit used to encode unresolved jmp as jmp -1
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
392 // 64bit can't produce this so it used jump to self.
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
393 // Now 32bit and 64bit use jump to self as the unresolved address
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
394 // which the inline cache code (and relocs) know about
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
395
0
a61af66fc99e Initial load
duke
parents:
diff changeset
396 // return -1 if jump to self
a61af66fc99e Initial load
duke
parents:
diff changeset
397 dest = (dest == (address) this) ? (address) -1 : dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
398 return dest;
a61af66fc99e Initial load
duke
parents:
diff changeset
399 }
a61af66fc99e Initial load
duke
parents:
diff changeset
400
a61af66fc99e Initial load
duke
parents:
diff changeset
401 void set_jump_destination(address dest) {
a61af66fc99e Initial load
duke
parents:
diff changeset
402 intptr_t val = dest - next_instruction_address();
314
3a26e9e4be71 6744422: incorrect handling of -1 in set_jump_destination
never
parents: 304
diff changeset
403 if (dest == (address) -1) {
3a26e9e4be71 6744422: incorrect handling of -1 in set_jump_destination
never
parents: 304
diff changeset
404 val = -5; // jump to self
3a26e9e4be71 6744422: incorrect handling of -1 in set_jump_destination
never
parents: 304
diff changeset
405 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
406 #ifdef AMD64
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
407 assert((labs(val) & 0xFFFFFFFF00000000) == 0 || dest == (address)-1, "must be 32bit offset or -1");
0
a61af66fc99e Initial load
duke
parents:
diff changeset
408 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
409 set_int_at(data_offset, (jint)val);
a61af66fc99e Initial load
duke
parents:
diff changeset
410 }
a61af66fc99e Initial load
duke
parents:
diff changeset
411
a61af66fc99e Initial load
duke
parents:
diff changeset
412 // Creation
a61af66fc99e Initial load
duke
parents:
diff changeset
413 inline friend NativeJump* nativeJump_at(address address);
a61af66fc99e Initial load
duke
parents:
diff changeset
414
a61af66fc99e Initial load
duke
parents:
diff changeset
415 void verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
416
a61af66fc99e Initial load
duke
parents:
diff changeset
417 // Unit testing stuff
a61af66fc99e Initial load
duke
parents:
diff changeset
418 static void test() {}
a61af66fc99e Initial load
duke
parents:
diff changeset
419
a61af66fc99e Initial load
duke
parents:
diff changeset
420 // Insertion of native jump instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
421 static void insert(address code_pos, address entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
422 // MT-safe insertion of native jump at verified method entry
a61af66fc99e Initial load
duke
parents:
diff changeset
423 static void check_verified_entry_alignment(address entry, address verified_entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
424 static void patch_verified_entry(address entry, address verified_entry, address dest);
a61af66fc99e Initial load
duke
parents:
diff changeset
425 };
a61af66fc99e Initial load
duke
parents:
diff changeset
426
a61af66fc99e Initial load
duke
parents:
diff changeset
427 inline NativeJump* nativeJump_at(address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
428 NativeJump* jump = (NativeJump*)(address - NativeJump::instruction_offset);
a61af66fc99e Initial load
duke
parents:
diff changeset
429 #ifdef ASSERT
a61af66fc99e Initial load
duke
parents:
diff changeset
430 jump->verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
431 #endif
a61af66fc99e Initial load
duke
parents:
diff changeset
432 return jump;
a61af66fc99e Initial load
duke
parents:
diff changeset
433 }
a61af66fc99e Initial load
duke
parents:
diff changeset
434
a61af66fc99e Initial load
duke
parents:
diff changeset
435 // Handles all kinds of jump on Intel. Long/far, conditional/unconditional
a61af66fc99e Initial load
duke
parents:
diff changeset
436 class NativeGeneralJump: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
437 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
438 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
439 // Constants does not apply, since the lengths and offsets depends on the actual jump
a61af66fc99e Initial load
duke
parents:
diff changeset
440 // used
a61af66fc99e Initial load
duke
parents:
diff changeset
441 // Instruction codes:
a61af66fc99e Initial load
duke
parents:
diff changeset
442 // Unconditional jumps: 0xE9 (rel32off), 0xEB (rel8off)
a61af66fc99e Initial load
duke
parents:
diff changeset
443 // Conditional jumps: 0x0F8x (rel32off), 0x7x (rel8off)
a61af66fc99e Initial load
duke
parents:
diff changeset
444 unconditional_long_jump = 0xe9,
a61af66fc99e Initial load
duke
parents:
diff changeset
445 unconditional_short_jump = 0xeb,
a61af66fc99e Initial load
duke
parents:
diff changeset
446 instruction_size = 5
a61af66fc99e Initial load
duke
parents:
diff changeset
447 };
a61af66fc99e Initial load
duke
parents:
diff changeset
448
a61af66fc99e Initial load
duke
parents:
diff changeset
449 address instruction_address() const { return addr_at(0); }
a61af66fc99e Initial load
duke
parents:
diff changeset
450 address jump_destination() const;
a61af66fc99e Initial load
duke
parents:
diff changeset
451
a61af66fc99e Initial load
duke
parents:
diff changeset
452 // Creation
a61af66fc99e Initial load
duke
parents:
diff changeset
453 inline friend NativeGeneralJump* nativeGeneralJump_at(address address);
a61af66fc99e Initial load
duke
parents:
diff changeset
454
a61af66fc99e Initial load
duke
parents:
diff changeset
455 // Insertion of native general jump instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
456 static void insert_unconditional(address code_pos, address entry);
a61af66fc99e Initial load
duke
parents:
diff changeset
457 static void replace_mt_safe(address instr_addr, address code_buffer);
a61af66fc99e Initial load
duke
parents:
diff changeset
458
a61af66fc99e Initial load
duke
parents:
diff changeset
459 void verify();
a61af66fc99e Initial load
duke
parents:
diff changeset
460 };
a61af66fc99e Initial load
duke
parents:
diff changeset
461
a61af66fc99e Initial load
duke
parents:
diff changeset
462 inline NativeGeneralJump* nativeGeneralJump_at(address address) {
a61af66fc99e Initial load
duke
parents:
diff changeset
463 NativeGeneralJump* jump = (NativeGeneralJump*)(address);
a61af66fc99e Initial load
duke
parents:
diff changeset
464 debug_only(jump->verify();)
a61af66fc99e Initial load
duke
parents:
diff changeset
465 return jump;
a61af66fc99e Initial load
duke
parents:
diff changeset
466 }
a61af66fc99e Initial load
duke
parents:
diff changeset
467
a61af66fc99e Initial load
duke
parents:
diff changeset
468 class NativePopReg : public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
469 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
470 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
471 instruction_code = 0x58,
a61af66fc99e Initial load
duke
parents:
diff changeset
472 instruction_size = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
473 instruction_offset = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
474 data_offset = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
475 next_instruction_offset = 1
a61af66fc99e Initial load
duke
parents:
diff changeset
476 };
a61af66fc99e Initial load
duke
parents:
diff changeset
477
a61af66fc99e Initial load
duke
parents:
diff changeset
478 // Insert a pop instruction
a61af66fc99e Initial load
duke
parents:
diff changeset
479 static void insert(address code_pos, Register reg);
a61af66fc99e Initial load
duke
parents:
diff changeset
480 };
a61af66fc99e Initial load
duke
parents:
diff changeset
481
a61af66fc99e Initial load
duke
parents:
diff changeset
482
a61af66fc99e Initial load
duke
parents:
diff changeset
483 class NativeIllegalInstruction: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
484 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
485 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
486 instruction_code = 0x0B0F, // Real byte order is: 0x0F, 0x0B
a61af66fc99e Initial load
duke
parents:
diff changeset
487 instruction_size = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
488 instruction_offset = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
489 next_instruction_offset = 2
a61af66fc99e Initial load
duke
parents:
diff changeset
490 };
a61af66fc99e Initial load
duke
parents:
diff changeset
491
a61af66fc99e Initial load
duke
parents:
diff changeset
492 // Insert illegal opcode as specific address
a61af66fc99e Initial load
duke
parents:
diff changeset
493 static void insert(address code_pos);
a61af66fc99e Initial load
duke
parents:
diff changeset
494 };
a61af66fc99e Initial load
duke
parents:
diff changeset
495
a61af66fc99e Initial load
duke
parents:
diff changeset
496 // return instruction that does not pop values of the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
497 class NativeReturn: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
498 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
499 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
500 instruction_code = 0xC3,
a61af66fc99e Initial load
duke
parents:
diff changeset
501 instruction_size = 1,
a61af66fc99e Initial load
duke
parents:
diff changeset
502 instruction_offset = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
503 next_instruction_offset = 1
a61af66fc99e Initial load
duke
parents:
diff changeset
504 };
a61af66fc99e Initial load
duke
parents:
diff changeset
505 };
a61af66fc99e Initial load
duke
parents:
diff changeset
506
a61af66fc99e Initial load
duke
parents:
diff changeset
507 // return instruction that does pop values of the stack
a61af66fc99e Initial load
duke
parents:
diff changeset
508 class NativeReturnX: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
509 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
510 enum Intel_specific_constants {
a61af66fc99e Initial load
duke
parents:
diff changeset
511 instruction_code = 0xC2,
a61af66fc99e Initial load
duke
parents:
diff changeset
512 instruction_size = 2,
a61af66fc99e Initial load
duke
parents:
diff changeset
513 instruction_offset = 0,
a61af66fc99e Initial load
duke
parents:
diff changeset
514 next_instruction_offset = 2
a61af66fc99e Initial load
duke
parents:
diff changeset
515 };
a61af66fc99e Initial load
duke
parents:
diff changeset
516 };
a61af66fc99e Initial load
duke
parents:
diff changeset
517
a61af66fc99e Initial load
duke
parents:
diff changeset
518 // Simple test vs memory
a61af66fc99e Initial load
duke
parents:
diff changeset
519 class NativeTstRegMem: public NativeInstruction {
a61af66fc99e Initial load
duke
parents:
diff changeset
520 public:
a61af66fc99e Initial load
duke
parents:
diff changeset
521 enum Intel_specific_constants {
2404
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
522 instruction_rex_prefix_mask = 0xF0,
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
523 instruction_rex_prefix = Assembler::REX,
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
524 instruction_code_memXregl = 0x85,
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
525 modrm_mask = 0x38, // select reg from the ModRM byte
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
526 modrm_reg = 0x00 // rax
0
a61af66fc99e Initial load
duke
parents:
diff changeset
527 };
a61af66fc99e Initial load
duke
parents:
diff changeset
528 };
a61af66fc99e Initial load
duke
parents:
diff changeset
529
a61af66fc99e Initial load
duke
parents:
diff changeset
530 inline bool NativeInstruction::is_illegal() { return (short)int_at(0) == (short)NativeIllegalInstruction::instruction_code; }
a61af66fc99e Initial load
duke
parents:
diff changeset
531 inline bool NativeInstruction::is_call() { return ubyte_at(0) == NativeCall::instruction_code; }
a61af66fc99e Initial load
duke
parents:
diff changeset
532 inline bool NativeInstruction::is_return() { return ubyte_at(0) == NativeReturn::instruction_code ||
a61af66fc99e Initial load
duke
parents:
diff changeset
533 ubyte_at(0) == NativeReturnX::instruction_code; }
a61af66fc99e Initial load
duke
parents:
diff changeset
534 inline bool NativeInstruction::is_jump() { return ubyte_at(0) == NativeJump::instruction_code ||
a61af66fc99e Initial load
duke
parents:
diff changeset
535 ubyte_at(0) == 0xEB; /* short jump */ }
a61af66fc99e Initial load
duke
parents:
diff changeset
536 inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ ||
a61af66fc99e Initial load
duke
parents:
diff changeset
537 (ubyte_at(0) & 0xF0) == 0x70; /* short jump */ }
a61af66fc99e Initial load
duke
parents:
diff changeset
538 inline bool NativeInstruction::is_safepoint_poll() {
a61af66fc99e Initial load
duke
parents:
diff changeset
539 #ifdef AMD64
2404
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
540 if (Assembler::is_polling_page_far()) {
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
541 // two cases, depending on the choice of the base register in the address.
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
542 if (((ubyte_at(0) & NativeTstRegMem::instruction_rex_prefix_mask) == NativeTstRegMem::instruction_rex_prefix &&
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
543 ubyte_at(1) == NativeTstRegMem::instruction_code_memXregl &&
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
544 (ubyte_at(2) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) ||
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
545 ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
546 (ubyte_at(1) & NativeTstRegMem::modrm_mask) == NativeTstRegMem::modrm_reg) {
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
547 return true;
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
548 } else {
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
549 return false;
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
550 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
551 } else {
2404
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
552 if (ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl &&
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
553 ubyte_at(1) == 0x05) { // 00 rax 101
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
554 address fault = addr_at(6) + int_at(2);
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
555 return os::is_poll_address(fault);
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
556 } else {
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
557 return false;
b40d4fa697bf 6964776: c2 should ensure the polling page is reachable on 64 bit
iveresov
parents: 1972
diff changeset
558 }
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
559 }
0
a61af66fc99e Initial load
duke
parents:
diff changeset
560 #else
304
dc7f315e41f7 5108146: Merge i486 and amd64 cpu directories
never
parents: 196
diff changeset
561 return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg ||
0
a61af66fc99e Initial load
duke
parents:
diff changeset
562 ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
563 (ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */
a61af66fc99e Initial load
duke
parents:
diff changeset
564 (os::is_poll_address((address)int_at(2)));
a61af66fc99e Initial load
duke
parents:
diff changeset
565 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
566 }
a61af66fc99e Initial load
duke
parents:
diff changeset
567
a61af66fc99e Initial load
duke
parents:
diff changeset
568 inline bool NativeInstruction::is_mov_literal64() {
a61af66fc99e Initial load
duke
parents:
diff changeset
569 #ifdef AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
570 return ((ubyte_at(0) == Assembler::REX_W || ubyte_at(0) == Assembler::REX_WB) &&
a61af66fc99e Initial load
duke
parents:
diff changeset
571 (ubyte_at(1) & (0xff ^ NativeMovConstReg::register_mask)) == 0xB8);
a61af66fc99e Initial load
duke
parents:
diff changeset
572 #else
a61af66fc99e Initial load
duke
parents:
diff changeset
573 return false;
a61af66fc99e Initial load
duke
parents:
diff changeset
574 #endif // AMD64
a61af66fc99e Initial load
duke
parents:
diff changeset
575 }
1972
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
576
f95d63e2154a 6989984: Use standard include model for Hospot
stefank
parents: 1552
diff changeset
577 #endif // CPU_X86_VM_NATIVEINST_X86_HPP