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 }