src/cpu/mips/vm/nativeInst_mips.hpp

Wed, 29 Mar 2017 09:41:51 +0800

author
aoqi
date
Wed, 29 Mar 2017 09:41:51 +0800
changeset 392
4bfb40d1e17a
parent 386
f50649f9eda6
child 397
1e8b8bc62356
permissions
-rw-r--r--

#4662 TieredCompilation is turned off.
TieredCompilation is not supported yet.

     1 /*
     2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * Copyright (c) 2015, 2016, Loongson Technology. All rights reserved.
     4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     5  *
     6  * This code is free software; you can redistribute it and/or modify it
     7  * under the terms of the GNU General Public License version 2 only, as
     8  * published by the Free Software Foundation.
     9  *
    10  * This code is distributed in the hope that it will be useful, but WITHOUT
    11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    13  * version 2 for more details (a copy is included in the LICENSE file that
    14  * accompanied this code).
    15  *
    16  * You should have received a copy of the GNU General Public License version
    17  * 2 along with this work; if not, write to the Free Software Foundation,
    18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    19  *
    20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    21  * or visit www.oracle.com if you need additional information or have any
    22  * questions.
    23  *
    24  */
    26 #ifndef CPU_MIPS_VM_NATIVEINST_MIPS_HPP
    27 #define CPU_MIPS_VM_NATIVEINST_MIPS_HPP
    29 #include "asm/assembler.hpp"
    30 #include "memory/allocation.hpp"
    31 #include "runtime/icache.hpp"
    32 #include "runtime/os.hpp"
    33 #include "utilities/top.hpp"
    35 // We have interfaces for the following instructions:
    36 // - NativeInstruction
    37 // - - NativeCall
    38 // - - NativeMovConstReg
    39 // - - NativeMovConstRegPatching
    40 // - - NativeMovRegMem
    41 // - - NativeMovRegMemPatching
    42 // - - NativeJump
    43 // - - NativeIllegalOpCode
    44 // - - NativeGeneralJump
    45 // - - NativeReturn
    46 // - - NativeReturnX (return with argument)
    47 // - - NativePushConst
    48 // - - NativeTstRegMem
    50 // The base class for different kinds of native instruction abstractions.
    51 // Provides the primitive operations to manipulate code relative to this.
    53 class NativeInstruction VALUE_OBJ_CLASS_SPEC {
    54   friend class Relocation;
    56  public:
    57   enum mips_specific_constants {
    58     nop_instruction_code        =    0,
    59     nop_instruction_size        =    4
    60   };
    62   bool is_nop()                        { return long_at(0) == nop_instruction_code; }
    63   bool is_dtrace_trap();
    64   inline bool is_call();
    65   inline bool is_illegal();
    66   inline bool is_return();
    67   bool is_jump();
    68   inline bool is_cond_jump();
    69   bool is_safepoint_poll();
    71   //mips has no instruction to generate a illegal instrucion exception
    72   //we define ours: break 11 
    73   static int illegal_instruction();
    75   bool is_int_branch();
    76   bool is_float_branch();
    79  protected:
    80   address addr_at(int offset) const    { return address(this) + offset; }
    81   address instruction_address() const       { return addr_at(0); }
    82   address next_instruction_address() const  { return addr_at(BytesPerInstWord); }
    83   address prev_instruction_address() const	{ return addr_at(-BytesPerInstWord); }
    85   s_char sbyte_at(int offset) const    { return *(s_char*) addr_at(offset); }
    86   u_char ubyte_at(int offset) const    { return *(u_char*) addr_at(offset); }
    87   jint int_at(int offset) const         { return *(jint*) addr_at(offset); }
    88   intptr_t ptr_at(int offset) const    { return *(intptr_t*) addr_at(offset); }
    89   oop  oop_at (int offset) const       { return *(oop*) addr_at(offset); }
    90   int  long_at(int offset) const       { return *(jint*)addr_at(offset); }
    93   void set_char_at(int offset, char c)        { *addr_at(offset) = (u_char)c; wrote(offset); }
    94   void set_int_at(int offset, jint  i)        { *(jint*)addr_at(offset) = i;  wrote(offset); }
    95   void set_ptr_at (int offset, intptr_t  ptr) { *(intptr_t*) addr_at(offset) = ptr;  wrote(offset); }
    96   void set_oop_at (int offset, oop  o)        { *(oop*) addr_at(offset) = o;  wrote(offset); }
    97   void set_long_at(int offset, long  i);
    98   //void set_jlong_at(int offset, jlong i);
    99   //void set_addr_at(int offset, address x);
   101   int  insn_word() const { return long_at(0); }
   102   static bool is_op (int insn, Assembler::ops op) { return Assembler::opcode(insn) == (int)op; }
   103   bool is_op (Assembler::ops op)     const { return is_op(insn_word(), op); }
   104   bool is_rs (int insn, Register rs) const { return Assembler::rs(insn) == (int)rs->encoding(); }
   105   bool is_rs (Register rs)           const { return is_rs(insn_word(), rs); }
   106   bool is_rt (int insn, Register rt) const { return Assembler::rt(insn) == (int)rt->encoding(); }
   107   bool is_rt (Register rt) 	     const { return is_rt(insn_word(), rt); }
   109   static bool is_special_op (int insn, Assembler::special_ops op) { 
   110     return is_op(insn, Assembler::special_op) && Assembler::special(insn)==(int)op; 
   111   }
   112   bool is_special_op (Assembler::special_ops op) const { return is_special_op(insn_word(), op); }
   114   // This doesn't really do anything on Intel, but it is the place where
   115   // cache invalidation belongs, generically:
   116   void wrote(int offset);
   118  public:
   120   // unit test stuff
   121   static void test() {}                 // override for testing
   123   inline friend NativeInstruction* nativeInstruction_at(address address);
   124 };
   126 inline NativeInstruction* nativeInstruction_at(address address) {
   127   NativeInstruction* inst = (NativeInstruction*)address;
   128 #ifdef ASSERT
   129   //inst->verify();
   130 #endif
   131   return inst;
   132 }
   134 inline NativeCall* nativeCall_at(address address);
   135 // The NativeCall is an abstraction for accessing/manipulating native call imm32/imm64
   136 // instructions (used to manipulate inline caches, primitive & dll calls, etc.).
   137 // MIPS has no call instruction with imm32/imm64. Usually, a call was done like this:
   138 // 32 bits:
   139 // 			lui 		rt, imm16
   140 // 			addiu		rt, rt, imm16
   141 // 			jalr 		rt
   142 //			nop
   143 // 			
   144 // 64 bits:
   145 //    		    lui   rd, imm(63...48);
   146 //		    ori   rd, rd, imm(47...32);
   147 //		    dsll  rd, rd, 16;
   148 //		    ori   rd, rd, imm(31...16);
   149 //		    dsll  rd, rd, 16;
   150 //		    ori   rd, rd, imm(15...0);
   151 //		    jalr  rd
   152 //      	    nop
   153 //		    
   155 // we just consider the above for instruction as one call instruction
   156 class NativeCall: public NativeInstruction {
   157   public:
   158     enum mips_specific_constants {
   159       instruction_offset          =    0,
   160 #ifndef _LP64
   161       instruction_size            =   4 * BytesPerInstWord,
   162       return_address_offset       =   4 * BytesPerInstWord,
   163 #else
   164       instruction_size            =   6 * BytesPerInstWord,
   165       return_address_offset_short =   4 * BytesPerInstWord,
   166       return_address_offset_long  =   6 * BytesPerInstWord,
   167 #endif
   168       displacement_offset         =   0
   169     };
   171     address instruction_address() const       { return addr_at(instruction_offset); }
   173     address next_instruction_address() const  { 
   174       if (is_special_op(int_at(8), Assembler::jalr_op)) {
   175         return addr_at(return_address_offset_short); 
   176       } else {
   177         return addr_at(return_address_offset_long); 
   178       }
   179     }
   181     address return_address() const            { 
   182       return next_instruction_address(); 
   183     }
   185     address destination() const;
   186     void  set_destination(address dest);
   187     void  set_destination_mt_safe(address dest) { set_destination(dest);}
   189     void  patch_set48_gs(address dest);
   190     void  patch_set48(address dest);
   192     void  patch_on_jalr_gs(address dest);
   193     void  patch_on_jalr(address dest);
   195     void  patch_on_jal_gs(address dest);
   196     void  patch_on_jal(address dest);
   198     void  patch_set32_gs(address dest);
   199     void  patch_set32(address dest);
   201     void  verify_alignment() {  }
   202     void  verify();
   203     void  print();
   205     // Creation
   206     inline friend NativeCall* nativeCall_at(address address);
   207     inline friend NativeCall* nativeCall_before(address return_address);
   209     static bool is_call_at(address instr) {
   210       return nativeInstruction_at(instr)->is_call();
   211     }
   213     static bool is_call_before(address return_address) {
   214       return is_call_at(return_address - return_address_offset_short) | is_call_at(return_address - return_address_offset_long);
   215     }
   217     static bool is_call_to(address instr, address target) {
   218       return nativeInstruction_at(instr)->is_call() &&
   219 	nativeCall_at(instr)->destination() == target;
   220     }
   222     // MT-safe patching of a call instruction.
   223     static void insert(address code_pos, address entry);
   225     static void replace_mt_safe(address instr_addr, address code_buffer);
   226 };
   228 inline NativeCall* nativeCall_at(address address) {
   229   NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset);
   230 #ifdef ASSERT
   231   call->verify();
   232 #endif
   233   return call;
   234 }
   236 inline NativeCall* nativeCall_before(address return_address) {
   237   NativeCall* call = NULL;
   238   if (NativeCall::is_call_at(return_address - NativeCall::return_address_offset_long)) {
   239     call = (NativeCall*)(return_address - NativeCall::return_address_offset_long);
   240   } else {
   241     call = (NativeCall*)(return_address - NativeCall::return_address_offset_short);
   242   }
   243 #ifdef ASSERT
   244   call->verify();
   245 #endif
   246   return call;
   247 }
   249 class NativeMovConstReg: public NativeInstruction {
   250  public:
   251   enum mips_specific_constants {
   252     instruction_offset  	=    0,
   253 #ifndef _LP64
   254     instruction_size  	      	=    2 * BytesPerInstWord,
   255     next_instruction_offset 	=    2 * BytesPerInstWord,
   256 #else
   257     instruction_size  	      	=    4 * BytesPerInstWord,
   258     next_instruction_offset 	=    4 * BytesPerInstWord,
   259 #endif
   260   };
   262   int     insn_word() const                 { return long_at(instruction_offset); }
   263   address instruction_address() const       { return addr_at(0); }
   264   address next_instruction_address() const  { return addr_at(next_instruction_offset); }
   265   intptr_t data() const;
   266   void    set_data(intptr_t x);
   268   void    patch_set48(intptr_t x);
   270   void  verify();
   271   void  print();
   273   // unit test stuff
   274   static void test() {}
   276   // Creation
   277   inline friend NativeMovConstReg* nativeMovConstReg_at(address address);
   278   inline friend NativeMovConstReg* nativeMovConstReg_before(address address);
   279 };
   281 inline NativeMovConstReg* nativeMovConstReg_at(address address) {
   282   NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_offset);
   283 #ifdef ASSERT
   284   test->verify();
   285 #endif
   286   return test;
   287 }
   289 inline NativeMovConstReg* nativeMovConstReg_before(address address) {
   290   NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_size - NativeMovConstReg::instruction_offset);
   291 #ifdef ASSERT
   292   test->verify();
   293 #endif
   294   return test;
   295 }
   297 class NativeMovConstRegPatching: public NativeMovConstReg {
   298  private:
   299     friend NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address) {
   300     NativeMovConstRegPatching* test = (NativeMovConstRegPatching*)(address - instruction_offset);
   301     #ifdef ASSERT
   302       test->verify();
   303     #endif
   304     return test;
   305   }
   306 };
   308 // An interface for accessing/manipulating native moves of the form:
   309 // 			lui   AT, split_high(offset)
   310 // 			addiu AT, split_low(offset)
   311 // 			add   reg, reg, AT
   312 // 			lb/lbu/sb/lh/lhu/sh/lw/sw/lwc1/swc1 dest, reg, 0
   313 // 			[lw/sw/lwc1/swc1                    dest, reg, 4]
   314 // 		or 
   315 // 			lb/lbu/sb/lh/lhu/sh/lw/sw/lwc1/swc1 dest, reg, offset
   316 // 			[lw/sw/lwc1/swc1                    dest, reg, offset+4]
   317 //
   318 // Warning: These routines must be able to handle any instruction sequences
   319 // that are generated as a result of the load/store byte,word,long
   320 // macros.  
   322 class NativeMovRegMem: public NativeInstruction {
   323  public:
   324   enum mips_specific_constants {
   325     instruction_offset  = 0,
   326     hiword_offset 	= 4,
   327     ldst_offset   	= 12,
   328     immediate_size	= 4,
   329     ldst_size     	= 16
   330   };
   332   //offset is less than 16 bits.
   333   bool is_immediate() const { return !is_op(long_at(instruction_offset), Assembler::lui_op); }
   334   bool is_64ldst() const {
   335     if (is_immediate()) {
   336       return (Assembler::opcode(long_at(hiword_offset)) == Assembler::opcode(long_at(instruction_offset))) &&
   337 	     (Assembler::imm_off(long_at(hiword_offset)) == Assembler::imm_off(long_at(instruction_offset)) + wordSize);
   338     } else {
   339       return (Assembler::opcode(long_at(ldst_offset+hiword_offset)) == Assembler::opcode(long_at(ldst_offset))) &&
   340 	     (Assembler::imm_off(long_at(ldst_offset+hiword_offset)) == Assembler::imm_off(long_at(ldst_offset)) + wordSize);
   341     }
   342   }
   344   address instruction_address() const       { return addr_at(instruction_offset); }
   345   address next_instruction_address() const  { 
   346     return addr_at( (is_immediate()? immediate_size : ldst_size) + (is_64ldst()? 4 : 0));  
   347   }
   348 /*  // helper
   349   int instruction_start() const;
   351   address instruction_address() const;
   353   address next_instruction_address() const;
   354 */
   356   int   offset() const;
   358   void  set_offset(int x);
   360   void  add_offset_in_bytes(int add_offset)     { set_offset ( ( offset() + add_offset ) ); }
   362   void verify();
   363   void print ();
   365   // unit test stuff
   366   static void test() {}
   368  private:
   369   inline friend NativeMovRegMem* nativeMovRegMem_at (address address);
   370 };
   372 inline NativeMovRegMem* nativeMovRegMem_at (address address) {
   373   NativeMovRegMem* test = (NativeMovRegMem*)(address - NativeMovRegMem::instruction_offset);
   374 #ifdef ASSERT
   375   test->verify();
   376 #endif
   377   return test;
   378 }
   380 class NativeMovRegMemPatching: public NativeMovRegMem {
   381  private:
   382   friend NativeMovRegMemPatching* nativeMovRegMemPatching_at (address address) {
   383     NativeMovRegMemPatching* test = (NativeMovRegMemPatching*)(address - instruction_offset);
   384     #ifdef ASSERT
   385       test->verify();
   386     #endif
   387     return test;
   388   }
   389 };
   392 // Handles all kinds of jump on Loongson. Long/far, conditional/unconditional
   393 // 32 bits:
   394 //    far jump:
   395 //				lui   reg, split_high(addr)
   396 //				addiu reg, split_low(addr)
   397 //				jr    reg
   398 //				nop
   399 //    or 
   400 //				beq 	ZERO, ZERO, offset
   401 //				nop
   402 //
   404 //64 bits:
   405 //    far jump:
   406 //			    lui   rd, imm(63...48);
   407 //			    ori   rd, rd, imm(47...32);
   408 //			    dsll  rd, rd, 16;
   409 //			    ori   rd, rd, imm(31...16);
   410 //			    dsll  rd, rd, 16;
   411 //			    ori   rd, rd, imm(15...0);
   412 //			    jalr  rd
   413 //			    nop
   414 //		    
   415 class NativeGeneralJump: public NativeInstruction {
   416 public:
   417   enum mips_specific_constants {
   418     instruction_offset 	=    0,
   419     beq_opcode         	=    0x10000000,//000100|00000|00000|offset
   420     b_mask       	=    0xffff0000,
   421     short_size    	=    8,
   422 #ifndef _LP64
   423     instruction_size   =    4 * BytesPerInstWord
   424 #else
   425     instruction_size   =    6 * BytesPerInstWord
   426 #endif
   427   };
   429   bool is_short() const { return (long_at(instruction_offset) & b_mask) == beq_opcode; }
   430 #ifdef _LP64
   431   bool is_b_far();
   432 #endif
   433   address instruction_address() const { return addr_at(instruction_offset); }
   434   address jump_destination();
   436   void  patch_set48_gs(address dest);
   437   void  patch_set48(address dest);
   439   void  patch_on_jr_gs(address dest);
   440   void  patch_on_jr(address dest);
   442   void  patch_on_j_gs(address dest);
   443   void  patch_on_j(address dest);
   445   void  set_jump_destination(address dest);
   447 	// Creation
   448   inline friend NativeGeneralJump* nativeGeneralJump_at(address address);
   450 	// Insertion of native general jump instruction
   451   static void insert_unconditional(address code_pos, address entry);
   452   static void replace_mt_safe(address instr_addr, address code_buffer);
   453   static void check_verified_entry_alignment(address entry, address verified_entry){}
   454   static void patch_verified_entry(address entry, address verified_entry, address dest);
   456   void verify();
   457 };
   459 inline NativeGeneralJump* nativeGeneralJump_at(address address) {
   460   NativeGeneralJump* jump = (NativeGeneralJump*)(address);
   461   debug_only(jump->verify();)
   462   return jump;
   463 }
   465 /*class NativePopReg : public NativeInstruction {
   466   public:
   467   enum Intel_specific_constants {
   468   instruction_code            = 0x58,
   469   instruction_size            =    1,
   470   instruction_offset          =    0,
   471   data_offset                 =    1,
   472   next_instruction_offset     =    1
   473   };
   475 // Insert a pop instruction
   476 static void insert(address code_pos, Register reg);
   477 };*/
   480 class NativeIllegalInstruction: public NativeInstruction {
   481 public:
   482   enum Intel_specific_constants {
   483     instruction_size          =    4,
   484     instruction_offset        =    0,
   485     next_instruction_offset   =    4
   486   };
   488   // Insert illegal opcode as specific address
   489   static void insert(address code_pos);
   490 };
   492 // return instruction that does not pop values of the stack
   493 // jr RA
   494 // delay slot
   495 class NativeReturn: public NativeInstruction {
   496 public:
   497   enum mips_specific_constants {
   498     instruction_size          =    8,
   499     instruction_offset        =    0,
   500     next_instruction_offset   =    8
   501   };
   502 };
   507 class NativeCondJump;
   508 inline NativeCondJump* nativeCondJump_at(address address);
   509 class NativeCondJump: public NativeInstruction {
   510 public:
   511   enum mips_specific_constants {
   512     instruction_size 	      = 16,
   513     instruction_offset        = 12,
   514     next_instruction_offset   = 20
   515   };
   518   int insn_word() const  { return long_at(instruction_offset); }
   519   address instruction_address() const { return addr_at(0); }
   520   address next_instruction_address() const { return addr_at(next_instruction_offset); }
   522   // Creation
   523   inline friend NativeCondJump* nativeCondJump_at(address address);
   525   address jump_destination()  const {
   526     return ::nativeCondJump_at(addr_at(12))->jump_destination();
   527   }
   529   void set_jump_destination(address dest) {
   530     ::nativeCondJump_at(addr_at(12))->set_jump_destination(dest);
   531   }
   533 };	
   535 inline NativeCondJump* nativeCondJump_at(address address) {
   536   NativeCondJump* jump = (NativeCondJump*)(address);
   537   return jump;
   538 }
   542 inline bool NativeInstruction::is_illegal() { return insn_word() == illegal_instruction(); }
   544 inline bool NativeInstruction::is_call()    { 
   545 #ifndef _LP64
   546   return is_op(long_at(0), Assembler::lui_op) &&
   547          is_op(long_at(4), Assembler::addiu_op) &&
   548 	 is_special_op(long_at(8), Assembler::jalr_op);
   549 #else
   551   // nop
   552   // nop
   553   // nop
   554   // nop
   555   // jal target 
   556   // nop
   557   if ( is_nop() &&
   558          nativeInstruction_at(addr_at(4))->is_nop()  &&
   559          nativeInstruction_at(addr_at(8))->is_nop()  &&
   560          nativeInstruction_at(addr_at(12))->is_nop() &&
   561          nativeInstruction_at(addr_at(16))->is_op(Assembler::jal_op) &&
   562          nativeInstruction_at(addr_at(20))->is_nop() ) {
   563       return true;
   564   }
   566   // li64
   567   if ( is_op(Assembler::lui_op) &&
   568 	is_op(int_at(4), Assembler::ori_op) &&
   569 	is_special_op(int_at(8), Assembler::dsll_op) &&
   570 	is_op(int_at(12), Assembler::ori_op) &&
   571 	is_special_op(int_at(16), Assembler::dsll_op) &&
   572 	is_op(int_at(20), Assembler::ori_op) &&
   573         is_special_op(int_at(24), Assembler::jalr_op) ) {
   574       return true;
   575   }
   577   //lui dst, imm16
   578   //ori dst, dst, imm16
   579   //dsll dst, dst, 16
   580   //ori dst, dst, imm16
   581   if (  is_op(Assembler::lui_op) &&
   582 	  is_op	(int_at(4), Assembler::ori_op) &&
   583 	  is_special_op(int_at(8), Assembler::dsll_op) &&
   584 	  is_op	(int_at(12), Assembler::ori_op) &&
   585           is_special_op(int_at(16), Assembler::jalr_op) ) {
   586       return true;
   587   }
   589   //ori dst, R0, imm16
   590   //dsll dst, dst, 16
   591   //ori dst, dst, imm16
   592   //nop
   593   if (  is_op(Assembler::ori_op) &&
   594 	  is_special_op(int_at(4), Assembler::dsll_op) &&
   595 	  is_op	(int_at(8), Assembler::ori_op) &&
   596           nativeInstruction_at(addr_at(12))->is_nop() &&
   597           is_special_op(int_at(16), Assembler::jalr_op) ) {
   598       return true;
   599   }
   601   //ori dst, R0, imm16
   602   //dsll dst, dst, 16
   603   //nop
   604   //nop
   605   if (  is_op(Assembler::ori_op) &&
   606 	  is_special_op(int_at(4), Assembler::dsll_op) &&
   607 	  nativeInstruction_at(addr_at(8))->is_nop()   &&
   608           nativeInstruction_at(addr_at(12))->is_nop() &&
   609           is_special_op(int_at(16), Assembler::jalr_op) ) {
   610       return true;
   611   }
   613   //daddiu dst, R0, imm16
   614   //nop
   615   //nop
   616   //nop
   617   if (  is_op(Assembler::daddiu_op) &&
   618 	  nativeInstruction_at(addr_at(4))->is_nop() &&
   619 	  nativeInstruction_at(addr_at(8))->is_nop() &&
   620 	  nativeInstruction_at(addr_at(12))->is_nop() &&
   621           is_special_op(int_at(16), Assembler::jalr_op) ) {
   622       return true;
   623   }
   625   //lui dst, imm16
   626   //ori dst, dst, imm16
   627   //nop
   628   //nop
   629   if (  is_op(Assembler::lui_op) &&
   630 	  is_op	(int_at(4), Assembler::ori_op) &&
   631 	  nativeInstruction_at(addr_at(8))->is_nop() &&
   632 	  nativeInstruction_at(addr_at(12))->is_nop() && 
   633           is_special_op(int_at(16), Assembler::jalr_op) ) {
   634       return true;
   635   }
   637   //lui dst, imm16
   638   //nop
   639   //nop
   640   //nop
   641   if (  is_op(Assembler::lui_op) &&
   642 	  nativeInstruction_at(addr_at(4))->is_nop() &&
   643 	  nativeInstruction_at(addr_at(8))->is_nop() &&
   644 	  nativeInstruction_at(addr_at(12))->is_nop() && 
   645           is_special_op(int_at(16), Assembler::jalr_op) ) {
   646       return true;
   647   }
   650   //daddiu dst, R0, imm16
   651   //nop
   652   if (  is_op(Assembler::daddiu_op) &&
   653 	  nativeInstruction_at(addr_at(4))->is_nop() &&
   654           is_special_op(int_at(8), Assembler::jalr_op) ) {
   655       return true;
   656   }
   658   //lui dst, imm16
   659   //ori dst, dst, imm16
   660   if (  is_op(Assembler::lui_op) &&
   661 	  is_op	(int_at(4), Assembler::ori_op) &&
   662           is_special_op(int_at(8), Assembler::jalr_op) ) {
   663       return true;
   664   }
   666   //lui dst, imm16
   667   //nop
   668   if (  is_op(Assembler::lui_op) &&
   669 	  nativeInstruction_at(addr_at(4))->is_nop() &&
   670           is_special_op(int_at(8), Assembler::jalr_op) ) {
   671       return true;
   672   }
   674   return false;
   676 #endif
   677 }
   679 inline bool NativeInstruction::is_return()  { return is_special_op(Assembler::jr_op) && is_rs(RA);}
   681 inline bool NativeInstruction::is_cond_jump()    { return is_int_branch() || is_float_branch(); }
   682 #endif // CPU_MIPS_VM_NATIVEINST_MIPS_HPP

mercurial