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