src/hotspot/cpu/x86/templateInterpreterGenerator_x86_32.cpp
changeset 47216 71c04702a3d5
parent 42580 56304dee97f3
child 49027 8dc742d9bbab
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.
       
     8  *
       
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    12  * version 2 for more details (a copy is included in the LICENSE file that
       
    13  * accompanied this code).
       
    14  *
       
    15  * You should have received a copy of the GNU General Public License version
       
    16  * 2 along with this work; if not, write to the Free Software Foundation,
       
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    18  *
       
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    20  * or visit www.oracle.com if you need additional information or have any
       
    21  * questions.
       
    22  *
       
    23  */
       
    24 
       
    25 #include "precompiled.hpp"
       
    26 #include "asm/macroAssembler.hpp"
       
    27 #include "interpreter/interp_masm.hpp"
       
    28 #include "interpreter/interpreter.hpp"
       
    29 #include "interpreter/interpreterRuntime.hpp"
       
    30 #include "interpreter/templateInterpreterGenerator.hpp"
       
    31 #include "runtime/arguments.hpp"
       
    32 #include "runtime/sharedRuntime.hpp"
       
    33 
       
    34 #define __ _masm->
       
    35 
       
    36 
       
    37 address TemplateInterpreterGenerator::generate_slow_signature_handler() {
       
    38   address entry = __ pc();
       
    39   // rbx,: method
       
    40   // rcx: temporary
       
    41   // rdi: pointer to locals
       
    42   // rsp: end of copied parameters area
       
    43   __ mov(rcx, rsp);
       
    44   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), rbx, rdi, rcx);
       
    45   __ ret(0);
       
    46   return entry;
       
    47 }
       
    48 
       
    49 /**
       
    50  * Method entry for static native methods:
       
    51  *   int java.util.zip.CRC32.update(int crc, int b)
       
    52  */
       
    53 address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
       
    54   if (UseCRC32Intrinsics) {
       
    55     address entry = __ pc();
       
    56 
       
    57     // rbx: Method*
       
    58     // rsi: senderSP must preserved for slow path, set SP to it on fast path
       
    59     // rdx: scratch
       
    60     // rdi: scratch
       
    61 
       
    62     Label slow_path;
       
    63     // If we need a safepoint check, generate full interpreter entry.
       
    64     ExternalAddress state(SafepointSynchronize::address_of_state());
       
    65     __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
       
    66              SafepointSynchronize::_not_synchronized);
       
    67     __ jcc(Assembler::notEqual, slow_path);
       
    68 
       
    69     // We don't generate local frame and don't align stack because
       
    70     // we call stub code and there is no safepoint on this path.
       
    71 
       
    72     // Load parameters
       
    73     const Register crc = rax;  // crc
       
    74     const Register val = rdx;  // source java byte value
       
    75     const Register tbl = rdi;  // scratch
       
    76 
       
    77     // Arguments are reversed on java expression stack
       
    78     __ movl(val, Address(rsp,   wordSize)); // byte value
       
    79     __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
       
    80 
       
    81     __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
       
    82     __ notl(crc); // ~crc
       
    83     __ update_byte_crc32(crc, val, tbl);
       
    84     __ notl(crc); // ~crc
       
    85     // result in rax
       
    86 
       
    87     // _areturn
       
    88     __ pop(rdi);                // get return address
       
    89     __ mov(rsp, rsi);           // set sp to sender sp
       
    90     __ jmp(rdi);
       
    91 
       
    92     // generate a vanilla native entry as the slow path
       
    93     __ bind(slow_path);
       
    94     __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
       
    95     return entry;
       
    96   }
       
    97   return NULL;
       
    98 }
       
    99 
       
   100 /**
       
   101  * Method entry for static native methods:
       
   102  *   int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
       
   103  *   int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
       
   104  */
       
   105 address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
       
   106   if (UseCRC32Intrinsics) {
       
   107     address entry = __ pc();
       
   108 
       
   109     // rbx,: Method*
       
   110     // rsi: senderSP must preserved for slow path, set SP to it on fast path
       
   111     // rdx: scratch
       
   112     // rdi: scratch
       
   113 
       
   114     Label slow_path;
       
   115     // If we need a safepoint check, generate full interpreter entry.
       
   116     ExternalAddress state(SafepointSynchronize::address_of_state());
       
   117     __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
       
   118              SafepointSynchronize::_not_synchronized);
       
   119     __ jcc(Assembler::notEqual, slow_path);
       
   120 
       
   121     // We don't generate local frame and don't align stack because
       
   122     // we call stub code and there is no safepoint on this path.
       
   123 
       
   124     // Load parameters
       
   125     const Register crc = rax;  // crc
       
   126     const Register buf = rdx;  // source java byte array address
       
   127     const Register len = rdi;  // length
       
   128 
       
   129     // value              x86_32
       
   130     // interp. arg ptr    ESP + 4
       
   131     // int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
       
   132     //                                         3           2      1        0
       
   133     // int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
       
   134     //                                              4         2,3      1        0
       
   135 
       
   136     // Arguments are reversed on java expression stack
       
   137     __ movl(len,   Address(rsp,   4 + 0)); // Length
       
   138     // Calculate address of start element
       
   139     if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
       
   140       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long buf
       
   141       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
       
   142       __ movl(crc,   Address(rsp, 4 + 4 * wordSize)); // Initial CRC
       
   143     } else {
       
   144       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
       
   145       __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
       
   146       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
       
   147       __ movl(crc,   Address(rsp, 4 + 3 * wordSize)); // Initial CRC
       
   148     }
       
   149 
       
   150     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
       
   151     // result in rax
       
   152 
       
   153     // _areturn
       
   154     __ pop(rdi);                // get return address
       
   155     __ mov(rsp, rsi);           // set sp to sender sp
       
   156     __ jmp(rdi);
       
   157 
       
   158     // generate a vanilla native entry as the slow path
       
   159     __ bind(slow_path);
       
   160     __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
       
   161     return entry;
       
   162   }
       
   163   return NULL;
       
   164 }
       
   165 
       
   166 /**
       
   167 * Method entry for static native methods:
       
   168 *   int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
       
   169 *   int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
       
   170 */
       
   171 address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
       
   172   if (UseCRC32CIntrinsics) {
       
   173     address entry = __ pc();
       
   174     // Load parameters
       
   175     const Register crc = rax;  // crc
       
   176     const Register buf = rcx;  // source java byte array address
       
   177     const Register len = rdx;  // length
       
   178     const Register end = len;
       
   179 
       
   180     // value              x86_32
       
   181     // interp. arg ptr    ESP + 4
       
   182     // int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int end)
       
   183     //                                         3           2      1        0
       
   184     // int java.util.zip.CRC32.updateByteBuffer(int crc, long address, int off, int end)
       
   185     //                                              4         2,3          1        0
       
   186 
       
   187     // Arguments are reversed on java expression stack
       
   188     __ movl(end, Address(rsp, 4 + 0)); // end
       
   189     __ subl(len, Address(rsp, 4 + 1 * wordSize));  // end - offset == length
       
   190     // Calculate address of start element
       
   191     if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
       
   192       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long address
       
   193       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
       
   194       __ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
       
   195     } else {
       
   196       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
       
   197       __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
       
   198       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
       
   199       __ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
       
   200     }
       
   201     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
       
   202     // result in rax
       
   203     // _areturn
       
   204     __ pop(rdi);                // get return address
       
   205     __ mov(rsp, rsi);           // set sp to sender sp
       
   206     __ jmp(rdi);
       
   207 
       
   208     return entry;
       
   209   }
       
   210   return NULL;
       
   211 }
       
   212 
       
   213 /**
       
   214  * Method entry for static native method:
       
   215  *    java.lang.Float.intBitsToFloat(int bits)
       
   216  */
       
   217 address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() {
       
   218   if (UseSSE >= 1) {
       
   219     address entry = __ pc();
       
   220 
       
   221     // rsi: the sender's SP
       
   222 
       
   223     // Skip safepoint check (compiler intrinsic versions of this method
       
   224     // do not perform safepoint checks either).
       
   225 
       
   226     // Load 'bits' into xmm0 (interpreter returns results in xmm0)
       
   227     __ movflt(xmm0, Address(rsp, wordSize));
       
   228 
       
   229     // Return
       
   230     __ pop(rdi); // get return address
       
   231     __ mov(rsp, rsi); // set rsp to the sender's SP
       
   232     __ jmp(rdi);
       
   233     return entry;
       
   234   }
       
   235 
       
   236   return NULL;
       
   237 }
       
   238 
       
   239 /**
       
   240  * Method entry for static native method:
       
   241  *    java.lang.Float.floatToRawIntBits(float value)
       
   242  */
       
   243 address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() {
       
   244   if (UseSSE >= 1) {
       
   245     address entry = __ pc();
       
   246 
       
   247     // rsi: the sender's SP
       
   248 
       
   249     // Skip safepoint check (compiler intrinsic versions of this method
       
   250     // do not perform safepoint checks either).
       
   251 
       
   252     // Load the parameter (a floating-point value) into rax.
       
   253     __ movl(rax, Address(rsp, wordSize));
       
   254 
       
   255     // Return
       
   256     __ pop(rdi); // get return address
       
   257     __ mov(rsp, rsi); // set rsp to the sender's SP
       
   258     __ jmp(rdi);
       
   259     return entry;
       
   260   }
       
   261 
       
   262   return NULL;
       
   263 }
       
   264 
       
   265 
       
   266 /**
       
   267  * Method entry for static native method:
       
   268  *    java.lang.Double.longBitsToDouble(long bits)
       
   269  */
       
   270 address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() {
       
   271    if (UseSSE >= 2) {
       
   272      address entry = __ pc();
       
   273 
       
   274      // rsi: the sender's SP
       
   275 
       
   276      // Skip safepoint check (compiler intrinsic versions of this method
       
   277      // do not perform safepoint checks either).
       
   278 
       
   279      // Load 'bits' into xmm0 (interpreter returns results in xmm0)
       
   280      __ movdbl(xmm0, Address(rsp, wordSize));
       
   281 
       
   282      // Return
       
   283      __ pop(rdi); // get return address
       
   284      __ mov(rsp, rsi); // set rsp to the sender's SP
       
   285      __ jmp(rdi);
       
   286      return entry;
       
   287    }
       
   288 
       
   289    return NULL;
       
   290 }
       
   291 
       
   292 /**
       
   293  * Method entry for static native method:
       
   294  *    java.lang.Double.doubleToRawLongBits(double value)
       
   295  */
       
   296 address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() {
       
   297   if (UseSSE >= 2) {
       
   298     address entry = __ pc();
       
   299 
       
   300     // rsi: the sender's SP
       
   301 
       
   302     // Skip safepoint check (compiler intrinsic versions of this method
       
   303     // do not perform safepoint checks either).
       
   304 
       
   305     // Load the parameter (a floating-point value) into rax.
       
   306     __ movl(rdx, Address(rsp, 2*wordSize));
       
   307     __ movl(rax, Address(rsp, wordSize));
       
   308 
       
   309     // Return
       
   310     __ pop(rdi); // get return address
       
   311     __ mov(rsp, rsi); // set rsp to the sender's SP
       
   312     __ jmp(rdi);
       
   313     return entry;
       
   314   }
       
   315 
       
   316   return NULL;
       
   317 }
       
   318 
       
   319 address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
       
   320 
       
   321   // rbx,: Method*
       
   322   // rcx: scratrch
       
   323   // rsi: sender sp
       
   324 
       
   325   if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
       
   326 
       
   327   address entry_point = __ pc();
       
   328 
       
   329   // These don't need a safepoint check because they aren't virtually
       
   330   // callable. We won't enter these intrinsics from compiled code.
       
   331   // If in the future we added an intrinsic which was virtually callable
       
   332   // we'd have to worry about how to safepoint so that this code is used.
       
   333 
       
   334   // mathematical functions inlined by compiler
       
   335   // (interpreter must provide identical implementation
       
   336   // in order to avoid monotonicity bugs when switching
       
   337   // from interpreter to compiler in the middle of some
       
   338   // computation)
       
   339   //
       
   340   // stack: [ ret adr ] <-- rsp
       
   341   //        [ lo(arg) ]
       
   342   //        [ hi(arg) ]
       
   343   //
       
   344   if (kind == Interpreter::java_lang_math_fmaD) {
       
   345     if (!UseFMA) {
       
   346       return NULL; // Generate a vanilla entry
       
   347     }
       
   348     __ movdbl(xmm2, Address(rsp, 5 * wordSize));
       
   349     __ movdbl(xmm1, Address(rsp, 3 * wordSize));
       
   350     __ movdbl(xmm0, Address(rsp, 1 * wordSize));
       
   351     __ fmad(xmm0, xmm1, xmm2, xmm0);
       
   352     __ pop(rdi);                               // get return address
       
   353     __ mov(rsp, rsi);                          // set sp to sender sp
       
   354     __ jmp(rdi);
       
   355 
       
   356     return entry_point;
       
   357   } else if (kind == Interpreter::java_lang_math_fmaF) {
       
   358     if (!UseFMA) {
       
   359       return NULL; // Generate a vanilla entry
       
   360     }
       
   361     __ movflt(xmm2, Address(rsp, 3 * wordSize));
       
   362     __ movflt(xmm1, Address(rsp, 2 * wordSize));
       
   363     __ movflt(xmm0, Address(rsp, 1 * wordSize));
       
   364     __ fmaf(xmm0, xmm1, xmm2, xmm0);
       
   365     __ pop(rdi);                               // get return address
       
   366     __ mov(rsp, rsi);                          // set sp to sender sp
       
   367     __ jmp(rdi);
       
   368 
       
   369     return entry_point;
       
   370  }
       
   371 
       
   372   __ fld_d(Address(rsp, 1*wordSize));
       
   373   switch (kind) {
       
   374     case Interpreter::java_lang_math_sin :
       
   375         __ subptr(rsp, 2 * wordSize);
       
   376         __ fstp_d(Address(rsp, 0));
       
   377         if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) {
       
   378           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin())));
       
   379         } else {
       
   380           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dsin));
       
   381         }
       
   382         __ addptr(rsp, 2 * wordSize);
       
   383         break;
       
   384     case Interpreter::java_lang_math_cos :
       
   385         __ subptr(rsp, 2 * wordSize);
       
   386         __ fstp_d(Address(rsp, 0));
       
   387         if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) {
       
   388           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos())));
       
   389         } else {
       
   390           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dcos));
       
   391         }
       
   392         __ addptr(rsp, 2 * wordSize);
       
   393         break;
       
   394     case Interpreter::java_lang_math_tan :
       
   395         __ subptr(rsp, 2 * wordSize);
       
   396         __ fstp_d(Address(rsp, 0));
       
   397         if (StubRoutines::dtan() != NULL) {
       
   398           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan())));
       
   399         } else {
       
   400           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dtan));
       
   401         }
       
   402         __ addptr(rsp, 2 * wordSize);
       
   403         break;
       
   404     case Interpreter::java_lang_math_sqrt:
       
   405         __ fsqrt();
       
   406         break;
       
   407     case Interpreter::java_lang_math_abs:
       
   408         __ fabs();
       
   409         break;
       
   410     case Interpreter::java_lang_math_log:
       
   411         __ subptr(rsp, 2 * wordSize);
       
   412         __ fstp_d(Address(rsp, 0));
       
   413         if (StubRoutines::dlog() != NULL) {
       
   414           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
       
   415         } else {
       
   416           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog));
       
   417         }
       
   418         __ addptr(rsp, 2 * wordSize);
       
   419         break;
       
   420     case Interpreter::java_lang_math_log10:
       
   421         __ subptr(rsp, 2 * wordSize);
       
   422         __ fstp_d(Address(rsp, 0));
       
   423         if (StubRoutines::dlog10() != NULL) {
       
   424           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10())));
       
   425         } else {
       
   426           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10));
       
   427         }
       
   428         __ addptr(rsp, 2 * wordSize);
       
   429         break;
       
   430     case Interpreter::java_lang_math_pow:
       
   431       __ fld_d(Address(rsp, 3*wordSize)); // second argument
       
   432       __ subptr(rsp, 4 * wordSize);
       
   433       __ fstp_d(Address(rsp, 0));
       
   434       __ fstp_d(Address(rsp, 2 * wordSize));
       
   435       if (StubRoutines::dpow() != NULL) {
       
   436         __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow())));
       
   437       } else {
       
   438         __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dpow));
       
   439       }
       
   440       __ addptr(rsp, 4 * wordSize);
       
   441       break;
       
   442     case Interpreter::java_lang_math_exp:
       
   443       __ subptr(rsp, 2*wordSize);
       
   444       __ fstp_d(Address(rsp, 0));
       
   445       if (StubRoutines::dexp() != NULL) {
       
   446         __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
       
   447       } else {
       
   448         __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dexp));
       
   449       }
       
   450       __ addptr(rsp, 2*wordSize);
       
   451     break;
       
   452     default                              :
       
   453         ShouldNotReachHere();
       
   454   }
       
   455 
       
   456   // return double result in xmm0 for interpreter and compilers.
       
   457   if (UseSSE >= 2) {
       
   458     __ subptr(rsp, 2*wordSize);
       
   459     __ fstp_d(Address(rsp, 0));
       
   460     __ movdbl(xmm0, Address(rsp, 0));
       
   461     __ addptr(rsp, 2*wordSize);
       
   462   }
       
   463 
       
   464   // done, result in FPU ST(0) or XMM0
       
   465   __ pop(rdi);                               // get return address
       
   466   __ mov(rsp, rsi);                          // set sp to sender sp
       
   467   __ jmp(rdi);
       
   468 
       
   469   return entry_point;
       
   470 }