src/cpu/mips/vm/templateTable_mips_64.cpp

Tue, 10 Apr 2018 10:21:49 +0800

author
fujie
date
Tue, 10 Apr 2018 10:21:49 +0800
changeset 8858
e3f4d3592615
parent 8027
23d8d77777e0
child 8863
5376ce0dc552
permissions
-rw-r--r--

[Upgrade] jdk8u77-b03 --> jdk8u91-b15 (ztos support for MIPS)

     1 /*
     2  * Copyright (c) 2003, 2013, 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 #include "precompiled.hpp"
    27 #include "asm/macroAssembler.hpp"
    28 #include "interpreter/interpreter.hpp"
    29 #include "interpreter/interpreterRuntime.hpp"
    30 #include "interpreter/templateTable.hpp"
    31 #include "memory/universe.inline.hpp"
    32 #include "oops/methodData.hpp"
    33 #include "oops/objArrayKlass.hpp"
    34 #include "oops/oop.inline.hpp"
    35 #include "prims/methodHandles.hpp"
    36 #include "runtime/sharedRuntime.hpp"
    37 #include "runtime/stubRoutines.hpp"
    38 #include "runtime/synchronizer.hpp"
    41 #ifndef CC_INTERP
    43 #define __ _masm->
    45 // Platform-dependent initialization
    47 void TemplateTable::pd_initialize() {
    48   // No mips specific initialization
    49 }
    51 // Address computation: local variables
    53 static inline Address iaddress(int n) {
    54   return Address(LVP, Interpreter::local_offset_in_bytes(n));
    55 }
    57 static inline Address laddress(int n) {
    58   return iaddress(n + 1);
    59 }
    61 static inline Address faddress(int n) {
    62   return iaddress(n);
    63 }
    65 static inline Address daddress(int n) {
    66   return laddress(n);
    67 }
    69 static inline Address aaddress(int n) {
    70   return iaddress(n);
    71 }
    72 static inline Address haddress(int n)            { return iaddress(n + 0); }
    75 static inline Address at_sp()             {  return Address(SP,   0); }
    76 static inline Address at_sp_p1()          { return Address(SP,  1 * wordSize); }
    77 static inline Address at_sp_p2()          { return Address(SP,  2 * wordSize); }
    79 // At top of Java expression stack which may be different than esp().  It
    80 // isn't for category 1 objects.
    81 static inline Address at_tos   () {
    82   Address tos = Address(SP,  Interpreter::expr_offset_in_bytes(0));
    83   return tos;
    84 }
    86 static inline Address at_tos_p1() {
    87   return Address(SP,  Interpreter::expr_offset_in_bytes(1));
    88 }
    90 static inline Address at_tos_p2() {
    91   return Address(SP,  Interpreter::expr_offset_in_bytes(2));
    92 }
    94 static inline Address at_tos_p3() {
    95   return Address(SP,  Interpreter::expr_offset_in_bytes(3));
    96 }
    98 // we use S0 as bcp, be sure you have bcp in S0 before you call any of the Template generator
    99 Address TemplateTable::at_bcp(int offset) {
   100   assert(_desc->uses_bcp(), "inconsistent uses_bcp information");
   101   return Address(BCP, offset);
   102 }
   104 // Miscelaneous helper routines
   105 // Store an oop (or NULL) at the address described by obj.
   106 // If val == noreg this means store a NULL
   108 // rdx --> T3
   109 // rbx --> T1
   110 // r8  --> T9
   111 // r15 --> TREG
   112 static void do_oop_store(InterpreterMacroAssembler* _masm,
   113                          Address obj,
   114                          Register val,
   115                          BarrierSet::Name barrier,
   116                          bool precise) {
   117   assert(val == noreg || val == V0, "parameter is just for looks");
   118   switch (barrier) {
   119 #if INCLUDE_ALL_GCS
   120     case BarrierSet::G1SATBCT:
   121     case BarrierSet::G1SATBCTLogging:
   122       {
   123         // flatten object address if needed
   124         if (obj.index() == noreg && obj.disp() == 0) {
   125           if (obj.base() != T3) {
   126             __ move(T3, obj.base());
   127           }
   128         } else {
   129           __ lea(T3, obj);
   130         }
   131         __ g1_write_barrier_pre(T3 /* obj */,
   132                                 T1 /* pre_val */,
   133                                 TREG /* thread */,
   134                                 T9  /* tmp */,
   135                                 val != noreg /* tosca_live */,
   136                                 false /* expand_call */);
   137         if (val == noreg) {
   138           __ store_heap_oop_null(Address(T3, 0));
   139         } else {
   140           // G1 barrier needs uncompressed oop for region cross check.
   141           Register new_val = val;
   142           if (UseCompressedOops) {
   143             new_val = T1;
   144             __ move(new_val, val);
   145           }
   146           __ store_heap_oop(Address(T3, 0), val);
   147           __ g1_write_barrier_post(T3 /* store_adr */,
   148                                    new_val /* new_val */,
   149                                    TREG /* thread */,
   150                                    T9 /* tmp */,
   151                                    T1 /* tmp2 */);
   152         }
   153       }
   154       break;
   155 #endif // INCLUDE_ALL_GCS
   156     case BarrierSet::CardTableModRef:
   157     case BarrierSet::CardTableExtension:
   158       {
   159         if (val == noreg) {
   160           __ store_heap_oop_null(obj);
   161         } else {
   162           __ store_heap_oop(obj, val);
   163           // flatten object address if needed
   164           if (!precise || (obj.index() == noreg && obj.disp() == 0)) {
   165             __ store_check(obj.base());
   166           } else {
   167             __ lea(T9, obj);
   168             __ store_check(T9);
   169           }
   170         }
   171       }
   172       break;
   173     case BarrierSet::ModRef:
   174     case BarrierSet::Other:
   175       if (val == noreg) {
   176         __ store_heap_oop_null(obj);
   177       } else {
   178         __ store_heap_oop(obj, val);
   179       }
   180       break;
   181     default      :
   182       ShouldNotReachHere();
   184   }
   185 }
   187 // bytecode folding
   188 void TemplateTable::patch_bytecode(Bytecodes::Code bc, Register bc_reg,
   189                                    Register tmp_reg, bool load_bc_into_bc_reg/*=true*/,
   190                                    int byte_no) {
   191   if (!RewriteBytecodes)  return;
   192   Label L_patch_done;
   194   switch (bc) {
   195   case Bytecodes::_fast_aputfield:
   196   case Bytecodes::_fast_bputfield:
   197   case Bytecodes::_fast_zputfield:
   198   case Bytecodes::_fast_cputfield:
   199   case Bytecodes::_fast_dputfield:
   200   case Bytecodes::_fast_fputfield:
   201   case Bytecodes::_fast_iputfield:
   202   case Bytecodes::_fast_lputfield:
   203   case Bytecodes::_fast_sputfield:
   204     {
   205       // We skip bytecode quickening for putfield instructions when
   206       // the put_code written to the constant pool cache is zero.
   207       // This is required so that every execution of this instruction
   208       // calls out to InterpreterRuntime::resolve_get_put to do
   209       // additional, required work.
   210       assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
   211       assert(load_bc_into_bc_reg, "we use bc_reg as temp");
   212       __ get_cache_and_index_and_bytecode_at_bcp(tmp_reg, bc_reg, tmp_reg, byte_no, 1);
   213       __ daddi(bc_reg, R0, bc);
   214       __ beq(tmp_reg, R0, L_patch_done);
   215       __ delayed()->nop();
   216     }
   217     break;
   218   default:
   219     assert(byte_no == -1, "sanity");
   220     // the pair bytecodes have already done the load.
   221     if (load_bc_into_bc_reg) {
   222       __ move(bc_reg, bc);
   223     }
   224   }
   226   if (JvmtiExport::can_post_breakpoint()) {
   227     Label L_fast_patch;
   228     // if a breakpoint is present we can't rewrite the stream directly
   229     __ lbu(tmp_reg, at_bcp(0));
   230     __ move(AT, Bytecodes::_breakpoint);
   231     __ bne(tmp_reg, AT, L_fast_patch);
   232     __ delayed()->nop();
   234     __ get_method(tmp_reg);
   235     // Let breakpoint table handling rewrite to quicker bytecode
   236     __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
   237     InterpreterRuntime::set_original_bytecode_at), tmp_reg, BCP, bc_reg);
   239     __ b(L_patch_done);
   240     __ delayed()->nop();
   241     __ bind(L_fast_patch);
   242   }
   244 #ifdef ASSERT
   245   Label L_okay;
   246   __ lbu(tmp_reg, at_bcp(0));
   247   __ move(AT, (int)Bytecodes::java_code(bc));
   248   __ beq(tmp_reg, AT, L_okay);
   249   __ delayed()->nop();
   250   __ beq(tmp_reg, bc_reg, L_patch_done);
   251   __ delayed()->nop();
   252   __ stop("patching the wrong bytecode");
   253   __ bind(L_okay);
   254 #endif
   256   // patch bytecode
   257   __ sb(bc_reg, at_bcp(0));
   258   __ bind(L_patch_done);
   259 }
   262 // Individual instructions
   264 void TemplateTable::nop() {
   265   transition(vtos, vtos);
   266   // nothing to do
   267 }
   269 void TemplateTable::shouldnotreachhere() {
   270   transition(vtos, vtos);
   271   __ stop("shouldnotreachhere bytecode");
   272 }
   274 void TemplateTable::aconst_null() {
   275   transition(vtos, atos);
   276   __ move(FSR, R0);
   277 }
   279 void TemplateTable::iconst(int value) {
   280   transition(vtos, itos);
   281   if (value == 0) {
   282     __ move(FSR, R0);
   283   } else {
   284     __ move(FSR, value);
   285   }
   286 }
   288 void TemplateTable::lconst(int value) {
   289   transition(vtos, ltos);
   290   if (value == 0) {
   291     __ move(FSR, R0);
   292   } else {
   293     __ move(FSR, value);
   294   }
   295 }
   297 void TemplateTable::fconst(int value) {
   298   transition(vtos, ftos);
   299   switch( value ) {
   300     case 0:  __ mtc1(R0, FSF);    return;
   301     case 1:  __ addiu(AT, R0, 1); break;
   302     case 2:  __ addiu(AT, R0, 2); break;
   303     default: ShouldNotReachHere();
   304   }
   305   __ mtc1(AT, FSF);
   306   __ cvt_s_w(FSF, FSF);
   307 }
   309 void TemplateTable::dconst(int value) {
   310   transition(vtos, dtos);
   311   switch( value ) {
   312     case 0:  __ dmtc1(R0, FSF);
   313              return;
   314     case 1:  __ daddiu(AT, R0, 1);
   315              __ dmtc1(AT, FSF);
   316              __ cvt_d_w(FSF, FSF);
   317              break;
   318     default: ShouldNotReachHere();
   319   }
   320 }
   322 void TemplateTable::bipush() {
   323   transition(vtos, itos);
   324   __ lb(FSR, at_bcp(1));
   325 }
   327 void TemplateTable::sipush() {
   328   transition(vtos, itos);
   329   __ lb(FSR, BCP, 1);
   330   __ lbu(AT, BCP, 2);
   331   __ dsll(FSR, FSR, 8);
   332   __ orr(FSR, FSR, AT);
   333 }
   335 // T1 : tags
   336 // T2 : index
   337 // T3 : cpool
   338 // T8 : tag
   339 void TemplateTable::ldc(bool wide) {
   340   transition(vtos, vtos);
   341   Label call_ldc, notFloat, notClass, Done;
   342   // get index in cpool
   343   if (wide) {
   344     __ get_unsigned_2_byte_index_at_bcp(T2, 1);
   345   } else {
   346     __ lbu(T2, at_bcp(1));
   347   }
   349   __ get_cpool_and_tags(T3, T1);
   351   const int base_offset = ConstantPool::header_size() * wordSize;
   352   const int tags_offset = Array<u1>::base_offset_in_bytes();
   354   // get type
   355   if (UseLoongsonISA && Assembler::is_simm(sizeof(tags_offset), 8)) {
   356     __ gslbx(T1, T1, T2, tags_offset);
   357   } else {
   358     __ dadd(AT, T1, T2);
   359     __ lb(T1, AT, tags_offset);
   360   }
   361   //now T1 is the tag
   363   // unresolved class - get the resolved class
   364   __ daddiu(AT, T1, - JVM_CONSTANT_UnresolvedClass);
   365   __ beq(AT, R0, call_ldc);
   366   __ delayed()->nop();
   368   // unresolved class in error (resolution failed) - call into runtime
   369   // so that the same error from first resolution attempt is thrown.
   370   __ daddiu(AT, T1, -JVM_CONSTANT_UnresolvedClassInError);
   371   __ beq(AT, R0, call_ldc);
   372   __ delayed()->nop();
   374   // resolved class - need to call vm to get java mirror of the class
   375   __ daddiu(AT, T1, - JVM_CONSTANT_Class);
   376   __ bne(AT, R0, notClass);
   377   __ delayed()->dsll(T2, T2, Address::times_8);
   379   __ bind(call_ldc);
   380   __ move(A1, wide);
   381   call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::ldc), A1);
   382   //__ push(atos);
   383   __ sd(FSR, SP, - Interpreter::stackElementSize);
   384   __ b(Done);
   385   __ delayed()->daddiu(SP, SP, - Interpreter::stackElementSize);
   386   __ nop(); // added for performance issue
   388   __ bind(notClass);
   389   __ daddiu(AT, T1, -JVM_CONSTANT_Float);
   390   __ bne(AT, R0, notFloat);
   391   __ delayed()->nop();
   392   // ftos
   393   if (UseLoongsonISA && Assembler::is_simm(sizeof(base_offset), 8)) {
   394     __ gslwxc1(FSF, T3, T2, base_offset);
   395   } else {
   396     __ dadd(AT, T3, T2);
   397     __ lwc1(FSF, AT, base_offset);
   398   }
   399   //__ push_f();
   400   __ swc1(FSF, SP, - Interpreter::stackElementSize);
   401   __ b(Done);
   402   __ delayed()->daddiu(SP, SP, - Interpreter::stackElementSize);
   404   __ bind(notFloat);
   405 #ifdef ASSERT
   406   {
   407     Label L;
   408     __ daddiu(AT, T1, -JVM_CONSTANT_Integer);
   409     __ beq(AT, R0, L);
   410     __ delayed()->nop();
   411     __ stop("unexpected tag type in ldc");
   412     __ bind(L);
   413   }
   414 #endif
   415   // itos JVM_CONSTANT_Integer only
   416   if (UseLoongsonISA && Assembler::is_simm(sizeof(base_offset), 8)) {
   417     __ gslwx(FSR, T3, T2, base_offset);
   418   } else {
   419     __ dadd(T0, T3, T2);
   420     __ lw(FSR, T0, base_offset);
   421   }
   422   __ push(itos);
   423   __ bind(Done);
   424 }
   426 // Fast path for caching oop constants.
   427 void TemplateTable::fast_aldc(bool wide) {
   428   transition(vtos, atos);
   430   Register result = FSR;
   431   Register tmp = SSR;
   432   int index_size = wide ? sizeof(u2) : sizeof(u1);
   434   Label resolved;
   436   // We are resolved if the resolved reference cache entry contains a
   437   // non-null object (String, MethodType, etc.)
   438   assert_different_registers(result, tmp);
   439   __ get_cache_index_at_bcp(tmp, 1, index_size);
   440   __ load_resolved_reference_at_index(result, tmp);
   441   __ bne(result, R0, resolved);
   442   __ delayed()->nop();
   444   address entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_ldc);
   445   // first time invocation - must resolve first
   446   int i = (int)bytecode();
   447   __ move(tmp, i);
   448   __ call_VM(result, entry, tmp);
   450   __ bind(resolved);
   452   if (VerifyOops) {
   453     __ verify_oop(result);
   454   }
   455 }
   458 // used register: T2, T3, T1
   459 // T2 : index
   460 // T3 : cpool
   461 // T1 : tag
   462 void TemplateTable::ldc2_w() {
   463   transition(vtos, vtos);
   464   Label Long, Done;
   466   // get index in cpool
   467   __ get_unsigned_2_byte_index_at_bcp(T2, 1);
   469   __ get_cpool_and_tags(T3, T1);
   471   const int base_offset = ConstantPool::header_size() * wordSize;
   472   const int tags_offset = Array<u1>::base_offset_in_bytes();
   474   // get type in T1
   475   if (UseLoongsonISA && Assembler::is_simm(tags_offset, 8)) {
   476     __ gslbx(T1, T1, T2, tags_offset);
   477   } else {
   478     __ dadd(AT, T1, T2);
   479     __ lb(T1, AT, tags_offset);
   480   }
   482   __ daddiu(AT, T1, - JVM_CONSTANT_Double);
   483   __ bne(AT, R0, Long);
   484   __ delayed()->dsll(T2, T2, Address::times_8);
   486   // dtos
   487   if (UseLoongsonISA && Assembler::is_simm(base_offset, 8)) {
   488     __ gsldxc1(FSF, T3, T2, base_offset);
   489   } else {
   490     __ daddu(AT, T3, T2);
   491     __ ldc1(FSF, AT, base_offset);
   492   }
   493   __ sdc1(FSF, SP, - 2 * wordSize);
   494   __ b(Done);
   495   __ delayed()->daddi(SP, SP, - 2 * wordSize);
   497   // ltos
   498   __ bind(Long);
   499   if (UseLoongsonISA && Assembler::is_simm(base_offset, 8)) {
   500     __ gsldx(FSR, T3, T2, base_offset);
   501   } else {
   502     __ dadd(AT, T3, T2);
   503     __ ld(FSR, AT, base_offset);
   504   }
   505   __ push(ltos);
   507   __ bind(Done);
   508 }
   510 // we compute the actual local variable address here
   511 // the x86 dont do so for it has scaled index memory access model, we dont have, so do here
   512 void TemplateTable::locals_index(Register reg, int offset) {
   513   __ lbu(reg, at_bcp(offset));
   514   __ dsll(reg, reg, Address::times_8);
   515   __ dsub(reg, LVP, reg);
   516 }
   518 // this method will do bytecode folding of the two form:
   519 // iload iload      iload caload
   520 // used register : T2, T3
   521 // T2 : bytecode
   522 // T3 : folded code
   523 void TemplateTable::iload() {
   524   transition(vtos, itos);
   525   if (RewriteFrequentPairs) {
   526     Label rewrite, done;
   527     // get the next bytecode in T2
   528     __ lbu(T2, at_bcp(Bytecodes::length_for(Bytecodes::_iload)));
   529     // if _iload, wait to rewrite to iload2.  We only want to rewrite the
   530     // last two iloads in a pair.  Comparing against fast_iload means that
   531     // the next bytecode is neither an iload or a caload, and therefore
   532     // an iload pair.
   533     __ move(AT, Bytecodes::_iload);
   534     __ beq(AT, T2, done);
   535     __ delayed()->nop();
   537     __ move(T3, Bytecodes::_fast_iload2);
   538     __ move(AT, Bytecodes::_fast_iload);
   539     __ beq(AT, T2, rewrite);
   540     __ delayed()->nop();
   542     // if _caload, rewrite to fast_icaload
   543     __ move(T3, Bytecodes::_fast_icaload);
   544     __ move(AT, Bytecodes::_caload);
   545     __ beq(AT, T2, rewrite);
   546     __ delayed()->nop();
   548     // rewrite so iload doesn't check again.
   549     __ move(T3, Bytecodes::_fast_iload);
   551     // rewrite
   552     // T3 : fast bytecode
   553     __ bind(rewrite);
   554     patch_bytecode(Bytecodes::_iload, T3, T2, false);
   555     __ bind(done);
   556   }
   558   // Get the local value into tos
   559   locals_index(T2);
   560   __ lw(FSR, T2, 0);
   561 }
   563 // used register T2
   564 // T2 : index
   565 void TemplateTable::fast_iload2() {
   566   transition(vtos, itos);
   567   locals_index(T2);
   568   __ lw(FSR, T2, 0);
   569   __ push(itos);
   570   locals_index(T2, 3);
   571   __ lw(FSR, T2, 0);
   572 }
   574 // used register T2
   575 // T2 : index
   576 void TemplateTable::fast_iload() {
   577   transition(vtos, itos);
   578   locals_index(T2);
   579   __ lw(FSR, T2, 0);
   580 }
   582 // used register T2
   583 // T2 : index
   584 void TemplateTable::lload() {
   585   transition(vtos, ltos);
   586   locals_index(T2);
   587   __ ld(FSR, T2, -wordSize);
   588 }
   590 // used register T2
   591 // T2 : index
   592 void TemplateTable::fload() {
   593   transition(vtos, ftos);
   594   locals_index(T2);
   595   __ lwc1(FSF, T2, 0);
   596 }
   598 // used register T2
   599 // T2 : index
   600 void TemplateTable::dload() {
   601   transition(vtos, dtos);
   602   locals_index(T2);
   603   __ ldc1(FSF, T2, -wordSize);
   604 }
   606 // used register T2
   607 // T2 : index
   608 void TemplateTable::aload() {
   609   transition(vtos, atos);
   610   locals_index(T2);
   611   __ ld(FSR, T2, 0);
   612 }
   614 void TemplateTable::locals_index_wide(Register reg) {
   615   __ get_unsigned_2_byte_index_at_bcp(reg, 2);
   616   __ dsll(reg, reg, Address::times_8);
   617   __ dsub(reg, LVP, reg);
   618 }
   620 // used register T2
   621 // T2 : index
   622 void TemplateTable::wide_iload() {
   623   transition(vtos, itos);
   624   locals_index_wide(T2);
   625   __ ld(FSR, T2, 0);
   626 }
   628 // used register T2
   629 // T2 : index
   630 void TemplateTable::wide_lload() {
   631   transition(vtos, ltos);
   632   locals_index_wide(T2);
   633   __ ld(FSR, T2, -wordSize);
   634 }
   636 // used register T2
   637 // T2 : index
   638 void TemplateTable::wide_fload() {
   639   transition(vtos, ftos);
   640   locals_index_wide(T2);
   641   __ lwc1(FSF, T2, 0);
   642 }
   644 // used register T2
   645 // T2 : index
   646 void TemplateTable::wide_dload() {
   647   transition(vtos, dtos);
   648   locals_index_wide(T2);
   649   __ ldc1(FSF, T2, -wordSize);
   650 }
   652 // used register T2
   653 // T2 : index
   654 void TemplateTable::wide_aload() {
   655   transition(vtos, atos);
   656   locals_index_wide(T2);
   657   __ ld(FSR, T2, 0);
   658 }
   660 // we use A2 as the regiser for index, BE CAREFUL!
   661 // we dont use our tge 29 now, for later optimization
   662 void TemplateTable::index_check(Register array, Register index) {
   663   // Pop ptr into array
   664   __ pop_ptr(array);
   665   index_check_without_pop(array, index);
   666 }
   668 void TemplateTable::index_check_without_pop(Register array, Register index) {
   669   // destroys ebx
   670   // check array
   671   __ null_check(array, arrayOopDesc::length_offset_in_bytes());
   673 #ifdef _LP64
   674   // sign extend since tos (index) might contain garbage in upper bits
   675   __ sll(index, index, 0);
   676 #endif // _LP64
   678   // check index
   679   Label ok;
   680   __ lw(AT, array, arrayOopDesc::length_offset_in_bytes());
   681 #ifndef OPT_RANGECHECK
   682   __ sltu(AT, index, AT);
   683   __ bne(AT, R0, ok);
   684   __ delayed()->nop();
   686   //throw_ArrayIndexOutOfBoundsException assume abberrant index in A2
   687   if (A2 != index) __ move(A2, index);
   688   __ jmp(Interpreter::_throw_ArrayIndexOutOfBoundsException_entry);
   689   __ delayed()->nop();
   690   __ bind(ok);
   691 #else
   692   __ lw(AT, array, arrayOopDesc::length_offset_in_bytes());
   693   __ move(A2, index);
   694   __ tgeu(A2, AT, 29);
   695 #endif
   696 }
   698 void TemplateTable::iaload() {
   699   transition(itos, itos);
   700   if(UseBoundCheckInstruction) {
   701     __ pop(SSR); //SSR:array    FSR: index
   702     __ dsll(FSR, FSR, 2);
   703     __ dadd(FSR, SSR, FSR);
   704     __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
   706     __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
   707     __ dsll(AT, AT, 2);
   708     __ dadd(AT, SSR, AT);
   709     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_INT));
   711     __ gslwle(FSR, FSR, AT);
   712   } else {
   713     index_check(SSR, FSR);
   714     __ dsll(FSR, FSR, 2);
   715     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_INT), 8)) {
   716       __ gslwx(FSR, FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_INT));
   717     } else {
   718       __ dadd(FSR, SSR, FSR);
   719       __ lw(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_INT));
   720     }
   721   }
   722 }
   724 void TemplateTable::laload() {
   725   transition(itos, ltos);
   726   if(UseBoundCheckInstruction) {
   727     __ pop(SSR); //SSR:array    FSR: index
   728     __ dsll(FSR, FSR, Address::times_8);
   729     __ dadd(FSR, SSR, FSR);
   730     __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
   732     __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
   733     __ dsll(AT, AT, Address::times_8);
   734     __ dadd(AT, SSR, AT);
   735     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);
   737     __ gsldle(FSR, FSR, AT);
   738   } else {
   739     index_check(SSR, FSR);
   740     __ dsll(AT, FSR, Address::times_8);
   741     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_LONG), 8)) {
   742       __ gsldx(FSR, SSR, AT, arrayOopDesc::base_offset_in_bytes(T_LONG));
   743     } else {
   744       __ dadd(AT, SSR, AT);
   745       __ ld(FSR, AT, arrayOopDesc::base_offset_in_bytes(T_LONG));
   746     }
   747   }
   748 }
   750 void TemplateTable::faload() {
   751   transition(itos, ftos);
   752   if(UseBoundCheckInstruction) {
   753     __ pop(SSR); //SSR:array    FSR: index
   754     __ shl(FSR, 2);
   755     __ dadd(FSR, SSR, FSR);
   756     __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
   758     __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
   759     __ shl(AT, 2);
   760     __ dadd(AT, SSR, AT);
   761     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
   763     __ gslwlec1(FSF, FSR, AT);
   764   } else {
   765     index_check(SSR, FSR);
   766     __ shl(FSR, 2);
   767     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 8)) {
   768       __ gslwxc1(FSF, SSR, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
   769     } else {
   770       __ dadd(FSR, SSR, FSR);
   771       __ lwc1(FSF, FSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
   772     }
   773   }
   774 }
   776 void TemplateTable::daload() {
   777   transition(itos, dtos);
   778   if(UseBoundCheckInstruction) {
   779     __ pop(SSR); //SSR:array    FSR: index
   780     __ dsll(FSR, FSR, 3);
   781     __ dadd(FSR, SSR, FSR);
   782     __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
   784     __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
   785     __ dsll(AT, AT, 3);
   786     __ dadd(AT, SSR, AT);
   787     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);
   789     __ gsldlec1(FSF, FSR, AT);
   790   } else {
   791     index_check(SSR, FSR);
   792     __ dsll(AT, FSR, 3);
   793     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 8)) {
   794       __ gsldxc1(FSF, SSR, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
   795     } else {
   796       __ dadd(AT, SSR, AT);
   797       __ ldc1(FSF, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
   798     }
   799   }
   800 }
   802 void TemplateTable::aaload() {
   803   transition(itos, atos);
   804   index_check(SSR, FSR);
   805   __ dsll(FSR, FSR, UseCompressedOops ? Address::times_4 : Address::times_8);
   806   __ dadd(FSR, SSR, FSR);
   807   //add for compressedoops
   808   __ load_heap_oop(FSR, Address(FSR, arrayOopDesc::base_offset_in_bytes(T_OBJECT)));
   809 }
   811 void TemplateTable::baload() {
   812   transition(itos, itos);
   813   if(UseBoundCheckInstruction) {
   814     __ pop(SSR); //SSR:array   FSR:index
   815     __ dadd(FSR, SSR, FSR);
   816     __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //base
   818     __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());
   819     __ dadd(AT, SSR, AT);
   820     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_BYTE)); //bound
   822     __ gslble(FSR, FSR, AT);
   823   } else {
   824     index_check(SSR, FSR);
   825     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_BYTE), 8)) {
   826       __ gslbx(FSR, SSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
   827     } else {
   828       __ dadd(FSR, SSR, FSR);
   829       __ lb(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
   830     }
   831   }
   832 }
   834 void TemplateTable::caload() {
   835   transition(itos, itos);
   836   index_check(SSR, FSR);
   837   __ dsll(FSR, FSR, Address::times_2);
   838   __ dadd(FSR, SSR, FSR);
   839   __ lhu(FSR, FSR,  arrayOopDesc::base_offset_in_bytes(T_CHAR));
   840 }
   842 // iload followed by caload frequent pair
   843 // used register : T2
   844 // T2 : index
   845 void TemplateTable::fast_icaload() {
   846   transition(vtos, itos);
   847   // load index out of locals
   848   locals_index(T2);
   849   __ lw(FSR, T2, 0);
   850   index_check(SSR, FSR);
   851   __ dsll(FSR, FSR, 1);
   852   __ dadd(FSR, SSR, FSR);
   853   __ lhu(FSR, FSR,  arrayOopDesc::base_offset_in_bytes(T_CHAR));
   854 }
   856 void TemplateTable::saload() {
   857   transition(itos, itos);
   858   if(UseBoundCheckInstruction) {
   859     __ pop(SSR); //SSR:array    FSR: index
   860     __ dsll(FSR, FSR, Address::times_2);
   861     __ dadd(FSR, SSR, FSR);
   862     __ addi(FSR, FSR, arrayOopDesc::base_offset_in_bytes(T_SHORT));
   864     __ lw(AT, SSR, arrayOopDesc::length_offset_in_bytes());  //bound
   865     __ dsll(AT, AT, Address::times_2);
   866     __ dadd(AT, SSR, AT);
   867     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_SHORT));
   869     __ gslhle(FSR, FSR, AT);
   870   } else {
   871     index_check(SSR, FSR);
   872     __ dsll(FSR, FSR, Address::times_2);
   873     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_SHORT), 8)) {
   874       __ gslhx(FSR, SSR, FSR,  arrayOopDesc::base_offset_in_bytes(T_SHORT));
   875     } else {
   876       __ dadd(FSR, SSR, FSR);
   877       __ lh(FSR, FSR,  arrayOopDesc::base_offset_in_bytes(T_SHORT));
   878     }
   879   }
   880 }
   882 void TemplateTable::iload(int n) {
   883   transition(vtos, itos);
   884   __ lw(FSR, iaddress(n));
   885 }
   887 void TemplateTable::lload(int n) {
   888   transition(vtos, ltos);
   889   __ ld(FSR, laddress(n));
   890 }
   892 void TemplateTable::fload(int n) {
   893   transition(vtos, ftos);
   894   __ lwc1(FSF, faddress(n));
   895 }
   897 void TemplateTable::dload(int n) {
   898   transition(vtos, dtos);
   899   __ ldc1(FSF, laddress(n));
   900 }
   902 void TemplateTable::aload(int n) {
   903   transition(vtos, atos);
   904   __ ld(FSR, aaddress(n));
   905 }
   907 // used register : T2, T3
   908 // T2 : bytecode
   909 // T3 : folded code
   910 void TemplateTable::aload_0() {
   911   transition(vtos, atos);
   912   // According to bytecode histograms, the pairs:
   913   //
   914   // _aload_0, _fast_igetfield
   915   // _aload_0, _fast_agetfield
   916   // _aload_0, _fast_fgetfield
   917   //
   918   // occur frequently. If RewriteFrequentPairs is set, the (slow)
   919   // _aload_0 bytecode checks if the next bytecode is either
   920   // _fast_igetfield, _fast_agetfield or _fast_fgetfield and then
   921   // rewrites the current bytecode into a pair bytecode; otherwise it
   922   // rewrites the current bytecode into _fast_aload_0 that doesn't do
   923   // the pair check anymore.
   924   //
   925   // Note: If the next bytecode is _getfield, the rewrite must be
   926   //       delayed, otherwise we may miss an opportunity for a pair.
   927   //
   928   // Also rewrite frequent pairs
   929   //   aload_0, aload_1
   930   //   aload_0, iload_1
   931   // These bytecodes with a small amount of code are most profitable
   932   // to rewrite
   933   if (RewriteFrequentPairs) {
   934     Label rewrite, done;
   935     // get the next bytecode in T2
   936     __ lbu(T2, at_bcp(Bytecodes::length_for(Bytecodes::_aload_0)));
   938     // do actual aload_0
   939     aload(0);
   941     // if _getfield then wait with rewrite
   942     __ move(AT, Bytecodes::_getfield);
   943     __ beq(AT, T2, done);
   944     __ delayed()->nop();
   946     // if _igetfield then reqrite to _fast_iaccess_0
   947     assert(Bytecodes::java_code(Bytecodes::_fast_iaccess_0) ==
   948         Bytecodes::_aload_0,
   949         "fix bytecode definition");
   950     __ move(T3, Bytecodes::_fast_iaccess_0);
   951     __ move(AT, Bytecodes::_fast_igetfield);
   952     __ beq(AT, T2, rewrite);
   953     __ delayed()->nop();
   955     // if _agetfield then reqrite to _fast_aaccess_0
   956     assert(Bytecodes::java_code(Bytecodes::_fast_aaccess_0) ==
   957         Bytecodes::_aload_0,
   958         "fix bytecode definition");
   959     __ move(T3, Bytecodes::_fast_aaccess_0);
   960     __ move(AT, Bytecodes::_fast_agetfield);
   961     __ beq(AT, T2, rewrite);
   962     __ delayed()->nop();
   964     // if _fgetfield then reqrite to _fast_faccess_0
   965     assert(Bytecodes::java_code(Bytecodes::_fast_faccess_0) ==
   966         Bytecodes::_aload_0,
   967         "fix bytecode definition");
   968     __ move(T3, Bytecodes::_fast_faccess_0);
   969     __ move(AT, Bytecodes::_fast_fgetfield);
   970     __ beq(AT, T2, rewrite);
   971     __ delayed()->nop();
   973     // else rewrite to _fast_aload0
   974     assert(Bytecodes::java_code(Bytecodes::_fast_aload_0) ==
   975         Bytecodes::_aload_0,
   976         "fix bytecode definition");
   977     __ move(T3, Bytecodes::_fast_aload_0);
   979     // rewrite
   980     __ bind(rewrite);
   981     patch_bytecode(Bytecodes::_aload_0, T3, T2, false);
   983     __ bind(done);
   984   } else {
   985     aload(0);
   986   }
   987 }
   989 void TemplateTable::istore() {
   990   transition(itos, vtos);
   991   locals_index(T2);
   992   __ sw(FSR, T2, 0);
   993 }
   995 void TemplateTable::lstore() {
   996   transition(ltos, vtos);
   997   locals_index(T2);
   998   __ sd(FSR, T2, -wordSize);
   999 }
  1001 void TemplateTable::fstore() {
  1002   transition(ftos, vtos);
  1003   locals_index(T2);
  1004   __ swc1(FSF, T2, 0);
  1007 void TemplateTable::dstore() {
  1008   transition(dtos, vtos);
  1009   locals_index(T2);
  1010   __ sdc1(FSF, T2, -wordSize);
  1013 void TemplateTable::astore() {
  1014   transition(vtos, vtos);
  1015   __ pop_ptr(FSR);
  1016   locals_index(T2);
  1017   __ sd(FSR, T2, 0);
  1020 void TemplateTable::wide_istore() {
  1021   transition(vtos, vtos);
  1022   __ pop_i(FSR);
  1023   locals_index_wide(T2);
  1024   __ sd(FSR, T2, 0);
  1027 void TemplateTable::wide_lstore() {
  1028   transition(vtos, vtos);
  1029   __ pop_l(FSR);
  1030   locals_index_wide(T2);
  1031   __ sd(FSR, T2, -wordSize);
  1034 void TemplateTable::wide_fstore() {
  1035   wide_istore();
  1038 void TemplateTable::wide_dstore() {
  1039   wide_lstore();
  1042 void TemplateTable::wide_astore() {
  1043   transition(vtos, vtos);
  1044   __ pop_ptr(FSR);
  1045   locals_index_wide(T2);
  1046   __ sd(FSR, T2, 0);
  1049 // used register : T2
  1050 void TemplateTable::iastore() {
  1051   transition(itos, vtos);
  1052   __ pop_i(SSR);   // T2: array  SSR: index
  1053   if(UseBoundCheckInstruction) {
  1054     __ pop_ptr(T2);
  1055     __ dsll(SSR, SSR, Address::times_4);
  1056     __ dadd(SSR, T2, SSR);
  1057     __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_INT));  // base
  1059     __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
  1060     __ dsll(AT, AT, Address::times_4);
  1061     __ dadd(AT, T2, AT);
  1062     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_INT));  //bound
  1064     __ gsswle(FSR, SSR, AT);
  1065   } else {
  1066     index_check(T2, SSR);  // prefer index in ebx
  1067     __ dsll(SSR, SSR, Address::times_4);
  1068     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_INT), 8)) {
  1069       __ gsswx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_INT));
  1070     } else {
  1071       __ dadd(T2, T2, SSR);
  1072       __ sw(FSR, T2, arrayOopDesc::base_offset_in_bytes(T_INT));
  1079 // used register T2, T3
  1080 void TemplateTable::lastore() {
  1081   transition(ltos, vtos);
  1082   __ pop_i (T2);
  1083   if(UseBoundCheckInstruction) {
  1084     __ pop_ptr(T3);
  1085     __ dsll(T2, T2, Address::times_8);
  1086     __ dadd(T2, T3, T2);
  1087     __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);  // base
  1089     __ lw(AT, T3, arrayOopDesc::length_offset_in_bytes());
  1090     __ dsll(AT, AT, Address::times_8);
  1091     __ dadd(AT, T3, AT);
  1092     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_LONG) + 0 * wordSize);  //bound
  1094     __ gssdle(FSR, T2, AT);
  1095   } else {
  1096     index_check(T3, T2);
  1097     __ dsll(T2, T2, Address::times_8);
  1098     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_LONG), 8)) {
  1099       __ gssdx(FSR, T3, T2, arrayOopDesc::base_offset_in_bytes(T_LONG));
  1100     } else {
  1101       __ dadd(T3, T3, T2);
  1102       __ sd(FSR, T3, arrayOopDesc::base_offset_in_bytes(T_LONG));
  1107 // used register T2
  1108 void TemplateTable::fastore() {
  1109   transition(ftos, vtos);
  1110   __ pop_i(SSR);
  1111   if(UseBoundCheckInstruction) {
  1112     __ pop_ptr(T2);
  1113     __ dsll(SSR, SSR, Address::times_4);
  1114     __ dadd(SSR, T2, SSR);
  1115     __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));  // base
  1117     __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
  1118     __ dsll(AT, AT, Address::times_4);
  1119     __ dadd(AT, T2, AT);
  1120     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_FLOAT));  //bound
  1122     __ gsswlec1(FSF, SSR, AT);
  1123   } else {
  1124     index_check(T2, SSR);
  1125     __ dsll(SSR, SSR, Address::times_4);
  1126     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_FLOAT), 8)) {
  1127       __ gsswxc1(FSF, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
  1128     } else {
  1129       __ dadd(T2, T2, SSR);
  1130       __ swc1(FSF, T2, arrayOopDesc::base_offset_in_bytes(T_FLOAT));
  1135 // used register T2, T3
  1136 void TemplateTable::dastore() {
  1137   transition(dtos, vtos);
  1138   __ pop_i (T2);
  1139   if(UseBoundCheckInstruction) {
  1140     __ pop_ptr(T3);
  1141     __ dsll(T2, T2, Address::times_8);
  1142     __ dadd(T2, T3, T2);
  1143     __ addi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);  // base
  1145     __ lw(AT, T3, arrayOopDesc::length_offset_in_bytes());
  1146     __ dsll(AT, AT, Address::times_8);
  1147     __ dadd(AT, T3, AT);
  1148     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_DOUBLE) + 0 * wordSize);  //bound
  1150     __ gssdlec1(FSF, T2, AT);
  1151   } else {
  1152     index_check(T3, T2);
  1153     __ dsll(T2, T2, Address::times_8);
  1154     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_DOUBLE), 8)) {
  1155       __ gssdxc1(FSF, T3, T2, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
  1156     } else {
  1157       __ daddu(T3, T3, T2);
  1158       __ sdc1(FSF, T3, arrayOopDesc::base_offset_in_bytes(T_DOUBLE));
  1163 // used register : T2, T3, T8
  1164 // T2 : array
  1165 // T3 : subklass
  1166 // T8 : supklass
  1167 void TemplateTable::aastore() {
  1168   Label is_null, ok_is_subtype, done;
  1169   transition(vtos, vtos);
  1170   // stack: ..., array, index, value
  1171   __ ld(FSR, at_tos());     // Value
  1172   __ lw(SSR, at_tos_p1());  // Index
  1173   __ ld(T2, at_tos_p2());  // Array
  1175   // index_check(T2, SSR);
  1176   index_check_without_pop(T2, SSR);
  1177   // do array store check - check for NULL value first
  1178   __ beq(FSR, R0, is_null);
  1179   __ delayed()->nop();
  1181   // Move subklass into T3
  1182   //add for compressedoops
  1183   __ load_klass(T3, FSR);
  1184   // Move superklass into T8
  1185   //add for compressedoops
  1186   __ load_klass(T8, T2);
  1187   __ ld(T8, Address(T8,  ObjArrayKlass::element_klass_offset()));
  1188   // Compress array+index*4+12 into a single register. T2
  1189   __ dsll(AT, SSR, UseCompressedOops? Address::times_4 : Address::times_8);
  1190   __ dadd(T2, T2, AT);
  1191   __ daddi(T2, T2, arrayOopDesc::base_offset_in_bytes(T_OBJECT));
  1193   // Generate subtype check.
  1194   // Superklass in T8.  Subklass in T3.
  1195   __ gen_subtype_check(T8, T3, ok_is_subtype);
  1196   // Come here on failure
  1197   // object is at FSR
  1198   __ jmp(Interpreter::_throw_ArrayStoreException_entry);
  1199   __ delayed()->nop();
  1200   // Come here on success
  1201   __ bind(ok_is_subtype);
  1202   do_oop_store(_masm, Address(T2, 0), FSR, _bs->kind(), true);
  1203   __ b(done);
  1204   __ delayed()->nop();
  1206   // Have a NULL in FSR, EDX=T2, SSR=index.  Store NULL at ary[idx]
  1207   __ bind(is_null);
  1208   __ profile_null_seen(T9);
  1209   __ dsll(AT, SSR, UseCompressedOops? Address::times_4 : Address::times_8);
  1210   __ dadd(T2, T2, AT);
  1211   do_oop_store(_masm, Address(T2, arrayOopDesc::base_offset_in_bytes(T_OBJECT)), noreg, _bs->kind(), true);
  1213   __ bind(done);
  1214   __ daddi(SP, SP, 3 * Interpreter::stackElementSize);
  1217 void TemplateTable::bastore() {
  1218   transition(itos, vtos);
  1219   __ pop_i(SSR);
  1220   if(UseBoundCheckInstruction) {
  1221     guarantee(false, "unimplemented yet!");
  1222     __ pop_ptr(T2);
  1223     __ dadd(SSR, T2, SSR);
  1224     __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));  // base
  1226     __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
  1227     __ dadd(AT, T2, AT);
  1228     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_BYTE));  //bound
  1230     __ gssble(FSR, SSR, AT);
  1231   } else {
  1232     index_check(T2, SSR);
  1234     // Need to check whether array is boolean or byte
  1235     // since both types share the bastore bytecode.
  1236     __ load_klass(T9, T2);
  1237     __ lw(T9, T9, in_bytes(Klass::layout_helper_offset()));
  1239     int diffbit = Klass::layout_helper_boolean_diffbit();
  1240     __ move(AT, diffbit);
  1242     Label L_skip;
  1243     __ andr(AT, T9, AT);
  1244     __ beq(AT, R0, L_skip);
  1245     __ nop();
  1246     __ andi(FSR, FSR, 0x1);
  1247     __ bind(L_skip);
  1249     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_BYTE), 8)) {
  1250       __ gssbx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
  1251     } else {
  1252       __ dadd(SSR, T2, SSR);
  1253       __ sb(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_BYTE));
  1258 void TemplateTable::castore() {
  1259   transition(itos, vtos);
  1260   __ pop_i(SSR);
  1261   if(UseBoundCheckInstruction) {
  1262     __ pop_ptr(T2);
  1263     __ dsll(SSR, SSR, Address::times_2);
  1264     __ dadd(SSR, T2, SSR);
  1265     __ addi(SSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));  // base
  1267     __ lw(AT, T2, arrayOopDesc::length_offset_in_bytes());
  1268     __ dsll(AT, AT, Address::times_2);
  1269     __ dadd(AT, T2, AT);
  1270     __ addi(AT, AT, arrayOopDesc::base_offset_in_bytes(T_CHAR));  //bound
  1272     __ gsshle(FSR, SSR, AT);
  1273   } else {
  1274     index_check(T2, SSR);
  1275     __ dsll(SSR, SSR, Address::times_2);
  1276     if (UseLoongsonISA && Assembler::is_simm(arrayOopDesc::base_offset_in_bytes(T_CHAR), 8)) {
  1277       __ gsshx(FSR, T2, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
  1278     } else {
  1279       __ dadd(SSR, T2, SSR);
  1280       __ sh(FSR, SSR, arrayOopDesc::base_offset_in_bytes(T_CHAR));
  1285 void TemplateTable::sastore() {
  1286   castore();
  1289 void TemplateTable::istore(int n) {
  1290   transition(itos, vtos);
  1291   __ sw(FSR, iaddress(n));
  1294 void TemplateTable::lstore(int n) {
  1295   transition(ltos, vtos);
  1296   __ sd(FSR, laddress(n));
  1299 void TemplateTable::fstore(int n) {
  1300   transition(ftos, vtos);
  1301   __ swc1(FSF, faddress(n));
  1304 void TemplateTable::dstore(int n) {
  1305   transition(dtos, vtos);
  1306   __ sdc1(FSF, laddress(n));
  1309 void TemplateTable::astore(int n) {
  1310   transition(vtos, vtos);
  1311   __ pop_ptr(FSR);
  1312   __ sd(FSR, aaddress(n));
  1315 void TemplateTable::pop() {
  1316   transition(vtos, vtos);
  1317   __ daddi(SP, SP, Interpreter::stackElementSize);
  1320 void TemplateTable::pop2() {
  1321   transition(vtos, vtos);
  1322   __ daddi(SP, SP, 2 * Interpreter::stackElementSize);
  1325 void TemplateTable::dup() {
  1326   transition(vtos, vtos);
  1327   // stack: ..., a
  1328   __ load_ptr(0, FSR);
  1329   __ push_ptr(FSR);
  1330   // stack: ..., a, a
  1333 // blows FSR
  1334 void TemplateTable::dup_x1() {
  1335   transition(vtos, vtos);
  1336   // stack: ..., a, b
  1337   __ load_ptr(0, FSR);  // load b
  1338   __ load_ptr(1, A5);  // load a
  1339   __ store_ptr(1, FSR); // store b
  1340   __ store_ptr(0, A5); // store a
  1341   __ push_ptr(FSR);             // push b
  1342   // stack: ..., b, a, b
  1345 // blows FSR
  1346 void TemplateTable::dup_x2() {
  1347   transition(vtos, vtos);
  1348   // stack: ..., a, b, c
  1349   __ load_ptr(0, FSR);  // load c
  1350   __ load_ptr(2, A5);  // load a
  1351   __ store_ptr(2, FSR); // store c in a
  1352   __ push_ptr(FSR);             // push c
  1353   // stack: ..., c, b, c, c
  1354   __ load_ptr(2, FSR);  // load b
  1355   __ store_ptr(2, A5); // store a in b
  1356   // stack: ..., c, a, c, c
  1357   __ store_ptr(1, FSR); // store b in c
  1358   // stack: ..., c, a, b, c
  1361 // blows FSR
  1362 void TemplateTable::dup2() {
  1363   transition(vtos, vtos);
  1364   // stack: ..., a, b
  1365   __ load_ptr(1, FSR);  // load a
  1366   __ push_ptr(FSR);             // push a
  1367   __ load_ptr(1, FSR);  // load b
  1368   __ push_ptr(FSR);             // push b
  1369   // stack: ..., a, b, a, b
  1372 // blows FSR
  1373 void TemplateTable::dup2_x1() {
  1374   transition(vtos, vtos);
  1375   // stack: ..., a, b, c
  1376   __ load_ptr(0, T2);  // load c
  1377   __ load_ptr(1, FSR);  // load b
  1378   __ push_ptr(FSR);             // push b
  1379   __ push_ptr(T2);             // push c
  1380   // stack: ..., a, b, c, b, c
  1381   __ store_ptr(3, T2); // store c in b
  1382   // stack: ..., a, c, c, b, c
  1383   __ load_ptr(4, T2);  // load a
  1384   __ store_ptr(2, T2); // store a in 2nd c
  1385   // stack: ..., a, c, a, b, c
  1386   __ store_ptr(4, FSR); // store b in a
  1387   // stack: ..., b, c, a, b, c
  1389   // stack: ..., b, c, a, b, c
  1392 // blows FSR, SSR
  1393 void TemplateTable::dup2_x2() {
  1394   transition(vtos, vtos);
  1395   // stack: ..., a, b, c, d
  1396   // stack: ..., a, b, c, d
  1397   __ load_ptr(0, T2);  // load d
  1398   __ load_ptr(1, FSR);  // load c
  1399   __ push_ptr(FSR);             // push c
  1400   __ push_ptr(T2);             // push d
  1401   // stack: ..., a, b, c, d, c, d
  1402   __ load_ptr(4, FSR);  // load b
  1403   __ store_ptr(2, FSR); // store b in d
  1404   __ store_ptr(4, T2); // store d in b
  1405   // stack: ..., a, d, c, b, c, d
  1406   __ load_ptr(5, T2);  // load a
  1407   __ load_ptr(3, FSR);  // load c
  1408   __ store_ptr(3, T2); // store a in c
  1409   __ store_ptr(5, FSR); // store c in a
  1410   // stack: ..., c, d, a, b, c, d
  1412   // stack: ..., c, d, a, b, c, d
  1415 // blows FSR
  1416 void TemplateTable::swap() {
  1417   transition(vtos, vtos);
  1418   // stack: ..., a, b
  1420   __ load_ptr(1, A5);  // load a
  1421   __ load_ptr(0, FSR);  // load b
  1422   __ store_ptr(0, A5); // store a in b
  1423   __ store_ptr(1, FSR); // store b in a
  1425   // stack: ..., b, a
  1428 void TemplateTable::iop2(Operation op) {
  1429   transition(itos, itos);
  1431   __ pop_i(SSR);
  1432   switch (op) {
  1433     case add  : __ addu32(FSR, SSR, FSR); break;
  1434     case sub  : __ subu32(FSR, SSR, FSR); break;
  1435     case mul  : __ mul(FSR, SSR, FSR);    break;
  1436     case _and : __ andr(FSR, SSR, FSR);   break;
  1437     case _or  : __ orr(FSR, SSR, FSR);    break;
  1438     case _xor : __ xorr(FSR, SSR, FSR);   break;
  1439     case shl  : __ sllv(FSR, SSR, FSR);   break; // implicit masking of lower 5 bits by Intel shift instr. mips also
  1440     case shr  : __ srav(FSR, SSR, FSR);   break; // implicit masking of lower 5 bits by Intel shift instr. mips also
  1441     case ushr : __ srlv(FSR, SSR, FSR);   break; // implicit masking of lower 5 bits by Intel shift instr. mips also
  1442     default   : ShouldNotReachHere();
  1446 // the result stored in FSR, SSR,
  1447 // used registers : T2, T3
  1448 void TemplateTable::lop2(Operation op) {
  1449   transition(ltos, ltos);
  1450   __ pop_l(T2);
  1452   switch (op) {
  1453     case add : __ daddu(FSR, T2, FSR); break;
  1454     case sub : __ dsubu(FSR, T2, FSR); break;
  1455     case _and: __ andr(FSR, T2, FSR);  break;
  1456     case _or : __ orr(FSR, T2, FSR);   break;
  1457     case _xor: __ xorr(FSR, T2, FSR);  break;
  1458     default : ShouldNotReachHere();
  1462 // java require this bytecode could handle 0x80000000/-1, dont cause a overflow exception,
  1463 // the result is 0x80000000
  1464 // the godson2 cpu do the same, so we need not handle this specially like x86
  1465 void TemplateTable::idiv() {
  1466   transition(itos, itos);
  1467   Label not_zero;
  1469   __ bne(FSR, R0, not_zero);
  1470   __ delayed()->nop();
  1471   __ jmp(Interpreter::_throw_ArithmeticException_entry);
  1472   __ delayed()->nop();
  1473   __ bind(not_zero);
  1475   __ pop_i(SSR);
  1476   if (UseLoongsonISA) {
  1477     __ gsdiv(FSR, SSR, FSR);
  1478   } else {
  1479     __ div(SSR, FSR);
  1480     __ mflo(FSR);
  1484 void TemplateTable::irem() {
  1485   transition(itos, itos);
  1486   Label not_zero;
  1487   __ pop_i(SSR);
  1488   __ div(SSR, FSR);
  1490   __ bne(FSR, R0, not_zero);
  1491   __ delayed()->nop();
  1492   //__ brk(7);
  1493   __ jmp(Interpreter::_throw_ArithmeticException_entry);
  1494   __ delayed()->nop();
  1496   __ bind(not_zero);
  1497   __ mfhi(FSR);
  1500 void TemplateTable::lmul() {
  1501   transition(ltos, ltos);
  1502   __ pop_l(T2);
  1503   if(UseLoongsonISA){
  1504     __ gsdmult(FSR, T2, FSR);
  1505   } else {
  1506     __ dmult(T2, FSR);
  1507     __ mflo(FSR);
  1511 // NOTE: i DONT use the Interpreter::_throw_ArithmeticException_entry
  1512 void TemplateTable::ldiv() {
  1513   transition(ltos, ltos);
  1514   Label normal;
  1516   __ bne(FSR, R0, normal);
  1517   __ delayed()->nop();
  1519   //__ brk(7);    //generate FPE
  1520   __ jmp(Interpreter::_throw_ArithmeticException_entry);
  1521   __ delayed()->nop();
  1523   __ bind(normal);
  1524   __ pop_l(A2);
  1525   if (UseLoongsonISA) {
  1526     __ gsddiv(FSR, A2, FSR);
  1527   } else {
  1528     __ ddiv(A2, FSR);
  1529     __ mflo(FSR);
  1533 // NOTE: i DONT use the Interpreter::_throw_ArithmeticException_entry
  1534 void TemplateTable::lrem() {
  1535   transition(ltos, ltos);
  1536   Label normal;
  1538   __ bne(FSR, R0, normal);
  1539   __ delayed()->nop();
  1541   __ jmp(Interpreter::_throw_ArithmeticException_entry);
  1542   __ delayed()->nop();
  1544   __ bind(normal);
  1545   __ pop_l (A2);
  1547   if(UseLoongsonISA){
  1548     __ gsdmod(FSR, A2, FSR);
  1549   } else {
  1550     __ ddiv(A2, FSR);
  1551     __ mfhi(FSR);
  1555 // result in FSR
  1556 // used registers : T0
  1557 void TemplateTable::lshl() {
  1558   transition(itos, ltos);
  1559   __ pop_l(T0);
  1560   __ dsllv(FSR, T0, FSR);
  1563 // used registers : T0
  1564 void TemplateTable::lshr() {
  1565   transition(itos, ltos);
  1566   __ pop_l(T0);
  1567   __ dsrav(FSR, T0, FSR);
  1570 // used registers : T0
  1571 void TemplateTable::lushr() {
  1572   transition(itos, ltos);
  1573   __ pop_l(T0);
  1574   __ dsrlv(FSR, T0, FSR);
  1577 // result in FSF
  1578 void TemplateTable::fop2(Operation op) {
  1579   transition(ftos, ftos);
  1580   switch (op) {
  1581     case add:
  1582       __ lwc1(FTF, at_sp());
  1583       __ add_s(FSF, FTF, FSF);
  1584       break;
  1585     case sub:
  1586       __ lwc1(FTF, at_sp());
  1587       __ sub_s(FSF, FTF, FSF);
  1588       break;
  1589     case mul:
  1590       __ lwc1(FTF, at_sp());
  1591       __ mul_s(FSF, FTF, FSF);
  1592       break;
  1593     case div:
  1594       __ lwc1(FTF, at_sp());
  1595       __ div_s(FSF, FTF, FSF);
  1596       break;
  1597     case rem:
  1598       __ mov_s(F13, FSF);
  1599       __ lwc1(F12, at_sp());
  1600        __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::frem), 2);
  1601       break;
  1602     default : ShouldNotReachHere();
  1605   __ daddi(SP, SP, 1 * wordSize);
  1608 // result in SSF||FSF
  1609 // i dont handle the strict flags
  1610 void TemplateTable::dop2(Operation op) {
  1611   transition(dtos, dtos);
  1612   switch (op) {
  1613     case add:
  1614       __ ldc1(FTF, at_sp());
  1615       __ add_d(FSF, FTF, FSF);
  1616       break;
  1617     case sub:
  1618       __ ldc1(FTF, at_sp());
  1619       __ sub_d(FSF, FTF, FSF);
  1620       break;
  1621     case mul:
  1622       __ ldc1(FTF, at_sp());
  1623       __ mul_d(FSF, FTF, FSF);
  1624       break;
  1625     case div:
  1626       __ ldc1(FTF, at_sp());
  1627       __ div_d(FSF, FTF, FSF);
  1628       break;
  1629     case rem:
  1630       __ mov_d(F13, FSF);
  1631       __ ldc1(F12, at_sp());
  1632       __ call_VM_leaf(CAST_FROM_FN_PTR(address, SharedRuntime::drem), 2);
  1633       break;
  1634     default : ShouldNotReachHere();
  1637   __ daddi(SP, SP, 2 * wordSize);
  1640 void TemplateTable::ineg() {
  1641   transition(itos, itos);
  1642   __ subu32(FSR, R0, FSR);
  1645 void TemplateTable::lneg() {
  1646   transition(ltos, ltos);
  1647   __ dsubu(FSR, R0, FSR);
  1650 void TemplateTable::fneg() {
  1651   transition(ftos, ftos);
  1652   __ neg_s(FSF, FSF);
  1655 void TemplateTable::dneg() {
  1656   transition(dtos, dtos);
  1657   __ neg_d(FSF, FSF);
  1660 // used registers : T2
  1661 void TemplateTable::iinc() {
  1662   transition(vtos, vtos);
  1663   locals_index(T2);
  1664   __ lw(FSR, T2, 0);
  1665   __ lb(AT, at_bcp(2));           // get constant
  1666   __ daddu(FSR, FSR, AT);
  1667   __ sw(FSR, T2, 0);
  1670 // used register : T2
  1671 void TemplateTable::wide_iinc() {
  1672   transition(vtos, vtos);
  1673   locals_index_wide(T2);
  1674   __ get_2_byte_integer_at_bcp(FSR, AT, 4);
  1675   __ hswap(FSR);
  1676   __ lw(AT, T2, 0);
  1677   __ daddu(FSR, AT, FSR);
  1678   __ sw(FSR, T2, 0);
  1681 void TemplateTable::convert() {
  1682   // Checking
  1683 #ifdef ASSERT
  1685     TosState tos_in  = ilgl;
  1686     TosState tos_out = ilgl;
  1687     switch (bytecode()) {
  1688       case Bytecodes::_i2l: // fall through
  1689       case Bytecodes::_i2f: // fall through
  1690       case Bytecodes::_i2d: // fall through
  1691       case Bytecodes::_i2b: // fall through
  1692       case Bytecodes::_i2c: // fall through
  1693       case Bytecodes::_i2s: tos_in = itos; break;
  1694       case Bytecodes::_l2i: // fall through
  1695       case Bytecodes::_l2f: // fall through
  1696       case Bytecodes::_l2d: tos_in = ltos; break;
  1697       case Bytecodes::_f2i: // fall through
  1698       case Bytecodes::_f2l: // fall through
  1699       case Bytecodes::_f2d: tos_in = ftos; break;
  1700       case Bytecodes::_d2i: // fall through
  1701       case Bytecodes::_d2l: // fall through
  1702       case Bytecodes::_d2f: tos_in = dtos; break;
  1703       default             : ShouldNotReachHere();
  1705     switch (bytecode()) {
  1706       case Bytecodes::_l2i: // fall through
  1707       case Bytecodes::_f2i: // fall through
  1708       case Bytecodes::_d2i: // fall through
  1709       case Bytecodes::_i2b: // fall through
  1710       case Bytecodes::_i2c: // fall through
  1711       case Bytecodes::_i2s: tos_out = itos; break;
  1712       case Bytecodes::_i2l: // fall through
  1713       case Bytecodes::_f2l: // fall through
  1714       case Bytecodes::_d2l: tos_out = ltos; break;
  1715       case Bytecodes::_i2f: // fall through
  1716       case Bytecodes::_l2f: // fall through
  1717       case Bytecodes::_d2f: tos_out = ftos; break;
  1718       case Bytecodes::_i2d: // fall through
  1719       case Bytecodes::_l2d: // fall through
  1720       case Bytecodes::_f2d: tos_out = dtos; break;
  1721       default             : ShouldNotReachHere();
  1723     transition(tos_in, tos_out);
  1725 #endif // ASSERT
  1727   // Conversion
  1728   // (Note: use pushl(ecx)/popl(ecx) for 1/2-word stack-ptr manipulation)
  1729   switch (bytecode()) {
  1730     case Bytecodes::_i2l:
  1731       __ sll(FSR, FSR, 0);
  1732       break;
  1733     case Bytecodes::_i2f:
  1734       __ mtc1(FSR, FSF);
  1735       __ cvt_s_w(FSF, FSF);
  1736       break;
  1737     case Bytecodes::_i2d:
  1738       __ mtc1(FSR, FSF);
  1739       __ cvt_d_w(FSF, FSF);
  1740       break;
  1741     case Bytecodes::_i2b:
  1742       __ seb(FSR, FSR);
  1743       break;
  1744     case Bytecodes::_i2c:
  1745       __ andi(FSR, FSR, 0xFFFF);  // truncate upper 56 bits
  1746       break;
  1747     case Bytecodes::_i2s:
  1748       __ seh(FSR, FSR);
  1749       break;
  1750     case Bytecodes::_l2i:
  1751       __ sll(FSR, FSR, 0);
  1752       break;
  1753     case Bytecodes::_l2f:
  1754       __ dmtc1(FSR, FSF);
  1755       __ cvt_s_l(FSF, FSF);
  1756       break;
  1757     case Bytecodes::_l2d:
  1758       __ dmtc1(FSR, FSF);
  1759       __ cvt_d_l(FSF, FSF);
  1760       break;
  1761     case Bytecodes::_f2i:
  1763       Label L;
  1765       __ trunc_w_s(F12, FSF);
  1766       __ move(AT, 0x7fffffff);
  1767       __ mfc1(FSR, F12);
  1768       __ c_un_s(FSF, FSF);    //NaN?
  1769       __ movt(FSR, R0);
  1771       __ bne(AT, FSR, L);
  1772       __ delayed()->lui(T9, 0x8000);
  1774       __ mfc1(AT, FSF);
  1775       __ andr(AT, AT, T9);
  1777       __ movn(FSR, T9, AT);
  1779       __ bind(L);
  1781       break;
  1782     case Bytecodes::_f2l:
  1784       Label L;
  1786       __ trunc_l_s(F12, FSF);
  1787       __ daddiu(AT, R0, -1);
  1788       __ dsrl(AT, AT, 1);
  1789       __ dmfc1(FSR, F12);
  1790       __ c_un_s(FSF, FSF);    //NaN?
  1791       __ movt(FSR, R0);
  1793       __ bne(AT, FSR, L);
  1794       __ delayed()->lui(T9, 0x8000);
  1796       __ mfc1(AT, FSF);
  1797       __ andr(AT, AT, T9);
  1799       __ dsll32(T9, T9, 0);
  1800       __ movn(FSR, T9, AT);
  1802       __ bind(L);
  1804       break;
  1805     case Bytecodes::_f2d:
  1806       __ cvt_d_s(FSF, FSF);
  1807       break;
  1808     case Bytecodes::_d2i:
  1810       Label L;
  1812       __ trunc_w_d(F12, FSF);
  1813       __ move(AT, 0x7fffffff);
  1814       __ mfc1(FSR, F12);
  1816       __ bne(FSR, AT, L);
  1817       __ delayed()->mtc1(R0, F12);
  1819       __ cvt_d_w(F12, F12);
  1820       __ c_ult_d(FSF, F12);
  1821       __ bc1f(L);
  1822       __ delayed()->addiu(T9, R0, -1);
  1824       __ c_un_d(FSF, FSF);    //NaN?
  1825       __ subu32(FSR, T9, AT);
  1826       __ movt(FSR, R0);
  1828       __ bind(L);
  1830       break;
  1831     case Bytecodes::_d2l:
  1833       Label L;
  1835       __ trunc_l_d(F12, FSF);
  1836       __ daddiu(AT, R0, -1);
  1837       __ dsrl(AT, AT, 1);
  1838       __ dmfc1(FSR, F12);
  1840       __ bne(FSR, AT, L);
  1841       __ delayed()->mtc1(R0, F12);
  1843       __ cvt_d_w(F12, F12);
  1844       __ c_ult_d(FSF, F12);
  1845       __ bc1f(L);
  1846       __ delayed()->daddiu(T9, R0, -1);
  1848       __ c_un_d(FSF, FSF);    //NaN?
  1849       __ subu(FSR, T9, AT);
  1850       __ movt(FSR, R0);
  1852     __ bind(L);
  1854       break;
  1855     case Bytecodes::_d2f:
  1856       __ cvt_s_d(FSF, FSF);
  1857       break;
  1858     default             :
  1859       ShouldNotReachHere();
  1863 void TemplateTable::lcmp() {
  1864   transition(ltos, itos);
  1866   Label low, high, done;
  1867   __ pop(T0);
  1868   __ pop(R0);
  1869   __ slt(AT, T0, FSR);
  1870   __ bne(AT, R0, low);
  1871   __ delayed()->nop();
  1873   __ bne(T0, FSR, high);
  1874   __ delayed()->nop();
  1876   __ li(FSR, (long)0);
  1877   __ b(done);
  1878   __ delayed()->nop();
  1880   __ bind(low);
  1881   __ li(FSR, (long)-1);
  1882   __ b(done);
  1883   __ delayed()->nop();
  1885   __ bind(high);
  1886   __ li(FSR, (long)1);
  1887   __ b(done);
  1888   __ delayed()->nop();
  1890   __ bind(done);
  1893 void TemplateTable::float_cmp(bool is_float, int unordered_result) {
  1894   Label less, done;
  1896   __ move(FSR, R0);
  1898   if (is_float) {
  1899     __ lwc1(FTF, at_sp());
  1900     __ c_eq_s(FTF, FSF);
  1901     __ bc1t(done);
  1902     __ delayed()->daddi(SP, SP, 1 * wordSize);
  1904     if (unordered_result<0)
  1905       __ c_ult_s(FTF, FSF);
  1906     else
  1907       __ c_olt_s(FTF, FSF);
  1908   } else {
  1909     __ ldc1(FTF, at_sp());
  1910     __ c_eq_d(FTF, FSF);
  1911     __ bc1t(done);
  1912     __ delayed()->daddi(SP, SP, 2 * wordSize);
  1914     if (unordered_result<0)
  1915       __ c_ult_d(FTF, FSF);
  1916     else
  1917       __ c_olt_d(FTF, FSF);
  1919   __ bc1t(less);
  1920   __ delayed()->nop();
  1921   __ move(FSR, 1);
  1922   __ b(done);
  1923   __ delayed()->nop();
  1924   __ bind(less);
  1925   __ move(FSR, -1);
  1926   __ bind(done);
  1930 // used registers : T3, A7, Rnext
  1931 // FSR : return bci, this is defined by the vm specification
  1932 // T2 : MDO taken count
  1933 // T3 : method
  1934 // A7 : offset
  1935 // Rnext : next bytecode, this is required by dispatch_base
  1936 void TemplateTable::branch(bool is_jsr, bool is_wide) {
  1937   __ get_method(T3);
  1938   __ profile_taken_branch(A7, T2);    // only C2 meaningful
  1940 #ifndef CORE
  1941   const ByteSize be_offset = MethodCounters::backedge_counter_offset() +
  1942                              InvocationCounter::counter_offset();
  1943   const ByteSize inv_offset = MethodCounters::invocation_counter_offset() +
  1944                               InvocationCounter::counter_offset();
  1945 #endif // CORE
  1947   // Load up T4 with the branch displacement
  1948   if (!is_wide) {
  1949     __ lb(A7, BCP, 1);
  1950     __ lbu(AT, BCP, 2);
  1951     __ dsll(A7, A7, 8);
  1952     __ orr(A7, A7, AT);
  1953   } else {
  1954     __ get_4_byte_integer_at_bcp(A7, AT, 1);
  1955     __ swap(A7);
  1958   // Handle all the JSR stuff here, then exit.
  1959   // It's much shorter and cleaner than intermingling with the non-JSR
  1960   // normal-branch stuff occuring below.
  1961   if (is_jsr) {
  1962     // Pre-load the next target bytecode into Rnext
  1963     __ dadd(AT, BCP, A7);
  1964     __ lbu(Rnext, AT, 0);
  1966     // compute return address as bci in FSR
  1967     __ daddi(FSR, BCP, (is_wide?5:3) - in_bytes(ConstMethod::codes_offset()));
  1968     __ ld(AT, T3, in_bytes(Method::const_offset()));
  1969     __ dsub(FSR, FSR, AT);
  1970     // Adjust the bcp in BCP by the displacement in A7
  1971     __ dadd(BCP, BCP, A7);
  1972     // jsr returns atos that is not an oop
  1973     // Push return address
  1974     __ push_i(FSR);
  1975     // jsr returns vtos
  1976     __ dispatch_only_noverify(vtos);
  1978     return;
  1981   // Normal (non-jsr) branch handling
  1983   // Adjust the bcp in S0 by the displacement in T4
  1984   __ dadd(BCP, BCP, A7);
  1986 #ifdef CORE
  1987   // Pre-load the next target bytecode into EBX
  1988   __ lbu(Rnext, BCP, 0);
  1989   // continue with the bytecode @ target
  1990   __ dispatch_only(vtos);
  1991 #else
  1992   assert(UseLoopCounter || !UseOnStackReplacement, "on-stack-replacement requires loop counters");
  1993   Label backedge_counter_overflow;
  1994   Label profile_method;
  1995   Label dispatch;
  1996   if (UseLoopCounter) {
  1997     // increment backedge counter for backward branches
  1998     // eax: MDO
  1999     // ebx: MDO bumped taken-count
  2000     // T3: method
  2001     // T4: target offset
  2002     // BCP: target bcp
  2003     // LVP: locals pointer
  2004     __ bgtz(A7, dispatch);  // check if forward or backward branch
  2005     __ delayed()->nop();
  2007     // check if MethodCounters exists
  2008     Label has_counters;
  2009     __ ld(AT, T3, in_bytes(Method::method_counters_offset()));  // use AT as MDO, TEMP
  2010     __ bne(AT, R0, has_counters);
  2011     __ nop();
  2012     __ push(T3);
  2013     //__ push(A7);
  2014     __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::build_method_counters),
  2015                T3);
  2016     //__ pop(A7);
  2017     __ pop(T3);
  2018     __ ld(AT, T3, in_bytes(Method::method_counters_offset()));  // use AT as MDO, TEMP
  2019     __ beq(AT, R0, dispatch);
  2020     __ nop();
  2021     __ bind(has_counters);
  2023     // increment back edge counter
  2024     __ ld(T1, T3, in_bytes(Method::method_counters_offset()));
  2025     __ lw(T0, T1, in_bytes(be_offset));
  2026     __ increment(T0, InvocationCounter::count_increment);
  2027     __ sw(T0, T1, in_bytes(be_offset));
  2029     // load invocation counter
  2030     __ lw(T1, T1, in_bytes(inv_offset));
  2031     // buffer bit added, mask no needed
  2033     // dadd backedge counter & invocation counter
  2034     __ dadd(T1, T1, T0);
  2036     if (ProfileInterpreter) {
  2037       // Test to see if we should create a method data oop
  2038       // T1 : backedge counter & invocation counter
  2039       if (Assembler::is_simm16(InvocationCounter::InterpreterProfileLimit)) {
  2040         __ slti(AT, T1, InvocationCounter::InterpreterProfileLimit);
  2041       } else {
  2042         __ li(AT, (long)&InvocationCounter::InterpreterProfileLimit);
  2043         __ lw(AT, AT, 0);
  2044         __ slt(AT, T1, AT);
  2047       __ bne(AT, R0, dispatch);
  2048       __ delayed()->nop();
  2050       // if no method data exists, go to profile method
  2051       __ test_method_data_pointer(T1, profile_method);
  2053       if (UseOnStackReplacement) {
  2054         if (Assembler::is_simm16(InvocationCounter::InterpreterBackwardBranchLimit)) {
  2055           __ slti(AT, T2, InvocationCounter::InterpreterBackwardBranchLimit);
  2056         } else {
  2057           __ li(AT, (long)&InvocationCounter::InterpreterBackwardBranchLimit);
  2058           __ lw(AT, AT, 0);
  2059           __ slt(AT, T2, AT);
  2062         __ bne(AT, R0, dispatch);
  2063         __ delayed()->nop();
  2065         // When ProfileInterpreter is on, the backedge_count comes
  2066         // from the methodDataOop, which value does not get reset on
  2067         // the call to  frequency_counter_overflow().
  2068         // To avoid excessive calls to the overflow routine while
  2069         // the method is being compiled, dadd a second test to make
  2070         // sure the overflow function is called only once every
  2071         // overflow_frequency.
  2072         const int overflow_frequency = 1024;
  2073         __ andi(AT, T2, overflow_frequency-1);
  2074         __ beq(AT, R0, backedge_counter_overflow);
  2075         __ delayed()->nop();
  2077     } else {
  2078       if (UseOnStackReplacement) {
  2079         // check for overflow against eax, which is the sum of the counters
  2080         __ li(AT, (long)&InvocationCounter::InterpreterBackwardBranchLimit);
  2081         __ lw(AT, AT, 0);
  2082         __ slt(AT, T1, AT);
  2083         __ beq(AT, R0, backedge_counter_overflow);
  2084         __ delayed()->nop();
  2087     __ bind(dispatch);
  2090   // Pre-load the next target bytecode into Rnext
  2091   __ lbu(Rnext, BCP, 0);
  2093   // continue with the bytecode @ target
  2094   // FSR: return bci for jsr's, unused otherwise
  2095   // Rnext: target bytecode
  2096   // BCP: target bcp
  2097   __ dispatch_only(vtos);
  2099   if (UseLoopCounter) {
  2100     if (ProfileInterpreter) {
  2101       // Out-of-line code to allocate method data oop.
  2102       __ bind(profile_method);
  2103       __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::profile_method));
  2104       __ lbu(Rnext, BCP, 0);
  2105       __ set_method_data_pointer_for_bcp();
  2106       __ b(dispatch);
  2107       __ delayed()->nop();
  2110     if (UseOnStackReplacement) {
  2111       // invocation counter overflow
  2112       __ bind(backedge_counter_overflow);
  2113       __ sub(A7, BCP, A7);  // branch bcp
  2114       call_VM(NOREG, CAST_FROM_FN_PTR(address,
  2115       InterpreterRuntime::frequency_counter_overflow), A7);
  2116       __ lbu(Rnext, BCP, 0);
  2118       // V0: osr nmethod (osr ok) or NULL (osr not possible)
  2119       // V1: osr adapter frame return address
  2120       // Rnext: target bytecode
  2121       // LVP: locals pointer
  2122       // BCP: bcp
  2123       __ beq(V0, R0, dispatch);
  2124       __ delayed()->nop();
  2125       // nmethod may have been invalidated (VM may block upon call_VM return)
  2126       __ lw(T3, V0, nmethod::entry_bci_offset());
  2127       __ move(AT, InvalidOSREntryBci);
  2128       __ beq(AT, T3, dispatch);
  2129       __ delayed()->nop();
  2130       // We need to prepare to execute the OSR method. First we must
  2131       // migrate the locals and monitors off of the stack.
  2132       //eax V0: osr nmethod (osr ok) or NULL (osr not possible)
  2133       //ebx V1: osr adapter frame return address
  2134       //edx  Rnext: target bytecode
  2135       //edi  LVP: locals pointer
  2136       //esi  BCP: bcp
  2137       __ move(BCP, V0);
  2138       // const Register thread = ecx;
  2139       const Register thread = TREG;
  2140 #ifndef OPT_THREAD
  2141       __ get_thread(thread);
  2142 #endif
  2143       call_VM(noreg, CAST_FROM_FN_PTR(address,
  2144       SharedRuntime::OSR_migration_begin));
  2145       // eax is OSR buffer, move it to expected parameter location
  2146       //refer to osrBufferPointer in c1_LIRAssembler_mips.cpp
  2147       __ move(T0, V0);
  2149       // pop the interpreter frame
  2150       __ ld(A7, Address(FP, frame::interpreter_frame_sender_sp_offset * wordSize));
  2151       //FIXME, shall we keep the return address on the stack?
  2152       __ leave();                                // remove frame anchor
  2153       __ move(LVP, RA);
  2154       __ move(SP, A7);
  2156       __ move(AT, -(StackAlignmentInBytes));
  2157       __ andr(SP , SP , AT);
  2159       // push the (possibly adjusted) return address
  2160       //refer to osr_entry in c1_LIRAssembler_mips.cpp
  2161       __ ld(AT, BCP, nmethod::osr_entry_point_offset());
  2162       __ jr(AT);
  2163       __ delayed()->nop();
  2166 #endif // not CORE
  2170 void TemplateTable::if_0cmp(Condition cc) {
  2171   transition(itos, vtos);
  2172   // assume branch is more often taken than not (loops use backward branches)
  2173   Label not_taken;
  2174   switch(cc) {
  2175     case not_equal:
  2176       __ beq(FSR, R0, not_taken);
  2177       break;
  2178     case equal:
  2179       __ bne(FSR, R0, not_taken);
  2180       break;
  2181     case less:
  2182       __ bgez(FSR, not_taken);
  2183       break;
  2184     case less_equal:
  2185       __ bgtz(FSR, not_taken);
  2186       break;
  2187     case greater:
  2188       __ blez(FSR, not_taken);
  2189       break;
  2190     case greater_equal:
  2191       __ bltz(FSR, not_taken);
  2192       break;
  2194   __ delayed()->nop();
  2196   branch(false, false);
  2198   __ bind(not_taken);
  2199   __ profile_not_taken_branch(FSR);
  2202 void TemplateTable::if_icmp(Condition cc) {
  2203   transition(itos, vtos);
  2204   // assume branch is more often taken than not (loops use backward branches)
  2205   Label not_taken;
  2207   __ pop_i(SSR);
  2208   switch(cc) {
  2209     case not_equal:
  2210       __ beq(SSR, FSR, not_taken);
  2211       break;
  2212     case equal:
  2213       __ bne(SSR, FSR, not_taken);
  2214       break;
  2215     case less:
  2216       __ slt(AT, SSR, FSR);
  2217       __ beq(AT, R0, not_taken);
  2218       break;
  2219     case less_equal:
  2220       __ slt(AT, FSR, SSR);
  2221       __ bne(AT, R0, not_taken);
  2222       break;
  2223     case greater:
  2224       __ slt(AT, FSR, SSR);
  2225       __ beq(AT, R0, not_taken);
  2226       break;
  2227     case greater_equal:
  2228       __ slt(AT, SSR, FSR);
  2229       __ bne(AT, R0, not_taken);
  2230       break;
  2232   __ delayed()->nop();
  2234   branch(false, false);
  2235   __ bind(not_taken);
  2236   __ profile_not_taken_branch(FSR);
  2239 void TemplateTable::if_nullcmp(Condition cc) {
  2240   transition(atos, vtos);
  2241   // assume branch is more often taken than not (loops use backward branches)
  2242   Label not_taken;
  2243   switch(cc) {
  2244     case not_equal:
  2245       __ beq(FSR, R0, not_taken);
  2246       break;
  2247     case equal:
  2248       __ bne(FSR, R0, not_taken);
  2249       break;
  2250     default:
  2251       ShouldNotReachHere();
  2253   __ delayed()->nop();
  2255   branch(false, false);
  2256   __ bind(not_taken);
  2257   __ profile_not_taken_branch(FSR);
  2261 void TemplateTable::if_acmp(Condition cc) {
  2262   transition(atos, vtos);
  2263   // assume branch is more often taken than not (loops use backward branches)
  2264   Label not_taken;
  2265   //  __ lw(SSR, SP, 0);
  2266   __ pop_ptr(SSR);
  2267   switch(cc) {
  2268     case not_equal:
  2269       __ beq(SSR, FSR, not_taken);
  2270       break;
  2271     case equal:
  2272       __ bne(SSR, FSR, not_taken);
  2273       break;
  2274     default:
  2275       ShouldNotReachHere();
  2277   __ delayed()->nop();
  2279   branch(false, false);
  2281   __ bind(not_taken);
  2282   __ profile_not_taken_branch(FSR);
  2285 // used registers : T1, T2, T3
  2286 // T1 : method
  2287 // T2 : returb bci
  2288 void TemplateTable::ret() {
  2289   transition(vtos, vtos);
  2291   locals_index(T2);
  2292   __ ld(T2, T2, 0);
  2293   __ profile_ret(T2, T3);
  2295   __ get_method(T1);
  2296   __ ld(BCP, T1, in_bytes(Method::const_offset()));
  2297   __ dadd(BCP, BCP, T2);
  2298   __ daddi(BCP, BCP, in_bytes(ConstMethod::codes_offset()));
  2300   __ dispatch_next(vtos);
  2303 // used registers : T1, T2, T3
  2304 // T1 : method
  2305 // T2 : returb bci
  2306 void TemplateTable::wide_ret() {
  2307   transition(vtos, vtos);
  2309   locals_index_wide(T2);
  2310   __ ld(T2, T2, 0);                   // get return bci, compute return bcp
  2311   __ profile_ret(T2, T3);
  2313   __ get_method(T1);
  2314   __ ld(BCP, T1, in_bytes(Method::const_offset()));
  2315   __ dadd(BCP, BCP, T2);
  2316   __ daddi(BCP, BCP, in_bytes(ConstMethod::codes_offset()));
  2318   __ dispatch_next(vtos);
  2321 // used register T2, T3, A7, Rnext
  2322 // T2 : bytecode pointer
  2323 // T3 : low
  2324 // A7 : high
  2325 // Rnext : dest bytecode, required by dispatch_base
  2326 void TemplateTable::tableswitch() {
  2327   Label default_case, continue_execution;
  2328   transition(itos, vtos);
  2330   // align BCP
  2331   __ daddi(T2, BCP, BytesPerInt);
  2332   __ li(AT, -BytesPerInt);
  2333   __ andr(T2, T2, AT);
  2335   // load lo & hi
  2336   __ lw(T3, T2, 1 * BytesPerInt);
  2337   __ swap(T3);
  2338   __ lw(A7, T2, 2 * BytesPerInt);
  2339   __ swap(A7);
  2341   // check against lo & hi
  2342   __ slt(AT, FSR, T3);
  2343   __ bne(AT, R0, default_case);
  2344   __ delayed()->nop();
  2346   __ slt(AT, A7, FSR);
  2347   __ bne(AT, R0, default_case);
  2348   __ delayed()->nop();
  2350   // lookup dispatch offset, in A7 big endian
  2351   __ dsub(FSR, FSR, T3);
  2352   __ dsll(AT, FSR, Address::times_4);
  2353   __ dadd(AT, T2, AT);
  2354   __ lw(A7, AT, 3 * BytesPerInt);
  2355   __ profile_switch_case(FSR, T9, T3);
  2357   __ bind(continue_execution);
  2358   __ swap(A7);
  2359   __ dadd(BCP, BCP, A7);
  2360   __ lbu(Rnext, BCP, 0);
  2361   __ dispatch_only(vtos);
  2363   // handle default
  2364   __ bind(default_case);
  2365   __ profile_switch_default(FSR);
  2366   __ lw(A7, T2, 0);
  2367   __ b(continue_execution);
  2368   __ delayed()->nop();
  2371 void TemplateTable::lookupswitch() {
  2372   transition(itos, itos);
  2373   __ stop("lookupswitch bytecode should have been rewritten");
  2376 // used registers : T2, T3, A7, Rnext
  2377 // T2 : bytecode pointer
  2378 // T3 : pair index
  2379 // A7 : offset
  2380 // Rnext : dest bytecode
  2381 // the data after the opcode is the same as lookupswitch
  2382 // see Rewriter::rewrite_method for more information
  2383 void TemplateTable::fast_linearswitch() {
  2384   transition(itos, vtos);
  2385   Label loop_entry, loop, found, continue_execution;
  2387   // swap eax so we can avoid swapping the table entries
  2388   __ swap(FSR);
  2390   // align BCP
  2391   __ daddi(T2, BCP, BytesPerInt);
  2392   __ li(AT, -BytesPerInt);
  2393   __ andr(T2, T2, AT);
  2395   // set counter
  2396   __ lw(T3, T2, BytesPerInt);
  2397   __ swap(T3);
  2398   __ b(loop_entry);
  2399   __ delayed()->nop();
  2401   // table search
  2402   __ bind(loop);
  2403   // get the entry value
  2404   __ dsll(AT, T3, Address::times_8);
  2405   __ dadd(AT, T2, AT);
  2406   __ lw(AT, AT, 2 * BytesPerInt);
  2408   // found?
  2409   __ beq(FSR, AT, found);
  2410   __ delayed()->nop();
  2412   __ bind(loop_entry);
  2413   __ bgtz(T3, loop);
  2414   __ delayed()->daddiu(T3, T3, -1);
  2416   // default case
  2417   __ profile_switch_default(FSR);
  2418   __ lw(A7, T2, 0);
  2419   __ b(continue_execution);
  2420   __ delayed()->nop();
  2422   // entry found -> get offset
  2423   __ bind(found);
  2424   __ dsll(AT, T3, Address::times_8);
  2425   __ dadd(AT, T2, AT);
  2426   __ lw(A7, AT, 3 * BytesPerInt);
  2427   __ profile_switch_case(T3, FSR, T2);
  2429   // continue execution
  2430   __ bind(continue_execution);
  2431   __ swap(A7);
  2432   __ dadd(BCP, BCP, A7);
  2433   __ lbu(Rnext, BCP, 0);
  2434   __ dispatch_only(vtos);
  2437 // used registers : T0, T1, T2, T3, A7, Rnext
  2438 // T2 : pairs address(array)
  2439 // Rnext : dest bytecode
  2440 // the data after the opcode is the same as lookupswitch
  2441 // see Rewriter::rewrite_method for more information
  2442 void TemplateTable::fast_binaryswitch() {
  2443   transition(itos, vtos);
  2444   // Implementation using the following core algorithm:
  2445   //
  2446   // int binary_search(int key, LookupswitchPair* array, int n) {
  2447   //   // Binary search according to "Methodik des Programmierens" by
  2448   //   // Edsger W. Dijkstra and W.H.J. Feijen, Addison Wesley Germany 1985.
  2449   //   int i = 0;
  2450   //   int j = n;
  2451   //   while (i+1 < j) {
  2452   //     // invariant P: 0 <= i < j <= n and (a[i] <= key < a[j] or Q)
  2453   //     // with      Q: for all i: 0 <= i < n: key < a[i]
  2454   //     // where a stands for the array and assuming that the (inexisting)
  2455   //     // element a[n] is infinitely big.
  2456   //     int h = (i + j) >> 1;
  2457   //     // i < h < j
  2458   //     if (key < array[h].fast_match()) {
  2459   //       j = h;
  2460   //     } else {
  2461   //       i = h;
  2462   //     }
  2463   //   }
  2464   //   // R: a[i] <= key < a[i+1] or Q
  2465   //   // (i.e., if key is within array, i is the correct index)
  2466   //   return i;
  2467   // }
  2469   // register allocation
  2470   const Register array = T2;
  2471   const Register i = T3, j = A7;
  2472   const Register h = T1;
  2473   const Register temp = T0;
  2474   const Register key = FSR;
  2476   // setup array
  2477   __ daddi(array, BCP, 3*BytesPerInt);
  2478   __ li(AT, -BytesPerInt);
  2479   __ andr(array, array, AT);
  2481   // initialize i & j
  2482   __ move(i, R0);
  2483   __ lw(j, array, - 1 * BytesPerInt);
  2484   // Convert j into native byteordering
  2485   __ swap(j);
  2487   // and start
  2488   Label entry;
  2489   __ b(entry);
  2490   __ delayed()->nop();
  2492   // binary search loop
  2494     Label loop;
  2495     __ bind(loop);
  2496     // int h = (i + j) >> 1;
  2497     __ dadd(h, i, j);
  2498     __ dsrl(h, h, 1);
  2499     // if (key < array[h].fast_match()) {
  2500     //   j = h;
  2501     // } else {
  2502     //   i = h;
  2503     // }
  2504     // Convert array[h].match to native byte-ordering before compare
  2505     __ dsll(AT, h, Address::times_8);
  2506     __ dadd(AT, array, AT);
  2507     __ lw(temp, AT, 0 * BytesPerInt);
  2508     __ swap(temp);
  2511       Label set_i, end_of_if;
  2512       __ slt(AT, key, temp);
  2513       __ beq(AT, R0, set_i);
  2514       __ delayed()->nop();
  2516       __ b(end_of_if);
  2517       __ delayed(); __ move(j, h);
  2519       __ bind(set_i);
  2520       __ move(i, h);
  2522       __ bind(end_of_if);
  2524     // while (i+1 < j)
  2525     __ bind(entry);
  2526     __ daddi(h, i, 1);
  2527     __ slt(AT, h, j);
  2528     __ bne(AT, R0, loop);
  2529     __ delayed()->nop();
  2532   // end of binary search, result index is i (must check again!)
  2533   Label default_case;
  2534   // Convert array[i].match to native byte-ordering before compare
  2535   __ dsll(AT, i, Address::times_8);
  2536   __ dadd(AT, array, AT);
  2537   __ lw(temp, AT, 0 * BytesPerInt);
  2538   __ swap(temp);
  2539   __ bne(key, temp, default_case);
  2540   __ delayed()->nop();
  2542   // entry found -> j = offset
  2543   __ dsll(AT, i, Address::times_8);
  2544   __ dadd(AT, array, AT);
  2545   __ lw(j, AT, 1 * BytesPerInt);
  2546   __ profile_switch_case(i, key, array);
  2547   __ swap(j);
  2549   __ dadd(BCP, BCP, j);
  2550   __ lbu(Rnext, BCP, 0);
  2551   __ dispatch_only(vtos);
  2553   // default case -> j = default offset
  2554   __ bind(default_case);
  2555   __ profile_switch_default(i);
  2556   __ lw(j, array, - 2 * BytesPerInt);
  2557   __ swap(j);
  2558   __ dadd(BCP, BCP, j);
  2559   __ lbu(Rnext, BCP, 0);
  2560   __ dispatch_only(vtos);
  2563 void TemplateTable::_return(TosState state) {
  2564   transition(state, state);
  2565   assert(_desc->calls_vm(),
  2566       "inconsistent calls_vm information"); // call in remove_activation
  2568   if (_desc->bytecode() == Bytecodes::_return_register_finalizer) {
  2569     assert(state == vtos, "only valid state");
  2570     __ ld(T1, aaddress(0));
  2571     __ load_klass(LVP, T1);
  2572     __ lw(LVP, LVP, in_bytes(Klass::access_flags_offset()));
  2573     __ move(AT, JVM_ACC_HAS_FINALIZER);
  2574     __ andr(AT, AT, LVP);//by_css
  2575     Label skip_register_finalizer;
  2576     __ beq(AT, R0, skip_register_finalizer);
  2577     __ delayed()->nop();
  2578     __ call_VM(noreg, CAST_FROM_FN_PTR(address,
  2579     InterpreterRuntime::register_finalizer), T1);
  2580     __ bind(skip_register_finalizer);
  2583   // Narrow result if state is itos but result type is smaller.
  2584   // Need to narrow in the return bytecode rather than in generate_return_entry
  2585   // since compiled code callers expect the result to already be narrowed.
  2586   if (state == itos) {
  2587     __ narrow(FSR);
  2590   __ remove_activation(state, T9);
  2591   __ sync();
  2593   __ jr(T9);
  2594   __ delayed()->nop();
  2597 // ----------------------------------------------------------------------------
  2598 // Volatile variables demand their effects be made known to all CPU's
  2599 // in order.  Store buffers on most chips allow reads & writes to
  2600 // reorder; the JMM's ReadAfterWrite.java test fails in -Xint mode
  2601 // without some kind of memory barrier (i.e., it's not sufficient that
  2602 // the interpreter does not reorder volatile references, the hardware
  2603 // also must not reorder them).
  2604 //
  2605 // According to the new Java Memory Model (JMM):
  2606 // (1) All volatiles are serialized wrt to each other.  ALSO reads &
  2607 //     writes act as aquire & release, so:
  2608 // (2) A read cannot let unrelated NON-volatile memory refs that
  2609 //     happen after the read float up to before the read.  It's OK for
  2610 //     non-volatile memory refs that happen before the volatile read to
  2611 //     float down below it.
  2612 // (3) Similar a volatile write cannot let unrelated NON-volatile
  2613 //     memory refs that happen BEFORE the write float down to after the
  2614 //     write.  It's OK for non-volatile memory refs that happen after the
  2615 //     volatile write to float up before it.
  2616 //
  2617 // We only put in barriers around volatile refs (they are expensive),
  2618 // not _between_ memory refs (that would require us to track the
  2619 // flavor of the previous memory refs).  Requirements (2) and (3)
  2620 // require some barriers before volatile stores and after volatile
  2621 // loads.  These nearly cover requirement (1) but miss the
  2622 // volatile-store-volatile-load case.  This final case is placed after
  2623 // volatile-stores although it could just as well go before
  2624 // volatile-loads.
  2625 void TemplateTable::volatile_barrier() {
  2626   if(os::is_MP()) __ sync();
  2629 // we dont shift left 2 bits in get_cache_and_index_at_bcp
  2630 // for we always need shift the index we use it. the ConstantPoolCacheEntry
  2631 // is 16-byte long, index is the index in
  2632 // ConstantPoolCache, so cache + base_offset() + index * 16 is
  2633 // the corresponding ConstantPoolCacheEntry
  2634 // used registers : T2
  2635 // NOTE : the returned index need also shift left 4 to get the address!
  2636 void TemplateTable::resolve_cache_and_index(int byte_no,
  2637                                             Register Rcache,
  2638                                             Register index,
  2639                                             size_t index_size) {
  2640   assert(byte_no == f1_byte || byte_no == f2_byte, "byte_no out of range");
  2641   const Register temp = A1;
  2642   assert_different_registers(Rcache, index);
  2644   Label resolved;
  2645   __ get_cache_and_index_and_bytecode_at_bcp(Rcache, index, temp, byte_no, 1, index_size);
  2646   // is resolved?
  2647   int i = (int)bytecode();
  2648   __ addi(temp, temp, -i);
  2649   __ beq(temp, R0, resolved);
  2650   __ delayed()->nop();
  2651   // resolve first time through
  2652   address entry;
  2653   switch (bytecode()) {
  2654     case Bytecodes::_getstatic      : // fall through
  2655     case Bytecodes::_putstatic      : // fall through
  2656     case Bytecodes::_getfield       : // fall through
  2657     case Bytecodes::_putfield       :
  2658       entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_get_put);
  2659       break;
  2660     case Bytecodes::_invokevirtual  : // fall through
  2661     case Bytecodes::_invokespecial  : // fall through
  2662     case Bytecodes::_invokestatic   : // fall through
  2663     case Bytecodes::_invokeinterface:
  2664       entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invoke);
  2665       break;
  2666     case Bytecodes::_invokehandle:
  2667       entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokehandle);
  2668       break;
  2669     case Bytecodes::_invokedynamic:
  2670       entry = CAST_FROM_FN_PTR(address, InterpreterRuntime::resolve_invokedynamic);
  2671       break;
  2672     default                          :
  2673       fatal(err_msg("unexpected bytecode: %s", Bytecodes::name(bytecode())));
  2674       break;
  2677   __ move(temp, i);
  2678   __ call_VM(NOREG, entry, temp);
  2680   // Update registers with resolved info
  2681   __ get_cache_and_index_at_bcp(Rcache, index, 1, index_size);
  2682   __ bind(resolved);
  2685 // The Rcache and index registers must be set before call
  2686 void TemplateTable::load_field_cp_cache_entry(Register obj,
  2687                                               Register cache,
  2688                                               Register index,
  2689                                               Register off,
  2690                                               Register flags,
  2691                                               bool is_static = false) {
  2692   assert_different_registers(cache, index, flags, off);
  2694   ByteSize cp_base_offset = ConstantPoolCache::base_offset();
  2695   // Field offset
  2696   __ dsll(AT, index, Address::times_ptr);
  2697   __ dadd(AT, cache, AT);
  2698   __ ld(off, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::f2_offset()));
  2699   // Flags
  2700   __ ld(flags, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::flags_offset()));
  2702   // klass overwrite register
  2703   if (is_static) {
  2704     __ ld(obj, AT, in_bytes(cp_base_offset + ConstantPoolCacheEntry::f1_offset()));
  2705     const int mirror_offset = in_bytes(Klass::java_mirror_offset());
  2706     __ ld(obj, Address(obj, mirror_offset));
  2708     __ verify_oop(obj);
  2712 // get the method, itable_index and flags of the current invoke
  2713 void TemplateTable::load_invoke_cp_cache_entry(int byte_no,
  2714                                                Register method,
  2715                                                Register itable_index,
  2716                                                Register flags,
  2717                                                bool is_invokevirtual,
  2718                                                bool is_invokevfinal, /*unused*/
  2719                                                bool is_invokedynamic) {
  2720   // setup registers
  2721   const Register cache = T3;
  2722   const Register index = T1;
  2723   assert_different_registers(method, flags);
  2724   assert_different_registers(method, cache, index);
  2725   assert_different_registers(itable_index, flags);
  2726   assert_different_registers(itable_index, cache, index);
  2727   assert(is_invokevirtual == (byte_no == f2_byte), "is invokevirtual flag redundant");
  2728   // determine constant pool cache field offsets
  2729   const int method_offset = in_bytes(
  2730     ConstantPoolCache::base_offset() +
  2731       ((byte_no == f2_byte)
  2732        ? ConstantPoolCacheEntry::f2_offset()
  2733        : ConstantPoolCacheEntry::f1_offset()));
  2734   const int flags_offset = in_bytes(ConstantPoolCache::base_offset() +
  2735                                     ConstantPoolCacheEntry::flags_offset());
  2736   // access constant pool cache fields
  2737   const int index_offset = in_bytes(ConstantPoolCache::base_offset() +
  2738                                     ConstantPoolCacheEntry::f2_offset());
  2740   size_t index_size = (is_invokedynamic ? sizeof(u4): sizeof(u2));
  2741   resolve_cache_and_index(byte_no, cache, index, index_size);
  2743   //assert(wordSize == 8, "adjust code below");
  2744   // note we shift 4 not 2, for we get is the true inde
  2745   // of ConstantPoolCacheEntry, not the shifted 2-bit index as x86 version
  2746   __ dsll(AT, index, Address::times_ptr);
  2747   __ dadd(AT, cache, AT);
  2748   __ ld(method, AT, method_offset);
  2750   if (itable_index != NOREG) {
  2751     __ ld(itable_index, AT, index_offset);
  2753   __ ld(flags, AT, flags_offset);
  2756 // The registers cache and index expected to be set before call.
  2757 // Correct values of the cache and index registers are preserved.
  2758 void TemplateTable::jvmti_post_field_access(Register cache, Register index,
  2759                                             bool is_static, bool has_tos) {
  2760   // do the JVMTI work here to avoid disturbing the register state below
  2761   // We use c_rarg registers here because we want to use the register used in
  2762   // the call to the VM
  2763   if (JvmtiExport::can_post_field_access()) {
  2764     // Check to see if a field access watch has been set before we
  2765     // take the time to call into the VM.
  2766     Label L1;
  2767     // kill FSR
  2768     Register tmp1 = T2;
  2769     Register tmp2 = T1;
  2770     Register tmp3 = T3;
  2771     assert_different_registers(cache, index, AT);
  2772     __ li(AT, (intptr_t)JvmtiExport::get_field_access_count_addr());
  2773     __ lw(AT, AT, 0);
  2774     __ beq(AT, R0, L1);
  2775     __ delayed()->nop();
  2777     __ get_cache_and_index_at_bcp(tmp2, tmp3, 1);
  2779     // cache entry pointer
  2780     __ daddi(tmp2, tmp2, in_bytes(ConstantPoolCache::base_offset()));
  2781     __ shl(tmp3, LogBytesPerWord);
  2782     __ dadd(tmp2, tmp2, tmp3);
  2783     if (is_static) {
  2784       __ move(tmp1, R0);
  2785     } else {
  2786       __ ld(tmp1, SP, 0);
  2787       __ verify_oop(tmp1);
  2789     // tmp1: object pointer or NULL
  2790     // tmp2: cache entry pointer
  2791     // tmp3: jvalue object on the stack
  2792     __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
  2793                                        InterpreterRuntime::post_field_access),
  2794                tmp1, tmp2, tmp3);
  2795     __ get_cache_and_index_at_bcp(cache, index, 1);
  2796     __ bind(L1);
  2800 void TemplateTable::pop_and_check_object(Register r) {
  2801   __ pop_ptr(r);
  2802   __ null_check(r);  // for field access must check obj.
  2803   __ verify_oop(r);
  2806 // used registers : T1, T2, T3, T1
  2807 // T1 : flags
  2808 // T2 : off
  2809 // T3 : obj
  2810 // T1 : field address
  2811 // The flags 31, 30, 29, 28 together build a 4 bit number 0 to 8 with the
  2812 // following mapping to the TosState states:
  2813 // btos: 0
  2814 // ctos: 1
  2815 // stos: 2
  2816 // itos: 3
  2817 // ltos: 4
  2818 // ftos: 5
  2819 // dtos: 6
  2820 // atos: 7
  2821 // vtos: 8
  2822 // see ConstantPoolCacheEntry::set_field for more info
  2823 void TemplateTable::getfield_or_static(int byte_no, bool is_static) {
  2824   transition(vtos, vtos);
  2826   const Register cache = T3;
  2827   const Register index = T0;
  2829   const Register obj   = T3;
  2830   const Register off   = T2;
  2831   const Register flags = T1;
  2833   const Register scratch = T8;
  2835   resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
  2836   jvmti_post_field_access(cache, index, is_static, false);
  2837   load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
  2840     __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
  2841     __ andr(scratch, scratch, flags);
  2843     Label notVolatile;
  2844     __ beq(scratch, R0, notVolatile);
  2845     __ nop();
  2846     volatile_barrier();
  2847     __ bind(notVolatile);
  2850   if (!is_static) pop_and_check_object(obj);
  2851   __ dadd(index, obj, off);
  2854   Label Done, notByte, notBool, notInt, notShort, notChar,
  2855               notLong, notFloat, notObj, notDouble;
  2857   assert(btos == 0, "change code, btos != 0");
  2858   __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
  2859   __ andi(flags, flags, ConstantPoolCacheEntry::tos_state_mask);
  2860   __ bne(flags, R0, notByte);
  2861   __ delayed()->nop();
  2863   // btos
  2864   __ lb(FSR, index, 0);
  2865   __ sd(FSR, SP, - wordSize);
  2867   // Rewrite bytecode to be faster
  2868   if (!is_static) {
  2869     patch_bytecode(Bytecodes::_fast_bgetfield, T3, T2);
  2871   __ b(Done);
  2872   __ delayed()->daddi(SP, SP, - wordSize);
  2875   __ bind(notByte);
  2876   __ move(AT, ztos);
  2877   __ bne(flags, AT, notBool);
  2878   __ delayed()->nop();
  2880   // ztos
  2881   __ lb(FSR, index, 0);
  2882   __ sd(FSR, SP, - wordSize);
  2884   // Rewrite bytecode to be faster
  2885   if (!is_static) {
  2886     // patch_bytecode(Bytecodes::_fast_igetfield, T3, T2);
  2887     patch_bytecode(Bytecodes::_fast_bgetfield, T3, T2);
  2889   __ b(Done);
  2890   __ delayed()->daddi(SP, SP, - wordSize);
  2893   __ bind(notBool);
  2894   __ move(AT, itos);
  2895   __ bne(flags, AT, notInt);
  2896   __ delayed()->nop();
  2898   // itos
  2899   __ lw(FSR, index, 0);
  2900   __ sd(FSR, SP, - wordSize);
  2902   // Rewrite bytecode to be faster
  2903   if (!is_static) {
  2904     // patch_bytecode(Bytecodes::_fast_igetfield, T3, T2);
  2905     patch_bytecode(Bytecodes::_fast_igetfield, T3, T2);
  2907   __ b(Done);
  2908   __ delayed()->daddi(SP, SP, - wordSize);
  2910   __ bind(notInt);
  2911   __ move(AT, atos);
  2912   __ bne(flags, AT, notObj);
  2913   __ delayed()->nop();
  2915   // atos
  2916   //add for compressedoops
  2917   __ load_heap_oop(FSR, Address(index, 0));
  2918   __ sd(FSR, SP, - wordSize);
  2920   if (!is_static) {
  2921     //patch_bytecode(Bytecodes::_fast_agetfield, T3, T2);
  2922     patch_bytecode(Bytecodes::_fast_agetfield, T3, T2);
  2924   __ b(Done);
  2925   __ delayed()->daddi(SP, SP, - wordSize);
  2927   __ bind(notObj);
  2928   __ move(AT, ctos);
  2929   __ bne(flags, AT, notChar);
  2930   __ delayed()->nop();
  2932   // ctos
  2933   __ lhu(FSR, index, 0);
  2934   __ sd(FSR, SP, - wordSize);
  2936   if (!is_static) {
  2937     patch_bytecode(Bytecodes::_fast_cgetfield, T3, T2);
  2939   __ b(Done);
  2940   __ delayed()->daddi(SP, SP, - wordSize);
  2942   __ bind(notChar);
  2943   __ move(AT, stos);
  2944   __ bne(flags, AT, notShort);
  2945   __ delayed()->nop();
  2947   // stos
  2948   __ lh(FSR, index, 0);
  2949   __ sd(FSR, SP, - wordSize);
  2951   if (!is_static) {
  2952     patch_bytecode(Bytecodes::_fast_sgetfield, T3, T2);
  2954   __ b(Done);
  2955   __ delayed()->daddi(SP, SP, - wordSize);
  2957   __ bind(notShort);
  2958   __ move(AT, ltos);
  2959   __ bne(flags, AT, notLong);
  2960   __ delayed()->nop();
  2962   // FIXME : the load/store should be atomic, we have no simple method to do this in mips32
  2963   // ltos
  2964   __ ld(FSR, index, 0 * wordSize);
  2965   __ sd(FSR, SP, -2 * wordSize);
  2966   __ sd(R0, SP, -1 * wordSize);
  2968   // Don't rewrite to _fast_lgetfield for potential volatile case.
  2969   __ b(Done);
  2970   __ delayed()->daddi(SP, SP, - 2 * wordSize);
  2972   __ bind(notLong);
  2973   __ move(AT, ftos);
  2974   __ bne(flags, AT, notFloat);
  2975   __ delayed()->nop();
  2977   // ftos
  2978   __ lwc1(FSF, index, 0);
  2979   __ sdc1(FSF, SP, - wordSize);
  2981   if (!is_static) {
  2982     patch_bytecode(Bytecodes::_fast_fgetfield, T3, T2);
  2984   __ b(Done);
  2985   __ delayed()->daddi(SP, SP, - wordSize);
  2987   __ bind(notFloat);
  2988   __ move(AT, dtos);
  2989 #ifdef ASSERT
  2990   __ bne(flags, AT, notDouble);
  2991   __ delayed()->nop();
  2992 #endif
  2994   // dtos
  2995   __ ldc1(FSF, index, 0 * wordSize);
  2996   __ sdc1(FSF, SP, - 2 * wordSize);
  2997   __ sd(R0, SP, - 1 * wordSize);
  2999   if (!is_static) {
  3000     patch_bytecode(Bytecodes::_fast_dgetfield, T3, T2);
  3003   __ daddi(SP, SP, - 2 * wordSize);
  3005 #ifdef ASSERT
  3006   __ b(Done);
  3007   __ nop();
  3008   __ bind(notDouble);
  3009   __ stop("Bad state");
  3010 #endif
  3012   __ bind(Done);
  3015     Label notVolatile;
  3016     __ beq(scratch, R0, notVolatile);
  3017     __ nop();
  3018     volatile_barrier();
  3019     __ bind(notVolatile);
  3024 void TemplateTable::getfield(int byte_no) {
  3025   getfield_or_static(byte_no, false);
  3028 void TemplateTable::getstatic(int byte_no) {
  3029   getfield_or_static(byte_no, true);
  3032 // The registers cache and index expected to be set before call.
  3033 // The function may destroy various registers, just not the cache and index registers.
  3034 void TemplateTable::jvmti_post_field_mod(Register cache, Register index, bool is_static) {
  3035   transition(vtos, vtos);
  3037   ByteSize cp_base_offset = ConstantPoolCache::base_offset();
  3039   if (JvmtiExport::can_post_field_modification()) {
  3040     // Check to see if a field modification watch has been set before
  3041     // we take the time to call into the VM.
  3042     Label L1;
  3043     //kill AT, T1, T2, T3, T9
  3044     Register tmp1 = T2;
  3045     Register tmp2 = T1;
  3046     Register tmp3 = T3;
  3047     Register tmp4 = T9;
  3048     assert_different_registers(cache, index, tmp4);
  3050     __ li(AT, JvmtiExport::get_field_modification_count_addr());
  3051     __ lw(AT, AT, 0);
  3052     __ beq(AT, R0, L1);
  3053     __ delayed()->nop();
  3055     __ get_cache_and_index_at_bcp(tmp2, tmp4, 1);
  3057     if (is_static) {
  3058       __ move(tmp1, R0);
  3059     } else {
  3060       // Life is harder. The stack holds the value on top, followed by
  3061       // the object.  We don't know the size of the value, though; it
  3062       // could be one or two words depending on its type. As a result,
  3063       // we must find the type to determine where the object is.
  3064       Label two_word, valsize_known;
  3065       __ dsll(AT, tmp4, Address::times_8);
  3066       __ dadd(AT, tmp2, AT);
  3067       __ ld(tmp3, AT, in_bytes(cp_base_offset +
  3068                                ConstantPoolCacheEntry::flags_offset()));
  3069       __ shr(tmp3, ConstantPoolCacheEntry::tos_state_shift);
  3071       // Make sure we don't need to mask ecx for tos_state_shift
  3072       // after the above shift
  3073       ConstantPoolCacheEntry::verify_tos_state_shift();
  3074       __ move(tmp1, SP);
  3075       __ move(AT, ltos);
  3076       __ beq(tmp3, AT, two_word);
  3077       __ delayed()->nop();
  3078       __ move(AT, dtos);
  3079       __ beq(tmp3, AT, two_word);
  3080       __ delayed()->nop();
  3081       __ b(valsize_known);
  3082       __ delayed()->daddi(tmp1, tmp1, Interpreter::expr_offset_in_bytes(1) );
  3084       __ bind(two_word);
  3085       __ daddi(tmp1, tmp1, Interpreter::expr_offset_in_bytes(2));
  3087       __ bind(valsize_known);
  3088       // setup object pointer
  3089       __ ld(tmp1, tmp1, 0*wordSize);
  3091     // cache entry pointer
  3092     __ daddi(tmp2, tmp2, in_bytes(cp_base_offset));
  3093     __ shl(tmp4, LogBytesPerWord);
  3094     __ daddu(tmp2, tmp2, tmp4);
  3095     // object (tos)
  3096     __ move(tmp3, SP);
  3097     // tmp1: object pointer set up above (NULL if static)
  3098     // tmp2: cache entry pointer
  3099     // tmp3: jvalue object on the stack
  3100     __ call_VM(NOREG,
  3101                CAST_FROM_FN_PTR(address,
  3102                                 InterpreterRuntime::post_field_modification),
  3103                tmp1, tmp2, tmp3);
  3104     __ get_cache_and_index_at_bcp(cache, index, 1);
  3105     __ bind(L1);
  3109 // used registers : T0, T1, T2, T3, T8
  3110 // T1 : flags
  3111 // T2 : off
  3112 // T3 : obj
  3113 // T8 : volatile bit
  3114 // see ConstantPoolCacheEntry::set_field for more info
  3115 void TemplateTable::putfield_or_static(int byte_no, bool is_static) {
  3116   transition(vtos, vtos);
  3118   const Register cache = T3;
  3119   const Register index = T0;
  3120   const Register obj   = T3;
  3121   const Register off   = T2;
  3122   const Register flags = T1;
  3123   const Register bc    = T3;
  3125   const Register scratch = T8;
  3127   resolve_cache_and_index(byte_no, cache, index, sizeof(u2));
  3128   jvmti_post_field_mod(cache, index, is_static);
  3129   load_field_cp_cache_entry(obj, cache, index, off, flags, is_static);
  3131   Label Done;
  3133     __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
  3134     __ andr(scratch, scratch, flags);
  3136     Label notVolatile;
  3137     __ beq(scratch, R0, notVolatile);
  3138     __ nop();
  3139     volatile_barrier();
  3140     __ bind(notVolatile);
  3144   Label notByte, notBool, notInt, notShort, notChar, notLong, notFloat, notObj, notDouble;
  3146   assert(btos == 0, "change code, btos != 0");
  3148   // btos
  3149   __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
  3150   __ andi(flags, flags, ConstantPoolCacheEntry::tos_state_mask);
  3151   __ bne(flags, R0, notByte);
  3152   __ delayed()->nop();
  3154   __ pop(btos);
  3155   if (!is_static) {
  3156     pop_and_check_object(obj);
  3158   __ dadd(AT, obj, off);
  3159   __ sb(FSR, AT, 0);
  3161   if (!is_static) {
  3162     patch_bytecode(Bytecodes::_fast_bputfield, bc, off, true, byte_no);
  3164   __ b(Done);
  3165   __ delayed()->nop();
  3167   // ztos
  3168   __ bind(notByte);
  3169   __ move(AT, ztos);
  3170   __ bne(flags, AT, notBool);
  3171   __ delayed()->nop();
  3173   __ pop(ztos);
  3174   if (!is_static) {
  3175     pop_and_check_object(obj);
  3177   __ dadd(AT, obj, off);
  3178   __ andi(FSR, FSR, 0x1);
  3179   __ sb(FSR, AT, 0);
  3181   if (!is_static) {
  3182     patch_bytecode(Bytecodes::_fast_zputfield, bc, off, true, byte_no);
  3184   __ b(Done);
  3185   __ delayed()->nop();
  3187   // itos
  3188   __ bind(notBool);
  3189   __ move(AT, itos);
  3190   __ bne(flags, AT, notInt);
  3191   __ delayed()->nop();
  3193   __ pop(itos);
  3194   if (!is_static) {
  3195     pop_and_check_object(obj);
  3197   __ dadd(AT, obj, off);
  3198   __ sw(FSR, AT, 0);
  3200   if (!is_static) {
  3201     patch_bytecode(Bytecodes::_fast_iputfield, bc, off, true, byte_no);
  3203   __ b(Done);
  3204   __ delayed()->nop();
  3206   // atos
  3207   __ bind(notInt);
  3208   __ move(AT, atos);
  3209   __ bne(flags, AT, notObj);
  3210   __ delayed()->nop();
  3212   __ pop(atos);
  3213   if (!is_static) {
  3214     pop_and_check_object(obj);
  3217   do_oop_store(_masm, Address(obj, off, Address::times_1, 0), FSR, _bs->kind(), false);
  3219   if (!is_static) {
  3220     patch_bytecode(Bytecodes::_fast_aputfield, bc, off, true, byte_no);
  3222   __ b(Done);
  3223   __ delayed()->nop();
  3225   // ctos
  3226   __ bind(notObj);
  3227   __ move(AT, ctos);
  3228   __ bne(flags, AT, notChar);
  3229   __ delayed()->nop();
  3231   __ pop(ctos);
  3232   if (!is_static) {
  3233     pop_and_check_object(obj);
  3235   __ dadd(AT, obj, off);
  3236   __ sh(FSR, AT, 0);
  3237   if (!is_static) {
  3238     patch_bytecode(Bytecodes::_fast_cputfield, bc, off, true, byte_no);
  3240   __ b(Done);
  3241   __ delayed()->nop();
  3243   // stos
  3244   __ bind(notChar);
  3245   __ move(AT, stos);
  3246   __ bne(flags, AT, notShort);
  3247   __ delayed()->nop();
  3249   __ pop(stos);
  3250   if (!is_static) {
  3251     pop_and_check_object(obj);
  3253   __ dadd(AT, obj, off);
  3254   __ sh(FSR, AT, 0);
  3255   if (!is_static) {
  3256     patch_bytecode(Bytecodes::_fast_sputfield, bc, off, true, byte_no);
  3258   __ b(Done);
  3259   __ delayed()->nop();
  3261   // ltos
  3262   __ bind(notShort);
  3263   __ move(AT, ltos);
  3264   __ bne(flags, AT, notLong);
  3265   __ delayed()->nop();
  3267   __ pop(ltos);
  3268   if (!is_static) {
  3269     pop_and_check_object(obj);
  3271   __ dadd(AT, obj, off);
  3272   __ sd(FSR, AT, 0);
  3273   if (!is_static) {
  3274     patch_bytecode(Bytecodes::_fast_lputfield, bc, off, true, byte_no);
  3276   __ b(Done);
  3277   __ delayed()->nop();
  3279   // ftos
  3280   __ bind(notLong);
  3281   __ move(AT, ftos);
  3282   __ bne(flags, AT, notFloat);
  3283   __ delayed()->nop();
  3285   __ pop(ftos);
  3286   if (!is_static) {
  3287     pop_and_check_object(obj);
  3289   __ dadd(AT, obj, off);
  3290   __ swc1(FSF, AT, 0);
  3291   if (!is_static) {
  3292     patch_bytecode(Bytecodes::_fast_fputfield, bc, off, true, byte_no);
  3294   __ b(Done);
  3295   __ delayed()->nop();
  3298   // dtos
  3299   __ bind(notFloat);
  3300   __ move(AT, dtos);
  3301 #ifdef ASSERT
  3302   __ bne(flags, AT, notDouble);
  3303   __ delayed()->nop();
  3304 #endif
  3306   __ pop(dtos);
  3307   if (!is_static) {
  3308     pop_and_check_object(obj);
  3310   __ dadd(AT, obj, off);
  3311   __ sdc1(FSF, AT, 0);
  3312   if (!is_static) {
  3313     patch_bytecode(Bytecodes::_fast_dputfield, bc, off, true, byte_no);
  3316 #ifdef ASSERT
  3317   __ b(Done);
  3318   __ delayed()->nop();
  3320   __ bind(notDouble);
  3321   __ stop("Bad state");
  3322 #endif
  3324   __ bind(Done);
  3327     Label notVolatile;
  3328     __ beq(scratch, R0, notVolatile);
  3329     __ nop();
  3330     volatile_barrier();
  3331     __ bind(notVolatile);
  3335 void TemplateTable::putfield(int byte_no) {
  3336   putfield_or_static(byte_no, false);
  3339 void TemplateTable::putstatic(int byte_no) {
  3340   putfield_or_static(byte_no, true);
  3343 // used registers : T1, T2, T3
  3344 // T1 : cp_entry
  3345 // T2 : obj
  3346 // T3 : value pointer
  3347 void TemplateTable::jvmti_post_fast_field_mod() {
  3348   if (JvmtiExport::can_post_field_modification()) {
  3349     // Check to see if a field modification watch has been set before
  3350     // we take the time to call into the VM.
  3351     Label L2;
  3352     //kill AT, T1, T2, T3, T9
  3353     Register tmp1 = T2;
  3354     Register tmp2 = T1;
  3355     Register tmp3 = T3;
  3356     Register tmp4 = T9;
  3357     __ li(AT, JvmtiExport::get_field_modification_count_addr());
  3358     __ lw(tmp3, AT, 0);
  3359     __ beq(tmp3, R0, L2);
  3360     __ delayed()->nop();
  3361     __ pop_ptr(tmp1);
  3362     __ verify_oop(tmp1);
  3363     __ push_ptr(tmp1);
  3364     switch (bytecode()) {          // load values into the jvalue object
  3365     case Bytecodes::_fast_aputfield: __ push_ptr(FSR); break;
  3366     case Bytecodes::_fast_bputfield: // fall through
  3367     case Bytecodes::_fast_zputfield: // fall through
  3368     case Bytecodes::_fast_sputfield: // fall through
  3369     case Bytecodes::_fast_cputfield: // fall through
  3370     case Bytecodes::_fast_iputfield: __ push_i(FSR); break;
  3371     case Bytecodes::_fast_dputfield: __ push_d(FSF); break;
  3372     case Bytecodes::_fast_fputfield: __ push_f(); break;
  3373     case Bytecodes::_fast_lputfield: __ push_l(FSR); break;
  3374       default:  ShouldNotReachHere();
  3376     __ move(tmp3, SP);
  3377     // access constant pool cache entry
  3378     __ get_cache_entry_pointer_at_bcp(tmp2, FSR, 1);
  3379     __ verify_oop(tmp1);
  3380     // tmp1: object pointer copied above
  3381     // tmp2: cache entry pointer
  3382     // tmp3: jvalue object on the stack
  3383     __ call_VM(NOREG,
  3384                CAST_FROM_FN_PTR(address,
  3385                                 InterpreterRuntime::post_field_modification),
  3386                tmp1, tmp2, tmp3);
  3388     switch (bytecode()) {             // restore tos values
  3389     case Bytecodes::_fast_aputfield: __ pop_ptr(FSR); break;
  3390     case Bytecodes::_fast_bputfield: // fall through
  3391     case Bytecodes::_fast_zputfield: // fall through
  3392     case Bytecodes::_fast_sputfield: // fall through
  3393     case Bytecodes::_fast_cputfield: // fall through
  3394     case Bytecodes::_fast_iputfield: __ pop_i(FSR); break;
  3395     case Bytecodes::_fast_dputfield: __ pop_d(); break;
  3396     case Bytecodes::_fast_fputfield: __ pop_f(); break;
  3397     case Bytecodes::_fast_lputfield: __ pop_l(FSR); break;
  3399     __ bind(L2);
  3403 // used registers : T2, T3, T1
  3404 // T2 : index & off & field address
  3405 // T3 : cache & obj
  3406 // T1 : flags
  3407 void TemplateTable::fast_storefield(TosState state) {
  3408   transition(state, vtos);
  3410   const Register scratch = T8;
  3412   ByteSize base = ConstantPoolCache::base_offset();
  3414   jvmti_post_fast_field_mod();
  3416   // access constant pool cache
  3417   __ get_cache_and_index_at_bcp(T3, T2, 1);
  3419   // test for volatile with edx but edx is tos register for lputfield.
  3420   __ dsll(AT, T2, Address::times_8);
  3421   __ dadd(AT, T3, AT);
  3422   __ ld(T1, AT, in_bytes(base + ConstantPoolCacheEntry::flags_offset()));
  3424   // replace index with field offset from cache entry
  3425   __ ld(T2, AT, in_bytes(base + ConstantPoolCacheEntry::f2_offset()));
  3427   Label Done;
  3429     __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
  3430     __ andr(scratch, scratch, T1);
  3432     Label notVolatile;
  3433     __ beq(scratch, R0, notVolatile);
  3434     __ nop();
  3435     volatile_barrier();
  3436     __ bind(notVolatile);
  3439   // Get object from stack
  3440   pop_and_check_object(T3);
  3442   if (bytecode() != Bytecodes::_fast_aputfield) {
  3443     // field address
  3444     __ dadd(T2, T3, T2);
  3447   // access field
  3448   switch (bytecode()) {
  3449     case Bytecodes::_fast_zputfield:
  3450       __ andi(FSR, FSR, 0x1);  // boolean is true if LSB is 1
  3451       // fall through to bputfield
  3452     case Bytecodes::_fast_bputfield:
  3453       __ sb(FSR, T2, 0);
  3454       break;
  3455     case Bytecodes::_fast_sputfield: // fall through
  3456     case Bytecodes::_fast_cputfield:
  3457       __ sh(FSR, T2, 0);
  3458       break;
  3459     case Bytecodes::_fast_iputfield:
  3460       __ sw(FSR, T2, 0);
  3461       break;
  3462     case Bytecodes::_fast_lputfield:
  3463       __ sd(FSR, T2, 0 * wordSize);
  3464       break;
  3465     case Bytecodes::_fast_fputfield:
  3466       __ swc1(FSF, T2, 0);
  3467       break;
  3468     case Bytecodes::_fast_dputfield:
  3469       __ sdc1(FSF, T2, 0 * wordSize);
  3470       break;
  3471     case Bytecodes::_fast_aputfield:
  3472       do_oop_store(_masm, Address(T3, T2, Address::times_1, 0), FSR, _bs->kind(), false);
  3473       break;
  3474     default:
  3475       ShouldNotReachHere();
  3479     Label notVolatile;
  3480     __ beq(scratch, R0, notVolatile);
  3481     __ nop();
  3482     volatile_barrier();
  3483     __ bind(notVolatile);
  3487 // used registers : T2, T3, T1
  3488 // T3 : cp_entry & cache
  3489 // T2 : index & offset
  3490 void TemplateTable::fast_accessfield(TosState state) {
  3491   transition(atos, state);
  3493   const Register scratch = T8;
  3495   // do the JVMTI work here to avoid disturbing the register state below
  3496   if (JvmtiExport::can_post_field_access()) {
  3497     // Check to see if a field access watch has been set before we take
  3498     // the time to call into the VM.
  3499     Label L1;
  3500     __ li(AT, (intptr_t)JvmtiExport::get_field_access_count_addr());
  3501     __ lw(T3, AT, 0);
  3502     __ beq(T3, R0, L1);
  3503     __ delayed()->nop();
  3504     // access constant pool cache entry
  3505     __ get_cache_entry_pointer_at_bcp(T3, T1, 1);
  3506     __ move(TSR, FSR);
  3507     __ verify_oop(FSR);
  3508     // FSR: object pointer copied above
  3509     // T3: cache entry pointer
  3510     __ call_VM(NOREG,
  3511                CAST_FROM_FN_PTR(address, InterpreterRuntime::post_field_access),
  3512                FSR, T3);
  3513     __ move(FSR, TSR);
  3514     __ bind(L1);
  3517   // access constant pool cache
  3518   __ get_cache_and_index_at_bcp(T3, T2, 1);
  3519   // replace index with field offset from cache entry
  3520   __ dsll(AT, T2, Address::times_8);
  3521   __ dadd(AT, T3, AT);
  3522   __ ld(T2, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
  3525     __ ld(AT, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
  3526     __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
  3527     __ andr(scratch, scratch, AT);
  3529     Label notVolatile;
  3530     __ beq(scratch, R0, notVolatile);
  3531     __ nop();
  3532     volatile_barrier();
  3533     __ bind(notVolatile);
  3536   // eax: object
  3537   __ verify_oop(FSR);
  3538   __ null_check(FSR);
  3539   // field addresses
  3540   __ dadd(FSR, FSR, T2);
  3542   // access field
  3543   switch (bytecode()) {
  3544     case Bytecodes::_fast_bgetfield:
  3545       __ lb(FSR, FSR, 0);
  3546       break;
  3547     case Bytecodes::_fast_sgetfield:
  3548       __ lh(FSR, FSR, 0);
  3549       break;
  3550     case Bytecodes::_fast_cgetfield:
  3551       __ lhu(FSR, FSR, 0);
  3552       break;
  3553     case Bytecodes::_fast_igetfield:
  3554       __ lw(FSR, FSR, 0);
  3555       break;
  3556     case Bytecodes::_fast_lgetfield:
  3557       __ stop("should not be rewritten");
  3558       break;
  3559     case Bytecodes::_fast_fgetfield:
  3560       __ lwc1(FSF, FSR, 0);
  3561       break;
  3562     case Bytecodes::_fast_dgetfield:
  3563       __ ldc1(FSF, FSR, 0);
  3564       break;
  3565     case Bytecodes::_fast_agetfield:
  3566       //add for compressedoops
  3567       __ load_heap_oop(FSR, Address(FSR, 0));
  3568       __ verify_oop(FSR);
  3569       break;
  3570     default:
  3571       ShouldNotReachHere();
  3575     Label notVolatile;
  3576     __ beq(scratch, R0, notVolatile);
  3577     __ nop();
  3578     volatile_barrier();
  3579     __ bind(notVolatile);
  3583 // generator for _fast_iaccess_0, _fast_aaccess_0, _fast_faccess_0
  3584 // used registers : T1, T2, T3, T1
  3585 // T1 : obj & field address
  3586 // T2 : off
  3587 // T3 : cache
  3588 // T1 : index
  3589 void TemplateTable::fast_xaccess(TosState state) {
  3590   transition(vtos, state);
  3592   const Register scratch = T8;
  3594   // get receiver
  3595   __ ld(T1, aaddress(0));
  3596   // access constant pool cache
  3597   __ get_cache_and_index_at_bcp(T3, T2, 2);
  3598   __ dsll(AT, T2, Address::times_8);
  3599   __ dadd(AT, T3, AT);
  3600   __ ld(T2, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::f2_offset()));
  3603     __ ld(AT, AT, in_bytes(ConstantPoolCache::base_offset() + ConstantPoolCacheEntry::flags_offset()));
  3604     __ move(scratch, 1 << ConstantPoolCacheEntry::is_volatile_shift);
  3605     __ andr(scratch, scratch, AT);
  3607     Label notVolatile;
  3608     __ beq(scratch, R0, notVolatile);
  3609     __ nop();
  3610     volatile_barrier();
  3611     __ bind(notVolatile);
  3614   // make sure exception is reported in correct bcp range (getfield is
  3615   // next instruction)
  3616   __ daddi(BCP, BCP, 1);
  3617   __ null_check(T1);
  3618   __ dadd(T1, T1, T2);
  3620   if (state == itos) {
  3621     __ lw(FSR, T1, 0);
  3622   } else if (state == atos) {
  3623     __ load_heap_oop(FSR, Address(T1, 0));
  3624     __ verify_oop(FSR);
  3625   } else if (state == ftos) {
  3626     __ lwc1(FSF, T1, 0);
  3627   } else {
  3628     ShouldNotReachHere();
  3630   __ daddi(BCP, BCP, -1);
  3633     Label notVolatile;
  3634     __ beq(scratch, R0, notVolatile);
  3635     __ nop();
  3636     volatile_barrier();
  3637     __ bind(notVolatile);
  3643 //-----------------------------------------------------------------------------
  3644 // Calls
  3646 void TemplateTable::count_calls(Register method, Register temp) {
  3647   // implemented elsewhere
  3648   ShouldNotReachHere();
  3651 // method, index, recv, flags: T1, T2, T3, T1
  3652 // byte_no = 2 for _invokevirtual, 1 else
  3653 // T0 : return address
  3654 // get the method & index of the invoke, and push the return address of
  3655 // the invoke(first word in the frame)
  3656 // this address is where the return code jmp to.
  3657 // NOTE : this method will set T3&T1 as recv&flags
  3658 void TemplateTable::prepare_invoke(int byte_no,
  3659                                    Register method,  // linked method (or i-klass)
  3660                                    Register index,   // itable index, MethodType, etc.
  3661                                    Register recv,    // if caller wants to see it
  3662                                    Register flags    // if caller wants to test it
  3663                                    ) {
  3664   // determine flags
  3665   const Bytecodes::Code code = bytecode();
  3666   const bool is_invokeinterface  = code == Bytecodes::_invokeinterface;
  3667   const bool is_invokedynamic    = code == Bytecodes::_invokedynamic;
  3668   const bool is_invokehandle     = code == Bytecodes::_invokehandle;
  3669   const bool is_invokevirtual    = code == Bytecodes::_invokevirtual;
  3670   const bool is_invokespecial    = code == Bytecodes::_invokespecial;
  3671   const bool load_receiver       = (recv  != noreg);
  3672   const bool save_flags          = (flags != noreg);
  3673   assert(load_receiver == (code != Bytecodes::_invokestatic && code != Bytecodes::_invokedynamic),"");
  3674   assert(save_flags    == (is_invokeinterface || is_invokevirtual), "need flags for vfinal");
  3675   assert(flags == noreg || flags == T1, "error flags reg.");
  3676   assert(recv  == noreg || recv  == T3, "error recv reg.");
  3678   // setup registers & access constant pool cache
  3679   if(recv == noreg) recv  = T3;
  3680   if(flags == noreg) flags  = T1;
  3681   assert_different_registers(method, index, recv, flags);
  3683   // save 'interpreter return address'
  3684   __ save_bcp();
  3686   load_invoke_cp_cache_entry(byte_no, method, index, flags, is_invokevirtual, false, is_invokedynamic);
  3688   if (is_invokedynamic || is_invokehandle) {
  3689    Label L_no_push;
  3690      __ move(AT, (1 << ConstantPoolCacheEntry::has_appendix_shift));
  3691      __ andr(AT, AT, flags);
  3692      __ beq(AT, R0, L_no_push);
  3693      __ delayed()->nop();
  3694      // Push the appendix as a trailing parameter.
  3695      // This must be done before we get the receiver,
  3696      // since the parameter_size includes it.
  3697      Register tmp = SSR;
  3698      __ push(tmp);
  3699      __ move(tmp, index);
  3700      assert(ConstantPoolCacheEntry::_indy_resolved_references_appendix_offset == 0, "appendix expected at index+0");
  3701      __ load_resolved_reference_at_index(index, tmp);
  3702      __ pop(tmp);
  3703      __ push(index);  // push appendix (MethodType, CallSite, etc.)
  3704      __ bind(L_no_push);
  3707   // load receiver if needed (after appendix is pushed so parameter size is correct)
  3708   // Note: no return address pushed yet
  3709   if (load_receiver) {
  3710     __ move(AT, ConstantPoolCacheEntry::parameter_size_mask);
  3711     __ andr(recv, flags, AT);
  3712     // 2014/07/31 Fu: Since we won't push RA on stack, no_return_pc_pushed_yet should be 0.
  3713     const int no_return_pc_pushed_yet = 0;  // argument slot correction before we push return address
  3714     const int receiver_is_at_end      = -1;  // back off one slot to get receiver
  3715     Address recv_addr = __ argument_address(recv, no_return_pc_pushed_yet + receiver_is_at_end);
  3716     __ ld(recv, recv_addr);
  3717     __ verify_oop(recv);
  3719   if(save_flags) {
  3720     __ move(BCP, flags);
  3723   // compute return type
  3724   __ dsrl(flags, flags, ConstantPoolCacheEntry::tos_state_shift);
  3725   __ andi(flags, flags, 0xf);
  3727   // Make sure we don't need to mask flags for tos_state_shift after the above shift
  3728   ConstantPoolCacheEntry::verify_tos_state_shift();
  3729   // load return address
  3731     const address table = (address) Interpreter::invoke_return_entry_table_for(code);
  3732     __ li(AT, (long)table);
  3733     __ dsll(flags, flags, LogBytesPerWord);
  3734     __ dadd(AT, AT, flags);
  3735     __ ld(RA, AT, 0);
  3738   if (save_flags) {
  3739     __ move(flags, BCP);
  3740     __ restore_bcp();
  3744 // used registers : T0, T3, T1, T2
  3745 // T3 : recv, this two register using convention is by prepare_invoke
  3746 // T1 : flags, klass
  3747 // Rmethod : method, index must be Rmethod
  3748 void TemplateTable::invokevirtual_helper(Register index,
  3749                                          Register recv,
  3750                                          Register flags) {
  3752   assert_different_registers(index, recv, flags, T2);
  3754   // Test for an invoke of a final method
  3755   Label notFinal;
  3756   __ move(AT, (1 << ConstantPoolCacheEntry::is_vfinal_shift));
  3757   __ andr(AT, flags, AT);
  3758   __ beq(AT, R0, notFinal);
  3759   __ delayed()->nop();
  3761   Register method = index;  // method must be Rmethod
  3762   assert(method == Rmethod, "methodOop must be Rmethod for interpreter calling convention");
  3764   // do the call - the index is actually the method to call
  3765   // the index is indeed methodOop, for this is vfinal,
  3766   // see ConstantPoolCacheEntry::set_method for more info
  3768   __ verify_oop(method);
  3770   // It's final, need a null check here!
  3771   __ null_check(recv);
  3773   // profile this call
  3774   __ profile_final_call(T2);
  3776   // 2014/11/24 Fu
  3777   // T2: tmp, used for mdp
  3778   // method: callee
  3779   // T9: tmp
  3780   // is_virtual: true
  3781   __ profile_arguments_type(T2, method, T9, true);
  3783   __ jump_from_interpreted(method, T2);
  3785   __ bind(notFinal);
  3787   // get receiver klass
  3788   __ null_check(recv, oopDesc::klass_offset_in_bytes());
  3789   __ load_klass(T2, recv);
  3790   __ verify_oop(T2);
  3792   // profile this call
  3793   __ profile_virtual_call(T2, T0, T1);
  3795   // get target methodOop & entry point
  3796   const int base = InstanceKlass::vtable_start_offset() * wordSize;
  3797   assert(vtableEntry::size() * wordSize == wordSize, "adjust the scaling in the code below");
  3798   __ dsll(AT, index, Address::times_ptr);
  3799   // T2: receiver
  3800   __ dadd(AT, T2, AT);
  3801   //this is a ualign read
  3802   __ ld(method, AT, base + vtableEntry::method_offset_in_bytes());
  3803   __ profile_arguments_type(T2, method, T9, true);
  3804   __ jump_from_interpreted(method, T2);
  3808 void TemplateTable::invokevirtual(int byte_no) {
  3809   transition(vtos, vtos);
  3810   assert(byte_no == f2_byte, "use this argument");
  3811   prepare_invoke(byte_no, Rmethod, NOREG, T3, T1);
  3812   // now recv & flags in T3, T1
  3813   invokevirtual_helper(Rmethod, T3, T1);
  3816 // T9 : entry
  3817 // Rmethod : method
  3818 void TemplateTable::invokespecial(int byte_no) {
  3819   transition(vtos, vtos);
  3820   assert(byte_no == f1_byte, "use this argument");
  3821   prepare_invoke(byte_no, Rmethod, NOREG, T3);
  3822   // now recv & flags in T3, T1
  3823   __ verify_oop(T3);
  3824   __ null_check(T3);
  3825   __ profile_call(T9);
  3827   // 2014/11/24 Fu
  3828   // T8: tmp, used for mdp
  3829   // Rmethod: callee
  3830   // T9: tmp
  3831   // is_virtual: false
  3832   __ profile_arguments_type(T8, Rmethod, T9, false);
  3834   __ jump_from_interpreted(Rmethod, T9);
  3835   __ move(T0, T3);//aoqi ?
  3838 void TemplateTable::invokestatic(int byte_no) {
  3839   transition(vtos, vtos);
  3840   assert(byte_no == f1_byte, "use this argument");
  3841   prepare_invoke(byte_no, Rmethod, NOREG);
  3842   __ verify_oop(Rmethod);
  3844   __ profile_call(T9);
  3846   // 2014/11/24 Fu
  3847   // T8: tmp, used for mdp
  3848   // Rmethod: callee
  3849   // T9: tmp
  3850   // is_virtual: false
  3851   __ profile_arguments_type(T8, Rmethod, T9, false);
  3853   __ jump_from_interpreted(Rmethod, T9);
  3856 // i have no idea what to do here, now. for future change. FIXME.
  3857 void TemplateTable::fast_invokevfinal(int byte_no) {
  3858   transition(vtos, vtos);
  3859   assert(byte_no == f2_byte, "use this argument");
  3860   __ stop("fast_invokevfinal not used on mips64");
  3863 // used registers : T0, T1, T2, T3, T1, A7
  3864 // T0 : itable, vtable, entry
  3865 // T1 : interface
  3866 // T3 : receiver
  3867 // T1 : flags, klass
  3868 // Rmethod : index, method, this is required by interpreter_entry
  3869 void TemplateTable::invokeinterface(int byte_no) {
  3870   transition(vtos, vtos);
  3871   //this method will use T1-T4 and T0
  3872   assert(byte_no == f1_byte, "use this argument");
  3873   prepare_invoke(byte_no, T2, Rmethod, T3, T1);
  3874   // T2: Interface
  3875   // Rmethod: index
  3876   // T3: receiver
  3877   // T1: flags
  3879   // Special case of invokeinterface called for virtual method of
  3880   // java.lang.Object.  See cpCacheOop.cpp for details.
  3881   // This code isn't produced by javac, but could be produced by
  3882   // another compliant java compiler.
  3883   Label notMethod;
  3884   __ move(AT, (1 << ConstantPoolCacheEntry::is_forced_virtual_shift));
  3885   __ andr(AT, T1, AT);
  3886   __ beq(AT, R0, notMethod);
  3887   __ delayed()->nop();
  3889   invokevirtual_helper(Rmethod, T3, T1);
  3890   __ bind(notMethod);
  3891   // Get receiver klass into T1 - also a null check
  3892   //add for compressedoops
  3893   __ load_klass(T1, T3);
  3894   __ verify_oop(T1);
  3896   // profile this call
  3897   __ profile_virtual_call(T1, T0, FSR);
  3899   // Compute start of first itableOffsetEntry (which is at the end of the vtable)
  3900   // TODO: x86 add a new method lookup_interface_method  // LEE
  3901   const int base = InstanceKlass::vtable_start_offset() * wordSize;
  3902   assert(vtableEntry::size() * wordSize == 8, "adjust the scaling in the code below");
  3903   __ lw(AT, T1, InstanceKlass::vtable_length_offset() * wordSize);
  3904   __ dsll(AT, AT, Address::times_8);
  3905   __ dadd(T0, T1, AT);
  3906   __ daddi(T0, T0, base);
  3907   if (HeapWordsPerLong > 1) {
  3908     // Round up to align_object_offset boundary
  3909     __ round_to(T0, BytesPerLong);
  3911   // now T0 is the begin of the itable
  3913   Label entry, search, interface_ok;
  3915   ///__ jmp(entry);
  3916   __ b(entry);
  3917   __ delayed()->nop();
  3919   __ bind(search);
  3920   __ increment(T0, itableOffsetEntry::size() * wordSize);
  3922   __ bind(entry);
  3924   // Check that the entry is non-null.  A null entry means that the receiver
  3925   // class doesn't implement the interface, and wasn't the same as the
  3926   // receiver class checked when the interface was resolved.
  3927   __ ld(AT, T0, itableOffsetEntry::interface_offset_in_bytes());
  3928   __ bne(AT, R0, interface_ok);
  3929   __ delayed()->nop();
  3930   // throw exception
  3931   // the call_VM checks for exception, so we should never return here.
  3933   //__ pop();//FIXME here,
  3934   // pop return address (pushed by prepare_invoke).
  3935   // no need now, we just save the value in RA now
  3937   __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_IncompatibleClassChangeError));
  3938   __ should_not_reach_here();
  3940   __ bind(interface_ok);
  3941   //NOTICE here, no pop as x86 do
  3942   __ bne(AT, T2, search);
  3943   __ delayed()->nop();
  3945   // now we get vtable of the interface
  3946   __ ld(T0, T0, itableOffsetEntry::offset_offset_in_bytes());
  3947   __ daddu(T0, T1, T0);
  3948   assert(itableMethodEntry::size() * wordSize == 8, "adjust the scaling in the code below");
  3949   __ dsll(AT, Rmethod, Address::times_8);
  3950   __ daddu(AT, T0, AT);
  3951   // now we get the method
  3952   __ ld(Rmethod, AT, 0);
  3953   // Rnext: methodOop to call
  3954   // T3: receiver
  3955   // Check for abstract method error
  3956   // Note: This should be done more efficiently via a throw_abstract_method_error
  3957   //       interpreter entry point and a conditional jump to it in case of a null
  3958   //       method.
  3960     Label L;
  3961     __ bne(Rmethod, R0, L);
  3962     __ delayed()->nop();
  3964     // throw exception
  3965     // note: must restore interpreter registers to canonical
  3966     //       state for exception handling to work correctly!
  3967     ///__ popl(ebx);          // pop return address (pushed by prepare_invoke)
  3968     //__ restore_bcp();      // esi must be correct for exception handler
  3969     //(was destroyed)
  3970     //__ restore_locals();   // make sure locals pointer
  3971     //is correct as well (was destroyed)
  3972     ///__ call_VM(noreg, CAST_FROM_FN_PTR(address,
  3973     //InterpreterRuntime::throw_AbstractMethodError));
  3974     __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::throw_AbstractMethodError));
  3975     // the call_VM checks for exception, so we should never return here.
  3976     __ should_not_reach_here();
  3977     __ bind(L);
  3980   // 2014/11/24 Fu
  3981   // T8: tmp, used for mdp
  3982   // Rmethod: callee
  3983   // T9: tmp
  3984   // is_virtual: true
  3985   __ profile_arguments_type(T8, Rmethod, T9, true);
  3987   __ jump_from_interpreted(Rmethod, T9);
  3991 void TemplateTable::invokehandle(int byte_no) {
  3992   transition(vtos, vtos);
  3993   assert(byte_no == f1_byte, "use this argument");
  3994   const Register T2_method = Rmethod;
  3995   const Register FSR_mtype  = FSR;
  3996   const Register T3_recv   = T3;
  3998   if (!EnableInvokeDynamic) {
  3999      // rewriter does not generate this bytecode
  4000      __ should_not_reach_here();
  4001      return;
  4004    prepare_invoke(byte_no, T2_method, FSR_mtype, T3_recv);
  4005    //??__ verify_method_ptr(T2_method);
  4006    __ verify_oop(T3_recv);
  4007    __ null_check(T3_recv);
  4009    // rax: MethodType object (from cpool->resolved_references[f1], if necessary)
  4010    // rbx: MH.invokeExact_MT method (from f2)
  4012    // Note:  rax_mtype is already pushed (if necessary) by prepare_invoke
  4014    // FIXME: profile the LambdaForm also
  4015    __ profile_final_call(T9);
  4017    // 2014/11/24 Fu
  4018    // T8: tmp, used for mdp
  4019    // T2_method: callee
  4020    // T9: tmp
  4021    // is_virtual: true
  4022    __ profile_arguments_type(T8, T2_method, T9, true);
  4024   __ jump_from_interpreted(T2_method, T9);
  4027  void TemplateTable::invokedynamic(int byte_no) {
  4028    transition(vtos, vtos);
  4029    assert(byte_no == f1_byte, "use this argument");
  4031    if (!EnableInvokeDynamic) {
  4032      // We should not encounter this bytecode if !EnableInvokeDynamic.
  4033      // The verifier will stop it.  However, if we get past the verifier,
  4034      // this will stop the thread in a reasonable way, without crashing the JVM.
  4035      __ call_VM(noreg, CAST_FROM_FN_PTR(address,
  4036                       InterpreterRuntime::throw_IncompatibleClassChangeError));
  4037      // the call_VM checks for exception, so we should never return here.
  4038      __ should_not_reach_here();
  4039      return;
  4042    //const Register Rmethod   = T2;
  4043    const Register T2_callsite = T2;
  4045    prepare_invoke(byte_no, Rmethod, T2_callsite);
  4047    // rax: CallSite object (from cpool->resolved_references[f1])
  4048    // rbx: MH.linkToCallSite method (from f2)
  4050    // Note:  rax_callsite is already pushed by prepare_invoke
  4051    // %%% should make a type profile for any invokedynamic that takes a ref argument
  4052    // profile this call
  4053    __ profile_call(T9);
  4055    // 2014/11/24 Fu
  4056    // T8: tmp, used for mdp
  4057    // Rmethod: callee
  4058    // T9: tmp
  4059    // is_virtual: false
  4060    __ profile_arguments_type(T8, Rmethod, T9, false);
  4062    __ verify_oop(T2_callsite);
  4064    __ jump_from_interpreted(Rmethod, T9);
  4067 //-----------------------------------------------------------------------------
  4068 // Allocation
  4069 // T1 : tags & buffer end & thread
  4070 // T2 : object end
  4071 // T3 : klass
  4072 // T1 : object size
  4073 // A1 : cpool
  4074 // A2 : cp index
  4075 // return object in FSR
  4076 void TemplateTable::_new() {
  4077   transition(vtos, atos);
  4078   __ get_unsigned_2_byte_index_at_bcp(A2, 1);
  4080   Label slow_case;
  4081   Label done;
  4082   Label initialize_header;
  4083   Label initialize_object; // including clearing the fields
  4084   Label allocate_shared;
  4086   // get InstanceKlass in T3
  4087   __ get_cpool_and_tags(A1, T1);
  4089   __ dsll(AT, A2, Address::times_8);
  4090   if (UseLoongsonISA && Assembler::is_simm(sizeof(ConstantPool), 8)) {
  4091     __ gsldx(T3, A1, AT, sizeof(ConstantPool));
  4092   } else {
  4093     __ dadd(AT, A1, AT);
  4094     __ ld(T3, AT, sizeof(ConstantPool));
  4097   // make sure the class we're about to instantiate has been resolved.
  4098   // Note: slow_case does a pop of stack, which is why we loaded class/pushed above
  4099   const int tags_offset = Array<u1>::base_offset_in_bytes();
  4100   if (UseLoongsonISA && Assembler::is_simm(tags_offset, 8)) {
  4101     __ gslbx(AT, T1, A2, tags_offset);
  4102   } else {
  4103     __ dadd(T1, T1, A2);
  4104     __ lb(AT, T1, tags_offset);
  4106   __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
  4107   __ bne(AT, R0, slow_case);
  4108   //__ delayed()->nop();
  4111   // make sure klass is initialized & doesn't have finalizer
  4112   // make sure klass is fully initialized
  4113   __ lhu(T1, T3, in_bytes(InstanceKlass::init_state_offset()));
  4114   __ daddiu(AT, T1, - (int)InstanceKlass::fully_initialized);
  4115   __ bne(AT, R0, slow_case);
  4116   //__ delayed()->nop();
  4118   // has_finalizer
  4119   __ lw(T0, T3, in_bytes(Klass::layout_helper_offset()) );
  4120   __ andi(AT, T0, Klass::_lh_instance_slow_path_bit);
  4121   __ bne(AT, R0, slow_case);
  4122   //__ delayed()->nop();
  4124   // Allocate the instance
  4125   // 1) Try to allocate in the TLAB
  4126   // 2) if fail and the object is large allocate in the shared Eden
  4127   // 3) if the above fails (or is not applicable), go to a slow case
  4128   // (creates a new TLAB, etc.)
  4130   const bool allow_shared_alloc =
  4131     Universe::heap()->supports_inline_contig_alloc() && !CMSIncrementalMode;
  4133   if (UseTLAB) {
  4134 #ifndef OPT_THREAD
  4135     const Register thread = T8;
  4136     __ get_thread(thread);
  4137 #else
  4138     const Register thread = TREG;
  4139 #endif
  4140     // get tlab_top
  4141     __ ld(FSR, thread, in_bytes(JavaThread::tlab_top_offset()));
  4142     // get tlab_end
  4143     __ ld(AT, thread, in_bytes(JavaThread::tlab_end_offset()));
  4144     __ dadd(T2, FSR, T0);
  4145     __ slt(AT, AT, T2);
  4146     __ bne(AT, R0, allow_shared_alloc ? allocate_shared : slow_case);
  4147     __ delayed()->nop();
  4148     __ sd(T2, thread, in_bytes(JavaThread::tlab_top_offset()));
  4150     if (ZeroTLAB) {
  4151       // the fields have been already cleared
  4152       __ beq(R0, R0, initialize_header);
  4153     } else {
  4154       // initialize both the header and fields
  4155       __ beq(R0, R0, initialize_object);
  4157     __ delayed()->nop();
  4160   // Allocation in the shared Eden , if allowed
  4161   // T0 : instance size in words
  4162   if(allow_shared_alloc){
  4163     __ bind(allocate_shared);
  4165     Label retry;
  4166     Address heap_top(T1);
  4167     __ set64(T1, (long)Universe::heap()->top_addr());
  4168     __ ld(FSR, heap_top);
  4170     __ bind(retry);
  4171     __ set64(AT, (long)Universe::heap()->end_addr());
  4172     __ ld(AT, AT, 0);
  4173     __ dadd(T2, FSR, T0);
  4174     __ slt(AT, AT, T2);
  4175     __ bne(AT, R0, slow_case);
  4176     __ delayed()->nop();
  4178     // Compare FSR with the top addr, and if still equal, store the new
  4179     // top addr in ebx at the address of the top addr pointer. Sets ZF if was
  4180     // equal, and clears it otherwise. Use lock prefix for atomicity on MPs.
  4181     //
  4182     // FSR: object begin
  4183     // T2: object end
  4184     // T0: instance size in words
  4186     // if someone beat us on the allocation, try again, otherwise continue
  4187     __ cmpxchg(T2, heap_top, FSR);
  4188     __ beq(AT, R0, retry);
  4189     __ delayed()->nop();
  4192   if (UseTLAB || Universe::heap()->supports_inline_contig_alloc()) {
  4193     // The object is initialized before the header.  If the object size is
  4194     // zero, go directly to the header initialization.
  4195     __ bind(initialize_object);
  4196     __ set64(AT, - sizeof(oopDesc));
  4197     __ daddu(T0, T0, AT);
  4198     __ beq(T0, R0, initialize_header);
  4199     __ delayed()->nop();
  4201     // initialize remaining object fields: T0 is a multiple of 2
  4203       Label loop;
  4204       __ dadd(T1, FSR, T0);
  4205       __ daddi(T1, T1, -oopSize);
  4207       __ bind(loop);
  4208       __ sd(R0, T1, sizeof(oopDesc) + 0 * oopSize);
  4209       __ bne(T1, FSR, loop); //dont clear header
  4210       __ delayed()->daddi(T1, T1, -oopSize);
  4213     //klass in T3,
  4214     // initialize object header only.
  4215     __ bind(initialize_header);
  4216     if (UseBiasedLocking) {
  4217       __ ld(AT, T3, in_bytes(Klass::prototype_header_offset()));
  4218       __ sd(AT, FSR, oopDesc::mark_offset_in_bytes ());
  4219     } else {
  4220       __ set64(AT, (long)markOopDesc::prototype());
  4221       __ sd(AT, FSR, oopDesc::mark_offset_in_bytes());
  4224     __ store_klass_gap(FSR, R0);
  4225     __ store_klass(FSR, T3);
  4228       SkipIfEqual skip_if(_masm, &DTraceAllocProbes, 0);
  4229       // Trigger dtrace event for fastpath
  4230       __ push(atos);
  4231       __ call_VM_leaf(
  4232            CAST_FROM_FN_PTR(address, SharedRuntime::dtrace_object_alloc), FSR);
  4233       __ pop(atos);
  4236     __ b(done);
  4237     __ delayed()->nop();
  4240   // slow case
  4241   __ bind(slow_case);
  4242   call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::_new), A1, A2);
  4244   // continue
  4245   __ bind(done);
  4246   __ sync();
  4249 void TemplateTable::newarray() {
  4250   transition(itos, atos);
  4251   __ lbu(A1, at_bcp(1));
  4252   //type, count
  4253   call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::newarray), A1, FSR);
  4254   __ sync();
  4257 void TemplateTable::anewarray() {
  4258   transition(itos, atos);
  4259   __ get_2_byte_integer_at_bcp(A2, AT, 1);
  4260   __ huswap(A2);
  4261   __ get_constant_pool(A1);
  4262   // cp, index, count
  4263   call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::anewarray), A1, A2, FSR);
  4264   __ sync();
  4267 void TemplateTable::arraylength() {
  4268   transition(atos, itos);
  4269   __ null_check(FSR, arrayOopDesc::length_offset_in_bytes());
  4270   __ lw(FSR, FSR, arrayOopDesc::length_offset_in_bytes());
  4273 // i use T2 as ebx, T3 as ecx, T1 as edx
  4274 // when invoke gen_subtype_check, super in T3, sub in T2, object in FSR(it's always)
  4275 // T2 : sub klass
  4276 // T3 : cpool
  4277 // T3 : super klass
  4278 void TemplateTable::checkcast() {
  4279   transition(atos, atos);
  4280   Label done, is_null, ok_is_subtype, quicked, resolved;
  4281   __ beq(FSR, R0, is_null);
  4282   __ delayed()->nop();
  4284   // Get cpool & tags index
  4285   __ get_cpool_and_tags(T3, T1);
  4286   __ get_2_byte_integer_at_bcp(T2, AT, 1);
  4287   __ huswap(T2);
  4289   // See if bytecode has already been quicked
  4290   __ dadd(AT, T1, T2);
  4291   __ lb(AT, AT, Array<u1>::base_offset_in_bytes());
  4292   __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
  4293   __ beq(AT, R0, quicked);
  4294   __ delayed()->nop();
  4296   /* 2012/6/2 Jin: In InterpreterRuntime::quicken_io_cc, lots of new classes may be loaded.
  4297    *  Then, GC will move the object in V0 to another places in heap.
  4298    *  Therefore, We should never save such an object in register.
  4299    *  Instead, we should save it in the stack. It can be modified automatically by the GC thread.
  4300    *  After GC, the object address in FSR is changed to a new place.
  4301    */
  4302   __ push(atos);
  4303   const Register thread = TREG;
  4304 #ifndef OPT_THREAD
  4305   __ get_thread(thread);
  4306 #endif
  4307   call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
  4308   __ get_vm_result_2(T3, thread);
  4309   __ pop_ptr(FSR);
  4310   __ b(resolved);
  4311   __ delayed()->nop();
  4313   // klass already in cp, get superklass in T3
  4314   __ bind(quicked);
  4315   __ dsll(AT, T2, Address::times_8);
  4316   __ dadd(AT, T3, AT);
  4317   __ ld(T3, AT, sizeof(ConstantPool));
  4319   __ bind(resolved);
  4321   // get subklass in T2
  4322   //add for compressedoops
  4323   __ load_klass(T2, FSR);
  4324   // Superklass in T3.  Subklass in T2.
  4325   __ gen_subtype_check(T3, T2, ok_is_subtype);
  4327   // Come here on failure
  4328   // object is at FSR
  4329   __ jmp(Interpreter::_throw_ClassCastException_entry);
  4330   __ delayed()->nop();
  4332   // Come here on success
  4333   __ bind(ok_is_subtype);
  4335   // Collect counts on whether this check-cast sees NULLs a lot or not.
  4336   if (ProfileInterpreter) {
  4337     __ b(done);
  4338     __ delayed()->nop();
  4339     __ bind(is_null);
  4340     __ profile_null_seen(T3);
  4341   } else {
  4342     __ bind(is_null);
  4344   __ bind(done);
  4347 // i use T3 as cpool, T1 as tags, T2 as index
  4348 // object always in FSR, superklass in T3, subklass in T2
  4349 void TemplateTable::instanceof() {
  4350   transition(atos, itos);
  4351   Label done, is_null, ok_is_subtype, quicked, resolved;
  4353   __ beq(FSR, R0, is_null);
  4354   __ delayed()->nop();
  4356   // Get cpool & tags index
  4357   __ get_cpool_and_tags(T3, T1);
  4358   // get index
  4359   __ get_2_byte_integer_at_bcp(T2, AT, 1);
  4360   __ hswap(T2);
  4362   // See if bytecode has already been quicked
  4363   // quicked
  4364   __ daddu(AT, T1, T2);
  4365   __ lb(AT, AT, Array<u1>::base_offset_in_bytes());
  4366   __ daddiu(AT, AT, - (int)JVM_CONSTANT_Class);
  4367   __ beq(AT, R0, quicked);
  4368   __ delayed()->nop();
  4370   __ push(atos);
  4371   const Register thread = TREG;
  4372 #ifndef OPT_THREAD
  4373   __ get_thread(thread);
  4374 #endif
  4375   call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::quicken_io_cc));
  4376   __ get_vm_result_2(T3, thread);
  4377   __ pop_ptr(FSR);
  4378   __ b(resolved);
  4379   __ delayed()->nop();
  4381   // get superklass in T3, subklass in T2
  4382   __ bind(quicked);
  4383   __ dsll(AT, T2, Address::times_8);
  4384   __ daddu(AT, T3, AT);
  4385   __ ld(T3, AT, sizeof(ConstantPool));
  4387   __ bind(resolved);
  4388   // get subklass in T2
  4389   //add for compressedoops
  4390   __ load_klass(T2, FSR);
  4392   // Superklass in T3.  Subklass in T2.
  4393   __ gen_subtype_check(T3, T2, ok_is_subtype);
  4394   // Come here on failure
  4395   __ b(done);
  4396   __ delayed(); __ move(FSR, R0);
  4398   // Come here on success
  4399   __ bind(ok_is_subtype);
  4400   __ move(FSR, 1);
  4402   // Collect counts on whether this test sees NULLs a lot or not.
  4403   if (ProfileInterpreter) {
  4404     __ beq(R0, R0, done);
  4405     __ nop();
  4406     __ bind(is_null);
  4407     __ profile_null_seen(T3);
  4408   } else {
  4409     __ bind(is_null);   // same as 'done'
  4411   __ bind(done);
  4412   // FSR = 0: obj == NULL or  obj is not an instanceof the specified klass
  4413   // FSR = 1: obj != NULL and obj is     an instanceof the specified klass
  4416 //--------------------------------------------------------
  4417 //--------------------------------------------
  4418 // Breakpoints
  4419 void TemplateTable::_breakpoint() {
  4420   // Note: We get here even if we are single stepping..
  4421   // jbug inists on setting breakpoints at every bytecode
  4422   // even if we are in single step mode.
  4424   transition(vtos, vtos);
  4426   // get the unpatched byte code
  4427   __ get_method(A1);
  4428   __ call_VM(NOREG,
  4429              CAST_FROM_FN_PTR(address,
  4430                               InterpreterRuntime::get_original_bytecode_at),
  4431              A1, BCP);
  4432   __ move(Rnext, V0); // Jin: Rnext will be used in dispatch_only_normal
  4434   // post the breakpoint event
  4435   __ get_method(A1);
  4436   __ call_VM(NOREG, CAST_FROM_FN_PTR(address, InterpreterRuntime::_breakpoint), A1, BCP);
  4438   // complete the execution of original bytecode
  4439   __ dispatch_only_normal(vtos);
  4442 //-----------------------------------------------------------------------------
  4443 // Exceptions
  4445 void TemplateTable::athrow() {
  4446   transition(atos, vtos);
  4447   __ null_check(FSR);
  4448   __ jmp(Interpreter::throw_exception_entry());
  4449   __ delayed()->nop();
  4452 //-----------------------------------------------------------------------------
  4453 // Synchronization
  4454 //
  4455 // Note: monitorenter & exit are symmetric routines; which is reflected
  4456 //       in the assembly code structure as well
  4457 //
  4458 // Stack layout:
  4459 //
  4460 // [expressions  ] <--- SP               = expression stack top
  4461 // ..
  4462 // [expressions  ]
  4463 // [monitor entry] <--- monitor block top = expression stack bot
  4464 // ..
  4465 // [monitor entry]
  4466 // [frame data   ] <--- monitor block bot
  4467 // ...
  4468 // [return addr  ] <--- FP
  4470 // we use T2 as monitor entry pointer, T3 as monitor top pointer, c_rarg0 as free slot pointer
  4471 // object always in FSR
  4472 void TemplateTable::monitorenter() {
  4473   transition(atos, vtos);
  4475   // check for NULL object
  4476   __ null_check(FSR);
  4478   const Address monitor_block_top(FP, frame::interpreter_frame_monitor_block_top_offset
  4479       * wordSize);
  4480   const int entry_size = (frame::interpreter_frame_monitor_size()* wordSize);
  4481   Label allocated;
  4483   // initialize entry pointer
  4484   __ move(c_rarg0, R0);
  4486   // find a free slot in the monitor block (result in edx)
  4488     Label entry, loop, exit, next;
  4489     __ ld(T2, monitor_block_top);
  4490     __ b(entry);
  4491     __ delayed()->daddi(T3, FP, frame::interpreter_frame_initial_sp_offset * wordSize);
  4493     // free slot?
  4494     __ bind(loop);
  4495     __ ld(AT, T2, BasicObjectLock::obj_offset_in_bytes());
  4496     __ bne(AT, R0, next);
  4497     __ delayed()->nop();
  4498     __ move(c_rarg0, T2);
  4500     __ bind(next);
  4501     __ beq(FSR, AT, exit);
  4502     __ delayed()->nop();
  4503     __ daddi(T2, T2, entry_size);
  4505     __ bind(entry);
  4506     __ bne(T3, T2, loop);
  4507     __ delayed()->nop();
  4508     __ bind(exit);
  4511   __ bne(c_rarg0, R0, allocated);
  4512   __ delayed()->nop();
  4514   // allocate one if there's no free slot
  4516     Label entry, loop;
  4517     // 1. compute new pointers                   // SP: old expression stack top
  4518     __ ld(c_rarg0, monitor_block_top);
  4519     __ daddi(SP, SP, - entry_size);
  4520     __ daddi(c_rarg0, c_rarg0, - entry_size);
  4521     __ sd(c_rarg0, monitor_block_top);
  4522     __ b(entry);
  4523     __ delayed(); __ move(T3, SP);
  4525     // 2. move expression stack contents
  4526     __ bind(loop);
  4527     __ ld(AT, T3, entry_size);
  4528     __ sd(AT, T3, 0);
  4529     __ daddi(T3, T3, wordSize);
  4530     __ bind(entry);
  4531     __ bne(T3, c_rarg0, loop);
  4532     __ delayed()->nop();
  4535   __ bind(allocated);
  4536   // Increment bcp to point to the next bytecode,
  4537   // so exception handling for async. exceptions work correctly.
  4538   // The object has already been poped from the stack, so the
  4539   // expression stack looks correct.
  4540   __ daddi(BCP, BCP, 1);
  4541   __ sd(FSR, c_rarg0, BasicObjectLock::obj_offset_in_bytes());
  4542   __ lock_object(c_rarg0);
  4543   // check to make sure this monitor doesn't cause stack overflow after locking
  4544   __ save_bcp();  // in case of exception
  4545   __ generate_stack_overflow_check(0);
  4546   // The bcp has already been incremented. Just need to dispatch to next instruction.
  4548   __ dispatch_next(vtos);
  4551 // T2 : top
  4552 // c_rarg0 : entry
  4553 void TemplateTable::monitorexit() {
  4554   transition(atos, vtos);
  4556   __ null_check(FSR);
  4558   const int entry_size =(frame::interpreter_frame_monitor_size()* wordSize);
  4559   Label found;
  4561   // find matching slot
  4563     Label entry, loop;
  4564     __ ld(c_rarg0, FP, frame::interpreter_frame_monitor_block_top_offset * wordSize);
  4565     __ b(entry);
  4566     __ delayed()->daddiu(T2, FP, frame::interpreter_frame_initial_sp_offset * wordSize);
  4568     __ bind(loop);
  4569     __ ld(AT, c_rarg0, BasicObjectLock::obj_offset_in_bytes());
  4570     __ beq(FSR, AT, found);
  4571     __ delayed()->nop();
  4572     __ daddiu(c_rarg0, c_rarg0, entry_size);
  4573     __ bind(entry);
  4574     __ bne(T2, c_rarg0, loop);
  4575     __ delayed()->nop();
  4578   // error handling. Unlocking was not block-structured
  4579   Label end;
  4580   __ call_VM(NOREG, CAST_FROM_FN_PTR(address,
  4581   InterpreterRuntime::throw_illegal_monitor_state_exception));
  4582   __ should_not_reach_here();
  4584   // call run-time routine
  4585   // c_rarg0: points to monitor entry
  4586   __ bind(found);
  4587   __ move(TSR, FSR);
  4588   __ unlock_object(c_rarg0);
  4589   __ move(FSR, TSR);
  4590   __ bind(end);
  4594 // Wide instructions
  4595 void TemplateTable::wide() {
  4596   transition(vtos, vtos);
  4597   // Note: the esi increment step is part of the individual wide bytecode implementations
  4598   __ lbu(Rnext, at_bcp(1));
  4599   __ dsll(T9, Rnext, Address::times_8);
  4600   __ li(AT, (long)Interpreter::_wentry_point);
  4601   __ dadd(AT, T9, AT);
  4602   __ ld(T9, AT, 0);
  4603   __ jr(T9);
  4604   __ delayed()->nop();
  4608 void TemplateTable::multianewarray() {
  4609   transition(vtos, atos);
  4610   // last dim is on top of stack; we want address of first one:
  4611   // first_addr = last_addr + (ndims - 1) * wordSize
  4612   __ lbu(A1, at_bcp(3));  // dimension
  4613   __ daddi(A1, A1, -1);
  4614   __ dsll(A1, A1, Address::times_8);
  4615   __ dadd(A1, SP, A1);    // now A1 pointer to the count array on the stack
  4616   call_VM(FSR, CAST_FROM_FN_PTR(address, InterpreterRuntime::multianewarray), A1);
  4617   __ lbu(AT, at_bcp(3));
  4618   __ dsll(AT, AT, Address::times_8);
  4619   __ dadd(SP, SP, AT);
  4620   __ sync();
  4622 #endif // !CC_INTERP

mercurial