1 /*
   2  * Copyright (c) 1997, 2015, 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/templateInterpreterGenerator.hpp"
  30 #include "runtime/arguments.hpp"
  31 
  32 #define __ _masm->
  33 
  34 
  35 /**
  36  * Method entry for static native methods:
  37  *   int java.util.zip.CRC32.update(int crc, int b)
  38  */
  39 address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
  40   if (UseCRC32Intrinsics) {
  41     address entry = __ pc();
  42 
  43     // rbx: Method*
  44     // rsi: senderSP must preserved for slow path, set SP to it on fast path
  45     // rdx: scratch
  46     // rdi: scratch
  47 
  48     Label slow_path;
  49     // If we need a safepoint check, generate full interpreter entry.
  50     ExternalAddress state(SafepointSynchronize::address_of_state());
  51     __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
  52              SafepointSynchronize::_not_synchronized);
  53     __ jcc(Assembler::notEqual, slow_path);
  54 
  55     // We don't generate local frame and don't align stack because
  56     // we call stub code and there is no safepoint on this path.
  57 
  58     // Load parameters
  59     const Register crc = rax;  // crc
  60     const Register val = rdx;  // source java byte value
  61     const Register tbl = rdi;  // scratch
  62 
  63     // Arguments are reversed on java expression stack
  64     __ movl(val, Address(rsp,   wordSize)); // byte value
  65     __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
  66 
  67     __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
  68     __ notl(crc); // ~crc
  69     __ update_byte_crc32(crc, val, tbl);
  70     __ notl(crc); // ~crc
  71     // result in rax
  72 
  73     // _areturn
  74     __ pop(rdi);                // get return address
  75     __ mov(rsp, rsi);           // set sp to sender sp
  76     __ jmp(rdi);
  77 
  78     // generate a vanilla native entry as the slow path
  79     __ bind(slow_path);
  80     __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
  81     return entry;
  82   }
  83   return NULL;
  84 }
  85 
  86 /**
  87  * Method entry for static native methods:
  88  *   int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
  89  *   int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
  90  */
  91 address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
  92   if (UseCRC32Intrinsics) {
  93     address entry = __ pc();
  94 
  95     // rbx,: Method*
  96     // rsi: senderSP must preserved for slow path, set SP to it on fast path
  97     // rdx: scratch
  98     // rdi: scratch
  99 
 100     Label slow_path;
 101     // If we need a safepoint check, generate full interpreter entry.
 102     ExternalAddress state(SafepointSynchronize::address_of_state());
 103     __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()),
 104              SafepointSynchronize::_not_synchronized);
 105     __ jcc(Assembler::notEqual, slow_path);
 106 
 107     // We don't generate local frame and don't align stack because
 108     // we call stub code and there is no safepoint on this path.
 109 
 110     // Load parameters
 111     const Register crc = rax;  // crc
 112     const Register buf = rdx;  // source java byte array address
 113     const Register len = rdi;  // length
 114 
 115     // value              x86_32
 116     // interp. arg ptr    ESP + 4
 117     // int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
 118     //                                         3           2      1        0
 119     // int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
 120     //                                              4         2,3      1        0
 121 
 122     // Arguments are reversed on java expression stack
 123     __ movl(len,   Address(rsp,   4 + 0)); // Length
 124     // Calculate address of start element
 125     if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
 126       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long buf
 127       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
 128       __ movl(crc,   Address(rsp, 4 + 4 * wordSize)); // Initial CRC
 129     } else {
 130       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
 131       __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
 132       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
 133       __ movl(crc,   Address(rsp, 4 + 3 * wordSize)); // Initial CRC
 134     }
 135 
 136     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
 137     // result in rax
 138 
 139     // _areturn
 140     __ pop(rdi);                // get return address
 141     __ mov(rsp, rsi);           // set sp to sender sp
 142     __ jmp(rdi);
 143 
 144     // generate a vanilla native entry as the slow path
 145     __ bind(slow_path);
 146     __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
 147     return entry;
 148   }
 149   return NULL;
 150 }
 151 
 152 /**
 153 * Method entry for static native methods:
 154 *   int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
 155 *   int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
 156 */
 157 address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
 158   if (UseCRC32CIntrinsics) {
 159     address entry = __ pc();
 160     // Load parameters
 161     const Register crc = rax;  // crc
 162     const Register buf = rcx;  // source java byte array address
 163     const Register len = rdx;  // length
 164     const Register end = len;
 165 
 166     // value              x86_32
 167     // interp. arg ptr    ESP + 4
 168     // int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int end)
 169     //                                         3           2      1        0
 170     // int java.util.zip.CRC32.updateByteBuffer(int crc, long address, int off, int end)
 171     //                                              4         2,3          1        0
 172 
 173     // Arguments are reversed on java expression stack
 174     __ movl(end, Address(rsp, 4 + 0)); // end
 175     __ subl(len, Address(rsp, 4 + 1 * wordSize));  // end - offset == length
 176     // Calculate address of start element
 177     if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
 178       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long address
 179       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
 180       __ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
 181     } else {
 182       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
 183       __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
 184       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
 185       __ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
 186     }
 187     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
 188     // result in rax
 189     // _areturn
 190     __ pop(rdi);                // get return address
 191     __ mov(rsp, rsi);           // set sp to sender sp
 192     __ jmp(rdi);
 193 
 194     return entry;
 195   }
 196   return NULL;
 197 }
 198 
 199 /**
 200  * Method entry for static native method:
 201  *    java.lang.Float.intBitsToFloat(int bits)
 202  */
 203 address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() {
 204   if (UseSSE >= 1) {
 205     address entry = __ pc();
 206 
 207     // rsi: the sender's SP
 208 
 209     // Skip safepoint check (compiler intrinsic versions of this method
 210     // do not perform safepoint checks either).
 211 
 212     // Load 'bits' into xmm0 (interpreter returns results in xmm0)
 213     __ movflt(xmm0, Address(rsp, wordSize));
 214 
 215     // Return
 216     __ pop(rdi); // get return address
 217     __ mov(rsp, rsi); // set rsp to the sender's SP
 218     __ jmp(rdi);
 219     return entry;
 220   }
 221 
 222   return NULL;
 223 }
 224 
 225 /**
 226  * Method entry for static native method:
 227  *    java.lang.Float.floatToRawIntBits(float value)
 228  */
 229 address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() {
 230   if (UseSSE >= 1) {
 231     address entry = __ pc();
 232 
 233     // rsi: the sender's SP
 234 
 235     // Skip safepoint check (compiler intrinsic versions of this method
 236     // do not perform safepoint checks either).
 237 
 238     // Load the parameter (a floating-point value) into rax.
 239     __ movl(rax, Address(rsp, wordSize));
 240 
 241     // Return
 242     __ pop(rdi); // get return address
 243     __ mov(rsp, rsi); // set rsp to the sender's SP
 244     __ jmp(rdi);
 245     return entry;
 246   }
 247 
 248   return NULL;
 249 }
 250 
 251 
 252 /**
 253  * Method entry for static native method:
 254  *    java.lang.Double.longBitsToDouble(long bits)
 255  */
 256 address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() {
 257    if (UseSSE >= 2) {
 258      address entry = __ pc();
 259 
 260      // rsi: the sender's SP
 261 
 262      // Skip safepoint check (compiler intrinsic versions of this method
 263      // do not perform safepoint checks either).
 264 
 265      // Load 'bits' into xmm0 (interpreter returns results in xmm0)
 266      __ movdbl(xmm0, Address(rsp, wordSize));
 267 
 268      // Return
 269      __ pop(rdi); // get return address
 270      __ mov(rsp, rsi); // set rsp to the sender's SP
 271      __ jmp(rdi);
 272      return entry;
 273    }
 274 
 275    return NULL;
 276 }
 277 
 278 /**
 279  * Method entry for static native method:
 280  *    java.lang.Double.doubleToRawLongBits(double value)
 281  */
 282 address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() {
 283   if (UseSSE >= 2) {
 284     address entry = __ pc();
 285 
 286     // rsi: the sender's SP
 287 
 288     // Skip safepoint check (compiler intrinsic versions of this method
 289     // do not perform safepoint checks either).
 290 
 291     // Load the parameter (a floating-point value) into rax.
 292     __ movl(rdx, Address(rsp, 2*wordSize));
 293     __ movl(rax, Address(rsp, wordSize));
 294 
 295     // Return
 296     __ pop(rdi); // get return address
 297     __ mov(rsp, rsi); // set rsp to the sender's SP
 298     __ jmp(rdi);
 299     return entry;
 300   }
 301 
 302   return NULL;
 303 }