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 * Method entry for static native methods: 36 * int java.util.zip.CRC32.update(int crc, int b) 37 */ 38 address TemplateInterpreterGenerator::generate_CRC32_update_entry() { 39 if (UseCRC32Intrinsics) { 40 address entry = __ pc(); 41 42 // rbx,: Method* 43 // r13: senderSP must preserved for slow path, set SP to it on fast path 44 // c_rarg0: scratch (rdi on non-Win64, rcx on Win64) 45 // c_rarg1: scratch (rsi on non-Win64, rdx on Win64) 46 47 Label slow_path; 48 // If we need a safepoint check, generate full interpreter entry. 49 ExternalAddress state(SafepointSynchronize::address_of_state()); 50 __ cmp32(ExternalAddress(SafepointSynchronize::address_of_state()), 51 SafepointSynchronize::_not_synchronized); 52 __ jcc(Assembler::notEqual, slow_path); 53 175 } else { 176 __ movptr(buf, Address(rsp, 3 * wordSize)); // byte[] array 177 __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size 178 __ movl2ptr(off, Address(rsp, 2 * wordSize)); // offset 179 __ addq(buf, off); // + offset 180 __ movl(crc, Address(rsp, 4 * wordSize)); // Initial CRC 181 } 182 __ movl(end, Address(rsp, wordSize)); // end 183 __ subl(end, off); // end - off 184 __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len); 185 // result in rax 186 // _areturn 187 __ pop(rdi); // get return address 188 __ mov(rsp, r13); // set sp to sender sp 189 __ jmp(rdi); 190 191 return entry; 192 } 193 194 return NULL; 195 } | 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 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 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp()))); 377 } else if (kind == Interpreter::java_lang_math_log) { 378 __ movdbl(xmm0, Address(rsp, wordSize)); 379 __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog()))); 380 } else { 381 __ fld_d(Address(rsp, wordSize)); 382 switch (kind) { 383 case Interpreter::java_lang_math_sin : 384 __ trigfunc('s'); 385 break; 386 case Interpreter::java_lang_math_cos : 387 __ trigfunc('c'); 388 break; 389 case Interpreter::java_lang_math_tan : 390 __ trigfunc('t'); 391 break; 392 case Interpreter::java_lang_math_abs: 393 __ fabs(); 394 break; 395 case Interpreter::java_lang_math_log10: 396 __ flog10(); 397 break; 398 case Interpreter::java_lang_math_pow: 399 __ fld_d(Address(rsp, 3*wordSize)); // second argument (one 400 // empty stack slot) 401 __ pow_with_fallback(0); 402 break; 403 default : 404 ShouldNotReachHere(); 405 } 406 407 // return double result in xmm0 for interpreter and compilers. 408 __ subptr(rsp, 2*wordSize); 409 // Round to 64bit precision 410 __ fstp_d(Address(rsp, 0)); 411 __ movdbl(xmm0, Address(rsp, 0)); 412 __ addptr(rsp, 2*wordSize); 413 } 414 415 416 __ pop(rax); 417 __ mov(rsp, r13); 418 __ jmp(rax); 419 420 return entry_point; 421 } |