Mercurial > hg > truffle
annotate src/cpu/x86/vm/nativeInst_x86.hpp @ 177:2a8ec427fbe1
6706604: Copyright headers need to be changed to GPL.
Summary: Update the copyrights
Reviewed-by: ohair
author | kamg |
---|---|
date | Thu, 29 May 2008 14:06:30 -0400 |
parents | 018d5b58dd4f |
children | d1605aabd0a1 |
rev | line source |
---|---|
0 | 1 /* |
2 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved. | |
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 * | |
19 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 // We have interfaces for the following instructions: | |
26 // - NativeInstruction | |
27 // - - NativeCall | |
28 // - - NativeMovConstReg | |
29 // - - NativeMovConstRegPatching | |
30 // - - NativeMovRegMem | |
31 // - - NativeMovRegMemPatching | |
32 // - - NativeJump | |
33 // - - NativeIllegalOpCode | |
34 // - - NativeGeneralJump | |
35 // - - NativeReturn | |
36 // - - NativeReturnX (return with argument) | |
37 // - - NativePushConst | |
38 // - - NativeTstRegMem | |
39 | |
40 // The base class for different kinds of native instruction abstractions. | |
41 // Provides the primitive operations to manipulate code relative to this. | |
42 | |
43 class NativeInstruction VALUE_OBJ_CLASS_SPEC { | |
44 friend class Relocation; | |
45 | |
46 public: | |
47 enum Intel_specific_constants { | |
48 nop_instruction_code = 0x90, | |
49 nop_instruction_size = 1 | |
50 }; | |
51 | |
52 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
|
53 bool is_dtrace_trap(); |
0 | 54 inline bool is_call(); |
55 inline bool is_illegal(); | |
56 inline bool is_return(); | |
57 inline bool is_jump(); | |
58 inline bool is_cond_jump(); | |
59 inline bool is_safepoint_poll(); | |
60 inline bool is_mov_literal64(); | |
61 | |
62 protected: | |
63 address addr_at(int offset) const { return address(this) + offset; } | |
64 | |
65 s_char sbyte_at(int offset) const { return *(s_char*) addr_at(offset); } | |
66 u_char ubyte_at(int offset) const { return *(u_char*) addr_at(offset); } | |
67 | |
68 jint int_at(int offset) const { return *(jint*) addr_at(offset); } | |
69 | |
70 intptr_t ptr_at(int offset) const { return *(intptr_t*) addr_at(offset); } | |
71 | |
72 oop oop_at (int offset) const { return *(oop*) addr_at(offset); } | |
73 | |
74 | |
75 void set_char_at(int offset, char c) { *addr_at(offset) = (u_char)c; wrote(offset); } | |
76 void set_int_at(int offset, jint i) { *(jint*)addr_at(offset) = i; wrote(offset); } | |
77 void set_ptr_at (int offset, intptr_t ptr) { *(intptr_t*) addr_at(offset) = ptr; wrote(offset); } | |
78 void set_oop_at (int offset, oop o) { *(oop*) addr_at(offset) = o; wrote(offset); } | |
79 | |
80 // This doesn't really do anything on Intel, but it is the place where | |
81 // cache invalidation belongs, generically: | |
82 void wrote(int offset); | |
83 | |
84 public: | |
85 | |
86 // unit test stuff | |
87 static void test() {} // override for testing | |
88 | |
89 inline friend NativeInstruction* nativeInstruction_at(address address); | |
90 }; | |
91 | |
92 inline NativeInstruction* nativeInstruction_at(address address) { | |
93 NativeInstruction* inst = (NativeInstruction*)address; | |
94 #ifdef ASSERT | |
95 //inst->verify(); | |
96 #endif | |
97 return inst; | |
98 } | |
99 | |
100 inline NativeCall* nativeCall_at(address address); | |
101 // The NativeCall is an abstraction for accessing/manipulating native call imm32/rel32off | |
102 // instructions (used to manipulate inline caches, primitive & dll calls, etc.). | |
103 | |
104 class NativeCall: public NativeInstruction { | |
105 public: | |
106 enum Intel_specific_constants { | |
107 instruction_code = 0xE8, | |
108 instruction_size = 5, | |
109 instruction_offset = 0, | |
110 displacement_offset = 1, | |
111 return_address_offset = 5 | |
112 }; | |
113 | |
114 enum { cache_line_size = BytesPerWord }; // conservative estimate! | |
115 | |
116 address instruction_address() const { return addr_at(instruction_offset); } | |
117 address next_instruction_address() const { return addr_at(return_address_offset); } | |
118 int displacement() const { return (jint) int_at(displacement_offset); } | |
119 address displacement_address() const { return addr_at(displacement_offset); } | |
120 address return_address() const { return addr_at(return_address_offset); } | |
121 address destination() const; | |
122 void set_destination(address dest) { | |
123 #ifdef AMD64 | |
124 assert((labs((intptr_t) dest - (intptr_t) return_address()) & | |
125 0xFFFFFFFF00000000) == 0, | |
126 "must be 32bit offset"); | |
127 #endif // AMD64 | |
128 set_int_at(displacement_offset, dest - return_address()); | |
129 } | |
130 void set_destination_mt_safe(address dest); | |
131 | |
132 void verify_alignment() { assert((intptr_t)addr_at(displacement_offset) % BytesPerInt == 0, "must be aligned"); } | |
133 void verify(); | |
134 void print(); | |
135 | |
136 // Creation | |
137 inline friend NativeCall* nativeCall_at(address address); | |
138 inline friend NativeCall* nativeCall_before(address return_address); | |
139 | |
140 static bool is_call_at(address instr) { | |
141 return ((*instr) & 0xFF) == NativeCall::instruction_code; | |
142 } | |
143 | |
144 static bool is_call_before(address return_address) { | |
145 return is_call_at(return_address - NativeCall::return_address_offset); | |
146 } | |
147 | |
148 static bool is_call_to(address instr, address target) { | |
149 return nativeInstruction_at(instr)->is_call() && | |
150 nativeCall_at(instr)->destination() == target; | |
151 } | |
152 | |
153 // MT-safe patching of a call instruction. | |
154 static void insert(address code_pos, address entry); | |
155 | |
156 static void replace_mt_safe(address instr_addr, address code_buffer); | |
157 }; | |
158 | |
159 inline NativeCall* nativeCall_at(address address) { | |
160 NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset); | |
161 #ifdef ASSERT | |
162 call->verify(); | |
163 #endif | |
164 return call; | |
165 } | |
166 | |
167 inline NativeCall* nativeCall_before(address return_address) { | |
168 NativeCall* call = (NativeCall*)(return_address - NativeCall::return_address_offset); | |
169 #ifdef ASSERT | |
170 call->verify(); | |
171 #endif | |
172 return call; | |
173 } | |
174 | |
175 // An interface for accessing/manipulating native mov reg, imm32 instructions. | |
176 // (used to manipulate inlined 32bit data dll calls, etc.) | |
177 class NativeMovConstReg: public NativeInstruction { | |
178 #ifdef AMD64 | |
179 static const bool has_rex = true; | |
180 static const int rex_size = 1; | |
181 #else | |
182 static const bool has_rex = false; | |
183 static const int rex_size = 0; | |
184 #endif // AMD64 | |
185 public: | |
186 enum Intel_specific_constants { | |
187 instruction_code = 0xB8, | |
188 instruction_size = 1 + rex_size + wordSize, | |
189 instruction_offset = 0, | |
190 data_offset = 1 + rex_size, | |
191 next_instruction_offset = instruction_size, | |
192 register_mask = 0x07 | |
193 }; | |
194 | |
195 address instruction_address() const { return addr_at(instruction_offset); } | |
196 address next_instruction_address() const { return addr_at(next_instruction_offset); } | |
197 intptr_t data() const { return ptr_at(data_offset); } | |
198 void set_data(intptr_t x) { set_ptr_at(data_offset, x); } | |
199 | |
200 void verify(); | |
201 void print(); | |
202 | |
203 // unit test stuff | |
204 static void test() {} | |
205 | |
206 // Creation | |
207 inline friend NativeMovConstReg* nativeMovConstReg_at(address address); | |
208 inline friend NativeMovConstReg* nativeMovConstReg_before(address address); | |
209 }; | |
210 | |
211 inline NativeMovConstReg* nativeMovConstReg_at(address address) { | |
212 NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_offset); | |
213 #ifdef ASSERT | |
214 test->verify(); | |
215 #endif | |
216 return test; | |
217 } | |
218 | |
219 inline NativeMovConstReg* nativeMovConstReg_before(address address) { | |
220 NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_size - NativeMovConstReg::instruction_offset); | |
221 #ifdef ASSERT | |
222 test->verify(); | |
223 #endif | |
224 return test; | |
225 } | |
226 | |
227 class NativeMovConstRegPatching: public NativeMovConstReg { | |
228 private: | |
229 friend NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address) { | |
230 NativeMovConstRegPatching* test = (NativeMovConstRegPatching*)(address - instruction_offset); | |
231 #ifdef ASSERT | |
232 test->verify(); | |
233 #endif | |
234 return test; | |
235 } | |
236 }; | |
237 | |
238 #ifndef AMD64 | |
239 | |
240 // An interface for accessing/manipulating native moves of the form: | |
241 // mov[b/w/l] [reg + offset], reg (instruction_code_reg2mem) | |
242 // mov[b/w/l] reg, [reg+offset] (instruction_code_mem2reg | |
243 // mov[s/z]x[w/b] [reg + offset], reg | |
244 // fld_s [reg+offset] | |
245 // fld_d [reg+offset] | |
246 // fstp_s [reg + offset] | |
247 // fstp_d [reg + offset] | |
248 // | |
249 // Warning: These routines must be able to handle any instruction sequences | |
250 // that are generated as a result of the load/store byte,word,long | |
251 // macros. For example: The load_unsigned_byte instruction generates | |
252 // an xor reg,reg inst prior to generating the movb instruction. This | |
253 // class must skip the xor instruction. | |
254 | |
255 class NativeMovRegMem: public NativeInstruction { | |
256 public: | |
257 enum Intel_specific_constants { | |
258 instruction_code_xor = 0x33, | |
259 instruction_extended_prefix = 0x0F, | |
260 instruction_code_mem2reg_movzxb = 0xB6, | |
261 instruction_code_mem2reg_movsxb = 0xBE, | |
262 instruction_code_mem2reg_movzxw = 0xB7, | |
263 instruction_code_mem2reg_movsxw = 0xBF, | |
264 instruction_operandsize_prefix = 0x66, | |
265 instruction_code_reg2meml = 0x89, | |
266 instruction_code_mem2regl = 0x8b, | |
267 instruction_code_reg2memb = 0x88, | |
268 instruction_code_mem2regb = 0x8a, | |
269 instruction_code_float_s = 0xd9, | |
270 instruction_code_float_d = 0xdd, | |
271 instruction_code_long_volatile = 0xdf, | |
272 instruction_code_xmm_ss_prefix = 0xf3, | |
273 instruction_code_xmm_sd_prefix = 0xf2, | |
274 instruction_code_xmm_code = 0x0f, | |
275 instruction_code_xmm_load = 0x10, | |
276 instruction_code_xmm_store = 0x11, | |
277 instruction_code_xmm_lpd = 0x12, | |
278 | |
279 instruction_size = 4, | |
280 instruction_offset = 0, | |
281 data_offset = 2, | |
282 next_instruction_offset = 4 | |
283 }; | |
284 | |
285 address instruction_address() const { | |
286 if (*addr_at(instruction_offset) == instruction_operandsize_prefix && | |
287 *addr_at(instruction_offset+1) != instruction_code_xmm_code) { | |
288 return addr_at(instruction_offset+1); // Not SSE instructions | |
289 } | |
290 else if (*addr_at(instruction_offset) == instruction_extended_prefix) { | |
291 return addr_at(instruction_offset+1); | |
292 } | |
293 else if (*addr_at(instruction_offset) == instruction_code_xor) { | |
294 return addr_at(instruction_offset+2); | |
295 } | |
296 else return addr_at(instruction_offset); | |
297 } | |
298 | |
299 address next_instruction_address() const { | |
300 switch (*addr_at(instruction_offset)) { | |
301 case instruction_operandsize_prefix: | |
302 if (*addr_at(instruction_offset+1) == instruction_code_xmm_code) | |
303 return instruction_address() + instruction_size; // SSE instructions | |
304 case instruction_extended_prefix: | |
305 return instruction_address() + instruction_size + 1; | |
306 case instruction_code_reg2meml: | |
307 case instruction_code_mem2regl: | |
308 case instruction_code_reg2memb: | |
309 case instruction_code_mem2regb: | |
310 case instruction_code_xor: | |
311 return instruction_address() + instruction_size + 2; | |
312 default: | |
313 return instruction_address() + instruction_size; | |
314 } | |
315 } | |
316 int offset() const{ | |
317 if (*addr_at(instruction_offset) == instruction_operandsize_prefix && | |
318 *addr_at(instruction_offset+1) != instruction_code_xmm_code) { | |
319 return int_at(data_offset+1); // Not SSE instructions | |
320 } | |
321 else if (*addr_at(instruction_offset) == instruction_extended_prefix) { | |
322 return int_at(data_offset+1); | |
323 } | |
324 else if (*addr_at(instruction_offset) == instruction_code_xor || | |
325 *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix || | |
326 *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix || | |
327 *addr_at(instruction_offset) == instruction_operandsize_prefix) { | |
328 return int_at(data_offset+2); | |
329 } | |
330 else return int_at(data_offset); | |
331 } | |
332 | |
333 void set_offset(int x) { | |
334 if (*addr_at(instruction_offset) == instruction_operandsize_prefix && | |
335 *addr_at(instruction_offset+1) != instruction_code_xmm_code) { | |
336 set_int_at(data_offset+1, x); // Not SSE instructions | |
337 } | |
338 else if (*addr_at(instruction_offset) == instruction_extended_prefix) { | |
339 set_int_at(data_offset+1, x); | |
340 } | |
341 else if (*addr_at(instruction_offset) == instruction_code_xor || | |
342 *addr_at(instruction_offset) == instruction_code_xmm_ss_prefix || | |
343 *addr_at(instruction_offset) == instruction_code_xmm_sd_prefix || | |
344 *addr_at(instruction_offset) == instruction_operandsize_prefix) { | |
345 set_int_at(data_offset+2, x); | |
346 } | |
347 else set_int_at(data_offset, x); | |
348 } | |
349 | |
350 void add_offset_in_bytes(int add_offset) { set_offset ( ( offset() + add_offset ) ); } | |
351 void copy_instruction_to(address new_instruction_address); | |
352 | |
353 void verify(); | |
354 void print (); | |
355 | |
356 // unit test stuff | |
357 static void test() {} | |
358 | |
359 private: | |
360 inline friend NativeMovRegMem* nativeMovRegMem_at (address address); | |
361 }; | |
362 | |
363 inline NativeMovRegMem* nativeMovRegMem_at (address address) { | |
364 NativeMovRegMem* test = (NativeMovRegMem*)(address - NativeMovRegMem::instruction_offset); | |
365 #ifdef ASSERT | |
366 test->verify(); | |
367 #endif | |
368 return test; | |
369 } | |
370 | |
371 class NativeMovRegMemPatching: public NativeMovRegMem { | |
372 private: | |
373 friend NativeMovRegMemPatching* nativeMovRegMemPatching_at (address address) { | |
374 NativeMovRegMemPatching* test = (NativeMovRegMemPatching*)(address - instruction_offset); | |
375 #ifdef ASSERT | |
376 test->verify(); | |
377 #endif | |
378 return test; | |
379 } | |
380 }; | |
381 | |
382 | |
383 | |
384 // An interface for accessing/manipulating native leal instruction of form: | |
385 // leal reg, [reg + offset] | |
386 | |
387 class NativeLoadAddress: public NativeMovRegMem { | |
388 public: | |
389 enum Intel_specific_constants { | |
390 instruction_code = 0x8D | |
391 }; | |
392 | |
393 void verify(); | |
394 void print (); | |
395 | |
396 // unit test stuff | |
397 static void test() {} | |
398 | |
399 private: | |
400 friend NativeLoadAddress* nativeLoadAddress_at (address address) { | |
401 NativeLoadAddress* test = (NativeLoadAddress*)(address - instruction_offset); | |
402 #ifdef ASSERT | |
403 test->verify(); | |
404 #endif | |
405 return test; | |
406 } | |
407 }; | |
408 | |
409 #endif // AMD64 | |
410 | |
411 // jump rel32off | |
412 | |
413 class NativeJump: public NativeInstruction { | |
414 public: | |
415 enum Intel_specific_constants { | |
416 instruction_code = 0xe9, | |
417 instruction_size = 5, | |
418 instruction_offset = 0, | |
419 data_offset = 1, | |
420 next_instruction_offset = 5 | |
421 }; | |
422 | |
423 address instruction_address() const { return addr_at(instruction_offset); } | |
424 address next_instruction_address() const { return addr_at(next_instruction_offset); } | |
425 address jump_destination() const { | |
426 address dest = (int_at(data_offset)+next_instruction_address()); | |
427 #ifdef AMD64 // What is this about? | |
428 // return -1 if jump to self | |
429 dest = (dest == (address) this) ? (address) -1 : dest; | |
430 #endif // AMD64 | |
431 return dest; | |
432 } | |
433 | |
434 void set_jump_destination(address dest) { | |
435 intptr_t val = dest - next_instruction_address(); | |
436 #ifdef AMD64 | |
437 if (dest == (address) -1) { // can't encode jump to -1 | |
438 val = -5; // jump to self | |
439 } else { | |
440 assert((labs(val) & 0xFFFFFFFF00000000) == 0, | |
441 "must be 32bit offset"); | |
442 } | |
443 #endif // AMD64 | |
444 set_int_at(data_offset, (jint)val); | |
445 } | |
446 | |
447 // Creation | |
448 inline friend NativeJump* nativeJump_at(address address); | |
449 | |
450 void verify(); | |
451 | |
452 // Unit testing stuff | |
453 static void test() {} | |
454 | |
455 // Insertion of native jump instruction | |
456 static void insert(address code_pos, address entry); | |
457 // MT-safe insertion of native jump at verified method entry | |
458 static void check_verified_entry_alignment(address entry, address verified_entry); | |
459 static void patch_verified_entry(address entry, address verified_entry, address dest); | |
460 }; | |
461 | |
462 inline NativeJump* nativeJump_at(address address) { | |
463 NativeJump* jump = (NativeJump*)(address - NativeJump::instruction_offset); | |
464 #ifdef ASSERT | |
465 jump->verify(); | |
466 #endif | |
467 return jump; | |
468 } | |
469 | |
470 // Handles all kinds of jump on Intel. Long/far, conditional/unconditional | |
471 class NativeGeneralJump: public NativeInstruction { | |
472 public: | |
473 enum Intel_specific_constants { | |
474 // Constants does not apply, since the lengths and offsets depends on the actual jump | |
475 // used | |
476 // Instruction codes: | |
477 // Unconditional jumps: 0xE9 (rel32off), 0xEB (rel8off) | |
478 // Conditional jumps: 0x0F8x (rel32off), 0x7x (rel8off) | |
479 unconditional_long_jump = 0xe9, | |
480 unconditional_short_jump = 0xeb, | |
481 instruction_size = 5 | |
482 }; | |
483 | |
484 address instruction_address() const { return addr_at(0); } | |
485 address jump_destination() const; | |
486 | |
487 // Creation | |
488 inline friend NativeGeneralJump* nativeGeneralJump_at(address address); | |
489 | |
490 // Insertion of native general jump instruction | |
491 static void insert_unconditional(address code_pos, address entry); | |
492 static void replace_mt_safe(address instr_addr, address code_buffer); | |
493 | |
494 void verify(); | |
495 }; | |
496 | |
497 inline NativeGeneralJump* nativeGeneralJump_at(address address) { | |
498 NativeGeneralJump* jump = (NativeGeneralJump*)(address); | |
499 debug_only(jump->verify();) | |
500 return jump; | |
501 } | |
502 | |
503 class NativePopReg : public NativeInstruction { | |
504 public: | |
505 enum Intel_specific_constants { | |
506 instruction_code = 0x58, | |
507 instruction_size = 1, | |
508 instruction_offset = 0, | |
509 data_offset = 1, | |
510 next_instruction_offset = 1 | |
511 }; | |
512 | |
513 // Insert a pop instruction | |
514 static void insert(address code_pos, Register reg); | |
515 }; | |
516 | |
517 | |
518 class NativeIllegalInstruction: public NativeInstruction { | |
519 public: | |
520 enum Intel_specific_constants { | |
521 instruction_code = 0x0B0F, // Real byte order is: 0x0F, 0x0B | |
522 instruction_size = 2, | |
523 instruction_offset = 0, | |
524 next_instruction_offset = 2 | |
525 }; | |
526 | |
527 // Insert illegal opcode as specific address | |
528 static void insert(address code_pos); | |
529 }; | |
530 | |
531 // return instruction that does not pop values of the stack | |
532 class NativeReturn: public NativeInstruction { | |
533 public: | |
534 enum Intel_specific_constants { | |
535 instruction_code = 0xC3, | |
536 instruction_size = 1, | |
537 instruction_offset = 0, | |
538 next_instruction_offset = 1 | |
539 }; | |
540 }; | |
541 | |
542 // return instruction that does pop values of the stack | |
543 class NativeReturnX: public NativeInstruction { | |
544 public: | |
545 enum Intel_specific_constants { | |
546 instruction_code = 0xC2, | |
547 instruction_size = 2, | |
548 instruction_offset = 0, | |
549 next_instruction_offset = 2 | |
550 }; | |
551 }; | |
552 | |
553 // Simple test vs memory | |
554 class NativeTstRegMem: public NativeInstruction { | |
555 public: | |
556 enum Intel_specific_constants { | |
557 instruction_code_memXregl = 0x85 | |
558 }; | |
559 }; | |
560 | |
561 inline bool NativeInstruction::is_illegal() { return (short)int_at(0) == (short)NativeIllegalInstruction::instruction_code; } | |
562 inline bool NativeInstruction::is_call() { return ubyte_at(0) == NativeCall::instruction_code; } | |
563 inline bool NativeInstruction::is_return() { return ubyte_at(0) == NativeReturn::instruction_code || | |
564 ubyte_at(0) == NativeReturnX::instruction_code; } | |
565 inline bool NativeInstruction::is_jump() { return ubyte_at(0) == NativeJump::instruction_code || | |
566 ubyte_at(0) == 0xEB; /* short jump */ } | |
567 inline bool NativeInstruction::is_cond_jump() { return (int_at(0) & 0xF0FF) == 0x800F /* long jump */ || | |
568 (ubyte_at(0) & 0xF0) == 0x70; /* short jump */ } | |
569 inline bool NativeInstruction::is_safepoint_poll() { | |
570 #ifdef AMD64 | |
571 return ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl && | |
572 ubyte_at(1) == 0x05 && // 00 rax 101 | |
573 ((intptr_t) addr_at(6)) + int_at(2) == (intptr_t) os::get_polling_page(); | |
574 #else | |
575 return ( ubyte_at(0) == NativeMovRegMem::instruction_code_mem2regl || | |
576 ubyte_at(0) == NativeTstRegMem::instruction_code_memXregl ) && | |
577 (ubyte_at(1)&0xC7) == 0x05 && /* Mod R/M == disp32 */ | |
578 (os::is_poll_address((address)int_at(2))); | |
579 #endif // AMD64 | |
580 } | |
581 | |
582 inline bool NativeInstruction::is_mov_literal64() { | |
583 #ifdef AMD64 | |
584 return ((ubyte_at(0) == Assembler::REX_W || ubyte_at(0) == Assembler::REX_WB) && | |
585 (ubyte_at(1) & (0xff ^ NativeMovConstReg::register_mask)) == 0xB8); | |
586 #else | |
587 return false; | |
588 #endif // AMD64 | |
589 } |