< prev index next >

src/cpu/sparc/vm/nativeInst_sparc.cpp

Print this page


   1 /*
   2  * Copyright (c) 1997, 2015, Oracle and/or its affiliates. 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 219   nc = nativeCall_at( cb.insts_begin() );
 220   nc->print();
 221 
 222   nc = nativeCall_overwriting_at( nc->next_instruction_address() );
 223   for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
 224     nc->set_destination( cb.insts_begin() + offsets[idx] );
 225     assert(nc->destination() == (cb.insts_begin() + offsets[idx]), "check unit test");
 226     nc->print();
 227   }
 228 
 229   nc = nativeCall_before( cb.insts_begin() + 8 );
 230   nc->print();
 231 
 232   VM_Version::revert();
 233 #endif
 234 }
 235 // End code for unit testing implementation of NativeCall class
 236 
 237 //-------------------------------------------------------------------
 238 
 239 #ifdef _LP64
 240 
 241 void NativeFarCall::set_destination(address dest) {
 242   // Address materialized in the instruction stream, so nothing to do.
 243   return;
 244 #if 0 // What we'd do if we really did want to change the destination
 245   if (destination() == dest) {
 246     return;
 247   }
 248   ResourceMark rm;
 249   CodeBuffer buf(addr_at(0), instruction_size + 1);
 250   MacroAssembler* _masm = new MacroAssembler(&buf);
 251   // Generate the new sequence
 252   AddressLiteral(dest);
 253   _masm->jumpl_to(dest, O7, O7);
 254   ICache::invalidate_range(addr_at(0), instruction_size );
 255 #endif
 256 }
 257 
 258 void NativeFarCall::verify() {
 259   // make sure code pattern is actually a jumpl_to instruction
 260   assert((int)instruction_size == (int)NativeJump::instruction_size, "same as jump_to");


 273 bool NativeFarCall::destination_is_compiled_verified_entry_point() {
 274   nmethod* callee = CodeCache::find_nmethod(destination());
 275   if (callee == NULL) {
 276     return false;
 277   } else {
 278     return destination() == callee->verified_entry_point();
 279   }
 280 }
 281 
 282 // MT-safe patching of a far call.
 283 void NativeFarCall::replace_mt_safe(address instr_addr, address code_buffer) {
 284   Unimplemented();
 285 }
 286 
 287 // Code for unit testing implementation of NativeFarCall class
 288 void NativeFarCall::test() {
 289   Unimplemented();
 290 }
 291 // End code for unit testing implementation of NativeFarCall class
 292 
 293 #endif // _LP64
 294 
 295 //-------------------------------------------------------------------
 296 
 297 
 298 void NativeMovConstReg::verify() {
 299   NativeInstruction::verify();
 300   // make sure code pattern is actually a "set_metadata" synthetic instruction
 301   // see MacroAssembler::set_oop()
 302   int i0 = long_at(sethi_offset);
 303   int i1 = long_at(add_offset);
 304 
 305   // verify the pattern "sethi %hi22(imm), reg ;  add reg, %lo10(imm), reg"
 306   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 ) {
 316     fatal("not a set_metadata");
 317   }
 318 #endif
 319 }
 320 
 321 
 322 void NativeMovConstReg::print() {
 323   tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, p2i(instruction_address()), data());
 324 }
 325 
 326 
 327 #ifdef _LP64
 328 intptr_t NativeMovConstReg::data() const {
 329   return data64(addr_at(sethi_offset), long_at(add_offset));
 330 }
 331 #else
 332 intptr_t NativeMovConstReg::data() const {
 333   return data32(long_at(sethi_offset), long_at(add_offset));
 334 }
 335 #endif
 336 
 337 
 338 void NativeMovConstReg::set_data(intptr_t x) {
 339 #ifdef _LP64
 340   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));
 345 
 346   // also store the value into an oop_Relocation cell, if any
 347   CodeBlob* cb = CodeCache::find_blob(instruction_address());
 348   nmethod*  nm = cb ? cb->as_nmethod_or_null() : NULL;
 349   if (nm != NULL) {
 350     RelocIterator iter(nm, instruction_address(), next_instruction_address());
 351     oop* oop_addr = NULL;
 352     Metadata** metadata_addr = NULL;
 353     while (iter.next()) {
 354       if (iter.type() == relocInfo::oop_type) {
 355         oop_Relocation *r = iter.oop_reloc();
 356         if (oop_addr == NULL) {
 357           oop_addr = r->oop_addr();
 358           *oop_addr = cast_to_oop(x);
 359         } else {
 360           assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
 361         }
 362       }
 363       if (iter.type() == relocInfo::metadata_type) {


 491   // The casual reader should note that on Sparc a nop is a special case if sethi
 492   // in which the destination register is %g0.
 493   Register rd0 = inv_rd(i0);
 494   Register rd1 = inv_rd(i1);
 495   if (!(is_op2(i0, Assembler::sethi_op2) && rd0 != G0 &&
 496         is_op2(i1, Assembler::sethi_op2) && rd1 == G0 &&        // nop is a special case of sethi
 497         is_op3(i2, Assembler::add_op3, Assembler::arith_op) &&
 498         inv_immed(i2) && (unsigned)get_simm13(i2) < (1 << 10) &&
 499         rd0 == inv_rs1(i2) && rd0 == inv_rd(i2))) {
 500     fatal("not a set_metadata");
 501   }
 502 }
 503 
 504 
 505 void NativeMovConstRegPatching::print() {
 506   tty->print_cr(INTPTR_FORMAT ": mov reg, 0x%x", p2i(instruction_address()), data());
 507 }
 508 
 509 
 510 int NativeMovConstRegPatching::data() const {
 511 #ifdef _LP64
 512   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 }
 517 
 518 
 519 void NativeMovConstRegPatching::set_data(int x) {
 520 #ifdef _LP64
 521   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));
 526 
 527   // also store the value into an oop_Relocation cell, if any
 528   CodeBlob* cb = CodeCache::find_blob(instruction_address());
 529   nmethod*  nm = cb ? cb->as_nmethod_or_null() : NULL;
 530   if (nm != NULL) {
 531     RelocIterator iter(nm, instruction_address(), next_instruction_address());
 532     oop* oop_addr = NULL;
 533     Metadata** metadata_addr = NULL;
 534     while (iter.next()) {
 535       if (iter.type() == relocInfo::oop_type) {
 536         oop_Relocation *r = iter.oop_reloc();
 537         if (oop_addr == NULL) {
 538           oop_addr = r->oop_addr();
 539           *oop_addr = cast_to_oop(x);
 540         } else {
 541           assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
 542         }
 543       }
 544       if (iter.type() == relocInfo::metadata_type) {


 741     nm->print();
 742   }
 743 
 744   VM_Version::revert();
 745 #endif // ASSERT
 746 }
 747 
 748 // End code for unit testing implementation of NativeMovRegMem class
 749 
 750 
 751 //--------------------------------------------------------------------------------
 752 
 753 
 754 void NativeJump::verify() {
 755   NativeInstruction::verify();
 756   int i0 = long_at(sethi_offset);
 757   int i1 = long_at(jmpl_offset);
 758   assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok");
 759   // verify the pattern "sethi %hi22(imm), treg ;  jmpl treg, %lo10(imm), lreg"
 760   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
 770   // jumps, for example is could be sethi, xor, jmp instead of the
 771   // 7 instructions for sethi.  So let's check sethi only.
 772   if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
 773     fatal("not a jump_to instruction");
 774   }
 775 #endif
 776 }
 777 
 778 
 779 void NativeJump::print() {
 780   tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, p2i(instruction_address()), p2i(jump_destination()));
 781 }
 782 
 783 
 784 // Code for unit testing implementation of NativeJump class
 785 void NativeJump::test() {
 786 #ifdef ASSERT
 787   ResourceMark rm;
 788   CodeBuffer cb("test", 100, 100);
 789   MacroAssembler* a = new MacroAssembler(&cb);
 790   NativeJump* nj;
 791   uint idx;
 792   int offsets[] = {
 793     0x0,
 794     0xffffffff,
 795     0x7fffffff,


   1 /*
   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.
   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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 219   nc = nativeCall_at( cb.insts_begin() );
 220   nc->print();
 221 
 222   nc = nativeCall_overwriting_at( nc->next_instruction_address() );
 223   for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) {
 224     nc->set_destination( cb.insts_begin() + offsets[idx] );
 225     assert(nc->destination() == (cb.insts_begin() + offsets[idx]), "check unit test");
 226     nc->print();
 227   }
 228 
 229   nc = nativeCall_before( cb.insts_begin() + 8 );
 230   nc->print();
 231 
 232   VM_Version::revert();
 233 #endif
 234 }
 235 // End code for unit testing implementation of NativeCall class
 236 
 237 //-------------------------------------------------------------------
 238 


 239 void NativeFarCall::set_destination(address dest) {
 240   // Address materialized in the instruction stream, so nothing to do.
 241   return;
 242 #if 0 // What we'd do if we really did want to change the destination
 243   if (destination() == dest) {
 244     return;
 245   }
 246   ResourceMark rm;
 247   CodeBuffer buf(addr_at(0), instruction_size + 1);
 248   MacroAssembler* _masm = new MacroAssembler(&buf);
 249   // Generate the new sequence
 250   AddressLiteral(dest);
 251   _masm->jumpl_to(dest, O7, O7);
 252   ICache::invalidate_range(addr_at(0), instruction_size );
 253 #endif
 254 }
 255 
 256 void NativeFarCall::verify() {
 257   // make sure code pattern is actually a jumpl_to instruction
 258   assert((int)instruction_size == (int)NativeJump::instruction_size, "same as jump_to");


 271 bool NativeFarCall::destination_is_compiled_verified_entry_point() {
 272   nmethod* callee = CodeCache::find_nmethod(destination());
 273   if (callee == NULL) {
 274     return false;
 275   } else {
 276     return destination() == callee->verified_entry_point();
 277   }
 278 }
 279 
 280 // MT-safe patching of a far call.
 281 void NativeFarCall::replace_mt_safe(address instr_addr, address code_buffer) {
 282   Unimplemented();
 283 }
 284 
 285 // Code for unit testing implementation of NativeFarCall class
 286 void NativeFarCall::test() {
 287   Unimplemented();
 288 }
 289 // End code for unit testing implementation of NativeFarCall class
 290 


 291 //-------------------------------------------------------------------
 292 
 293 
 294 void NativeMovConstReg::verify() {
 295   NativeInstruction::verify();
 296   // make sure code pattern is actually a "set_metadata" synthetic instruction
 297   // see MacroAssembler::set_oop()
 298   int i0 = long_at(sethi_offset);
 299   int i1 = long_at(add_offset);
 300 
 301   // verify the pattern "sethi %hi22(imm), reg ;  add reg, %lo10(imm), reg"
 302   Register rd = inv_rd(i0);








 303   if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
 304     fatal("not a set_metadata");
 305   }

 306 }
 307 
 308 
 309 void NativeMovConstReg::print() {
 310   tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, p2i(instruction_address()), data());
 311 }
 312 
 313 

 314 intptr_t NativeMovConstReg::data() const {
 315   return data64(addr_at(sethi_offset), long_at(add_offset));
 316 }





 317 
 318 
 319 void NativeMovConstReg::set_data(intptr_t x) {

 320   set_data64_sethi(addr_at(sethi_offset), x);



 321   set_long_at(add_offset,   set_data32_simm13( long_at(add_offset),   x));
 322 
 323   // also store the value into an oop_Relocation cell, if any
 324   CodeBlob* cb = CodeCache::find_blob(instruction_address());
 325   nmethod*  nm = cb ? cb->as_nmethod_or_null() : NULL;
 326   if (nm != NULL) {
 327     RelocIterator iter(nm, instruction_address(), next_instruction_address());
 328     oop* oop_addr = NULL;
 329     Metadata** metadata_addr = NULL;
 330     while (iter.next()) {
 331       if (iter.type() == relocInfo::oop_type) {
 332         oop_Relocation *r = iter.oop_reloc();
 333         if (oop_addr == NULL) {
 334           oop_addr = r->oop_addr();
 335           *oop_addr = cast_to_oop(x);
 336         } else {
 337           assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
 338         }
 339       }
 340       if (iter.type() == relocInfo::metadata_type) {


 468   // The casual reader should note that on Sparc a nop is a special case if sethi
 469   // in which the destination register is %g0.
 470   Register rd0 = inv_rd(i0);
 471   Register rd1 = inv_rd(i1);
 472   if (!(is_op2(i0, Assembler::sethi_op2) && rd0 != G0 &&
 473         is_op2(i1, Assembler::sethi_op2) && rd1 == G0 &&        // nop is a special case of sethi
 474         is_op3(i2, Assembler::add_op3, Assembler::arith_op) &&
 475         inv_immed(i2) && (unsigned)get_simm13(i2) < (1 << 10) &&
 476         rd0 == inv_rs1(i2) && rd0 == inv_rd(i2))) {
 477     fatal("not a set_metadata");
 478   }
 479 }
 480 
 481 
 482 void NativeMovConstRegPatching::print() {
 483   tty->print_cr(INTPTR_FORMAT ": mov reg, 0x%x", p2i(instruction_address()), data());
 484 }
 485 
 486 
 487 int NativeMovConstRegPatching::data() const {

 488   return data64(addr_at(sethi_offset), long_at(add_offset));



 489 }
 490 
 491 
 492 void NativeMovConstRegPatching::set_data(int x) {

 493   set_data64_sethi(addr_at(sethi_offset), x);



 494   set_long_at(add_offset, set_data32_simm13(long_at(add_offset), x));
 495 
 496   // also store the value into an oop_Relocation cell, if any
 497   CodeBlob* cb = CodeCache::find_blob(instruction_address());
 498   nmethod*  nm = cb ? cb->as_nmethod_or_null() : NULL;
 499   if (nm != NULL) {
 500     RelocIterator iter(nm, instruction_address(), next_instruction_address());
 501     oop* oop_addr = NULL;
 502     Metadata** metadata_addr = NULL;
 503     while (iter.next()) {
 504       if (iter.type() == relocInfo::oop_type) {
 505         oop_Relocation *r = iter.oop_reloc();
 506         if (oop_addr == NULL) {
 507           oop_addr = r->oop_addr();
 508           *oop_addr = cast_to_oop(x);
 509         } else {
 510           assert(oop_addr == r->oop_addr(), "must be only one set-oop here");
 511         }
 512       }
 513       if (iter.type() == relocInfo::metadata_type) {


 710     nm->print();
 711   }
 712 
 713   VM_Version::revert();
 714 #endif // ASSERT
 715 }
 716 
 717 // End code for unit testing implementation of NativeMovRegMem class
 718 
 719 
 720 //--------------------------------------------------------------------------------
 721 
 722 
 723 void NativeJump::verify() {
 724   NativeInstruction::verify();
 725   int i0 = long_at(sethi_offset);
 726   int i1 = long_at(jmpl_offset);
 727   assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok");
 728   // verify the pattern "sethi %hi22(imm), treg ;  jmpl treg, %lo10(imm), lreg"
 729   Register rd = inv_rd(i0);








 730   // In LP64, the jump instruction location varies for non relocatable
 731   // jumps, for example is could be sethi, xor, jmp instead of the
 732   // 7 instructions for sethi.  So let's check sethi only.
 733   if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) {
 734     fatal("not a jump_to instruction");
 735   }

 736 }
 737 
 738 
 739 void NativeJump::print() {
 740   tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, p2i(instruction_address()), p2i(jump_destination()));
 741 }
 742 
 743 
 744 // Code for unit testing implementation of NativeJump class
 745 void NativeJump::test() {
 746 #ifdef ASSERT
 747   ResourceMark rm;
 748   CodeBuffer cb("test", 100, 100);
 749   MacroAssembler* a = new MacroAssembler(&cb);
 750   NativeJump* nj;
 751   uint idx;
 752   int offsets[] = {
 753     0x0,
 754     0xffffffff,
 755     0x7fffffff,


< prev index next >