Mercurial > hg > truffle
annotate src/cpu/x86/vm/nativeInst_x86.hpp @ 2007:5ddfcf4b079e
7003554: (tiered) assert(is_null_object() || handle() != NULL) failed: cannot embed null pointer
Summary: C1 with profiling doesn't check whether the MDO has been really allocated, which can silently fail if the perm gen is full. The solution is to check if the allocation failed and bailout out of inlining or compilation.
Reviewed-by: kvn, never
author | iveresov |
---|---|
date | Thu, 02 Dec 2010 17:21:12 -0800 |
parents | f95d63e2154a |
children | b40d4fa697bf |
rev | line source |
---|---|
0 | 1 /* |
1972 | 2 * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved. |
0 | 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
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 * | |
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 | 22 * |
23 */ | |
24 | |
1972 | 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 "utilities/top.hpp" | |
33 | |
0 | 34 // We have interfaces for the following instructions: |
35 // - NativeInstruction | |
36 // - - NativeCall | |
37 // - - NativeMovConstReg | |
38 // - - NativeMovConstRegPatching | |
39 // - - NativeMovRegMem | |
40 // - - NativeMovRegMemPatching | |
41 // - - NativeJump | |
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 | |
52 class NativeInstruction VALUE_OBJ_CLASS_SPEC { | |
53 friend class Relocation; | |
54 | |
55 public: | |
56 enum Intel_specific_constants { | |
57 nop_instruction_code = 0x90, | |
58 nop_instruction_size = 1 | |
59 }; | |
60 | |
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 | 63 inline bool is_call(); |
64 inline bool is_illegal(); | |
65 inline bool is_return(); | |
66 inline bool is_jump(); | |
67 inline bool is_cond_jump(); | |
68 inline bool is_safepoint_poll(); | |
69 inline bool is_mov_literal64(); | |
70 | |
71 protected: | |
72 address addr_at(int offset) const { return address(this) + offset; } | |
73 | |
74 s_char sbyte_at(int offset) const { return *(s_char*) addr_at(offset); } | |
75 u_char ubyte_at(int offset) const { return *(u_char*) addr_at(offset); } | |
76 | |
77 jint int_at(int offset) const { return *(jint*) addr_at(offset); } | |
78 | |
79 intptr_t ptr_at(int offset) const { return *(intptr_t*) addr_at(offset); } | |
80 | |
81 oop oop_at (int offset) const { return *(oop*) addr_at(offset); } | |
82 | |
83 | |
84 void set_char_at(int offset, char c) { *addr_at(offset) = (u_char)c; wrote(offset); } | |
85 void set_int_at(int offset, jint i) { *(jint*)addr_at(offset) = i; wrote(offset); } | |
86 void set_ptr_at (int offset, intptr_t ptr) { *(intptr_t*) addr_at(offset) = ptr; wrote(offset); } | |
87 void set_oop_at (int offset, oop o) { *(oop*) addr_at(offset) = o; wrote(offset); } | |
88 | |
89 // This doesn't really do anything on Intel, but it is the place where | |
90 // cache invalidation belongs, generically: | |
91 void wrote(int offset); | |
92 | |
93 public: | |
94 | |
95 // unit test stuff | |
96 static void test() {} // override for testing | |
97 | |
98 inline friend NativeInstruction* nativeInstruction_at(address address); | |
99 }; | |
100 | |
101 inline NativeInstruction* nativeInstruction_at(address address) { | |
102 NativeInstruction* inst = (NativeInstruction*)address; | |
103 #ifdef ASSERT | |
104 //inst->verify(); | |
105 #endif | |
106 return inst; | |
107 } | |
108 | |
109 inline NativeCall* nativeCall_at(address address); | |
110 // The NativeCall is an abstraction for accessing/manipulating native call imm32/rel32off | |
111 // instructions (used to manipulate inline caches, primitive & dll calls, etc.). | |
112 | |
113 class NativeCall: public NativeInstruction { | |
114 public: | |
115 enum Intel_specific_constants { | |
116 instruction_code = 0xE8, | |
117 instruction_size = 5, | |
118 instruction_offset = 0, | |
119 displacement_offset = 1, | |
120 return_address_offset = 5 | |
121 }; | |
122 | |
123 enum { cache_line_size = BytesPerWord }; // conservative estimate! | |
124 | |
125 address instruction_address() const { return addr_at(instruction_offset); } | |
126 address next_instruction_address() const { return addr_at(return_address_offset); } | |
127 int displacement() const { return (jint) int_at(displacement_offset); } | |
128 address displacement_address() const { return addr_at(displacement_offset); } | |
129 address return_address() const { return addr_at(return_address_offset); } | |
130 address destination() const; | |
131 void set_destination(address dest) { | |
132 #ifdef AMD64 | |
133 assert((labs((intptr_t) dest - (intptr_t) return_address()) & | |
134 0xFFFFFFFF00000000) == 0, | |
135 "must be 32bit offset"); | |
136 #endif // AMD64 | |
137 set_int_at(displacement_offset, dest - return_address()); | |
138 } | |
139 void set_destination_mt_safe(address dest); | |
140 | |
141 void verify_alignment() { assert((intptr_t)addr_at(displacement_offset) % BytesPerInt == 0, "must be aligned"); } | |
142 void verify(); | |
143 void print(); | |
144 | |
145 // Creation | |
146 inline friend NativeCall* nativeCall_at(address address); | |
147 inline friend NativeCall* nativeCall_before(address return_address); | |
148 | |
149 static bool is_call_at(address instr) { | |
150 return ((*instr) & 0xFF) == NativeCall::instruction_code; | |
151 } | |
152 | |
153 static bool is_call_before(address return_address) { | |
154 return is_call_at(return_address - NativeCall::return_address_offset); | |
155 } | |
156 | |
157 static bool is_call_to(address instr, address target) { | |
158 return nativeInstruction_at(instr)->is_call() && | |
159 nativeCall_at(instr)->destination() == target; | |
160 } | |
161 | |
162 // MT-safe patching of a call instruction. | |
163 static void insert(address code_pos, address entry); | |
164 | |
165 static void replace_mt_safe(address instr_addr, address code_buffer); | |
166 }; | |
167 | |
168 inline NativeCall* nativeCall_at(address address) { | |
169 NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset); | |
170 #ifdef ASSERT | |
171 call->verify(); | |
172 #endif | |
173 return call; | |
174 } | |
175 | |
176 inline NativeCall* nativeCall_before(address return_address) { | |
177 NativeCall* call = (NativeCall*)(return_address - NativeCall::return_address_offset); | |
178 #ifdef ASSERT | |
179 call->verify(); | |
180 #endif | |
181 return call; | |
182 } | |
183 | |
184 // An interface for accessing/manipulating native mov reg, imm32 instructions. | |
185 // (used to manipulate inlined 32bit data dll calls, etc.) | |
186 class NativeMovConstReg: public NativeInstruction { | |
187 #ifdef AMD64 | |
188 static const bool has_rex = true; | |
189 static const int rex_size = 1; | |
190 #else | |
191 static const bool has_rex = false; | |
192 static const int rex_size = 0; | |
193 #endif // AMD64 | |
194 public: | |
195 enum Intel_specific_constants { | |
196 instruction_code = 0xB8, | |
197 instruction_size = 1 + rex_size + wordSize, | |
198 instruction_offset = 0, | |
199 data_offset = 1 + rex_size, | |
200 next_instruction_offset = instruction_size, | |
201 register_mask = 0x07 | |
202 }; | |
203 | |
204 address instruction_address() const { return addr_at(instruction_offset); } | |
205 address next_instruction_address() const { return addr_at(next_instruction_offset); } | |
206 intptr_t data() const { return ptr_at(data_offset); } | |
207 void set_data(intptr_t x) { set_ptr_at(data_offset, x); } | |
208 | |
209 void verify(); | |
210 void print(); | |
211 | |
212 // unit test stuff | |
213 static void test() {} | |
214 | |
215 // Creation | |
216 inline friend NativeMovConstReg* nativeMovConstReg_at(address address); | |
217 inline friend NativeMovConstReg* nativeMovConstReg_before(address address); | |
218 }; | |
219 | |
220 inline NativeMovConstReg* nativeMovConstReg_at(address address) { | |
221 NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_offset); | |
222 #ifdef ASSERT | |
223 test->verify(); | |
224 #endif | |
225 return test; | |
226 } | |
227 | |
228 inline NativeMovConstReg* nativeMovConstReg_before(address address) { | |
229 NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_size - NativeMovConstReg::instruction_offset); | |
230 #ifdef ASSERT | |
231 test->verify(); | |
232 #endif | |
233 return test; | |
234 } | |
235 | |
236 class NativeMovConstRegPatching: public NativeMovConstReg { | |
237 private: | |
238 friend NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address) { | |
239 NativeMovConstRegPatching* test = (NativeMovConstRegPatching*)(address - instruction_offset); | |
240 #ifdef ASSERT | |
241 test->verify(); | |
242 #endif | |
243 return test; | |
244 } | |
245 }; | |
246 | |
247 // An interface for accessing/manipulating native moves of the form: | |
304 | 248 // mov[b/w/l/q] [reg + offset], reg (instruction_code_reg2mem) |
249 // mov[b/w/l/q] reg, [reg+offset] (instruction_code_mem2reg | |
250 // mov[s/z]x[w/b/q] [reg + offset], reg | |
0 | 251 // fld_s [reg+offset] |
252 // fld_d [reg+offset] | |
253 // fstp_s [reg + offset] | |
254 // fstp_d [reg + offset] | |
304 | 255 // mov_literal64 scratch,<pointer> ; mov[b/w/l/q] 0(scratch),reg | mov[b/w/l/q] reg,0(scratch) |
0 | 256 // |
257 // Warning: These routines must be able to handle any instruction sequences | |
258 // that are generated as a result of the load/store byte,word,long | |
259 // macros. For example: The load_unsigned_byte instruction generates | |
260 // an xor reg,reg inst prior to generating the movb instruction. This | |
261 // class must skip the xor instruction. | |
262 | |
263 class NativeMovRegMem: public NativeInstruction { | |
264 public: | |
265 enum Intel_specific_constants { | |
304 | 266 instruction_prefix_wide_lo = Assembler::REX, |
267 instruction_prefix_wide_hi = Assembler::REX_WRXB, | |
0 | 268 instruction_code_xor = 0x33, |
269 instruction_extended_prefix = 0x0F, | |
304 | 270 instruction_code_mem2reg_movslq = 0x63, |
0 | 271 instruction_code_mem2reg_movzxb = 0xB6, |
272 instruction_code_mem2reg_movsxb = 0xBE, | |
273 instruction_code_mem2reg_movzxw = 0xB7, | |
274 instruction_code_mem2reg_movsxw = 0xBF, | |
275 instruction_operandsize_prefix = 0x66, | |
304 | 276 instruction_code_reg2mem = 0x89, |
277 instruction_code_mem2reg = 0x8b, | |
0 | 278 instruction_code_reg2memb = 0x88, |
279 instruction_code_mem2regb = 0x8a, | |
280 instruction_code_float_s = 0xd9, | |
281 instruction_code_float_d = 0xdd, | |
282 instruction_code_long_volatile = 0xdf, | |
283 instruction_code_xmm_ss_prefix = 0xf3, | |
284 instruction_code_xmm_sd_prefix = 0xf2, | |
285 instruction_code_xmm_code = 0x0f, | |
286 instruction_code_xmm_load = 0x10, | |
287 instruction_code_xmm_store = 0x11, | |
288 instruction_code_xmm_lpd = 0x12, | |
289 | |
290 instruction_size = 4, | |
291 instruction_offset = 0, | |
292 data_offset = 2, | |
293 next_instruction_offset = 4 | |
294 }; | |
295 | |
304 | 296 // helper |
297 int instruction_start() const; | |
298 | |
299 address instruction_address() const; | |
0 | 300 |
304 | 301 address next_instruction_address() const; |
0 | 302 |
304 | 303 int offset() const; |
304 | |
305 void set_offset(int x); | |
0 | 306 |
307 void add_offset_in_bytes(int add_offset) { set_offset ( ( offset() + add_offset ) ); } | |
308 | |
309 void verify(); | |
310 void print (); | |
311 | |
312 // unit test stuff | |
313 static void test() {} | |
314 | |
315 private: | |
316 inline friend NativeMovRegMem* nativeMovRegMem_at (address address); | |
317 }; | |
318 | |
319 inline NativeMovRegMem* nativeMovRegMem_at (address address) { | |
320 NativeMovRegMem* test = (NativeMovRegMem*)(address - NativeMovRegMem::instruction_offset); | |
321 #ifdef ASSERT | |
322 test->verify(); | |
323 #endif | |
324 return test; | |
325 } | |
326 | |
327 class NativeMovRegMemPatching: public NativeMovRegMem { | |
328 private: | |
329 friend NativeMovRegMemPatching* nativeMovRegMemPatching_at (address address) { | |
330 NativeMovRegMemPatching* test = (NativeMovRegMemPatching*)(address - instruction_offset); | |
331 #ifdef ASSERT | |
332 test->verify(); | |
333 #endif | |
334 return test; | |
335 } | |
336 }; | |
337 | |
338 | |
339 | |
340 // An interface for accessing/manipulating native leal instruction of form: | |
341 // leal reg, [reg + offset] | |
342 | |
343 class NativeLoadAddress: public NativeMovRegMem { | |
304 | 344 #ifdef AMD64 |
345 static const bool has_rex = true; | |
346 static const int rex_size = 1; | |
347 #else | |
348 static const bool has_rex = false; | |
349 static const int rex_size = 0; | |
350 #endif // AMD64 | |
0 | 351 public: |
352 enum Intel_specific_constants { | |
304 | 353 instruction_prefix_wide = Assembler::REX_W, |
354 instruction_prefix_wide_extended = Assembler::REX_WB, | |
355 lea_instruction_code = 0x8D, | |
356 mov64_instruction_code = 0xB8 | |
0 | 357 }; |
358 | |
359 void verify(); | |
360 void print (); | |
361 | |
362 // unit test stuff | |
363 static void test() {} | |
364 | |
365 private: | |
366 friend NativeLoadAddress* nativeLoadAddress_at (address address) { | |
367 NativeLoadAddress* test = (NativeLoadAddress*)(address - instruction_offset); | |
368 #ifdef ASSERT | |
369 test->verify(); | |
370 #endif | |
371 return test; | |
372 } | |
373 }; | |
374 | |
375 // jump rel32off | |
376 | |
377 class NativeJump: public NativeInstruction { | |
378 public: | |
379 enum Intel_specific_constants { | |
380 instruction_code = 0xe9, | |
381 instruction_size = 5, | |
382 instruction_offset = 0, | |
383 data_offset = 1, | |
384 next_instruction_offset = 5 | |
385 }; | |
386 | |
387 address instruction_address() const { return addr_at(instruction_offset); } | |
388 address next_instruction_address() const { return addr_at(next_instruction_offset); } | |
389 address jump_destination() const { | |
390 address dest = (int_at(data_offset)+next_instruction_address()); | |
304 | 391 // 32bit used to encode unresolved jmp as jmp -1 |
392 // 64bit can't produce this so it used jump to self. | |
393 // Now 32bit and 64bit use jump to self as the unresolved address | |
394 // which the inline cache code (and relocs) know about | |
395 | |
0 | 396 // return -1 if jump to self |
397 dest = (dest == (address) this) ? (address) -1 : dest; | |
398 return dest; | |
399 } | |
400 | |
401 void set_jump_destination(address dest) { | |
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 | 406 #ifdef AMD64 |
304 | 407 assert((labs(val) & 0xFFFFFFFF00000000) == 0 || dest == (address)-1, "must be 32bit offset or -1"); |
0 | 408 #endif // AMD64 |
409 set_int_at(data_offset, (jint)val); | |
410 } | |
411 | |
412 // Creation | |
413 inline friend NativeJump* nativeJump_at(address address); | |
414 | |
415 void verify(); | |
416 | |
417 // Unit testing stuff | |
418 static void test() {} | |
419 | |
420 // Insertion of native jump instruction | |
421 static void insert(address code_pos, address entry); | |
422 // MT-safe insertion of native jump at verified method entry | |
423 static void check_verified_entry_alignment(address entry, address verified_entry); | |
424 static void patch_verified_entry(address entry, address verified_entry, address dest); | |
425 }; | |
426 | |
427 inline NativeJump* nativeJump_at(address address) { | |
428 NativeJump* jump = (NativeJump*)(address - NativeJump::instruction_offset); | |
429 #ifdef ASSERT | |
430 jump->verify(); | |
431 #endif | |
432 return jump; | |
433 } | |
434 | |
435 // Handles all kinds of jump on Intel. Long/far, conditional/unconditional | |
436 class NativeGeneralJump: public NativeInstruction { | |
437 public: | |
438 enum Intel_specific_constants { | |
439 // Constants does not apply, since the lengths and offsets depends on the actual jump | |
440 // used | |
441 // Instruction codes: | |
442 // Unconditional jumps: 0xE9 (rel32off), 0xEB (rel8off) | |
443 // Conditional jumps: 0x0F8x (rel32off), 0x7x (rel8off) | |
444 unconditional_long_jump = 0xe9, | |
445 unconditional_short_jump = 0xeb, | |
446 instruction_size = 5 | |
447 }; | |
448 | |
449 address instruction_address() const { return addr_at(0); } | |
450 address jump_destination() const; | |
451 | |
452 // Creation | |
453 inline friend NativeGeneralJump* nativeGeneralJump_at(address address); | |
454 | |
455 // Insertion of native general jump instruction | |
456 static void insert_unconditional(address code_pos, address entry); | |
457 static void replace_mt_safe(address instr_addr, address code_buffer); | |
458 | |
459 void verify(); | |
460 }; | |
461 | |
462 inline NativeGeneralJump* nativeGeneralJump_at(address address) { | |
463 NativeGeneralJump* jump = (NativeGeneralJump*)(address); | |
464 debug_only(jump->verify();) | |
465 return jump; | |
466 } | |
467 | |
468 class NativePopReg : public NativeInstruction { | |
469 public: | |
470 enum Intel_specific_constants { | |
471 instruction_code = 0x58, | |
472 instruction_size = 1, | |
473 instruction_offset = 0, | |
474 data_offset = 1, | |
475 next_instruction_offset = 1 | |
476 }; | |
477 | |
478 // Insert a pop instruction | |
479 static void insert(address code_pos, Register reg); | |
480 }; | |
481 | |
482 | |
483 class NativeIllegalInstruction: public NativeInstruction { | |
484 public: | |
485 enum Intel_specific_constants { | |
486 instruction_code = 0x0B0F, // Real byte order is: 0x0F, 0x0B | |
487 instruction_size = 2, | |
488 instruction_offset = 0, | |
489 next_instruction_offset = 2 | |
490 }; | |
491 | |
492 // Insert illegal opcode as specific address | |
493 static void insert(address code_pos); | |
494 }; | |
495 | |
496 // return instruction that does not pop values of the stack | |
497 class NativeReturn: public NativeInstruction { | |
498 public: | |
499 enum Intel_specific_constants { | |
500 instruction_code = 0xC3, | |
501 instruction_size = 1, | |
502 instruction_offset = 0, | |
503 next_instruction_offset = 1 | |
504 }; | |
505 }; | |
506 | |
507 // return instruction that does pop values of the stack | |
508 class NativeReturnX: public NativeInstruction { | |
509 public: | |
510 enum Intel_specific_constants { | |
511 instruction_code = 0xC2, | |
512 instruction_size = 2, | |
513 instruction_offset = 0, | |
514 next_instruction_offset = 2 | |
515 }; | |
516 }; | |
517 | |
518 // Simple test vs memory | |
519 class NativeTstRegMem: public NativeInstruction { | |
520 public: | |
521 enum Intel_specific_constants { | |
522 instruction_code_memXregl = 0x85 | |
523 }; | |
524 }; | |
525 | |
526 inline bool NativeInstruction::is_illegal() { return (short)int_at(0) == (short)NativeIllegalInstruction::instruction_code; } | |
527 inline bool NativeInstruction::is_call() { return ubyte_at(0) == NativeCall::instruction_code; } | |
528 inline bool NativeInstruction::is_return() { return ubyte_at(0) == NativeReturn::instruction_code || | |
529 ubyte_at(0) == NativeReturnX::instruction_code; } | |
530 inline bool NativeInstruction::is_jump() { return ubyte_at(0) == NativeJump::instruction_code || | |
531 ubyte_at(0) == 0xEB; /* short jump */ } | |
532 inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ || | |
533 (ubyte_at(0) & 0xF0) == 0x70; /* short jump */ } | |
534 inline bool NativeInstruction::is_safepoint_poll() { | |
535 #ifdef AMD64 | |
304 | 536 if ( ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && |
537 ubyte_at(1) == 0x05 ) { // 00 rax 101 | |
538 address fault = addr_at(6) + int_at(2); | |
539 return os::is_poll_address(fault); | |
540 } else { | |
541 return false; | |
542 } | |
0 | 543 #else |
304 | 544 return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2reg || |
0 | 545 ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) && |
546 (ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */ | |
547 (os::is_poll_address((address)int_at(2))); | |
548 #endif // AMD64 | |
549 } | |
550 | |
551 inline bool NativeInstruction::is_mov_literal64() { | |
552 #ifdef AMD64 | |
553 return ((ubyte_at(0) == Assembler::REX_W || ubyte_at(0) == Assembler::REX_WB) && | |
554 (ubyte_at(1) & (0xff ^ NativeMovConstReg::register_mask)) == 0xB8); | |
555 #else | |
556 return false; | |
557 #endif // AMD64 | |
558 } | |
1972 | 559 |
560 #endif // CPU_X86_VM_NATIVEINST_X86_HPP |