src/cpu/mips/vm/nativeInst_mips.hpp

Thu, 24 May 2018 19:49:50 +0800

author
aoqi
date
Thu, 24 May 2018 19:49:50 +0800
changeset 8865
ffcdff41a92f
parent 8863
5376ce0dc552
child 9146
4c971a763d55
permissions
-rw-r--r--

some C1 fix
Contributed-by: chenhaoxuan, zhaixiang, aoqi

     1 /*
     2  * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved.
     3  * Copyright (c) 2015, 2018, 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     sync_instruction_code       =    0xf
    61   };
    63   bool is_nop()                        { return long_at(0) == nop_instruction_code; }
    64   bool is_sync()                       { return long_at(0) == sync_instruction_code; }
    65   bool is_dtrace_trap();
    66   inline bool is_call();
    67   inline bool is_illegal();
    68   inline bool is_return();
    69   bool is_jump();
    70   inline bool is_cond_jump();
    71   bool is_safepoint_poll();
    73   //mips has no instruction to generate a illegal instrucion exception
    74   //we define ours: break 11
    75   static int illegal_instruction();
    77   bool is_int_branch();
    78   bool is_float_branch();
    81  protected:
    82   address addr_at(int offset) const    { return address(this) + offset; }
    83   address instruction_address() const       { return addr_at(0); }
    84   address next_instruction_address() const  { return addr_at(BytesPerInstWord); }
    85   address prev_instruction_address() const  { return addr_at(-BytesPerInstWord); }
    87   s_char sbyte_at(int offset) const    { return *(s_char*) addr_at(offset); }
    88   u_char ubyte_at(int offset) const    { return *(u_char*) addr_at(offset); }
    90   jint int_at(int offset) const         { return *(jint*) addr_at(offset); }
    92   intptr_t ptr_at(int offset) const    { return *(intptr_t*) addr_at(offset); }
    94   oop  oop_at (int offset) const       { return *(oop*) addr_at(offset); }
    95   int  long_at(int offset) const       { return *(jint*)addr_at(offset); }
    98   void set_char_at(int offset, char c)        { *addr_at(offset) = (u_char)c; wrote(offset); }
    99   void set_int_at(int offset, jint  i)        { *(jint*)addr_at(offset) = i;  wrote(offset); }
   100   void set_ptr_at (int offset, intptr_t  ptr) { *(intptr_t*) addr_at(offset) = ptr;  wrote(offset); }
   101   void set_oop_at (int offset, oop  o)        { *(oop*) addr_at(offset) = o;  wrote(offset); }
   102   void set_long_at(int offset, long  i);
   104   int  insn_word() const { return long_at(0); }
   105   static bool is_op (int insn, Assembler::ops op) { return Assembler::opcode(insn) == (int)op; }
   106   bool is_op (Assembler::ops op)     const { return is_op(insn_word(), op); }
   107   bool is_rs (int insn, Register rs) const { return Assembler::rs(insn) == (int)rs->encoding(); }
   108   bool is_rs (Register rs)           const { return is_rs(insn_word(), rs); }
   109   bool is_rt (int insn, Register rt) const { return Assembler::rt(insn) == (int)rt->encoding(); }
   110   bool is_rt (Register rt)        const { return is_rt(insn_word(), rt); }
   112   static bool is_special_op (int insn, Assembler::special_ops op) {
   113     return is_op(insn, Assembler::special_op) && Assembler::special(insn)==(int)op;
   114   }
   115   bool is_special_op (Assembler::special_ops op) const { return is_special_op(insn_word(), op); }
   117   // This doesn't really do anything on Intel, but it is the place where
   118   // cache invalidation belongs, generically:
   119   void wrote(int offset);
   121  public:
   123   // unit test stuff
   124   static void test() {}                 // override for testing
   126   inline friend NativeInstruction* nativeInstruction_at(address address);
   127 };
   129 inline NativeInstruction* nativeInstruction_at(address address) {
   130   NativeInstruction* inst = (NativeInstruction*)address;
   131 #ifdef ASSERT
   132   //inst->verify();
   133 #endif
   134   return inst;
   135 }
   137 inline NativeCall* nativeCall_at(address address);
   138 // The NativeCall is an abstraction for accessing/manipulating native call imm32/imm64
   139 // instructions (used to manipulate inline caches, primitive & dll calls, etc.).
   140 // MIPS has no call instruction with imm32/imm64. Usually, a call was done like this:
   141 // 32 bits:
   142 //       lui     rt, imm16
   143 //       addiu    rt, rt, imm16
   144 //       jalr     rt
   145 //       nop
   146 //
   147 // 64 bits:
   148 //       lui   rd, imm(63...48);
   149 //       ori   rd, rd, imm(47...32);
   150 //       dsll  rd, rd, 16;
   151 //       ori   rd, rd, imm(31...16);
   152 //       dsll  rd, rd, 16;
   153 //       ori   rd, rd, imm(15...0);
   154 //       jalr  rd
   155 //       nop
   156 //
   158 // we just consider the above for instruction as one call instruction
   159 class NativeCall: public NativeInstruction {
   160  public:
   161   enum mips_specific_constants {
   162     instruction_offset          =    0,
   163 #ifndef _LP64
   164     instruction_size            =   4 * BytesPerInstWord,
   165     return_address_offset       =   4 * BytesPerInstWord,
   166 #else
   167     instruction_size            =   6 * BytesPerInstWord,
   168     return_address_offset_short =   4 * BytesPerInstWord,
   169     return_address_offset_long  =   6 * BytesPerInstWord,
   170 #endif
   171     displacement_offset         =   0
   172   };
   174   address instruction_address() const       { return addr_at(instruction_offset); }
   176   address next_instruction_address() const  {
   177     if (is_special_op(int_at(8), Assembler::jalr_op)) {
   178       return addr_at(return_address_offset_short);
   179     } else {
   180       return addr_at(return_address_offset_long);
   181     }
   182   }
   184   address return_address() const            {
   185     return next_instruction_address();
   186   }
   188   address destination() const;
   189   void  set_destination(address dest);
   190   void  set_destination_mt_safe(address dest) { set_destination(dest);}
   192   void  patch_set48_gs(address dest);
   193   void  patch_set48(address dest);
   195   void  patch_on_jalr_gs(address dest);
   196   void  patch_on_jalr(address dest);
   198   void  patch_on_jal_gs(address dest);
   199   void  patch_on_jal(address dest);
   201   void  patch_on_jal_only(address dest);
   203   void  patch_set32_gs(address dest);
   204   void  patch_set32(address dest);
   206   void  verify_alignment() {  }
   207   void  verify();
   208   void  print();
   210   // Creation
   211   inline friend NativeCall* nativeCall_at(address address);
   212   inline friend NativeCall* nativeCall_before(address return_address);
   214   static bool is_call_at(address instr) {
   215     return nativeInstruction_at(instr)->is_call();
   216   }
   218   static bool is_call_before(address return_address) {
   219     return is_call_at(return_address - return_address_offset_short) | is_call_at(return_address - return_address_offset_long);
   220   }
   222   static bool is_call_to(address instr, address target) {
   223     return nativeInstruction_at(instr)->is_call() &&
   224 nativeCall_at(instr)->destination() == target;
   225   }
   227   // MT-safe patching of a call instruction.
   228   static void insert(address code_pos, address entry);
   230   static void replace_mt_safe(address instr_addr, address code_buffer);
   231 };
   233 inline NativeCall* nativeCall_at(address address) {
   234   NativeCall* call = (NativeCall*)(address - NativeCall::instruction_offset);
   235 #ifdef ASSERT
   236   call->verify();
   237 #endif
   238   return call;
   239 }
   241 inline NativeCall* nativeCall_before(address return_address) {
   242   NativeCall* call = NULL;
   243   if (NativeCall::is_call_at(return_address - NativeCall::return_address_offset_long)) {
   244     call = (NativeCall*)(return_address - NativeCall::return_address_offset_long);
   245   } else {
   246     call = (NativeCall*)(return_address - NativeCall::return_address_offset_short);
   247   }
   248 #ifdef ASSERT
   249   call->verify();
   250 #endif
   251   return call;
   252 }
   254 class NativeMovConstReg: public NativeInstruction {
   255  public:
   256   enum mips_specific_constants {
   257     instruction_offset    =    0,
   258 #ifndef _LP64
   259     instruction_size            =    2 * BytesPerInstWord,
   260     next_instruction_offset   =    2 * BytesPerInstWord,
   261 #else
   262     instruction_size            =    4 * BytesPerInstWord,
   263     next_instruction_offset   =    4 * BytesPerInstWord,
   264 #endif
   265   };
   267   int     insn_word() const                 { return long_at(instruction_offset); }
   268   address instruction_address() const       { return addr_at(0); }
   269   address next_instruction_address() const  { return addr_at(next_instruction_offset); }
   270   intptr_t data() const;
   271   void    set_data(intptr_t x);
   273   void    patch_set48(intptr_t x);
   275   void  verify();
   276   void  print();
   278   // unit test stuff
   279   static void test() {}
   281   // Creation
   282   inline friend NativeMovConstReg* nativeMovConstReg_at(address address);
   283   inline friend NativeMovConstReg* nativeMovConstReg_before(address address);
   284 };
   286 inline NativeMovConstReg* nativeMovConstReg_at(address address) {
   287   NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_offset);
   288 #ifdef ASSERT
   289   test->verify();
   290 #endif
   291   return test;
   292 }
   294 inline NativeMovConstReg* nativeMovConstReg_before(address address) {
   295   NativeMovConstReg* test = (NativeMovConstReg*)(address - NativeMovConstReg::instruction_size - NativeMovConstReg::instruction_offset);
   296 #ifdef ASSERT
   297   test->verify();
   298 #endif
   299   return test;
   300 }
   302 class NativeMovConstRegPatching: public NativeMovConstReg {
   303  private:
   304     friend NativeMovConstRegPatching* nativeMovConstRegPatching_at(address address) {
   305     NativeMovConstRegPatching* test = (NativeMovConstRegPatching*)(address - instruction_offset);
   306     #ifdef ASSERT
   307       test->verify();
   308     #endif
   309     return test;
   310   }
   311 };
   313 // An interface for accessing/manipulating native moves of the form:
   314 //       lui   AT, split_high(offset)
   315 //       addiu AT, split_low(offset)
   316 //       add   reg, reg, AT
   317 //       lb/lbu/sb/lh/lhu/sh/lw/sw/lwc1/swc1 dest, reg, 0
   318 //       [lw/sw/lwc1/swc1                    dest, reg, 4]
   319 //     or
   320 //       lb/lbu/sb/lh/lhu/sh/lw/sw/lwc1/swc1 dest, reg, offset
   321 //       [lw/sw/lwc1/swc1                    dest, reg, offset+4]
   322 //
   323 // Warning: These routines must be able to handle any instruction sequences
   324 // that are generated as a result of the load/store byte,word,long
   325 // macros.
   327 class NativeMovRegMem: public NativeInstruction {
   328  public:
   329   enum mips_specific_constants {
   330     instruction_offset  = 0,
   331     hiword_offset   = 4,
   332     ldst_offset     = 12,
   333     immediate_size  = 4,
   334     ldst_size       = 16
   335   };
   337   //offset is less than 16 bits.
   338   bool is_immediate() const { return !is_op(long_at(instruction_offset), Assembler::lui_op); }
   339   bool is_64ldst() const {
   340     if (is_immediate()) {
   341       return (Assembler::opcode(long_at(hiword_offset)) == Assembler::opcode(long_at(instruction_offset))) &&
   342        (Assembler::imm_off(long_at(hiword_offset)) == Assembler::imm_off(long_at(instruction_offset)) + wordSize);
   343     } else {
   344       return (Assembler::opcode(long_at(ldst_offset+hiword_offset)) == Assembler::opcode(long_at(ldst_offset))) &&
   345        (Assembler::imm_off(long_at(ldst_offset+hiword_offset)) == Assembler::imm_off(long_at(ldst_offset)) + wordSize);
   346     }
   347   }
   349   address instruction_address() const       { return addr_at(instruction_offset); }
   350   address next_instruction_address() const  {
   351     return addr_at( (is_immediate()? immediate_size : ldst_size) + (is_64ldst()? 4 : 0));
   352   }
   354   int   offset() const;
   356   void  set_offset(int x);
   358   void  add_offset_in_bytes(int add_offset)     { set_offset ( ( offset() + add_offset ) ); }
   360   void verify();
   361   void print ();
   363   // unit test stuff
   364   static void test() {}
   366  private:
   367   inline friend NativeMovRegMem* nativeMovRegMem_at (address address);
   368 };
   370 inline NativeMovRegMem* nativeMovRegMem_at (address address) {
   371   NativeMovRegMem* test = (NativeMovRegMem*)(address - NativeMovRegMem::instruction_offset);
   372 #ifdef ASSERT
   373   test->verify();
   374 #endif
   375   return test;
   376 }
   378 class NativeMovRegMemPatching: public NativeMovRegMem {
   379  private:
   380   friend NativeMovRegMemPatching* nativeMovRegMemPatching_at (address address) {
   381     NativeMovRegMemPatching* test = (NativeMovRegMemPatching*)(address - instruction_offset);
   382     #ifdef ASSERT
   383       test->verify();
   384     #endif
   385     return test;
   386   }
   387 };
   390 // Handles all kinds of jump on Loongson. Long/far, conditional/unconditional
   391 // 32 bits:
   392 //    far jump:
   393 //        lui   reg, split_high(addr)
   394 //        addiu reg, split_low(addr)
   395 //        jr    reg
   396 //        nop
   397 //    or
   398 //        beq   ZERO, ZERO, offset
   399 //        nop
   400 //
   402 //64 bits:
   403 //    far jump:
   404 //          lui   rd, imm(63...48);
   405 //          ori   rd, rd, imm(47...32);
   406 //          dsll  rd, rd, 16;
   407 //          ori   rd, rd, imm(31...16);
   408 //          dsll  rd, rd, 16;
   409 //          ori   rd, rd, imm(15...0);
   410 //          jalr  rd
   411 //          nop
   412 //
   413 class NativeGeneralJump: public NativeInstruction {
   414  public:
   415   enum mips_specific_constants {
   416     instruction_offset   =    0,
   417     beq_opcode           =    0x10000000,//000100|00000|00000|offset
   418     b_mask         =    0xffff0000,
   419     short_size      =    8,
   420 #ifndef _LP64
   421     instruction_size   =    4 * BytesPerInstWord
   422 #else
   423     instruction_size   =    6 * BytesPerInstWord
   424 #endif
   425   };
   427   bool is_short() const { return (long_at(instruction_offset) & b_mask) == beq_opcode; }
   428 #ifdef _LP64
   429   bool is_b_far();
   430 #endif
   431   address instruction_address() const { return addr_at(instruction_offset); }
   432   address jump_destination();
   434   void  patch_set48_gs(address dest);
   435   void  patch_set48(address dest);
   437   void  patch_on_jr_gs(address dest);
   438   void  patch_on_jr(address dest);
   440   void  patch_on_j_gs(address dest);
   441   void  patch_on_j(address dest);
   443   void  patch_on_j_only(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 }
   466 class NativeIllegalInstruction: public NativeInstruction {
   467 public:
   468   enum Intel_specific_constants {
   469     instruction_size          =    4,
   470     instruction_offset        =    0,
   471     next_instruction_offset   =    4
   472   };
   474   // Insert illegal opcode as specific address
   475   static void insert(address code_pos);
   476 };
   478 // return instruction that does not pop values of the stack
   479 // jr RA
   480 // delay slot
   481 class NativeReturn: public NativeInstruction {
   482  public:
   483   enum mips_specific_constants {
   484     instruction_size          =    8,
   485     instruction_offset        =    0,
   486     next_instruction_offset   =    8
   487   };
   488 };
   493 class NativeCondJump;
   494 inline NativeCondJump* nativeCondJump_at(address address);
   495 class NativeCondJump: public NativeInstruction {
   496  public:
   497   enum mips_specific_constants {
   498     instruction_size         = 16,
   499     instruction_offset        = 12,
   500     next_instruction_offset   = 20
   501   };
   504   int insn_word() const  { return long_at(instruction_offset); }
   505   address instruction_address() const { return addr_at(0); }
   506   address next_instruction_address() const { return addr_at(next_instruction_offset); }
   508   // Creation
   509   inline friend NativeCondJump* nativeCondJump_at(address address);
   511   address jump_destination()  const {
   512     return ::nativeCondJump_at(addr_at(12))->jump_destination();
   513   }
   515   void set_jump_destination(address dest) {
   516     ::nativeCondJump_at(addr_at(12))->set_jump_destination(dest);
   517   }
   519 };
   521 inline NativeCondJump* nativeCondJump_at(address address) {
   522   NativeCondJump* jump = (NativeCondJump*)(address);
   523   return jump;
   524 }
   528 inline bool NativeInstruction::is_illegal() { return insn_word() == illegal_instruction(); }
   530 inline bool NativeInstruction::is_call()    {
   531 #ifndef _LP64
   532   return is_op(long_at(0), Assembler::lui_op) &&
   533          is_op(long_at(4), Assembler::addiu_op) &&
   534    is_special_op(long_at(8), Assembler::jalr_op);
   535 #else
   536   // jal target
   537   // nop
   538   if ( nativeInstruction_at(addr_at(0))->is_op(Assembler::jal_op) &&
   539          nativeInstruction_at(addr_at(4))->is_nop() ) {
   540       return true;
   541   }
   543   // nop
   544   // nop
   545   // nop
   546   // nop
   547   // jal target
   548   // nop
   549   if ( is_nop() &&
   550          nativeInstruction_at(addr_at(4))->is_nop()  &&
   551          nativeInstruction_at(addr_at(8))->is_nop()  &&
   552          nativeInstruction_at(addr_at(12))->is_nop() &&
   553          nativeInstruction_at(addr_at(16))->is_op(Assembler::jal_op) &&
   554          nativeInstruction_at(addr_at(20))->is_nop() ) {
   555     return true;
   556   }
   558   // li64
   559   if ( is_op(Assembler::lui_op) &&
   560        is_op(int_at(4), Assembler::ori_op) &&
   561        is_special_op(int_at(8), Assembler::dsll_op) &&
   562        is_op(int_at(12), Assembler::ori_op) &&
   563        is_special_op(int_at(16), Assembler::dsll_op) &&
   564        is_op(int_at(20), Assembler::ori_op) &&
   565        is_special_op(int_at(24), Assembler::jalr_op) ) {
   566     return true;
   567   }
   569   //lui dst, imm16
   570   //ori dst, dst, imm16
   571   //dsll dst, dst, 16
   572   //ori dst, dst, imm16
   573   if (  is_op(Assembler::lui_op) &&
   574         is_op  (int_at(4), Assembler::ori_op) &&
   575         is_special_op(int_at(8), Assembler::dsll_op) &&
   576         is_op  (int_at(12), Assembler::ori_op) &&
   577         is_special_op(int_at(16), Assembler::jalr_op) ) {
   578     return true;
   579   }
   581   //ori dst, R0, imm16
   582   //dsll dst, dst, 16
   583   //ori dst, dst, imm16
   584   //nop
   585   if (  is_op(Assembler::ori_op) &&
   586         is_special_op(int_at(4), Assembler::dsll_op) &&
   587         is_op  (int_at(8), Assembler::ori_op) &&
   588         nativeInstruction_at(addr_at(12))->is_nop() &&
   589         is_special_op(int_at(16), Assembler::jalr_op) ) {
   590     return true;
   591   }
   593   //ori dst, R0, imm16
   594   //dsll dst, dst, 16
   595   //nop
   596   //nop
   597   if (  is_op(Assembler::ori_op) &&
   598         is_special_op(int_at(4), Assembler::dsll_op) &&
   599         nativeInstruction_at(addr_at(8))->is_nop()   &&
   600         nativeInstruction_at(addr_at(12))->is_nop() &&
   601         is_special_op(int_at(16), Assembler::jalr_op) ) {
   602     return true;
   603   }
   605   //daddiu dst, R0, imm16
   606   //nop
   607   //nop
   608   //nop
   609   if (  is_op(Assembler::daddiu_op) &&
   610         nativeInstruction_at(addr_at(4))->is_nop() &&
   611         nativeInstruction_at(addr_at(8))->is_nop() &&
   612         nativeInstruction_at(addr_at(12))->is_nop() &&
   613         is_special_op(int_at(16), Assembler::jalr_op) ) {
   614     return true;
   615   }
   617   //lui dst, imm16
   618   //ori dst, dst, imm16
   619   //nop
   620   //nop
   621   if (  is_op(Assembler::lui_op) &&
   622         is_op  (int_at(4), Assembler::ori_op) &&
   623         nativeInstruction_at(addr_at(8))->is_nop() &&
   624         nativeInstruction_at(addr_at(12))->is_nop() &&
   625         is_special_op(int_at(16), Assembler::jalr_op) ) {
   626     return true;
   627   }
   629   //lui dst, imm16
   630   //nop
   631   //nop
   632   //nop
   633   if (  is_op(Assembler::lui_op) &&
   634         nativeInstruction_at(addr_at(4))->is_nop() &&
   635         nativeInstruction_at(addr_at(8))->is_nop() &&
   636         nativeInstruction_at(addr_at(12))->is_nop() &&
   637         is_special_op(int_at(16), Assembler::jalr_op) ) {
   638     return true;
   639   }
   642   //daddiu dst, R0, imm16
   643   //nop
   644   if (  is_op(Assembler::daddiu_op) &&
   645         nativeInstruction_at(addr_at(4))->is_nop() &&
   646         is_special_op(int_at(8), Assembler::jalr_op) ) {
   647     return true;
   648   }
   650   //lui dst, imm16
   651   //ori dst, dst, imm16
   652   if (  is_op(Assembler::lui_op) &&
   653         is_op  (int_at(4), Assembler::ori_op) &&
   654         is_special_op(int_at(8), Assembler::jalr_op) ) {
   655     return true;
   656   }
   658   //lui dst, imm16
   659   //nop
   660   if (  is_op(Assembler::lui_op) &&
   661         nativeInstruction_at(addr_at(4))->is_nop() &&
   662         is_special_op(int_at(8), Assembler::jalr_op) ) {
   663     return true;
   664   }
   666   return false;
   668 #endif
   669 }
   671 inline bool NativeInstruction::is_return()  { return is_special_op(Assembler::jr_op) && is_rs(RA);}
   673 inline bool NativeInstruction::is_cond_jump()    { return is_int_branch() || is_float_branch(); }
   675 #endif // CPU_MIPS_VM_NATIVEINST_MIPS_HPP

mercurial