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
generate_slow_signature_handler()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 */
generate_CRC32_update_entry()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 */
generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind)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 */
generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind)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 */
generate_Float_intBitsToFloat_entry()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 */
generate_Float_floatToRawIntBits_entry()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 */
generate_Double_longBitsToDouble_entry()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 */
generate_Double_doubleToRawLongBits_entry()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
generate_math_entry(AbstractInterpreter::MethodKind kind)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 }
466