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 }