< prev index next >

src/cpu/sparc/vm/nativeInst_sparc.hpp

Print this page


   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  *


 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 #ifdef _LP64
 125     return is_op3(x, Assembler::ldx_op3,  Assembler::ldst_op) &&
 126 #else
 127     return is_op3(x, Assembler::lduw_op3, Assembler::ldst_op) &&
 128 #endif
 129       (inv_rd(x) == G0) && (inv_immed(x) ? Assembler::inv_simm13(x) == 0 : inv_rs2(x) == G0);
 130   }
 131 
 132   bool is_zero_test(Register &reg);
 133   bool is_load_store_with_small_offset(Register reg);
 134 
 135  public:
 136 #ifdef ASSERT
 137   static int rdpc_instruction()        { return Assembler::op(Assembler::arith_op ) | Assembler::op3(Assembler::rdreg_op3) | Assembler::u_field(5, 18, 14) | Assembler::rd(O7); }
 138 #else
 139   // Temporary fix: in optimized mode, u_field is a macro for efficiency reasons (see Assembler::u_field) - needs to be fixed
 140   static int rdpc_instruction()        { return Assembler::op(Assembler::arith_op ) | Assembler::op3(Assembler::rdreg_op3) |            u_field(5, 18, 14) | Assembler::rd(O7); }
 141 #endif
 142   static int nop_instruction()         { return Assembler::op(Assembler::branch_op) | Assembler::op2(Assembler::sethi_op2); }
 143   static int illegal_instruction();    // the output of __ breakpoint_trap()
 144   static int call_instruction(address destination, address pc) { return Assembler::op(Assembler::call_op) | Assembler::wdisp((intptr_t)destination, (intptr_t)pc, 30); }
 145 
 146   static int branch_instruction(Assembler::op2s op2val, Assembler::Condition c, bool a) {
 147     return Assembler::op(Assembler::branch_op) | Assembler::op2(op2val) | Assembler::annul(a) | Assembler::cond(c);
 148   }


 415   return call;
 416 }
 417 
 418 class NativeCallReg: public NativeInstruction {
 419  public:
 420   enum Sparc_specific_constants {
 421     instruction_size      = 8,
 422     return_address_offset = 8,
 423     instruction_offset    = 0
 424   };
 425 
 426   address next_instruction_address() const {
 427     return addr_at(instruction_size);
 428   }
 429 };
 430 
 431 // The NativeFarCall is an abstraction for accessing/manipulating native call-anywhere
 432 // instructions in the sparcv9 vm.  Used to call native methods which may be loaded
 433 // anywhere in the address space, possibly out of reach of a call instruction.
 434 
 435 #ifndef _LP64
 436 
 437 // On 32-bit systems, a far call is the same as a near one.
 438 class NativeFarCall;
 439 inline NativeFarCall* nativeFarCall_at(address instr);
 440 class NativeFarCall : public NativeCall {
 441 public:
 442   friend inline NativeFarCall* nativeFarCall_at(address instr) { return (NativeFarCall*)nativeCall_at(instr); }
 443   friend NativeFarCall* nativeFarCall_overwriting_at(address instr, address destination = NULL)
 444                                                         { return (NativeFarCall*)nativeCall_overwriting_at(instr, destination); }
 445   friend NativeFarCall* nativeFarCall_before(address return_address)
 446                                                         { return (NativeFarCall*)nativeCall_before(return_address); }
 447 };
 448 
 449 #else
 450 
 451 // The format of this extended-range call is:
 452 //      jumpl_to addr, lreg
 453 //      == sethi %hi54(addr), O7 ;  jumpl O7, %lo10(addr), O7 ;  <delay>
 454 // That is, it is essentially the same as a NativeJump.
 455 class NativeFarCall;
 456 inline NativeFarCall* nativeFarCall_overwriting_at(address instr, address destination);
 457 inline NativeFarCall* nativeFarCall_at(address instr);
 458 class NativeFarCall: public NativeInstruction {
 459  public:
 460   enum Sparc_specific_constants {
 461     // instruction_size includes the delay slot instruction.
 462     instruction_size                   = 9 * BytesPerInstWord,
 463     return_address_offset              = 9 * BytesPerInstWord,
 464     jmpl_offset                        = 7 * BytesPerInstWord,
 465     displacement_offset                = 0,
 466     instruction_offset                 = 0
 467   };
 468   address instruction_address() const       { return addr_at(0); }
 469   address next_instruction_address() const  { return addr_at(instruction_size); }
 470   address return_address() const            { return addr_at(return_address_offset); }


 498     return call;
 499   }
 500 
 501   friend NativeFarCall* nativeFarCall_before(address return_address) {
 502     NativeFarCall* call = (NativeFarCall*)(return_address - return_address_offset);
 503     #ifdef ASSERT
 504       call->verify();
 505     #endif
 506     return call;
 507   }
 508 
 509   static bool is_call_at(address instr);
 510 
 511   // MT-safe patching of a call instruction.
 512   static void insert(address code_pos, address entry) {
 513     (void)nativeFarCall_overwriting_at(code_pos, entry);
 514   }
 515   static void replace_mt_safe(address instr_addr, address code_buffer);
 516 };
 517 
 518 #endif // _LP64
 519 
 520 // An interface for accessing/manipulating 32 bit native set_metadata imm, reg instructions
 521 // (used to manipulate inlined data references, etc.)
 522 //      set_metadata imm, reg
 523 //      == sethi %hi22(imm), reg ;  add reg, %lo10(imm), reg
 524 class NativeMovConstReg32;
 525 inline NativeMovConstReg32* nativeMovConstReg32_at(address address);
 526 class NativeMovConstReg32: public NativeInstruction {
 527  public:
 528   enum Sparc_specific_constants {
 529     sethi_offset           = 0,
 530     add_offset             = 4,
 531     instruction_size       = 8
 532   };
 533 
 534   address instruction_address() const       { return addr_at(0); }
 535   address next_instruction_address() const  { return addr_at(instruction_size); }
 536 
 537   // (The [set_]data accessor respects oop_type relocs also.)
 538   intptr_t data() const;


 550   // Creation
 551   friend inline NativeMovConstReg32* nativeMovConstReg32_at(address address) {
 552     NativeMovConstReg32* test = (NativeMovConstReg32*)address;
 553     #ifdef ASSERT
 554       test->verify();
 555     #endif
 556     return test;
 557   }
 558 };
 559 
 560 // An interface for accessing/manipulating native set_metadata imm, reg instructions.
 561 // (used to manipulate inlined data references, etc.)
 562 //      set_metadata imm, reg
 563 //      == sethi %hi22(imm), reg ;  add reg, %lo10(imm), reg
 564 class NativeMovConstReg;
 565 inline NativeMovConstReg* nativeMovConstReg_at(address address);
 566 class NativeMovConstReg: public NativeInstruction {
 567  public:
 568   enum Sparc_specific_constants {
 569     sethi_offset           = 0,
 570 #ifdef _LP64
 571     add_offset             = 7 * BytesPerInstWord,
 572     instruction_size       = 8 * BytesPerInstWord
 573 #else
 574     add_offset             = 4,
 575     instruction_size       = 8
 576 #endif
 577   };
 578 
 579   address instruction_address() const       { return addr_at(0); }
 580   address next_instruction_address() const  { return addr_at(instruction_size); }
 581 
 582   // (The [set_]data accessor respects oop_type relocs also.)
 583   intptr_t data() const;
 584   void set_data(intptr_t x);
 585 
 586   // report the destination register
 587   Register destination() { return inv_rd(long_at(sethi_offset)); }
 588 
 589   void  verify();
 590   void  print();
 591 
 592   // unit test stuff
 593   static void test();
 594 
 595   // Creation
 596   friend inline NativeMovConstReg* nativeMovConstReg_at(address address) {


 609     #endif
 610     return test;
 611   }
 612 
 613 };
 614 
 615 
 616 // An interface for accessing/manipulating native set_metadata imm, reg instructions.
 617 // (used to manipulate inlined data references, etc.)
 618 //      set_metadata imm, reg
 619 //      == sethi %hi22(imm), reg; nop; add reg, %lo10(imm), reg
 620 //
 621 // Note that it is identical to NativeMovConstReg with the exception of a nop between the
 622 // sethi and the add.  The nop is required to be in the delay slot of the call instruction
 623 // which overwrites the sethi during patching.
 624 class NativeMovConstRegPatching;
 625 inline NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address);class NativeMovConstRegPatching: public NativeInstruction {
 626  public:
 627   enum Sparc_specific_constants {
 628     sethi_offset           = 0,
 629 #ifdef _LP64
 630     nop_offset             = 7 * BytesPerInstWord,
 631 #else
 632     nop_offset             = sethi_offset + BytesPerInstWord,
 633 #endif
 634     add_offset             = nop_offset   + BytesPerInstWord,
 635     instruction_size       = add_offset   + BytesPerInstWord
 636   };
 637 
 638   address instruction_address() const       { return addr_at(0); }
 639   address next_instruction_address() const  { return addr_at(instruction_size); }
 640 
 641   // (The [set_]data accessor respects oop_type relocs also.)
 642   int data() const;
 643   void  set_data(int x);
 644 
 645   // report the destination register
 646   Register destination() { return inv_rd(long_at(sethi_offset)); }
 647 
 648   void  verify();
 649   void  print();
 650 
 651   // unit test stuff
 652   static void test();
 653 


 688                   1 << Assembler::ldub_op3 |
 689                   1 << Assembler::lduh_op3 |
 690                   1 << Assembler::ldd_op3 |
 691                   1 << Assembler::ldsw_op3 |
 692                   1 << Assembler::ldsb_op3 |
 693                   1 << Assembler::ldsh_op3 |
 694                   1 << Assembler::ldx_op3,
 695     op3_mask_st = 1 << Assembler::stw_op3 |
 696                   1 << Assembler::stb_op3 |
 697                   1 << Assembler::sth_op3 |
 698                   1 << Assembler::std_op3 |
 699                   1 << Assembler::stx_op3,
 700     op3_ldst_int_limit = Assembler::ldf_op3,
 701     op3_mask_ldf = 1 << (Assembler::ldf_op3  - op3_ldst_int_limit) |
 702                    1 << (Assembler::lddf_op3 - op3_ldst_int_limit),
 703     op3_mask_stf = 1 << (Assembler::stf_op3  - op3_ldst_int_limit) |
 704                    1 << (Assembler::stdf_op3 - op3_ldst_int_limit),
 705 
 706     offset_width    = 13,
 707     sethi_offset    = 0,
 708 #ifdef _LP64
 709     add_offset      = 7 * BytesPerInstWord,
 710 #else
 711     add_offset      = 4,
 712 #endif
 713     ldst_offset     = add_offset + BytesPerInstWord
 714   };
 715   bool is_immediate() const {
 716     // check if instruction is ld* [reg + offset], reg or st* reg, [reg + offset]
 717     int i0 = long_at(0);
 718     return (is_op(i0, Assembler::ldst_op));
 719   }
 720 
 721   address instruction_address() const           { return addr_at(0); }
 722   address next_instruction_address() const      {
 723 #ifdef _LP64
 724     return addr_at(is_immediate() ? 4 : (7 * BytesPerInstWord));
 725 #else
 726     return addr_at(is_immediate() ? 4 : 12);
 727 #endif
 728   }
 729   intptr_t   offset() const                             {
 730      return is_immediate()? inv_simm(long_at(0), offset_width) :
 731                             nativeMovConstReg_at(addr_at(0))->data();
 732   }
 733   void  set_offset(intptr_t x) {
 734     if (is_immediate()) {
 735       guarantee(fits_in_simm(x, offset_width), "data block offset overflow");
 736       set_long_at(0, set_simm(long_at(0), x, offset_width));
 737     } else
 738       nativeMovConstReg_at(addr_at(0))->set_data(x);
 739   }
 740 
 741   void  add_offset_in_bytes(intptr_t radd_offset)     {
 742       set_offset (offset() + radd_offset);
 743   }
 744 
 745   void  copy_instruction_to(address new_instruction_address);
 746 
 747   void verify();


 760   }
 761 };
 762 
 763 
 764 // An interface for accessing/manipulating native jumps
 765 //      jump_to addr
 766 //      == sethi %hi22(addr), temp ;  jumpl reg, %lo10(addr), G0 ;  <delay>
 767 //      jumpl_to addr, lreg
 768 //      == sethi %hi22(addr), temp ;  jumpl reg, %lo10(addr), lreg ;  <delay>
 769 class NativeJump;
 770 inline NativeJump* nativeJump_at(address address);
 771 class NativeJump: public NativeInstruction {
 772  private:
 773   void guarantee_displacement(int disp, int width) {
 774     guarantee(fits_in_simm(disp, width + 2), "branch displacement overflow");
 775   }
 776 
 777  public:
 778   enum Sparc_specific_constants {
 779     sethi_offset           = 0,
 780 #ifdef _LP64
 781     jmpl_offset            = 7 * BytesPerInstWord,
 782     instruction_size       = 9 * BytesPerInstWord  // includes delay slot
 783 #else
 784     jmpl_offset            = 1 * BytesPerInstWord,
 785     instruction_size       = 3 * BytesPerInstWord  // includes delay slot
 786 #endif
 787   };
 788 
 789   address instruction_address() const       { return addr_at(0); }
 790   address next_instruction_address() const  { return addr_at(instruction_size); }
 791 
 792 #ifdef _LP64
 793   address jump_destination() const {
 794     return (address) data64(instruction_address(), long_at(jmpl_offset));
 795   }
 796   void set_jump_destination(address dest) {
 797     set_data64_sethi( instruction_address(), (intptr_t)dest);
 798     set_long_at(jmpl_offset,  set_data32_simm13( long_at(jmpl_offset),  (intptr_t)dest));
 799   }
 800 #else
 801   address jump_destination() const {
 802     return (address) data32(long_at(sethi_offset), long_at(jmpl_offset));
 803   }
 804   void set_jump_destination(address dest) {
 805     set_long_at(sethi_offset, set_data32_sethi(  long_at(sethi_offset), (intptr_t)dest));
 806     set_long_at(jmpl_offset,  set_data32_simm13( long_at(jmpl_offset),  (intptr_t)dest));
 807   }
 808 #endif
 809 
 810   // Creation
 811   friend inline NativeJump* nativeJump_at(address address) {
 812     NativeJump* jump = (NativeJump*)address;
 813     #ifdef ASSERT
 814       jump->verify();
 815     #endif
 816     return jump;
 817   }
 818 
 819   void verify();
 820   void print();
 821 
 822   // Unit testing stuff
 823   static void test();
 824 
 825   // Insertion of native jump instruction
 826   static void insert(address code_pos, address entry);
 827   // MT-safe insertion of native jump at verified method entry
 828   static void check_verified_entry_alignment(address entry, address verified_entry) {


   1 /*
   2  * Copyright (c) 1997, 2017, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  *


 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   }


 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); }


 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;


 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) {


 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 


 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();


 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) {


< prev index next >