1 /*
   2  * Copyright (c) 1997, 2013, 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  *
  23  */
  24 
  25 #ifndef CPU_SPARC_VM_NATIVEINST_SPARC_HPP
  26 #define CPU_SPARC_VM_NATIVEINST_SPARC_HPP
  27 
  28 #include "asm/macroAssembler.hpp"
  29 #include "memory/allocation.hpp"
  30 #include "runtime/icache.hpp"
  31 #include "runtime/os.hpp"
  32 
  33 // We have interface for the following instructions:
  34 // - NativeInstruction
  35 // - - NativeCall
  36 // - - NativeFarCall
  37 // - - NativeMovConstReg
  38 // - - NativeMovConstRegPatching
  39 // - - NativeMovRegMem
  40 // - - NativeJump
  41 // - - NativeGeneralJump
  42 // - - NativeIllegalInstruction
  43 // The base class for different kinds of native instruction abstractions.
  44 // Provides the primitive operations to manipulate code relative to this.
  45 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
  46   friend class Relocation;
  47 
  48  public:
  49   enum Sparc_specific_constants {
  50     nop_instruction_size        =    4
  51   };
  52 
  53   bool is_nop()                        { return long_at(0) == nop_instruction(); }
  54   bool is_call()                       { return is_op(long_at(0), Assembler::call_op); }
  55   bool is_call_reg()                   { return is_op(long_at(0), Assembler::arith_op); }
  56   bool is_sethi()                      { return (is_op2(long_at(0), Assembler::sethi_op2)
  57                                           && inv_rd(long_at(0)) != G0); }
  58 
  59   bool sets_cc() {
  60     // conservative (returns true for some instructions that do not set the
  61     // the condition code, such as, "save".
  62     // Does not return true for the deprecated tagged instructions, such as, TADDcc
  63     int x = long_at(0);
  64     return (is_op(x, Assembler::arith_op) &&
  65             (inv_op3(x) & Assembler::cc_bit_op3) == Assembler::cc_bit_op3);
  66   }
  67   bool is_illegal();
  68   bool is_zombie() {
  69     int x = long_at(0);
  70     return is_op3(x,
  71                   Assembler::ldsw_op3,
  72                   Assembler::ldst_op)
  73         && Assembler::inv_rs1(x) == G0
  74         && Assembler::inv_rd(x) == O7;
  75   }
  76   bool is_ic_miss_trap();       // Inline-cache uses a trap to detect a miss
  77   bool is_return() {
  78     // is it the output of MacroAssembler::ret or MacroAssembler::retl?
  79     int x = long_at(0);
  80     const int pc_return_offset = 8; // see frame_sparc.hpp
  81     return is_op3(x, Assembler::jmpl_op3, Assembler::arith_op)
  82         && (inv_rs1(x) == I7 || inv_rs1(x) == O7)
  83         && inv_immed(x) && inv_simm(x, 13) == pc_return_offset
  84         && inv_rd(x) == G0;
  85   }
  86   bool is_int_jump() {
  87     // is it the output of MacroAssembler::b?
  88     int x = long_at(0);
  89     return is_op2(x, Assembler::bp_op2) || is_op2(x, Assembler::br_op2);
  90   }
  91   bool is_float_jump() {
  92     // is it the output of MacroAssembler::fb?
  93     int x = long_at(0);
  94     return is_op2(x, Assembler::fbp_op2) || is_op2(x, Assembler::fb_op2);
  95   }
  96   bool is_jump() {
  97     return is_int_jump() || is_float_jump();
  98   }
  99   bool is_cond_jump() {
 100     int x = long_at(0);
 101     return (is_int_jump() && Assembler::inv_cond(x) != Assembler::always) ||
 102            (is_float_jump() && Assembler::inv_cond(x) != Assembler::f_always);
 103   }
 104 
 105   bool is_stack_bang() {
 106     int x = long_at(0);
 107     return is_op3(x, Assembler::stw_op3, Assembler::ldst_op) &&
 108       (inv_rd(x) == G0) && (inv_rs1(x) == SP) && (inv_rs2(x) == G3_scratch);
 109   }
 110 
 111   bool is_prefetch() {
 112     int x = long_at(0);
 113     return is_op3(x, Assembler::prefetch_op3, Assembler::ldst_op);
 114   }
 115 
 116   bool is_membar() {
 117     int x = long_at(0);
 118     return is_op3(x, Assembler::membar_op3, Assembler::arith_op) &&
 119       (inv_rd(x) == G0) && (inv_rs1(x) == O7);
 120   }
 121 
 122   bool is_safepoint_poll() {
 123     int x = long_at(0);
 124     return is_op3(x, Assembler::ldx_op3,  Assembler::ldst_op) &&
 125       (inv_rd(x) == G0) && (inv_immed(x) ? Assembler::inv_simm13(x) == 0 : inv_rs2(x) == G0);
 126   }
 127 
 128   bool is_zero_test(Register &reg);
 129   bool is_load_store_with_small_offset(Register reg);
 130 
 131  public:
 132 #ifdef ASSERT
 133   static int rdpc_instruction()        { return Assembler::op(Assembler::arith_op ) | Assembler::op3(Assembler::rdreg_op3) | Assembler::u_field(5, 18, 14) | Assembler::rd(O7); }
 134 #else
 135   // Temporary fix: in optimized mode, u_field is a macro for efficiency reasons (see Assembler::u_field) - needs to be fixed
 136   static int rdpc_instruction()        { return Assembler::op(Assembler::arith_op ) | Assembler::op3(Assembler::rdreg_op3) |            u_field(5, 18, 14) | Assembler::rd(O7); }
 137 #endif
 138   static int nop_instruction()         { return Assembler::op(Assembler::branch_op) | Assembler::op2(Assembler::sethi_op2); }
 139   static int illegal_instruction();    // the output of __ breakpoint_trap()
 140   static int call_instruction(address destination, address pc) { return Assembler::op(Assembler::call_op) | Assembler::wdisp((intptr_t)destination, (intptr_t)pc, 30); }
 141 
 142   static int branch_instruction(Assembler::op2s op2val, Assembler::Condition c, bool a) {
 143     return Assembler::op(Assembler::branch_op) | Assembler::op2(op2val) | Assembler::annul(a) | Assembler::cond(c);
 144   }
 145 
 146   static int op3_instruction(Assembler::ops opval, Register rd, Assembler::op3s op3val, Register rs1, int simm13a) {
 147     return Assembler::op(opval) | Assembler::rd(rd) | Assembler::op3(op3val) | Assembler::rs1(rs1) | Assembler::immed(true) | Assembler::simm(simm13a, 13);
 148   }
 149 
 150   static int sethi_instruction(Register rd, int imm22a) {
 151     return Assembler::op(Assembler::branch_op) | Assembler::rd(rd) | Assembler::op2(Assembler::sethi_op2) | Assembler::hi22(imm22a);
 152   }
 153 
 154  protected:
 155   address  addr_at(int offset) const    { return address(this) + offset; }
 156   int      long_at(int offset) const    { return *(int*)addr_at(offset); }
 157   void set_long_at(int offset, int i);      /* deals with I-cache */
 158   void set_jlong_at(int offset, jlong i);   /* deals with I-cache */
 159   void set_addr_at(int offset, address x);  /* deals with I-cache */
 160 
 161   address instruction_address() const       { return addr_at(0); }
 162   address next_instruction_address() const  { return addr_at(BytesPerInstWord); }
 163 
 164   static bool is_op( int x, Assembler::ops opval)  {
 165     return Assembler::inv_op(x) == opval;
 166   }
 167   static bool is_op2(int x, Assembler::op2s op2val) {
 168     return Assembler::inv_op(x) == Assembler::branch_op && Assembler::inv_op2(x) == op2val;
 169   }
 170   static bool is_op3(int x, Assembler::op3s op3val, Assembler::ops opval) {
 171     return Assembler::inv_op(x) == opval && Assembler::inv_op3(x) == op3val;
 172   }
 173 
 174   // utilities to help subclasses decode:
 175   static Register inv_rd(  int x ) { return Assembler::inv_rd( x); }
 176   static Register inv_rs1( int x ) { return Assembler::inv_rs1(x); }
 177   static Register inv_rs2( int x ) { return Assembler::inv_rs2(x); }
 178 
 179   static bool inv_immed( int x ) { return Assembler::inv_immed(x); }
 180   static bool inv_annul( int x ) { return (Assembler::annul(true) & x) != 0; }
 181   static int  inv_cond(  int x ) { return Assembler::inv_cond(x); }
 182 
 183   static int inv_op(  int x ) { return Assembler::inv_op( x); }
 184   static int inv_op2( int x ) { return Assembler::inv_op2(x); }
 185   static int inv_op3( int x ) { return Assembler::inv_op3(x); }
 186 
 187   static int inv_simm(    int x, int nbits ) { return Assembler::inv_simm(x, nbits); }
 188   static intptr_t inv_wdisp(   int x, int nbits ) { return Assembler::inv_wdisp(  x, 0, nbits); }
 189   static intptr_t inv_wdisp16( int x )            { return Assembler::inv_wdisp16(x, 0); }
 190   static int branch_destination_offset(int x) { return MacroAssembler::branch_destination(x, 0); }
 191   static int patch_branch_destination_offset(int dest_offset, int x) {
 192     return MacroAssembler::patched_branch(dest_offset, x, 0);
 193   }
 194 
 195   // utility for checking if x is either of 2 small constants
 196   static bool is_either(int x, int k1, int k2) {
 197     // return x == k1 || x == k2;
 198     return (1 << x) & (1 << k1 | 1 << k2);
 199   }
 200 
 201   // utility for checking overflow of signed instruction fields
 202   static bool fits_in_simm(int x, int nbits) {
 203     // cf. Assembler::assert_signed_range()
 204     // return -(1 << nbits-1) <= x  &&  x < ( 1 << nbits-1),
 205     return (unsigned)(x + (1 << nbits-1)) < (unsigned)(1 << nbits);
 206   }
 207 
 208   // set a signed immediate field
 209   static int set_simm(int insn, int imm, int nbits) {
 210     return (insn &~ Assembler::simm(-1, nbits)) | Assembler::simm(imm, nbits);
 211   }
 212 
 213   // set a wdisp field (disp should be the difference of two addresses)
 214   static int set_wdisp(int insn, intptr_t disp, int nbits) {
 215     return (insn &~ Assembler::wdisp((intptr_t)-4, (intptr_t)0, nbits)) | Assembler::wdisp(disp, 0, nbits);
 216   }
 217 
 218   static int set_wdisp16(int insn, intptr_t disp) {
 219     return (insn &~ Assembler::wdisp16((intptr_t)-4, 0)) | Assembler::wdisp16(disp, 0);
 220   }
 221 
 222   // get a simm13 field from an arithmetic or memory instruction
 223   static int get_simm13(int insn) {
 224     assert(is_either(Assembler::inv_op(insn),
 225                      Assembler::arith_op, Assembler::ldst_op) &&
 226             (insn & Assembler::immed(true)), "must have a simm13 field");
 227     return Assembler::inv_simm(insn, 13);
 228   }
 229 
 230   // set the simm13 field of an arithmetic or memory instruction
 231   static bool set_simm13(int insn, int imm) {
 232     get_simm13(insn);           // tickle the assertion check
 233     return set_simm(insn, imm, 13);
 234   }
 235 
 236   // combine the fields of a sethi stream (7 instructions ) and an add, jmp or ld/st
 237   static intptr_t data64( address pc, int arith_insn ) {
 238     assert(is_op2(*(unsigned int *)pc, Assembler::sethi_op2), "must be sethi");
 239     intptr_t hi = (intptr_t)gethi( (unsigned int *)pc );
 240     intptr_t lo = (intptr_t)get_simm13(arith_insn);
 241     assert((unsigned)lo < (1 << 10), "offset field of set_metadata must be 10 bits");
 242     return hi | lo;
 243   }
 244 
 245   // Regenerate the instruction sequence that performs the 64 bit
 246   // sethi.  This only does the sethi.  The disp field (bottom 10 bits)
 247   // must be handled separately.
 248   static void set_data64_sethi(address instaddr, intptr_t x);
 249   static void verify_data64_sethi(address instaddr, intptr_t x);
 250 
 251   // combine the fields of a sethi/simm13 pair (simm13 = or, add, jmpl, ld/st)
 252   static int data32(int sethi_insn, int arith_insn) {
 253     assert(is_op2(sethi_insn, Assembler::sethi_op2), "must be sethi");
 254     int hi = Assembler::inv_hi22(sethi_insn);
 255     int lo = get_simm13(arith_insn);
 256     assert((unsigned)lo < (1 << 10), "offset field of set_metadata must be 10 bits");
 257     return hi | lo;
 258   }
 259 
 260   static int set_data32_sethi(int sethi_insn, int imm) {
 261     // note that Assembler::hi22 clips the low 10 bits for us
 262     assert(is_op2(sethi_insn, Assembler::sethi_op2), "must be sethi");
 263     return (sethi_insn &~ Assembler::hi22(-1)) | Assembler::hi22(imm);
 264   }
 265 
 266   static int set_data32_simm13(int arith_insn, int imm) {
 267     get_simm13(arith_insn);             // tickle the assertion check
 268     int imm10 = Assembler::low10(imm);
 269     return (arith_insn &~ Assembler::simm(-1, 13)) | Assembler::simm(imm10, 13);
 270   }
 271 
 272   static int low10(int imm) {
 273     return Assembler::low10(imm);
 274   }
 275 
 276   // Perform the inverse of the LP64 Macroassembler::sethi
 277   // routine.  Extracts the 54 bits of address from the instruction
 278   // stream. This routine must agree with the sethi routine in
 279   // assembler_inline_sparc.hpp
 280   static address gethi( unsigned int *pc ) {
 281     int i = 0;
 282     uintptr_t adr;
 283     // We first start out with the real sethi instruction
 284     assert(is_op2(*pc, Assembler::sethi_op2), "in gethi - must be sethi");
 285     adr = (unsigned int)Assembler::inv_hi22( *(pc++) );
 286     i++;
 287     while ( i < 7 ) {
 288        // We're done if we hit a nop
 289        if ( (int)*pc == nop_instruction() ) break;
 290        assert ( Assembler::inv_op(*pc) == Assembler::arith_op, "in gethi - must be arith_op" );
 291        switch  ( Assembler::inv_op3(*pc) ) {
 292          case Assembler::xor_op3:
 293            adr ^= (intptr_t)get_simm13( *pc );
 294            return ( (address)adr );
 295            break;
 296          case Assembler::sll_op3:
 297            adr <<= ( *pc & 0x3f );
 298            break;
 299          case Assembler::or_op3:
 300            adr |= (intptr_t)get_simm13( *pc );
 301            break;
 302          default:
 303            assert ( 0, "in gethi - Should not reach here" );
 304            break;
 305        }
 306        pc++;
 307        i++;
 308     }
 309     return ( (address)adr );
 310   }
 311 
 312  public:
 313   void  verify();
 314   void  print();
 315 
 316   // unit test stuff
 317   static void test() {}                 // override for testing
 318 
 319   inline friend NativeInstruction* nativeInstruction_at(address address);
 320 };
 321 
 322 inline NativeInstruction* nativeInstruction_at(address address) {
 323     NativeInstruction* inst = (NativeInstruction*)address;
 324 #ifdef ASSERT
 325       inst->verify();
 326 #endif
 327     return inst;
 328 }
 329 
 330 
 331 
 332 //-----------------------------------------------------------------------------
 333 
 334 // The NativeCall is an abstraction for accessing/manipulating native call imm32 instructions.
 335 // (used to manipulate inline caches, primitive & dll calls, etc.)
 336 inline NativeCall* nativeCall_at(address instr);
 337 inline NativeCall* nativeCall_overwriting_at(address instr,
 338                                              address destination);
 339 inline NativeCall* nativeCall_before(address return_address);
 340 class NativeCall: public NativeInstruction {
 341  public:
 342   enum Sparc_specific_constants {
 343     instruction_size                   = 8,
 344     return_address_offset              = 8,
 345     call_displacement_width            = 30,
 346     displacement_offset                = 0,
 347     instruction_offset                 = 0
 348   };
 349   address instruction_address() const       { return addr_at(0); }
 350   address next_instruction_address() const  { return addr_at(instruction_size); }
 351   address return_address() const            { return addr_at(return_address_offset); }
 352 
 353   address destination() const               { return inv_wdisp(long_at(0), call_displacement_width) + instruction_address(); }
 354   address displacement_address() const      { return addr_at(displacement_offset); }
 355   void  set_destination(address dest)       { set_long_at(0, set_wdisp(long_at(0), dest - instruction_address(), call_displacement_width)); }
 356   void  set_destination_mt_safe(address dest);
 357 
 358   void  verify_alignment() {} // do nothing on sparc
 359   void  verify();
 360   void  print();
 361 
 362   // unit test stuff
 363   static void  test();
 364 
 365   // Creation
 366   friend inline NativeCall* nativeCall_at(address instr);
 367   friend NativeCall* nativeCall_overwriting_at(address instr, address destination = NULL) {
 368     // insert a "blank" call:
 369     NativeCall* call = (NativeCall*)instr;
 370     call->set_long_at(0 * BytesPerInstWord, call_instruction(destination, instr));
 371     call->set_long_at(1 * BytesPerInstWord, nop_instruction());
 372     assert(call->addr_at(2 * BytesPerInstWord) - instr == instruction_size, "instruction size");
 373     // check its structure now:
 374     assert(nativeCall_at(instr)->destination() == destination, "correct call destination");
 375     return call;
 376   }
 377 
 378   friend inline NativeCall* nativeCall_before(address return_address) {
 379     NativeCall* call = (NativeCall*)(return_address - return_address_offset);
 380     #ifdef ASSERT
 381       call->verify();
 382     #endif
 383     return call;
 384   }
 385 
 386   static bool is_call_at(address instr) {
 387     return nativeInstruction_at(instr)->is_call();
 388   }
 389 
 390   static bool is_call_before(address instr) {
 391     return nativeInstruction_at(instr - return_address_offset)->is_call();
 392   }
 393 
 394   static bool is_call_to(address instr, address target) {
 395     return nativeInstruction_at(instr)->is_call() &&
 396       nativeCall_at(instr)->destination() == target;
 397   }
 398 
 399   // MT-safe patching of a call instruction.
 400   static void insert(address code_pos, address entry) {
 401     (void)nativeCall_overwriting_at(code_pos, entry);
 402   }
 403 
 404   static void replace_mt_safe(address instr_addr, address code_buffer);
 405 };
 406 inline NativeCall* nativeCall_at(address instr) {
 407   NativeCall* call = (NativeCall*)instr;
 408 #ifdef ASSERT
 409   call->verify();
 410 #endif
 411   return call;
 412 }
 413 
 414 class NativeCallReg: public NativeInstruction {
 415  public:
 416   enum Sparc_specific_constants {
 417     instruction_size      = 8,
 418     return_address_offset = 8,
 419     instruction_offset    = 0
 420   };
 421 
 422   address next_instruction_address() const {
 423     return addr_at(instruction_size);
 424   }
 425 };
 426 
 427 // The NativeFarCall is an abstraction for accessing/manipulating native call-anywhere
 428 // instructions in the sparcv9 vm.  Used to call native methods which may be loaded
 429 // anywhere in the address space, possibly out of reach of a call instruction.
 430 
 431 // The format of this extended-range call is:
 432 //      jumpl_to addr, lreg
 433 //      == sethi %hi54(addr), O7 ;  jumpl O7, %lo10(addr), O7 ;  <delay>
 434 // That is, it is essentially the same as a NativeJump.
 435 class NativeFarCall;
 436 inline NativeFarCall* nativeFarCall_overwriting_at(address instr, address destination);
 437 inline NativeFarCall* nativeFarCall_at(address instr);
 438 class NativeFarCall: public NativeInstruction {
 439  public:
 440   enum Sparc_specific_constants {
 441     // instruction_size includes the delay slot instruction.
 442     instruction_size                   = 9 * BytesPerInstWord,
 443     return_address_offset              = 9 * BytesPerInstWord,
 444     jmpl_offset                        = 7 * BytesPerInstWord,
 445     displacement_offset                = 0,
 446     instruction_offset                 = 0
 447   };
 448   address instruction_address() const       { return addr_at(0); }
 449   address next_instruction_address() const  { return addr_at(instruction_size); }
 450   address return_address() const            { return addr_at(return_address_offset); }
 451 
 452   address destination() const {
 453     return (address) data64(addr_at(0), long_at(jmpl_offset));
 454   }
 455   address displacement_address() const      { return addr_at(displacement_offset); }
 456   void set_destination(address dest);
 457 
 458   bool destination_is_compiled_verified_entry_point();
 459 
 460   void  verify();
 461   void  print();
 462 
 463   // unit test stuff
 464   static void  test();
 465 
 466   // Creation
 467   friend inline NativeFarCall* nativeFarCall_at(address instr) {
 468     NativeFarCall* call = (NativeFarCall*)instr;
 469     #ifdef ASSERT
 470       call->verify();
 471     #endif
 472     return call;
 473   }
 474 
 475   friend inline NativeFarCall* nativeFarCall_overwriting_at(address instr, address destination = NULL) {
 476     Unimplemented();
 477     NativeFarCall* call = (NativeFarCall*)instr;
 478     return call;
 479   }
 480 
 481   friend NativeFarCall* nativeFarCall_before(address return_address) {
 482     NativeFarCall* call = (NativeFarCall*)(return_address - return_address_offset);
 483     #ifdef ASSERT
 484       call->verify();
 485     #endif
 486     return call;
 487   }
 488 
 489   static bool is_call_at(address instr);
 490 
 491   // MT-safe patching of a call instruction.
 492   static void insert(address code_pos, address entry) {
 493     (void)nativeFarCall_overwriting_at(code_pos, entry);
 494   }
 495   static void replace_mt_safe(address instr_addr, address code_buffer);
 496 };
 497 
 498 
 499 // An interface for accessing/manipulating 32 bit native set_metadata imm, reg instructions
 500 // (used to manipulate inlined data references, etc.)
 501 //      set_metadata imm, reg
 502 //      == sethi %hi22(imm), reg ;  add reg, %lo10(imm), reg
 503 class NativeMovConstReg32;
 504 inline NativeMovConstReg32* nativeMovConstReg32_at(address address);
 505 class NativeMovConstReg32: public NativeInstruction {
 506  public:
 507   enum Sparc_specific_constants {
 508     sethi_offset           = 0,
 509     add_offset             = 4,
 510     instruction_size       = 8
 511   };
 512 
 513   address instruction_address() const       { return addr_at(0); }
 514   address next_instruction_address() const  { return addr_at(instruction_size); }
 515 
 516   // (The [set_]data accessor respects oop_type relocs also.)
 517   intptr_t data() const;
 518   void set_data(intptr_t x);
 519 
 520   // report the destination register
 521   Register destination() { return inv_rd(long_at(sethi_offset)); }
 522 
 523   void  verify();
 524   void  print();
 525 
 526   // unit test stuff
 527   static void test();
 528 
 529   // Creation
 530   friend inline NativeMovConstReg32* nativeMovConstReg32_at(address address) {
 531     NativeMovConstReg32* test = (NativeMovConstReg32*)address;
 532     #ifdef ASSERT
 533       test->verify();
 534     #endif
 535     return test;
 536   }
 537 };
 538 
 539 // An interface for accessing/manipulating native set_metadata imm, reg instructions.
 540 // (used to manipulate inlined data references, etc.)
 541 //      set_metadata imm, reg
 542 //      == sethi %hi22(imm), reg ;  add reg, %lo10(imm), reg
 543 class NativeMovConstReg;
 544 inline NativeMovConstReg* nativeMovConstReg_at(address address);
 545 class NativeMovConstReg: public NativeInstruction {
 546  public:
 547   enum Sparc_specific_constants {
 548     sethi_offset           = 0,
 549     add_offset             = 7 * BytesPerInstWord,
 550     instruction_size       = 8 * BytesPerInstWord
 551   };
 552 
 553   address instruction_address() const       { return addr_at(0); }
 554   address next_instruction_address() const  { return addr_at(instruction_size); }
 555 
 556   // (The [set_]data accessor respects oop_type relocs also.)
 557   intptr_t data() const;
 558   void set_data(intptr_t x);
 559 
 560   // report the destination register
 561   Register destination() { return inv_rd(long_at(sethi_offset)); }
 562 
 563   void  verify();
 564   void  print();
 565 
 566   // unit test stuff
 567   static void test();
 568 
 569   // Creation
 570   friend inline NativeMovConstReg* nativeMovConstReg_at(address address) {
 571     NativeMovConstReg* test = (NativeMovConstReg*)address;
 572     #ifdef ASSERT
 573       test->verify();
 574     #endif
 575     return test;
 576   }
 577 
 578 
 579   friend NativeMovConstReg* nativeMovConstReg_before(address address) {
 580     NativeMovConstReg* test = (NativeMovConstReg*)(address - instruction_size);
 581     #ifdef ASSERT
 582       test->verify();
 583     #endif
 584     return test;
 585   }
 586 
 587 };
 588 
 589 
 590 // An interface for accessing/manipulating native set_metadata imm, reg instructions.
 591 // (used to manipulate inlined data references, etc.)
 592 //      set_metadata imm, reg
 593 //      == sethi %hi22(imm), reg; nop; add reg, %lo10(imm), reg
 594 //
 595 // Note that it is identical to NativeMovConstReg with the exception of a nop between the
 596 // sethi and the add.  The nop is required to be in the delay slot of the call instruction
 597 // which overwrites the sethi during patching.
 598 class NativeMovConstRegPatching;
 599 inline NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address);class NativeMovConstRegPatching: public NativeInstruction {
 600  public:
 601   enum Sparc_specific_constants {
 602     sethi_offset           = 0,
 603     nop_offset             = 7 * BytesPerInstWord,
 604     add_offset             = nop_offset   + BytesPerInstWord,
 605     instruction_size       = add_offset   + BytesPerInstWord
 606   };
 607 
 608   address instruction_address() const       { return addr_at(0); }
 609   address next_instruction_address() const  { return addr_at(instruction_size); }
 610 
 611   // (The [set_]data accessor respects oop_type relocs also.)
 612   int data() const;
 613   void  set_data(int x);
 614 
 615   // report the destination register
 616   Register destination() { return inv_rd(long_at(sethi_offset)); }
 617 
 618   void  verify();
 619   void  print();
 620 
 621   // unit test stuff
 622   static void test();
 623 
 624   // Creation
 625   friend inline NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address) {
 626     NativeMovConstRegPatching* test = (NativeMovConstRegPatching*)address;
 627     #ifdef ASSERT
 628       test->verify();
 629     #endif
 630     return test;
 631   }
 632 
 633 
 634   friend NativeMovConstRegPatching* nativeMovConstRegPatching_before(address address) {
 635     NativeMovConstRegPatching* test = (NativeMovConstRegPatching*)(address - instruction_size);
 636     #ifdef ASSERT
 637       test->verify();
 638     #endif
 639     return test;
 640   }
 641 
 642 };
 643 
 644 
 645 // An interface for accessing/manipulating native memory ops
 646 //      ld* [reg + offset], reg
 647 //      st* reg, [reg + offset]
 648 //      sethi %hi(imm), reg; add reg, %lo(imm), reg; ld* [reg1 + reg], reg2
 649 //      sethi %hi(imm), reg; add reg, %lo(imm), reg; st* reg2, [reg1 + reg]
 650 // Ops covered: {lds,ldu,st}{w,b,h}, {ld,st}{d,x}
 651 //
 652 class NativeMovRegMem;
 653 inline NativeMovRegMem* nativeMovRegMem_at (address address);
 654 class NativeMovRegMem: public NativeInstruction {
 655  public:
 656   enum Sparc_specific_constants {
 657     op3_mask_ld = 1 << Assembler::lduw_op3 |
 658                   1 << Assembler::ldub_op3 |
 659                   1 << Assembler::lduh_op3 |
 660                   1 << Assembler::ldd_op3 |
 661                   1 << Assembler::ldsw_op3 |
 662                   1 << Assembler::ldsb_op3 |
 663                   1 << Assembler::ldsh_op3 |
 664                   1 << Assembler::ldx_op3,
 665     op3_mask_st = 1 << Assembler::stw_op3 |
 666                   1 << Assembler::stb_op3 |
 667                   1 << Assembler::sth_op3 |
 668                   1 << Assembler::std_op3 |
 669                   1 << Assembler::stx_op3,
 670     op3_ldst_int_limit = Assembler::ldf_op3,
 671     op3_mask_ldf = 1 << (Assembler::ldf_op3  - op3_ldst_int_limit) |
 672                    1 << (Assembler::lddf_op3 - op3_ldst_int_limit),
 673     op3_mask_stf = 1 << (Assembler::stf_op3  - op3_ldst_int_limit) |
 674                    1 << (Assembler::stdf_op3 - op3_ldst_int_limit),
 675 
 676     offset_width    = 13,
 677     sethi_offset    = 0,
 678     add_offset      = 7 * BytesPerInstWord,
 679     ldst_offset     = add_offset + BytesPerInstWord
 680   };
 681   bool is_immediate() const {
 682     // check if instruction is ld* [reg + offset], reg or st* reg, [reg + offset]
 683     int i0 = long_at(0);
 684     return (is_op(i0, Assembler::ldst_op));
 685   }
 686 
 687   address instruction_address() const           { return addr_at(0); }
 688   address next_instruction_address() const      {
 689     return addr_at(is_immediate() ? 4 : (7 * BytesPerInstWord));
 690   }
 691   intptr_t   offset() const                             {
 692      return is_immediate()? inv_simm(long_at(0), offset_width) :
 693                             nativeMovConstReg_at(addr_at(0))->data();
 694   }
 695   void  set_offset(intptr_t x) {
 696     if (is_immediate()) {
 697       guarantee(fits_in_simm(x, offset_width), "data block offset overflow");
 698       set_long_at(0, set_simm(long_at(0), x, offset_width));
 699     } else
 700       nativeMovConstReg_at(addr_at(0))->set_data(x);
 701   }
 702 
 703   void  add_offset_in_bytes(intptr_t radd_offset)     {
 704       set_offset (offset() + radd_offset);
 705   }
 706 
 707   void  copy_instruction_to(address new_instruction_address);
 708 
 709   void verify();
 710   void print ();
 711 
 712   // unit test stuff
 713   static void test();
 714 
 715  private:
 716   friend inline NativeMovRegMem* nativeMovRegMem_at (address address) {
 717     NativeMovRegMem* test = (NativeMovRegMem*)address;
 718     #ifdef ASSERT
 719       test->verify();
 720     #endif
 721     return test;
 722   }
 723 };
 724 
 725 
 726 // An interface for accessing/manipulating native jumps
 727 //      jump_to addr
 728 //      == sethi %hi22(addr), temp ;  jumpl reg, %lo10(addr), G0 ;  <delay>
 729 //      jumpl_to addr, lreg
 730 //      == sethi %hi22(addr), temp ;  jumpl reg, %lo10(addr), lreg ;  <delay>
 731 class NativeJump;
 732 inline NativeJump* nativeJump_at(address address);
 733 class NativeJump: public NativeInstruction {
 734  private:
 735   void guarantee_displacement(int disp, int width) {
 736     guarantee(fits_in_simm(disp, width + 2), "branch displacement overflow");
 737   }
 738 
 739  public:
 740   enum Sparc_specific_constants {
 741     sethi_offset           = 0,
 742     jmpl_offset            = 7 * BytesPerInstWord,
 743     instruction_size       = 9 * BytesPerInstWord  // includes delay slot
 744   };
 745 
 746   address instruction_address() const       { return addr_at(0); }
 747   address next_instruction_address() const  { return addr_at(instruction_size); }
 748 
 749   address jump_destination() const {
 750     return (address) data64(instruction_address(), long_at(jmpl_offset));
 751   }
 752   void set_jump_destination(address dest) {
 753     set_data64_sethi( instruction_address(), (intptr_t)dest);
 754     set_long_at(jmpl_offset,  set_data32_simm13( long_at(jmpl_offset),  (intptr_t)dest));
 755   }
 756 
 757   // Creation
 758   friend inline NativeJump* nativeJump_at(address address) {
 759     NativeJump* jump = (NativeJump*)address;
 760     #ifdef ASSERT
 761       jump->verify();
 762     #endif
 763     return jump;
 764   }
 765 
 766   void verify();
 767   void print();
 768 
 769   // Unit testing stuff
 770   static void test();
 771 
 772   // Insertion of native jump instruction
 773   static void insert(address code_pos, address entry);
 774   // MT-safe insertion of native jump at verified method entry
 775   static void check_verified_entry_alignment(address entry, address verified_entry) {
 776     // nothing to do for sparc.
 777   }
 778   static void patch_verified_entry(address entry, address verified_entry, address dest);
 779 };
 780 
 781 
 782 
 783 // Despite the name, handles only simple branches.
 784 class NativeGeneralJump;
 785 inline NativeGeneralJump* nativeGeneralJump_at(address address);
 786 class NativeGeneralJump: public NativeInstruction {
 787  public:
 788   enum Sparc_specific_constants {
 789     instruction_size                   = 8
 790   };
 791 
 792   address instruction_address() const       { return addr_at(0); }
 793   address jump_destination()    const       { return addr_at(0) + branch_destination_offset(long_at(0)); }
 794   void set_jump_destination(address dest) {
 795     int patched_instr = patch_branch_destination_offset(dest - addr_at(0), long_at(0));
 796     set_long_at(0, patched_instr);
 797   }
 798   NativeInstruction *delay_slot_instr() { return nativeInstruction_at(addr_at(4));}
 799   void fill_delay_slot(int instr) { set_long_at(4, instr);}
 800   Assembler::Condition condition() {
 801     int x = long_at(0);
 802     return (Assembler::Condition) Assembler::inv_cond(x);
 803   }
 804 
 805   // Creation
 806   friend inline NativeGeneralJump* nativeGeneralJump_at(address address) {
 807     NativeGeneralJump* jump = (NativeGeneralJump*)(address);
 808 #ifdef ASSERT
 809       jump->verify();
 810 #endif
 811     return jump;
 812   }
 813 
 814   // Insertion of native general jump instruction
 815   static void insert_unconditional(address code_pos, address entry);
 816   static void replace_mt_safe(address instr_addr, address code_buffer);
 817 
 818   void verify();
 819 };
 820 
 821 
 822 class NativeIllegalInstruction: public NativeInstruction {
 823  public:
 824   enum Sparc_specific_constants {
 825     instruction_size            =    4
 826   };
 827 
 828   // Insert illegal opcode as specific address
 829   static void insert(address code_pos);
 830 };
 831 
 832 #endif // CPU_SPARC_VM_NATIVEINST_SPARC_HPP