1 /* |
1 /* |
2 * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
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 |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. |
7 * published by the Free Software Foundation. |
234 } |
234 } |
235 // End code for unit testing implementation of NativeCall class |
235 // End code for unit testing implementation of NativeCall class |
236 |
236 |
237 //------------------------------------------------------------------- |
237 //------------------------------------------------------------------- |
238 |
238 |
239 #ifdef _LP64 |
|
240 |
|
241 void NativeFarCall::set_destination(address dest) { |
239 void NativeFarCall::set_destination(address dest) { |
242 // Address materialized in the instruction stream, so nothing to do. |
240 // Address materialized in the instruction stream, so nothing to do. |
243 return; |
241 return; |
244 #if 0 // What we'd do if we really did want to change the destination |
242 #if 0 // What we'd do if we really did want to change the destination |
245 if (destination() == dest) { |
243 if (destination() == dest) { |
302 int i0 = long_at(sethi_offset); |
298 int i0 = long_at(sethi_offset); |
303 int i1 = long_at(add_offset); |
299 int i1 = long_at(add_offset); |
304 |
300 |
305 // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg" |
301 // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg" |
306 Register rd = inv_rd(i0); |
302 Register rd = inv_rd(i0); |
307 #ifndef _LP64 |
|
308 if (!(is_op2(i0, Assembler::sethi_op2) && rd != G0 && |
|
309 is_op3(i1, Assembler::add_op3, Assembler::arith_op) && |
|
310 inv_immed(i1) && (unsigned)get_simm13(i1) < (1 << 10) && |
|
311 rd == inv_rs1(i1) && rd == inv_rd(i1))) { |
|
312 fatal("not a set_metadata"); |
|
313 } |
|
314 #else |
|
315 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) { |
303 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) { |
316 fatal("not a set_metadata"); |
304 fatal("not a set_metadata"); |
317 } |
305 } |
318 #endif |
|
319 } |
306 } |
320 |
307 |
321 |
308 |
322 void NativeMovConstReg::print() { |
309 void NativeMovConstReg::print() { |
323 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, p2i(instruction_address()), data()); |
310 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, p2i(instruction_address()), data()); |
324 } |
311 } |
325 |
312 |
326 |
313 |
327 #ifdef _LP64 |
|
328 intptr_t NativeMovConstReg::data() const { |
314 intptr_t NativeMovConstReg::data() const { |
329 return data64(addr_at(sethi_offset), long_at(add_offset)); |
315 return data64(addr_at(sethi_offset), long_at(add_offset)); |
330 } |
316 } |
331 #else |
|
332 intptr_t NativeMovConstReg::data() const { |
|
333 return data32(long_at(sethi_offset), long_at(add_offset)); |
|
334 } |
|
335 #endif |
|
336 |
317 |
337 |
318 |
338 void NativeMovConstReg::set_data(intptr_t x) { |
319 void NativeMovConstReg::set_data(intptr_t x) { |
339 #ifdef _LP64 |
|
340 set_data64_sethi(addr_at(sethi_offset), x); |
320 set_data64_sethi(addr_at(sethi_offset), x); |
341 #else |
|
342 set_long_at(sethi_offset, set_data32_sethi( long_at(sethi_offset), x)); |
|
343 #endif |
|
344 set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x)); |
321 set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x)); |
345 |
322 |
346 // also store the value into an oop_Relocation cell, if any |
323 // also store the value into an oop_Relocation cell, if any |
347 CodeBlob* cb = CodeCache::find_blob(instruction_address()); |
324 CodeBlob* cb = CodeCache::find_blob(instruction_address()); |
348 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL; |
325 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL; |
506 tty->print_cr(INTPTR_FORMAT ": mov reg, 0x%x", p2i(instruction_address()), data()); |
483 tty->print_cr(INTPTR_FORMAT ": mov reg, 0x%x", p2i(instruction_address()), data()); |
507 } |
484 } |
508 |
485 |
509 |
486 |
510 int NativeMovConstRegPatching::data() const { |
487 int NativeMovConstRegPatching::data() const { |
511 #ifdef _LP64 |
|
512 return data64(addr_at(sethi_offset), long_at(add_offset)); |
488 return data64(addr_at(sethi_offset), long_at(add_offset)); |
513 #else |
|
514 return data32(long_at(sethi_offset), long_at(add_offset)); |
|
515 #endif |
|
516 } |
489 } |
517 |
490 |
518 |
491 |
519 void NativeMovConstRegPatching::set_data(int x) { |
492 void NativeMovConstRegPatching::set_data(int x) { |
520 #ifdef _LP64 |
|
521 set_data64_sethi(addr_at(sethi_offset), x); |
493 set_data64_sethi(addr_at(sethi_offset), x); |
522 #else |
|
523 set_long_at(sethi_offset, set_data32_sethi(long_at(sethi_offset), x)); |
|
524 #endif |
|
525 set_long_at(add_offset, set_data32_simm13(long_at(add_offset), x)); |
494 set_long_at(add_offset, set_data32_simm13(long_at(add_offset), x)); |
526 |
495 |
527 // also store the value into an oop_Relocation cell, if any |
496 // also store the value into an oop_Relocation cell, if any |
528 CodeBlob* cb = CodeCache::find_blob(instruction_address()); |
497 CodeBlob* cb = CodeCache::find_blob(instruction_address()); |
529 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL; |
498 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL; |
756 int i0 = long_at(sethi_offset); |
725 int i0 = long_at(sethi_offset); |
757 int i1 = long_at(jmpl_offset); |
726 int i1 = long_at(jmpl_offset); |
758 assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); |
727 assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); |
759 // verify the pattern "sethi %hi22(imm), treg ; jmpl treg, %lo10(imm), lreg" |
728 // verify the pattern "sethi %hi22(imm), treg ; jmpl treg, %lo10(imm), lreg" |
760 Register rd = inv_rd(i0); |
729 Register rd = inv_rd(i0); |
761 #ifndef _LP64 |
|
762 if (!(is_op2(i0, Assembler::sethi_op2) && rd != G0 && |
|
763 (is_op3(i1, Assembler::jmpl_op3, Assembler::arith_op)) && |
|
764 inv_immed(i1) && (unsigned)get_simm13(i1) < (1 << 10) && |
|
765 rd == inv_rs1(i1))) { |
|
766 fatal("not a jump_to instruction"); |
|
767 } |
|
768 #else |
|
769 // In LP64, the jump instruction location varies for non relocatable |
730 // In LP64, the jump instruction location varies for non relocatable |
770 // jumps, for example is could be sethi, xor, jmp instead of the |
731 // jumps, for example is could be sethi, xor, jmp instead of the |
771 // 7 instructions for sethi. So let's check sethi only. |
732 // 7 instructions for sethi. So let's check sethi only. |
772 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) { |
733 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) { |
773 fatal("not a jump_to instruction"); |
734 fatal("not a jump_to instruction"); |
774 } |
735 } |
775 #endif |
|
776 } |
736 } |
777 |
737 |
778 |
738 |
779 void NativeJump::print() { |
739 void NativeJump::print() { |
780 tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, p2i(instruction_address()), p2i(jump_destination())); |
740 tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, p2i(instruction_address()), p2i(jump_destination())); |