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