400 a->sethi(al2, O2); 401 a->add(O2, al2.low10(), O2); 402 403 nm = nativeMovConstReg_at( cb.insts_begin() ); 404 nm->print(); 405 406 nm = nativeMovConstReg_at( nm->next_instruction_address() ); 407 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) { 408 nm->set_data( offsets[idx] ); 409 assert(nm->data() == offsets[idx], "check unit test"); 410 } 411 nm->print(); 412 413 VM_Version::revert(); 414 #endif 415 } 416 // End code for unit testing implementation of NativeMovConstReg class 417 418 //------------------------------------------------------------------- 419 420 void NativeMovConstRegPatching::verify() { 421 NativeInstruction::verify(); 422 // Make sure code pattern is sethi/nop/add. 423 int i0 = long_at(sethi_offset); 424 int i1 = long_at(nop_offset); 425 int i2 = long_at(add_offset); 426 assert((int)nop_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); 427 428 // Verify the pattern "sethi %hi22(imm), reg; nop; add reg, %lo10(imm), reg" 429 // The casual reader should note that on Sparc a nop is a special case if sethi 430 // in which the destination register is %g0. 431 Register rd0 = inv_rd(i0); 432 Register rd1 = inv_rd(i1); 433 if (!(is_op2(i0, Assembler::sethi_op2) && rd0 != G0 && 434 is_op2(i1, Assembler::sethi_op2) && rd1 == G0 && // nop is a special case of sethi 435 is_op3(i2, Assembler::add_op3, Assembler::arith_op) && 436 inv_immed(i2) && (unsigned)get_simm13(i2) < (1 << 10) && 437 rd0 == inv_rs1(i2) && rd0 == inv_rd(i2))) { 438 fatal("not a set_metadata"); 439 } | 400 a->sethi(al2, O2); 401 a->add(O2, al2.low10(), O2); 402 403 nm = nativeMovConstReg_at( cb.insts_begin() ); 404 nm->print(); 405 406 nm = nativeMovConstReg_at( nm->next_instruction_address() ); 407 for (idx = 0; idx < ARRAY_SIZE(offsets); idx++) { 408 nm->set_data( offsets[idx] ); 409 assert(nm->data() == offsets[idx], "check unit test"); 410 } 411 nm->print(); 412 413 VM_Version::revert(); 414 #endif 415 } 416 // End code for unit testing implementation of NativeMovConstReg class 417 418 //------------------------------------------------------------------- 419 420 void NativeMovConstReg32::verify() { 421 NativeInstruction::verify(); 422 // make sure code pattern is actually a "set_metadata" synthetic instruction 423 // see MacroAssembler::set_oop() 424 int i0 = long_at(sethi_offset); 425 int i1 = long_at(add_offset); 426 427 // verify the pattern "sethi %hi22(imm), reg ; add reg, %lo10(imm), reg" 428 Register rd = inv_rd(i0); 429 if (!is_op2(i0, Assembler::sethi_op2) && rd != G0 ) { 430 fatal("not a set_metadata"); 431 } 432 } 433 434 435 void NativeMovConstReg32::print() { 436 tty->print_cr(INTPTR_FORMAT ": mov reg, " INTPTR_FORMAT, instruction_address(), data()); 437 } 438 439 440 intptr_t NativeMovConstReg32::data() const { 441 return data32(long_at(sethi_offset), long_at(add_offset)); 442 } 443 444 445 void NativeMovConstReg32::set_data(intptr_t x) { 446 set_long_at(sethi_offset, set_data32_sethi( long_at(sethi_offset), x)); 447 set_long_at(add_offset, set_data32_simm13( long_at(add_offset), x)); 448 449 // also store the value into an oop_Relocation cell, if any 450 CodeBlob* cb = CodeCache::find_blob(instruction_address()); 451 nmethod* nm = cb ? cb->as_nmethod_or_null() : NULL; 452 if (nm != NULL) { 453 RelocIterator iter(nm, instruction_address(), next_instruction_address()); 454 oop* oop_addr = NULL; 455 Metadata** metadata_addr = NULL; 456 while (iter.next()) { 457 if (iter.type() == relocInfo::oop_type) { 458 oop_Relocation *r = iter.oop_reloc(); 459 if (oop_addr == NULL) { 460 oop_addr = r->oop_addr(); 461 *oop_addr = cast_to_oop(x); 462 } else { 463 assert(oop_addr == r->oop_addr(), "must be only one set-oop here"); 464 } 465 } 466 if (iter.type() == relocInfo::metadata_type) { 467 metadata_Relocation *r = iter.metadata_reloc(); 468 if (metadata_addr == NULL) { 469 metadata_addr = r->metadata_addr(); 470 *metadata_addr = (Metadata*)x; 471 } else { 472 assert(metadata_addr == r->metadata_addr(), "must be only one set-metadata here"); 473 } 474 } 475 } 476 } 477 } 478 479 //------------------------------------------------------------------- 480 481 void NativeMovConstRegPatching::verify() { 482 NativeInstruction::verify(); 483 // Make sure code pattern is sethi/nop/add. 484 int i0 = long_at(sethi_offset); 485 int i1 = long_at(nop_offset); 486 int i2 = long_at(add_offset); 487 assert((int)nop_offset == (int)NativeMovConstReg::add_offset, "sethi size ok"); 488 489 // Verify the pattern "sethi %hi22(imm), reg; nop; add reg, %lo10(imm), reg" 490 // The casual reader should note that on Sparc a nop is a special case if sethi 491 // in which the destination register is %g0. 492 Register rd0 = inv_rd(i0); 493 Register rd1 = inv_rd(i1); 494 if (!(is_op2(i0, Assembler::sethi_op2) && rd0 != G0 && 495 is_op2(i1, Assembler::sethi_op2) && rd1 == G0 && // nop is a special case of sethi 496 is_op3(i2, Assembler::add_op3, Assembler::arith_op) && 497 inv_immed(i2) && (unsigned)get_simm13(i2) < (1 << 10) && 498 rd0 == inv_rs1(i2) && rd0 == inv_rd(i2))) { 499 fatal("not a set_metadata"); 500 } |