1 #ifdef USE_PRAGMA_IDENT_SRC 2 #pragma ident "@(#)nativeInst_sparc.cpp 1.97 07/05/05 17:04:31 JVM" 3 #endif 4 /* 5 * Copyright 1997-2007 Sun Microsystems, Inc. All Rights Reserved. 6 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7 * 8 * This code is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License version 2 only, as 10 * published by the Free Software Foundation. 11 * 12 * This code is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 * version 2 for more details (a copy is included in the LICENSE file that 16 * accompanied this code). 17 * 18 * You should have received a copy of the GNU General Public License version 19 * 2 along with this work; if not, write to the Free Software Foundation, 20 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 21 * 22 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 23 * CA 95054 USA or visit www.sun.com if you need additional information or 24 * have any questions. 25 * 26 */ 27 28 # include "incls/_precompiled.incl" 29 # include "incls/_nativeInst_sparc.cpp.incl" 30 31 32 void NativeInstruction::set_data64_sethi(address instaddr, intptr_t x) { 33 ResourceMark rm; 34 CodeBuffer buf(instaddr, 10 * BytesPerInstWord ); 35 MacroAssembler* _masm = new MacroAssembler(&buf); 36 Register destreg; 37 38 destreg = inv_rd(*(unsigned int *)instaddr); 39 // Generate a the new sequence 40 Address dest( destreg, (address)x ); 41 _masm->sethi( dest, true ); 42 ICache::invalidate_range(instaddr, 7 * BytesPerInstWord); 43 } 44 45 void NativeInstruction::verify() { 46 // make sure code pattern is actually an instruction address 47 address addr = addr_at(0); 48 if (addr == 0 || ((intptr_t)addr & 3) != 0) { 49 fatal("not an instruction address"); 50 } 51 } 52 53 void NativeInstruction::print() { 54 tty->print_cr(INTPTR_FORMAT ": 0x%x", addr_at(0), long_at(0)); 55 } 56 57 void NativeInstruction::set_long_at(int offset, int i) { 58 address addr = addr_at(offset); 59 *(int*)addr = i; 60 ICache::invalidate_word(addr); 61 } 62 63 void NativeInstruction::set_jlong_at(int offset, jlong i) { 64 address addr = addr_at(offset); 65 *(jlong*)addr = i; 66 // Don't need to invalidate 2 words here, because 67 // the flush instruction operates on doublewords. 68 ICache::invalidate_word(addr); 69 } 70 71 void NativeInstruction::set_addr_at(int offset, address x) { 72 address addr = addr_at(offset); 73 assert( ((intptr_t)addr & (wordSize-1)) == 0, "set_addr_at bad address alignment"); 74 *(uintptr_t*)addr = (uintptr_t)x; 75 // Don't need to invalidate 2 words here in the 64-bit case, 76 // because the flush instruction operates on doublewords. 77 ICache::invalidate_word(addr); 78 // The Intel code has this assertion for NativeCall::set_destination, 79 // NativeMovConstReg::set_data, NativeMovRegMem::set_offset, 80 // NativeJump::set_jump_destination, and NativePushImm32::set_data 81 //assert (Patching_lock->owned_by_self(), "must hold lock to patch instruction") 82 } 83 84 bool NativeInstruction::is_zero_test(Register ®) { 85 int x = long_at(0); 86 Assembler::op3s temp = (Assembler::op3s) (Assembler::sub_op3 | Assembler::cc_bit_op3); 87 if (is_op3(x, temp, Assembler::arith_op) && 88 inv_immed(x) && inv_rd(x) == G0) { 89 if (inv_rs1(x) == G0) { 90 reg = inv_rs2(x); 91 return true; 92 } else if (inv_rs2(x) == G0) { 93 reg = inv_rs1(x); 94 return true; 95 } 96 } 97 return false; 98 } 99 100 bool NativeInstruction::is_load_store_with_small_offset(Register reg) { 101 int x = long_at(0); 102 if (is_op(x, Assembler::ldst_op) && 103 inv_rs1(x) == reg && inv_immed(x)) { 104 return true; 105 } 106 return false; 107 } 108 109 void NativeCall::verify() { 110 NativeInstruction::verify(); 111 // make sure code pattern is actually a call instruction 112 if (!is_op(long_at(0), Assembler::call_op)) { 113 fatal("not a call"); 114 } 115 } 116 117 void NativeCall::print() { 118 tty->print_cr(INTPTR_FORMAT ": call " INTPTR_FORMAT, instruction_address(), destination()); 119 } 120 121 122 // MT-safe patching of a call instruction (and following word). 123 // First patches the second word, and then atomicly replaces 124 // the first word with the first new instruction word. 125 // Other processors might briefly see the old first word 126 // followed by the new second word. This is OK if the old 127 // second word is harmless, and the new second word may be 128 // harmlessly executed in the delay slot of the call. 129 void NativeCall::replace_mt_safe(address instr_addr, address code_buffer) { 130 assert(Patching_lock->is_locked() || 131 SafepointSynchronize::is_at_safepoint(), "concurrent code patching"); 132 assert (instr_addr != NULL, "illegal address for code patching"); 133 NativeCall* n_call = nativeCall_at (instr_addr); // checking that it is a call 134 assert(NativeCall::instruction_size == 8, "wrong instruction size; must be 8"); 135 int i0 = ((int*)code_buffer)[0]; 136 int i1 = ((int*)code_buffer)[1]; 137 int* contention_addr = (int*) n_call->addr_at(1*BytesPerInstWord); 138 assert(inv_op(*contention_addr) == Assembler::arith_op || 139 *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(), 140 "must not interfere with original call"); 141 // The set_long_at calls do the ICacheInvalidate so we just need to do them in reverse order 142 n_call->set_long_at(1*BytesPerInstWord, i1); 143 n_call->set_long_at(0*BytesPerInstWord, i0); 144 // NOTE: It is possible that another thread T will execute 145 // only the second patched word. 146 // In other words, since the original instruction is this 147 // call patching_stub; nop (NativeCall) 148 // and the new sequence from the buffer is this: 149 // sethi %hi(K), %r; add %r, %lo(K), %r (NativeMovConstReg) 150 // what T will execute is this: 151 // call patching_stub; add %r, %lo(K), %r 152 // thereby putting garbage into %r before calling the patching stub. 153 // This is OK, because the patching stub ignores the value of %r. 154 155 // Make sure the first-patched instruction, which may co-exist 156 // briefly with the call, will do something harmless. 157 assert(inv_op(*contention_addr) == Assembler::arith_op || 158 *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(), 159 "must not interfere with original call"); 160 } 161 162 // Similar to replace_mt_safe, but just changes the destination. The 163 // important thing is that free-running threads are able to execute this 164 // call instruction at all times. Thus, the displacement field must be 165 // instruction-word-aligned. This is always true on SPARC. 166 // 167 // Used in the runtime linkage of calls; see class CompiledIC. 168 void NativeCall::set_destination_mt_safe(address dest) { 169 assert(Patching_lock->is_locked() || 170 SafepointSynchronize::is_at_safepoint(), "concurrent code patching"); 171 // set_destination uses set_long_at which does the ICache::invalidate 172 set_destination(dest); 173 } 174 175 // Code for unit testing implementation of NativeCall class 176 void NativeCall::test() { 177 #ifdef ASSERT 178 ResourceMark rm; 179 CodeBuffer cb("test", 100, 100); 180 MacroAssembler* a = new MacroAssembler(&cb); 181 NativeCall *nc; 182 uint idx; 183 int offsets[] = { 184 0x0, 185 0xfffffff0, 186 0x7ffffff0, 187 0x80000000, 188 0x20, 189 0x4000, 190 }; 191 192 VM_Version::allow_all(); 193 194 a->call( a->pc(), relocInfo::none ); 195 a->delayed()->nop(); 196 nc = nativeCall_at( cb.code_begin() ); 197 nc->print(); 198 199 nc = nativeCall_overwriting_at( nc->next_instruction_address() ); 200 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) { 201 nc->set_destination( cb.code_begin() + offsets[idx] ); 202 assert(nc->destination() == (cb.code_begin() + offsets[idx]), "check unit test"); 203 nc->print(); 204 } 205 206 nc = nativeCall_before( cb.code_begin() + 8 ); 207 nc->print(); 208 209 VM_Version::revert(); 210 #endif 211 } 212 // End code for unit testing implementation of NativeCall class 213 214 //------------------------------------------------------------------- 215 216 #ifdef _LP64 217 218 void NativeFarCall::set_destination(address dest) { 219 // Address materialized in the instruction stream, so nothing to do. 220 return; 221 #if 0 // What we'd do if we really did want to change the destination 222 if (destination() == dest) { 223 return; 224 } 225 ResourceMark rm; 226 CodeBuffer buf(addr_at(0), instruction_size + 1); 227 MacroAssembler* _masm = new MacroAssembler(&buf); 228 // Generate the new sequence 229 Address(O7, dest); 230 _masm->jumpl_to(dest, O7); 231 ICache::invalidate_range(addr_at(0), instruction_size ); 232 #endif 233 } 234 235 void NativeFarCall::verify() { 236 // make sure code pattern is actually a jumpl_to instruction 237 assert((int)instruction_size == (int)NativeJump::instruction_size, "same as jump_to"); 238 assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); 239 nativeJump_at(addr_at(0))->verify(); 240 } 241 242 bool NativeFarCall::is_call_at(address instr) { 243 return nativeInstruction_at(instr)->is_sethi(); 244 } 245 246 void NativeFarCall::print() { 247 tty->print_cr(INTPTR_FORMAT ": call " INTPTR_FORMAT, instruction_address(), destination()); 248 } 249 250 bool NativeFarCall::destination_is_compiled_verified_entry_point() { 251 nmethod* callee = CodeCache::find_nmethod(destination()); 252 if (callee == NULL) { 253 return false; 254 } else { 255 return destination() == callee->verified_entry_point(); 256 } 257 } 258 259 // MT-safe patching of a far call. 260 void NativeFarCall::replace_mt_safe(address instr_addr, address code_buffer) { 261 Unimplemented(); 262 } 263 264 // Code for unit testing implementation of NativeFarCall class 265 void NativeFarCall::test() { 266 Unimplemented(); 267 } 268 // End code for unit testing implementation of NativeFarCall class 269 270 #endif // _LP64 271 272 //------------------------------------------------------------------- 273 274 275 void NativeMovConstReg::verify() { 276 NativeInstruction::verify(); 277 // make sure code pattern is actually a "set_oop" synthetic instruction 278 // see MacroAssembler::set_oop() 279 int i0 = long_at(sethi_offset); 280 int i1 = long_at(add_offset); 281 282 // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg" 283 Register rd = inv_rd(i0); 284 #ifndef _LP64 285 if (!(is_op2(i0, Assembler::sethi_op2) && rd != G0 && 286 is_op3(i1, Assembler::add_op3, Assembler::arith_op) && 287 inv_immed(i1) && (unsigned)get_simm13(i1) < (1 << 10) && 288 rd == inv_rs1(i1) && rd == inv_rd(i1))) { 289 fatal("not a set_oop"); 290 } 291 #else 292 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) { 293 fatal("not a set_oop"); 294 } 295 #endif 296 } 297 298 299 void NativeMovConstReg::print() { 300 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data()); 301 } 302 303 304 #ifdef _LP64 305 intptr_t NativeMovConstReg::data() const { 306 return data64(addr_at(sethi_offset), long_at(add_offset)); 307 } 308 #else 309 intptr_t NativeMovConstReg::data() const { 310 return data32(long_at(sethi_offset), long_at(add_offset)); 311 } 312 #endif 313 314 315 void NativeMovConstReg::set_data(intptr_t x) { 316 #ifdef _LP64 317 set_data64_sethi(addr_at(sethi_offset), x); 318 #else 319 set_long_at(sethi_offset, set_data32_sethi( long_at(sethi_offset), x)); 320 #endif 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* nm = CodeCache::find_blob(instruction_address()); 325 if (nm != NULL) { 326 RelocIterator iter(nm, instruction_address(), next_instruction_address()); 327 oop* oop_addr = NULL; 328 while (iter.next()) { 329 if (iter.type() == relocInfo::oop_type) { 330 oop_Relocation *r = iter.oop_reloc(); 331 if (oop_addr == NULL) { 332 oop_addr = r->oop_addr(); 333 *oop_addr = (oop)x; 334 } else { 335 assert(oop_addr == r->oop_addr(), "must be only one set-oop here"); 336 } 337 } 338 } 339 } 340 } 341 342 343 // Code for unit testing implementation of NativeMovConstReg class 344 void NativeMovConstReg::test() { 345 #ifdef ASSERT 346 ResourceMark rm; 347 CodeBuffer cb("test", 100, 100); 348 MacroAssembler* a = new MacroAssembler(&cb); 349 NativeMovConstReg* nm; 350 uint idx; 351 int offsets[] = { 352 0x0, 353 0x7fffffff, 354 0x80000000, 355 0xffffffff, 356 0x20, 357 4096, 358 4097, 359 }; 360 361 VM_Version::allow_all(); 362 363 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); 364 a->add(I3, low10(0xaaaabbbb), I3); 365 a->sethi(0xccccdddd, O2, true, RelocationHolder::none); 366 a->add(O2, low10(0xccccdddd), O2); 367 368 nm = nativeMovConstReg_at( cb.code_begin() ); 369 nm->print(); 370 371 nm = nativeMovConstReg_at( nm->next_instruction_address() ); 372 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) { 373 nm->set_data( offsets[idx] ); 374 assert(nm->data() == offsets[idx], "check unit test"); 375 } 376 nm->print(); 377 378 VM_Version::revert(); 379 #endif 380 } 381 // End code for unit testing implementation of NativeMovConstReg class 382 383 //------------------------------------------------------------------- 384 385 void NativeMovConstRegPatching::verify() { 386 NativeInstruction::verify(); 387 // Make sure code pattern is sethi/nop/add. 388 int i0 = long_at(sethi_offset); 389 int i1 = long_at(nop_offset); 390 int i2 = long_at(add_offset); 391 assert((int)nop_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); 392 393 // Verify the pattern "sethi %hi22(imm), reg; nop; add reg, %lo10(imm), reg" 394 // The casual reader should note that on Sparc a nop is a special case if sethi 395 // in which the destination register is %g0. 396 Register rd0 = inv_rd(i0); 397 Register rd1 = inv_rd(i1); 398 if (!(is_op2(i0, Assembler::sethi_op2) && rd0 != G0 && 399 is_op2(i1, Assembler::sethi_op2) && rd1 == G0 && // nop is a special case of sethi 400 is_op3(i2, Assembler::add_op3, Assembler::arith_op) && 401 inv_immed(i2) && (unsigned)get_simm13(i2) < (1 << 10) && 402 rd0 == inv_rs1(i2) && rd0 == inv_rd(i2))) { 403 fatal("not a set_oop"); 404 } 405 } 406 407 408 void NativeMovConstRegPatching::print() { 409 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data()); 410 } 411 412 413 int NativeMovConstRegPatching::data() const { 414 #ifdef _LP64 415 return data64(addr_at(sethi_offset), long_at(add_offset)); 416 #else 417 return data32(long_at(sethi_offset), long_at(add_offset)); 418 #endif 419 } 420 421 422 void NativeMovConstRegPatching::set_data(int x) { 423 #ifdef _LP64 424 set_data64_sethi(addr_at(sethi_offset), x); 425 #else 426 set_long_at(sethi_offset, set_data32_sethi(long_at(sethi_offset), x)); 427 #endif 428 set_long_at(add_offset, set_data32_simm13(long_at(add_offset), x)); 429 430 // also store the value into an oop_Relocation cell, if any 431 CodeBlob* nm = CodeCache::find_blob(instruction_address()); 432 if (nm != NULL) { 433 RelocIterator iter(nm, instruction_address(), next_instruction_address()); 434 oop* oop_addr = NULL; 435 while (iter.next()) { 436 if (iter.type() == relocInfo::oop_type) { 437 oop_Relocation *r = iter.oop_reloc(); 438 if (oop_addr == NULL) { 439 oop_addr = r->oop_addr(); 440 *oop_addr = (oop)x; 441 } else { 442 assert(oop_addr == r->oop_addr(), "must be only one set-oop here"); 443 } 444 } 445 } 446 } 447 } 448 449 450 // Code for unit testing implementation of NativeMovConstRegPatching class 451 void NativeMovConstRegPatching::test() { 452 #ifdef ASSERT 453 ResourceMark rm; 454 CodeBuffer cb("test", 100, 100); 455 MacroAssembler* a = new MacroAssembler(&cb); 456 NativeMovConstRegPatching* nm; 457 uint idx; 458 int offsets[] = { 459 0x0, 460 0x7fffffff, 461 0x80000000, 462 0xffffffff, 463 0x20, 464 4096, 465 4097, 466 }; 467 468 VM_Version::allow_all(); 469 470 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); 471 a->nop(); 472 a->add(I3, low10(0xaaaabbbb), I3); 473 a->sethi(0xccccdddd, O2, true, RelocationHolder::none); 474 a->nop(); 475 a->add(O2, low10(0xccccdddd), O2); 476 477 nm = nativeMovConstRegPatching_at( cb.code_begin() ); 478 nm->print(); 479 480 nm = nativeMovConstRegPatching_at( nm->next_instruction_address() ); 481 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) { 482 nm->set_data( offsets[idx] ); 483 assert(nm->data() == offsets[idx], "check unit test"); 484 } 485 nm->print(); 486 487 VM_Version::revert(); 488 #endif // ASSERT 489 } 490 // End code for unit testing implementation of NativeMovConstRegPatching class 491 492 493 //------------------------------------------------------------------- 494 495 496 void NativeMovRegMem::copy_instruction_to(address new_instruction_address) { 497 Untested("copy_instruction_to"); 498 int instruction_size = next_instruction_address() - instruction_address(); 499 for (int i = 0; i < instruction_size; i += BytesPerInstWord) { 500 *(int*)(new_instruction_address + i) = *(int*)(address(this) + i); 501 } 502 } 503 504 505 void NativeMovRegMem::verify() { 506 NativeInstruction::verify(); 507 // make sure code pattern is actually a "ld" or "st" of some sort. 508 int i0 = long_at(0); 509 int op3 = inv_op3(i0); 510 511 assert((int)add_offset == NativeMovConstReg::add_offset, "sethi size ok"); 512 513 if (!(is_op(i0, Assembler::ldst_op) && 514 inv_immed(i0) && 515 0 != (op3 < op3_ldst_int_limit 516 ? (1 << op3 ) & (op3_mask_ld | op3_mask_st) 517 : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf)))) 518 { 519 int i1 = long_at(ldst_offset); 520 Register rd = inv_rd(i0); 521 522 op3 = inv_op3(i1); 523 if (!is_op(i1, Assembler::ldst_op) && rd == inv_rs2(i1) && 524 0 != (op3 < op3_ldst_int_limit 525 ? (1 << op3 ) & (op3_mask_ld | op3_mask_st) 526 : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf))) { 527 fatal("not a ld* or st* op"); 528 } 529 } 530 } 531 532 533 void NativeMovRegMem::print() { 534 if (is_immediate()) { 535 tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + %x]", instruction_address(), offset()); 536 } else { 537 tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + reg]", instruction_address()); 538 } 539 } 540 541 542 // Code for unit testing implementation of NativeMovRegMem class 543 void NativeMovRegMem::test() { 544 #ifdef ASSERT 545 ResourceMark rm; 546 CodeBuffer cb("test", 1000, 1000); 547 MacroAssembler* a = new MacroAssembler(&cb); 548 NativeMovRegMem* nm; 549 uint idx = 0; 550 uint idx1; 551 int offsets[] = { 552 0x0, 553 0xffffffff, 554 0x7fffffff, 555 0x80000000, 556 4096, 557 4097, 558 0x20, 559 0x4000, 560 }; 561 562 VM_Version::allow_all(); 563 564 a->ldsw( G5, low10(0xffffffff), G4 ); idx++; 565 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 566 a->ldsw( G5, I3, G4 ); idx++; 567 a->ldsb( G5, low10(0xffffffff), G4 ); idx++; 568 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 569 a->ldsb( G5, I3, G4 ); idx++; 570 a->ldsh( G5, low10(0xffffffff), G4 ); idx++; 571 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 572 a->ldsh( G5, I3, G4 ); idx++; 573 a->lduw( G5, low10(0xffffffff), G4 ); idx++; 574 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 575 a->lduw( G5, I3, G4 ); idx++; 576 a->ldub( G5, low10(0xffffffff), G4 ); idx++; 577 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 578 a->ldub( G5, I3, G4 ); idx++; 579 a->lduh( G5, low10(0xffffffff), G4 ); idx++; 580 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 581 a->lduh( G5, I3, G4 ); idx++; 582 a->ldx( G5, low10(0xffffffff), G4 ); idx++; 583 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 584 a->ldx( G5, I3, G4 ); idx++; 585 a->ldd( G5, low10(0xffffffff), G4 ); idx++; 586 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 587 a->ldd( G5, I3, G4 ); idx++; 588 a->ldf( FloatRegisterImpl::D, O2, -1, F14 ); idx++; 589 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 590 a->ldf( FloatRegisterImpl::S, O0, I3, F15 ); idx++; 591 592 a->stw( G5, G4, low10(0xffffffff) ); idx++; 593 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 594 a->stw( G5, G4, I3 ); idx++; 595 a->stb( G5, G4, low10(0xffffffff) ); idx++; 596 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 597 a->stb( G5, G4, I3 ); idx++; 598 a->sth( G5, G4, low10(0xffffffff) ); idx++; 599 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 600 a->sth( G5, G4, I3 ); idx++; 601 a->stx( G5, G4, low10(0xffffffff) ); idx++; 602 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 603 a->stx( G5, G4, I3 ); idx++; 604 a->std( G5, G4, low10(0xffffffff) ); idx++; 605 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 606 a->std( G5, G4, I3 ); idx++; 607 a->stf( FloatRegisterImpl::S, F18, O2, -1 ); idx++; 608 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->add(I3, low10(0xaaaabbbb), I3); 609 a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++; 610 611 nm = nativeMovRegMem_at( cb.code_begin() ); 612 nm->print(); 613 nm->set_offset( low10(0) ); 614 nm->print(); 615 nm->add_offset_in_bytes( low10(0xbb) * wordSize ); 616 nm->print(); 617 618 while (--idx) { 619 nm = nativeMovRegMem_at( nm->next_instruction_address() ); 620 nm->print(); 621 for (idx1 = 0; idx1 < ARRAY_SIZE(offsets); idx1++) { 622 nm->set_offset( nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1] ); 623 assert(nm->offset() == (nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1]), 624 "check unit test"); 625 nm->print(); 626 } 627 nm->add_offset_in_bytes( low10(0xbb) * wordSize ); 628 nm->print(); 629 } 630 631 VM_Version::revert(); 632 #endif // ASSERT 633 } 634 635 // End code for unit testing implementation of NativeMovRegMem class 636 637 //-------------------------------------------------------------------------------- 638 639 640 void NativeMovRegMemPatching::copy_instruction_to(address new_instruction_address) { 641 Untested("copy_instruction_to"); 642 int instruction_size = next_instruction_address() - instruction_address(); 643 for (int i = 0; i < instruction_size; i += wordSize) { 644 *(long*)(new_instruction_address + i) = *(long*)(address(this) + i); 645 } 646 } 647 648 649 void NativeMovRegMemPatching::verify() { 650 NativeInstruction::verify(); 651 // make sure code pattern is actually a "ld" or "st" of some sort. 652 int i0 = long_at(0); 653 int op3 = inv_op3(i0); 654 655 assert((int)nop_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); 656 657 if (!(is_op(i0, Assembler::ldst_op) && 658 inv_immed(i0) && 659 0 != (op3 < op3_ldst_int_limit 660 ? (1 << op3 ) & (op3_mask_ld | op3_mask_st) 661 : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf)))) { 662 int i1 = long_at(ldst_offset); 663 Register rd = inv_rd(i0); 664 665 op3 = inv_op3(i1); 666 if (!is_op(i1, Assembler::ldst_op) && rd == inv_rs2(i1) && 667 0 != (op3 < op3_ldst_int_limit 668 ? (1 << op3 ) & (op3_mask_ld | op3_mask_st) 669 : (1 << (op3 - op3_ldst_int_limit)) & (op3_mask_ldf | op3_mask_stf))) { 670 fatal("not a ld* or st* op"); 671 } 672 } 673 } 674 675 676 void NativeMovRegMemPatching::print() { 677 if (is_immediate()) { 678 tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + %x]", instruction_address(), offset()); 679 } else { 680 tty->print_cr(INTPTR_FORMAT ": mov reg, [reg + reg]", instruction_address()); 681 } 682 } 683 684 685 // Code for unit testing implementation of NativeMovRegMemPatching class 686 void NativeMovRegMemPatching::test() { 687 #ifdef ASSERT 688 ResourceMark rm; 689 CodeBuffer cb("test", 1000, 1000); 690 MacroAssembler* a = new MacroAssembler(&cb); 691 NativeMovRegMemPatching* nm; 692 uint idx = 0; 693 uint idx1; 694 int offsets[] = { 695 0x0, 696 0xffffffff, 697 0x7fffffff, 698 0x80000000, 699 4096, 700 4097, 701 0x20, 702 0x4000, 703 }; 704 705 VM_Version::allow_all(); 706 707 a->ldsw( G5, low10(0xffffffff), G4 ); idx++; 708 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 709 a->ldsw( G5, I3, G4 ); idx++; 710 a->ldsb( G5, low10(0xffffffff), G4 ); idx++; 711 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 712 a->ldsb( G5, I3, G4 ); idx++; 713 a->ldsh( G5, low10(0xffffffff), G4 ); idx++; 714 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 715 a->ldsh( G5, I3, G4 ); idx++; 716 a->lduw( G5, low10(0xffffffff), G4 ); idx++; 717 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 718 a->lduw( G5, I3, G4 ); idx++; 719 a->ldub( G5, low10(0xffffffff), G4 ); idx++; 720 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 721 a->ldub( G5, I3, G4 ); idx++; 722 a->lduh( G5, low10(0xffffffff), G4 ); idx++; 723 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 724 a->lduh( G5, I3, G4 ); idx++; 725 a->ldx( G5, low10(0xffffffff), G4 ); idx++; 726 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 727 a->ldx( G5, I3, G4 ); idx++; 728 a->ldd( G5, low10(0xffffffff), G4 ); idx++; 729 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 730 a->ldd( G5, I3, G4 ); idx++; 731 a->ldf( FloatRegisterImpl::D, O2, -1, F14 ); idx++; 732 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 733 a->ldf( FloatRegisterImpl::S, O0, I3, F15 ); idx++; 734 735 a->stw( G5, G4, low10(0xffffffff) ); idx++; 736 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 737 a->stw( G5, G4, I3 ); idx++; 738 a->stb( G5, G4, low10(0xffffffff) ); idx++; 739 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 740 a->stb( G5, G4, I3 ); idx++; 741 a->sth( G5, G4, low10(0xffffffff) ); idx++; 742 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 743 a->sth( G5, G4, I3 ); idx++; 744 a->stx( G5, G4, low10(0xffffffff) ); idx++; 745 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 746 a->stx( G5, G4, I3 ); idx++; 747 a->std( G5, G4, low10(0xffffffff) ); idx++; 748 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 749 a->std( G5, G4, I3 ); idx++; 750 a->stf( FloatRegisterImpl::S, F18, O2, -1 ); idx++; 751 a->sethi(0xaaaabbbb, I3, true, RelocationHolder::none); a->nop(); a->add(I3, low10(0xaaaabbbb), I3); 752 a->stf( FloatRegisterImpl::S, F15, O0, I3 ); idx++; 753 754 nm = nativeMovRegMemPatching_at( cb.code_begin() ); 755 nm->print(); 756 nm->set_offset( low10(0) ); 757 nm->print(); 758 nm->add_offset_in_bytes( low10(0xbb) * wordSize ); 759 nm->print(); 760 761 while (--idx) { 762 nm = nativeMovRegMemPatching_at( nm->next_instruction_address() ); 763 nm->print(); 764 for (idx1 = 0; idx1 < ARRAY_SIZE(offsets); idx1++) { 765 nm->set_offset( nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1] ); 766 assert(nm->offset() == (nm->is_immediate() ? low10(offsets[idx1]) : offsets[idx1]), 767 "check unit test"); 768 nm->print(); 769 } 770 nm->add_offset_in_bytes( low10(0xbb) * wordSize ); 771 nm->print(); 772 } 773 774 VM_Version::revert(); 775 #endif // ASSERT 776 } 777 // End code for unit testing implementation of NativeMovRegMemPatching class 778 779 780 //-------------------------------------------------------------------------------- 781 782 783 void NativeJump::verify() { 784 NativeInstruction::verify(); 785 int i0 = long_at(sethi_offset); 786 int i1 = long_at(jmpl_offset); 787 assert((int)jmpl_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); 788 // verify the pattern "sethi %hi22(imm), treg ; jmpl treg, %lo10(imm), lreg" 789 Register rd = inv_rd(i0); 790 #ifndef _LP64 791 if (!(is_op2(i0, Assembler::sethi_op2) && rd != G0 && 792 (is_op3(i1, Assembler::jmpl_op3, Assembler::arith_op) || 793 (TraceJumps && is_op3(i1, Assembler::add_op3, Assembler::arith_op))) && 794 inv_immed(i1) && (unsigned)get_simm13(i1) < (1 << 10) && 795 rd == inv_rs1(i1))) { 796 fatal("not a jump_to instruction"); 797 } 798 #else 799 // In LP64, the jump instruction location varies for non relocatable 800 // jumps, for example is could be sethi, xor, jmp instead of the 801 // 7 instructions for sethi. So let's check sethi only. 802 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) { 803 fatal("not a jump_to instruction"); 804 } 805 #endif 806 } 807 808 809 void NativeJump::print() { 810 tty->print_cr(INTPTR_FORMAT ": jmpl reg, " INTPTR_FORMAT, instruction_address(), jump_destination()); 811 } 812 813 814 // Code for unit testing implementation of NativeJump class 815 void NativeJump::test() { 816 #ifdef ASSERT 817 ResourceMark rm; 818 CodeBuffer cb("test", 100, 100); 819 MacroAssembler* a = new MacroAssembler(&cb); 820 NativeJump* nj; 821 uint idx; 822 int offsets[] = { 823 0x0, 824 0xffffffff, 825 0x7fffffff, 826 0x80000000, 827 4096, 828 4097, 829 0x20, 830 0x4000, 831 }; 832 833 VM_Version::allow_all(); 834 835 a->sethi(0x7fffbbbb, I3, true, RelocationHolder::none); 836 a->jmpl(I3, low10(0x7fffbbbb), G0, RelocationHolder::none); 837 a->delayed()->nop(); 838 a->sethi(0x7fffbbbb, I3, true, RelocationHolder::none); 839 a->jmpl(I3, low10(0x7fffbbbb), L3, RelocationHolder::none); 840 a->delayed()->nop(); 841 842 nj = nativeJump_at( cb.code_begin() ); 843 nj->print(); 844 845 nj = nativeJump_at( nj->next_instruction_address() ); 846 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) { 847 nj->set_jump_destination( nj->instruction_address() + offsets[idx] ); 848 assert(nj->jump_destination() == (nj->instruction_address() + offsets[idx]), "check unit test"); 849 nj->print(); 850 } 851 852 VM_Version::revert(); 853 #endif // ASSERT 854 } 855 // End code for unit testing implementation of NativeJump class 856 857 858 void NativeJump::insert(address code_pos, address entry) { 859 Unimplemented(); 860 } 861 862 // MT safe inserting of a jump over an unknown instruction sequence (used by nmethod::makeZombie) 863 // The problem: jump_to <dest> is a 3-word instruction (including its delay slot). 864 // Atomic write can be only with 1 word. 865 void NativeJump::patch_verified_entry(address entry, address verified_entry, address dest) { 866 // Here's one way to do it: Pre-allocate a three-word jump sequence somewhere 867 // in the header of the nmethod, within a short branch's span of the patch point. 868 // Set up the jump sequence using NativeJump::insert, and then use an annulled 869 // unconditional branch at the target site (an atomic 1-word update). 870 // Limitations: You can only patch nmethods, with any given nmethod patched at 871 // most once, and the patch must be in the nmethod's header. 872 // It's messy, but you can ask the CodeCache for the nmethod containing the 873 // target address. 874 875 // %%%%% For now, do something MT-stupid: 876 ResourceMark rm; 877 int code_size = 1 * BytesPerInstWord; 878 CodeBuffer cb(verified_entry, code_size + 1); 879 MacroAssembler* a = new MacroAssembler(&cb); 880 if (VM_Version::v9_instructions_work()) { 881 a->ldsw(G0, 0, O7); // "ld" must agree with code in the signal handler 882 } else { 883 a->lduw(G0, 0, O7); // "ld" must agree with code in the signal handler 884 } 885 ICache::invalidate_range(verified_entry, code_size); 886 } 887 888 889 void NativeIllegalInstruction::insert(address code_pos) { 890 NativeIllegalInstruction* nii = (NativeIllegalInstruction*) nativeInstruction_at(code_pos); 891 nii->set_long_at(0, illegal_instruction()); 892 } 893 894 static int illegal_instruction_bits = 0; 895 896 int NativeInstruction::illegal_instruction() { 897 if (illegal_instruction_bits == 0) { 898 ResourceMark rm; 899 char buf[40]; 900 CodeBuffer cbuf((address)&buf[0], 20); 901 MacroAssembler* a = new MacroAssembler(&cbuf); 902 address ia = a->pc(); 903 a->trap(ST_RESERVED_FOR_USER_0 + 1); 904 int bits = *(int*)ia; 905 assert(is_op3(bits, Assembler::trap_op3, Assembler::arith_op), "bad instruction"); 906 illegal_instruction_bits = bits; 907 assert(illegal_instruction_bits != 0, "oops"); 908 } 909 return illegal_instruction_bits; 910 } 911 912 static int ic_miss_trap_bits = 0; 913 914 bool NativeInstruction::is_ic_miss_trap() { 915 if (ic_miss_trap_bits == 0) { 916 ResourceMark rm; 917 char buf[40]; 918 CodeBuffer cbuf((address)&buf[0], 20); 919 MacroAssembler* a = new MacroAssembler(&cbuf); 920 address ia = a->pc(); 921 a->trap(Assembler::notEqual, Assembler::ptr_cc, G0, ST_RESERVED_FOR_USER_0 + 2); 922 int bits = *(int*)ia; 923 assert(is_op3(bits, Assembler::trap_op3, Assembler::arith_op), "bad instruction"); 924 ic_miss_trap_bits = bits; 925 assert(ic_miss_trap_bits != 0, "oops"); 926 } 927 return long_at(0) == ic_miss_trap_bits; 928 } 929 930 931 bool NativeInstruction::is_illegal() { 932 if (illegal_instruction_bits == 0) { 933 return false; 934 } 935 return long_at(0) == illegal_instruction_bits; 936 } 937 938 939 void NativeGeneralJump::verify() { 940 assert(((NativeInstruction *)this)->is_jump() || 941 ((NativeInstruction *)this)->is_cond_jump(), "not a general jump instruction"); 942 } 943 944 945 void NativeGeneralJump::insert_unconditional(address code_pos, address entry) { 946 Assembler::Condition condition = Assembler::always; 947 int x = Assembler::op2(Assembler::br_op2) | Assembler::annul(false) | 948 Assembler::cond(condition) | Assembler::wdisp((intptr_t)entry, (intptr_t)code_pos, 22); 949 NativeGeneralJump* ni = (NativeGeneralJump*) nativeInstruction_at(code_pos); 950 ni->set_long_at(0, x); 951 } 952 953 954 // MT-safe patching of a jmp instruction (and following word). 955 // First patches the second word, and then atomicly replaces 956 // the first word with the first new instruction word. 957 // Other processors might briefly see the old first word 958 // followed by the new second word. This is OK if the old 959 // second word is harmless, and the new second word may be 960 // harmlessly executed in the delay slot of the call. 961 void NativeGeneralJump::replace_mt_safe(address instr_addr, address code_buffer) { 962 assert(Patching_lock->is_locked() || 963 SafepointSynchronize::is_at_safepoint(), "concurrent code patching"); 964 assert (instr_addr != NULL, "illegal address for code patching"); 965 NativeGeneralJump* h_jump = nativeGeneralJump_at (instr_addr); // checking that it is a call 966 assert(NativeGeneralJump::instruction_size == 8, "wrong instruction size; must be 8"); 967 int i0 = ((int*)code_buffer)[0]; 968 int i1 = ((int*)code_buffer)[1]; 969 int* contention_addr = (int*) h_jump->addr_at(1*BytesPerInstWord); 970 assert(inv_op(*contention_addr) == Assembler::arith_op || 971 *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(), 972 "must not interfere with original call"); 973 // The set_long_at calls do the ICacheInvalidate so we just need to do them in reverse order 974 h_jump->set_long_at(1*BytesPerInstWord, i1); 975 h_jump->set_long_at(0*BytesPerInstWord, i0); 976 // NOTE: It is possible that another thread T will execute 977 // only the second patched word. 978 // In other words, since the original instruction is this 979 // jmp patching_stub; nop (NativeGeneralJump) 980 // and the new sequence from the buffer is this: 981 // sethi %hi(K), %r; add %r, %lo(K), %r (NativeMovConstReg) 982 // what T will execute is this: 983 // jmp patching_stub; add %r, %lo(K), %r 984 // thereby putting garbage into %r before calling the patching stub. 985 // This is OK, because the patching stub ignores the value of %r. 986 987 // Make sure the first-patched instruction, which may co-exist 988 // briefly with the call, will do something harmless. 989 assert(inv_op(*contention_addr) == Assembler::arith_op || 990 *contention_addr == nop_instruction() || !VM_Version::v9_instructions_work(), 991 "must not interfere with original call"); 992 } 993