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/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 345 __ fld_d(Address(rsp, 1*wordSize)); 346 switch (kind) { 347 case Interpreter::java_lang_math_sin : 348 __ trigfunc('s'); 349 break; 350 case Interpreter::java_lang_math_cos : 351 __ trigfunc('c'); 352 break; 353 case Interpreter::java_lang_math_tan : 354 __ trigfunc('t'); 355 break; 356 case Interpreter::java_lang_math_sqrt: 357 __ fsqrt(); 358 break; 359 case Interpreter::java_lang_math_abs: 360 __ fabs(); 361 break; 362 case Interpreter::java_lang_math_log: 363 __ subptr(rsp, 2 * wordSize); 364 __ fstp_d(Address(rsp, 0)); 365 if (VM_Version::supports_sse2()) { 366 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog()))); 367 } 368 else { 369 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog))); 370 } 371 __ addptr(rsp, 2 * wordSize); 372 break; 373 case Interpreter::java_lang_math_log10: 374 __ flog10(); 375 // Store to stack to convert 80bit precision back to 64bits 376 __ push_fTOS(); 377 __ pop_fTOS(); 378 break; 379 case Interpreter::java_lang_math_pow: 380 __ fld_d(Address(rsp, 3*wordSize)); // second argument 381 __ pow_with_fallback(0); 382 // Store to stack to convert 80bit precision back to 64bits 383 __ push_fTOS(); 384 __ pop_fTOS(); 385 break; 386 case Interpreter::java_lang_math_exp: 387 __ subptr(rsp, 2*wordSize); 388 __ fstp_d(Address(rsp, 0)); 389 if (VM_Version::supports_sse2()) { 390 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp()))); 391 } else { 392 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dexp))); 393 } 394 __ addptr(rsp, 2*wordSize); 395 break; 396 default : 397 ShouldNotReachHere(); 398 } 399 400 // return double result in xmm0 for interpreter and compilers. 401 if (UseSSE >= 2) { 402 __ subptr(rsp, 2*wordSize); 403 __ fstp_d(Address(rsp, 0)); 404 __ movdbl(xmm0, Address(rsp, 0)); 405 __ addptr(rsp, 2*wordSize); 406 } 407 408 // done, result in FPU ST(0) or XMM0 409 __ pop(rdi); // get return address 410 __ mov(rsp, rsi); // set sp to sender sp 411 __ jmp(rdi); 412 413 return entry_point; 414 }