src/cpu/sparc/vm/nativeInst_sparc.cpp

Mon, 25 Feb 2008 15:05:44 -0800

author
kvn
date
Mon, 25 Feb 2008 15:05:44 -0800
changeset 464
d5fc211aea19
parent 435
a61af66fc99e
child 551
018d5b58dd4f
permissions
-rw-r--r--

6633953: type2aelembytes{T_ADDRESS} should be 8 bytes in 64 bit VM
Summary: T_ADDRESS size is defined as 'int' size (4 bytes) but C2 use it for raw pointers and as memory type for StoreP and LoadP nodes.
Reviewed-by: jrose

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

mercurial