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