1 /* 2 * Copyright (c) 2003, 2016, 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 33 #define __ _masm-> 34 35 #ifdef _WIN64 36 address TemplateInterpreterGenerator::generate_slow_signature_handler() { 37 address entry = __ pc(); 38 39 // rbx: method 40 // r14: pointer to locals 41 // c_rarg3: first stack arg - wordSize 42 __ mov(c_rarg3, rsp); 43 // adjust rsp 44 __ subptr(rsp, 4 * wordSize); 45 __ call_VM(noreg, 46 CAST_FROM_FN_PTR(address, 47 InterpreterRuntime::slow_signature_handler), 48 rbx, r14, c_rarg3); 49 50 // rax: result handler 51 52 // Stack layout: 53 // rsp: 3 integer or float args (if static first is unused) 54 // 1 float/double identifiers 55 // return address 56 // stack args 57 // garbage 58 // expression stack bottom 59 // bcp (NULL) 60 // ... 61 62 // Do FP first so we can use c_rarg3 as temp 63 __ movl(c_rarg3, Address(rsp, 3 * wordSize)); // float/double identifiers 64 65 for ( int i= 0; i < Argument::n_int_register_parameters_c-1; i++ ) { 66 XMMRegister floatreg = as_XMMRegister(i+1); 67 Label isfloatordouble, isdouble, next; 68 69 __ testl(c_rarg3, 1 << (i*2)); // Float or Double? 70 __ jcc(Assembler::notZero, isfloatordouble); 71 72 // Do Int register here 73 switch ( i ) { 74 case 0: 75 __ movl(rscratch1, Address(rbx, Method::access_flags_offset())); 76 __ testl(rscratch1, JVM_ACC_STATIC); 77 __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); 78 break; 79 case 1: 80 __ movptr(c_rarg2, Address(rsp, wordSize)); 81 break; 82 case 2: 83 __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); 84 break; 85 default: 86 break; 87 } 88 89 __ jmp (next); 90 91 __ bind(isfloatordouble); 92 __ testl(c_rarg3, 1 << ((i*2)+1)); // Double? 93 __ jcc(Assembler::notZero, isdouble); 94 95 // Do Float Here 96 __ movflt(floatreg, Address(rsp, i * wordSize)); 97 __ jmp(next); 98 99 // Do Double here 100 __ bind(isdouble); 101 __ movdbl(floatreg, Address(rsp, i * wordSize)); 102 103 __ bind(next); 104 } 105 106 107 // restore rsp 108 __ addptr(rsp, 4 * wordSize); 109 110 __ ret(0); 111 112 return entry; 113 } 114 #else 115 address TemplateInterpreterGenerator::generate_slow_signature_handler() { 116 address entry = __ pc(); 117 118 // rbx: method 119 // r14: pointer to locals 120 // c_rarg3: first stack arg - wordSize 121 __ mov(c_rarg3, rsp); 122 // adjust rsp 123 __ subptr(rsp, 14 * wordSize); 124 __ call_VM(noreg, 125 CAST_FROM_FN_PTR(address, 126 InterpreterRuntime::slow_signature_handler), 127 rbx, r14, c_rarg3); 128 129 // rax: result handler 130 131 // Stack layout: 132 // rsp: 5 integer args (if static first is unused) 133 // 1 float/double identifiers 134 // 8 double args 135 // return address 136 // stack args 137 // garbage 138 // expression stack bottom 139 // bcp (NULL) 140 // ... 141 142 // Do FP first so we can use c_rarg3 as temp 143 __ movl(c_rarg3, Address(rsp, 5 * wordSize)); // float/double identifiers 144 145 for (int i = 0; i < Argument::n_float_register_parameters_c; i++) { 146 const XMMRegister r = as_XMMRegister(i); 147 148 Label d, done; 149 150 __ testl(c_rarg3, 1 << i); 151 __ jcc(Assembler::notZero, d); 152 __ movflt(r, Address(rsp, (6 + i) * wordSize)); 153 __ jmp(done); 154 __ bind(d); 155 __ movdbl(r, Address(rsp, (6 + i) * wordSize)); 156 __ bind(done); 157 } 158 159 // Now handle integrals. Only do c_rarg1 if not static. 160 __ movl(c_rarg3, Address(rbx, Method::access_flags_offset())); 161 __ testl(c_rarg3, JVM_ACC_STATIC); 162 __ cmovptr(Assembler::zero, c_rarg1, Address(rsp, 0)); 163 164 __ movptr(c_rarg2, Address(rsp, wordSize)); 165 __ movptr(c_rarg3, Address(rsp, 2 * wordSize)); 166 __ movptr(c_rarg4, Address(rsp, 3 * wordSize)); 167 __ movptr(c_rarg5, Address(rsp, 4 * wordSize)); 168 169 // restore rsp 170 __ addptr(rsp, 14 * wordSize); 171 172 __ ret(0); 173 174 return entry; 175 } 176 #endif // __WIN64 177 178 /** 179 * Method entry for static native methods: 180 * int java.util.zip.CRC32.update(int crc, int b) 181 */ 182 address TemplateInterpreterGenerator::generate_CRC32_update_entry() { 183 if (UseCRC32Intrinsics) { 184 address entry = __ pc(); 185 186 // rbx,: Method* 187 // r13: senderSP must preserved for slow path, set SP to it on fast path 188 // c_rarg0: scratch (rdi on non-Win64, rcx on Win64) 189 // c_rarg1: scratch (rsi on non-Win64, rdx on Win64) 190 191 Label slow_path; 192 // If we need a safepoint check, generate full interpreter entry. 193 ExternalAddress state(SafepointSynchronize::address_of_state()); 194 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 195 SafepointSynchronize::_not_synchronized); 196 __ jcc(Assembler::notEqual, slow_path); 197 198 // We don't generate local frame and don't align stack because 199 // we call stub code and there is no safepoint on this path. 200 201 // Load parameters 202 const Register crc = rax; // crc 203 const Register val = c_rarg0; // source java byte value 204 const Register tbl = c_rarg1; // scratch 205 206 // Arguments are reversed on java expression stack 207 __ movl(val, Address(rsp, wordSize)); // byte value 208 __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC 209 210 __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr())); 211 __ notl(crc); // ~crc 212 __ update_byte_crc32(crc, val, tbl); 213 __ notl(crc); // ~crc 214 // result in rax 215 216 // _areturn 217 __ pop(rdi); // get return address 218 __ mov(rsp, r13); // set sp to sender sp 219 __ jmp(rdi); 220 221 // generate a vanilla native entry as the slow path 222 __ bind(slow_path); 223 __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native)); 224 return entry; 225 } 226 return NULL; 227 } 228 229 /** 230 * Method entry for static native methods: 231 * int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len) 232 * int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len) 233 */ 234 address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) { 235 if (UseCRC32Intrinsics) { 236 address entry = __ pc(); 237 238 // rbx,: Method* 239 // r13: senderSP must preserved for slow path, set SP to it on fast path 240 241 Label slow_path; 242 // If we need a safepoint check, generate full interpreter entry. 243 ExternalAddress state(SafepointSynchronize::address_of_state()); 244 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 245 SafepointSynchronize::_not_synchronized); 246 __ jcc(Assembler::notEqual, slow_path); 247 248 // We don't generate local frame and don't align stack because 249 // we call stub code and there is no safepoint on this path. 250 251 // Load parameters 252 const Register crc = c_rarg0; // crc 253 const Register buf = c_rarg1; // source java byte array address 254 const Register len = c_rarg2; // length 255 const Register off = len; // offset (never overlaps with 'len') 256 257 // Arguments are reversed on java expression stack 258 // Calculate address of start element 259 if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) { 260 __ movptr(buf, Address(rsp, 3*wordSize)); // long buf 261 __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset 262 __ addq(buf, off); // + offset 263 __ movl(crc, Address(rsp, 5*wordSize)); // Initial CRC 264 } else { 265 __ movptr(buf, Address(rsp, 3*wordSize)); // byte[] array 266 __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size 267 __ movl2ptr(off, Address(rsp, 2*wordSize)); // offset 268 __ addq(buf, off); // + offset 269 __ movl(crc, Address(rsp, 4*wordSize)); // Initial CRC 270 } 271 // Can now load 'len' since we're finished with 'off' 272 __ movl(len, Address(rsp, wordSize)); // Length 273 274 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len); 275 // result in rax 276 277 // _areturn 278 __ pop(rdi); // get return address 279 __ mov(rsp, r13); // set sp to sender sp 280 __ jmp(rdi); 281 282 // generate a vanilla native entry as the slow path 283 __ bind(slow_path); 284 __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native)); 285 return entry; 286 } 287 return NULL; 288 } 289 290 /** 291 * Method entry for static native methods: 292 * int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end) 293 * int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end) 294 */ 295 address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) { 296 if (UseCRC32CIntrinsics) { 297 address entry = __ pc(); 298 // Load parameters 299 const Register crc = c_rarg0; // crc 300 const Register buf = c_rarg1; // source java byte array address 301 const Register len = c_rarg2; 302 const Register off = c_rarg3; // offset 303 const Register end = len; 304 305 // Arguments are reversed on java expression stack 306 // Calculate address of start element 307 if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) { 308 __ movptr(buf, Address(rsp, 3 * wordSize)); // long buf 309 __ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset 310 __ addq(buf, off); // + offset 311 __ movl(crc, Address(rsp, 5 * wordSize)); // Initial CRC 312 // Note on 5 * wordSize vs. 4 * wordSize: 313 // * int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end) 314 // 4 2,3 1 0 315 // end starts at SP + 8 316 // The Java(R) Virtual Machine Specification Java SE 7 Edition 317 // 4.10.2.3. Values of Types long and double 318 // "When calculating operand stack length, values of type long and double have length two." 319 } else { 320 __ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array 321 __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size 322 __ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset 323 __ addq(buf, off); // + offset 324 __ movl(crc, Address(rsp, 4 * wordSize)); // Initial CRC 325 } 326 __ movl(end, Address(rsp, wordSize)); // end 327 __ subl(end, off); // end - off 328 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len); 329 // result in rax 330 // _areturn 331 __ pop(rdi); // get return address 332 __ mov(rsp, r13); // set sp to sender sp 333 __ jmp(rdi); 334 335 return entry; 336 } 337 338 return NULL; 339 } 340 341 // 342 // Various method entries 343 // 344 345 address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) { 346 347 // rbx,: Method* 348 // rcx: scratrch 349 // r13: sender sp 350 351 if (!InlineIntrinsics) return NULL; // Generate a vanilla entry 352 353 address entry_point = __ pc(); 354 355 // These don't need a safepoint check because they aren't virtually 356 // callable. We won't enter these intrinsics from compiled code. 357 // If in the future we added an intrinsic which was virtually callable 358 // we'd have to worry about how to safepoint so that this code is used. 359 360 // mathematical functions inlined by compiler 361 // (interpreter must provide identical implementation 362 // in order to avoid monotonicity bugs when switching 363 // from interpreter to compiler in the middle of some 364 // computation) 365 // 366 // stack: [ ret adr ] <-- rsp 367 // [ lo(arg) ] 368 // [ hi(arg) ] 369 // 370 371 372 if (kind == Interpreter::java_lang_math_sqrt) { 373 __ sqrtsd(xmm0, Address(rsp, wordSize)); 374 } else if (kind == Interpreter::java_lang_math_exp) { 375 __ movdbl(xmm0, Address(rsp, wordSize)); 376 if (StubRoutines::dexp() != NULL) { 377 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp()))); 378 } else { 379 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dexp))); 380 } 381 } else if (kind == Interpreter::java_lang_math_log) { 382 __ movdbl(xmm0, Address(rsp, wordSize)); 383 if (StubRoutines::dlog() != NULL) { 384 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog()))); 385 } else { 386 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog))); 387 } 388 } else if (kind == Interpreter::java_lang_math_log10) { 389 __ movdbl(xmm0, Address(rsp, wordSize)); 390 if (StubRoutines::dlog10() != NULL) { 391 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10()))); 392 } else { 393 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10))); 394 } 395 } else if (kind == Interpreter::java_lang_math_sin) { 396 __ movdbl(xmm0, Address(rsp, wordSize)); 397 if (StubRoutines::dsin() != NULL) { 398 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin()))); 399 } else { 400 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dsin))); 401 } 402 } else if (kind == Interpreter::java_lang_math_cos) { 403 __ movdbl(xmm0, Address(rsp, wordSize)); 404 if (StubRoutines::dcos() != NULL) { 405 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos()))); 406 } else { 407 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dcos))); 408 } 409 } else if (kind == Interpreter::java_lang_math_pow) { 410 __ movdbl(xmm1, Address(rsp, wordSize)); 411 __ movdbl(xmm0, Address(rsp, 3 * wordSize)); 412 if (StubRoutines::dpow() != NULL) { 413 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow()))); 414 } else { 415 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dpow))); 416 } 417 } else if (kind == Interpreter::java_lang_math_tan) { 418 __ movdbl(xmm0, Address(rsp, wordSize)); 419 if (StubRoutines::dtan() != NULL) { 420 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan()))); 421 } else { 422 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, SharedRuntime::dtan))); 423 } 424 } else { 425 __ fld_d(Address(rsp, wordSize)); 426 switch (kind) { 427 case Interpreter::java_lang_math_abs: 428 __ fabs(); 429 break; 430 default : 431 ShouldNotReachHere(); 432 } 433 434 // return double result in xmm0 for interpreter and compilers. 435 __ subptr(rsp, 2*wordSize); 436 // Round to 64bit precision 437 __ fstp_d(Address(rsp, 0)); 438 __ movdbl(xmm0, Address(rsp, 0)); 439 __ addptr(rsp, 2*wordSize); 440 } 441 442 443 __ pop(rax); 444 __ mov(rsp, r13); 445 __ jmp(rax); 446 447 return entry_point; 448 }