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 "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 #include "runtime/sharedRuntime.hpp"
33 
34 #define __ _masm->
35 
36 
generate_slow_signature_handler()37 address TemplateInterpreterGenerator::generate_slow_signature_handler() {
38   address entry = __ pc();
39   // rbx,: method
40   // rcx: temporary
41   // rdi: pointer to locals
42   // rsp: end of copied parameters area
43   __ mov(rcx, rsp);
44   __ call_VM(noreg, CAST_FROM_FN_PTR(address, InterpreterRuntime::slow_signature_handler), rbx, rdi, rcx);
45   __ ret(0);
46   return entry;
47 }
48 
49 /**
50  * Method entry for static native methods:
51  *   int java.util.zip.CRC32.update(int crc, int b)
52  */
generate_CRC32_update_entry()53 address TemplateInterpreterGenerator::generate_CRC32_update_entry() {
54   if (UseCRC32Intrinsics) {
55     address entry = __ pc();
56 
57     // rbx: Method*
58     // rsi: senderSP must preserved for slow path, set SP to it on fast path
59     // rdx: scratch
60     // rdi: scratch
61 
62     Label slow_path;
63     // If we need a safepoint check, generate full interpreter entry.
64     __ safepoint_poll(slow_path, noreg, rdi);
65 
66     // We don't generate local frame and don't align stack because
67     // we call stub code and there is no safepoint on this path.
68 
69     // Load parameters
70     const Register crc = rax;  // crc
71     const Register val = rdx;  // source java byte value
72     const Register tbl = rdi;  // scratch
73 
74     // Arguments are reversed on java expression stack
75     __ movl(val, Address(rsp,   wordSize)); // byte value
76     __ movl(crc, Address(rsp, 2*wordSize)); // Initial CRC
77 
78     __ lea(tbl, ExternalAddress(StubRoutines::crc_table_addr()));
79     __ notl(crc); // ~crc
80     __ update_byte_crc32(crc, val, tbl);
81     __ notl(crc); // ~crc
82     // result in rax
83 
84     // _areturn
85     __ pop(rdi);                // get return address
86     __ mov(rsp, rsi);           // set sp to sender sp
87     __ jmp(rdi);
88 
89     // generate a vanilla native entry as the slow path
90     __ bind(slow_path);
91     __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
92     return entry;
93   }
94   return NULL;
95 }
96 
97 /**
98  * Method entry for static native methods:
99  *   int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
100  *   int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
101  */
generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind)102 address TemplateInterpreterGenerator::generate_CRC32_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
103   if (UseCRC32Intrinsics) {
104     address entry = __ pc();
105 
106     // rbx,: Method*
107     // rsi: senderSP must preserved for slow path, set SP to it on fast path
108     // rdx: scratch
109     // rdi: scratch
110 
111     Label slow_path;
112     // If we need a safepoint check, generate full interpreter entry.
113     __ safepoint_poll(slow_path, noreg, rdi);
114 
115     // We don't generate local frame and don't align stack because
116     // we call stub code and there is no safepoint on this path.
117 
118     // Load parameters
119     const Register crc = rax;  // crc
120     const Register buf = rdx;  // source java byte array address
121     const Register len = rdi;  // length
122 
123     // value              x86_32
124     // interp. arg ptr    ESP + 4
125     // int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int len)
126     //                                         3           2      1        0
127     // int java.util.zip.CRC32.updateByteBuffer(int crc, long buf, int off, int len)
128     //                                              4         2,3      1        0
129 
130     // Arguments are reversed on java expression stack
131     __ movl(len,   Address(rsp,   4 + 0)); // Length
132     // Calculate address of start element
133     if (kind == Interpreter::java_util_zip_CRC32_updateByteBuffer) {
134       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long buf
135       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
136       __ movl(crc,   Address(rsp, 4 + 4 * wordSize)); // Initial CRC
137     } else {
138       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
139       __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
140       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
141       __ movl(crc,   Address(rsp, 4 + 3 * wordSize)); // Initial CRC
142     }
143 
144     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32()), crc, buf, len);
145     // result in rax
146 
147     // _areturn
148     __ pop(rdi);                // get return address
149     __ mov(rsp, rsi);           // set sp to sender sp
150     __ jmp(rdi);
151 
152     // generate a vanilla native entry as the slow path
153     __ bind(slow_path);
154     __ jump_to_entry(Interpreter::entry_for_kind(Interpreter::native));
155     return entry;
156   }
157   return NULL;
158 }
159 
160 /**
161 * Method entry for static native methods:
162 *   int java.util.zip.CRC32C.updateBytes(int crc, byte[] b, int off, int end)
163 *   int java.util.zip.CRC32C.updateByteBuffer(int crc, long address, int off, int end)
164 */
generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind)165 address TemplateInterpreterGenerator::generate_CRC32C_updateBytes_entry(AbstractInterpreter::MethodKind kind) {
166   if (UseCRC32CIntrinsics) {
167     address entry = __ pc();
168     // Load parameters
169     const Register crc = rax;  // crc
170     const Register buf = rcx;  // source java byte array address
171     const Register len = rdx;  // length
172     const Register end = len;
173 
174     // value              x86_32
175     // interp. arg ptr    ESP + 4
176     // int java.util.zip.CRC32.updateBytes(int crc, byte[] b, int off, int end)
177     //                                         3           2      1        0
178     // int java.util.zip.CRC32.updateByteBuffer(int crc, long address, int off, int end)
179     //                                              4         2,3          1        0
180 
181     // Arguments are reversed on java expression stack
182     __ movl(end, Address(rsp, 4 + 0)); // end
183     __ subl(len, Address(rsp, 4 + 1 * wordSize));  // end - offset == length
184     // Calculate address of start element
185     if (kind == Interpreter::java_util_zip_CRC32C_updateDirectByteBuffer) {
186       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // long address
187       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
188       __ movl(crc, Address(rsp, 4 + 4 * wordSize)); // Initial CRC
189     } else {
190       __ movptr(buf, Address(rsp, 4 + 2 * wordSize)); // byte[] array
191       __ addptr(buf, arrayOopDesc::base_offset_in_bytes(T_BYTE)); // + header size
192       __ addptr(buf, Address(rsp, 4 + 1 * wordSize)); // + offset
193       __ movl(crc, Address(rsp, 4 + 3 * wordSize)); // Initial CRC
194     }
195     __ super_call_VM_leaf(CAST_FROM_FN_PTR(address, StubRoutines::updateBytesCRC32C()), crc, buf, len);
196     // result in rax
197     // _areturn
198     __ pop(rdi);                // get return address
199     __ mov(rsp, rsi);           // set sp to sender sp
200     __ jmp(rdi);
201 
202     return entry;
203   }
204   return NULL;
205 }
206 
207 /**
208  * Method entry for static native method:
209  *    java.lang.Float.intBitsToFloat(int bits)
210  */
generate_Float_intBitsToFloat_entry()211 address TemplateInterpreterGenerator::generate_Float_intBitsToFloat_entry() {
212   if (UseSSE >= 1) {
213     address entry = __ pc();
214 
215     // rsi: the sender's SP
216 
217     // Skip safepoint check (compiler intrinsic versions of this method
218     // do not perform safepoint checks either).
219 
220     // Load 'bits' into xmm0 (interpreter returns results in xmm0)
221     __ movflt(xmm0, Address(rsp, wordSize));
222 
223     // Return
224     __ pop(rdi); // get return address
225     __ mov(rsp, rsi); // set rsp to the sender's SP
226     __ jmp(rdi);
227     return entry;
228   }
229 
230   return NULL;
231 }
232 
233 /**
234  * Method entry for static native method:
235  *    java.lang.Float.floatToRawIntBits(float value)
236  */
generate_Float_floatToRawIntBits_entry()237 address TemplateInterpreterGenerator::generate_Float_floatToRawIntBits_entry() {
238   if (UseSSE >= 1) {
239     address entry = __ pc();
240 
241     // rsi: the sender's SP
242 
243     // Skip safepoint check (compiler intrinsic versions of this method
244     // do not perform safepoint checks either).
245 
246     // Load the parameter (a floating-point value) into rax.
247     __ movl(rax, Address(rsp, wordSize));
248 
249     // Return
250     __ pop(rdi); // get return address
251     __ mov(rsp, rsi); // set rsp to the sender's SP
252     __ jmp(rdi);
253     return entry;
254   }
255 
256   return NULL;
257 }
258 
259 
260 /**
261  * Method entry for static native method:
262  *    java.lang.Double.longBitsToDouble(long bits)
263  */
generate_Double_longBitsToDouble_entry()264 address TemplateInterpreterGenerator::generate_Double_longBitsToDouble_entry() {
265    if (UseSSE >= 2) {
266      address entry = __ pc();
267 
268      // rsi: the sender's SP
269 
270      // Skip safepoint check (compiler intrinsic versions of this method
271      // do not perform safepoint checks either).
272 
273      // Load 'bits' into xmm0 (interpreter returns results in xmm0)
274      __ movdbl(xmm0, Address(rsp, wordSize));
275 
276      // Return
277      __ pop(rdi); // get return address
278      __ mov(rsp, rsi); // set rsp to the sender's SP
279      __ jmp(rdi);
280      return entry;
281    }
282 
283    return NULL;
284 }
285 
286 /**
287  * Method entry for static native method:
288  *    java.lang.Double.doubleToRawLongBits(double value)
289  */
generate_Double_doubleToRawLongBits_entry()290 address TemplateInterpreterGenerator::generate_Double_doubleToRawLongBits_entry() {
291   if (UseSSE >= 2) {
292     address entry = __ pc();
293 
294     // rsi: the sender's SP
295 
296     // Skip safepoint check (compiler intrinsic versions of this method
297     // do not perform safepoint checks either).
298 
299     // Load the parameter (a floating-point value) into rax.
300     __ movl(rdx, Address(rsp, 2*wordSize));
301     __ movl(rax, Address(rsp, wordSize));
302 
303     // Return
304     __ pop(rdi); // get return address
305     __ mov(rsp, rsi); // set rsp to the sender's SP
306     __ jmp(rdi);
307     return entry;
308   }
309 
310   return NULL;
311 }
312 
generate_math_entry(AbstractInterpreter::MethodKind kind)313 address TemplateInterpreterGenerator::generate_math_entry(AbstractInterpreter::MethodKind kind) {
314 
315   // rbx,: Method*
316   // rcx: scratrch
317   // rsi: sender sp
318 
319   if (!InlineIntrinsics) return NULL; // Generate a vanilla entry
320 
321   address entry_point = __ pc();
322 
323   // These don't need a safepoint check because they aren't virtually
324   // callable. We won't enter these intrinsics from compiled code.
325   // If in the future we added an intrinsic which was virtually callable
326   // we'd have to worry about how to safepoint so that this code is used.
327 
328   // mathematical functions inlined by compiler
329   // (interpreter must provide identical implementation
330   // in order to avoid monotonicity bugs when switching
331   // from interpreter to compiler in the middle of some
332   // computation)
333   //
334   // stack: [ ret adr ] <-- rsp
335   //        [ lo(arg) ]
336   //        [ hi(arg) ]
337   //
338   if (kind == Interpreter::java_lang_math_fmaD) {
339     if (!UseFMA) {
340       return NULL; // Generate a vanilla entry
341     }
342     __ movdbl(xmm2, Address(rsp, 5 * wordSize));
343     __ movdbl(xmm1, Address(rsp, 3 * wordSize));
344     __ movdbl(xmm0, Address(rsp, 1 * wordSize));
345     __ fmad(xmm0, xmm1, xmm2, xmm0);
346     __ pop(rdi);                               // get return address
347     __ mov(rsp, rsi);                          // set sp to sender sp
348     __ jmp(rdi);
349 
350     return entry_point;
351   } else if (kind == Interpreter::java_lang_math_fmaF) {
352     if (!UseFMA) {
353       return NULL; // Generate a vanilla entry
354     }
355     __ movflt(xmm2, Address(rsp, 3 * wordSize));
356     __ movflt(xmm1, Address(rsp, 2 * wordSize));
357     __ movflt(xmm0, Address(rsp, 1 * wordSize));
358     __ fmaf(xmm0, xmm1, xmm2, xmm0);
359     __ pop(rdi);                               // get return address
360     __ mov(rsp, rsi);                          // set sp to sender sp
361     __ jmp(rdi);
362 
363     return entry_point;
364  }
365 
366   __ fld_d(Address(rsp, 1*wordSize));
367   switch (kind) {
368     case Interpreter::java_lang_math_sin :
369         __ subptr(rsp, 2 * wordSize);
370         __ fstp_d(Address(rsp, 0));
371         if (VM_Version::supports_sse2() && StubRoutines::dsin() != NULL) {
372           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dsin())));
373         } else {
374           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dsin));
375         }
376         __ addptr(rsp, 2 * wordSize);
377         break;
378     case Interpreter::java_lang_math_cos :
379         __ subptr(rsp, 2 * wordSize);
380         __ fstp_d(Address(rsp, 0));
381         if (VM_Version::supports_sse2() && StubRoutines::dcos() != NULL) {
382           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dcos())));
383         } else {
384           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dcos));
385         }
386         __ addptr(rsp, 2 * wordSize);
387         break;
388     case Interpreter::java_lang_math_tan :
389         __ subptr(rsp, 2 * wordSize);
390         __ fstp_d(Address(rsp, 0));
391         if (StubRoutines::dtan() != NULL) {
392           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dtan())));
393         } else {
394           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dtan));
395         }
396         __ addptr(rsp, 2 * wordSize);
397         break;
398     case Interpreter::java_lang_math_sqrt:
399         __ fsqrt();
400         break;
401     case Interpreter::java_lang_math_abs:
402         __ fabs();
403         break;
404     case Interpreter::java_lang_math_log:
405         __ subptr(rsp, 2 * wordSize);
406         __ fstp_d(Address(rsp, 0));
407         if (StubRoutines::dlog() != NULL) {
408           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog())));
409         } else {
410           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog));
411         }
412         __ addptr(rsp, 2 * wordSize);
413         break;
414     case Interpreter::java_lang_math_log10:
415         __ subptr(rsp, 2 * wordSize);
416         __ fstp_d(Address(rsp, 0));
417         if (StubRoutines::dlog10() != NULL) {
418           __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dlog10())));
419         } else {
420           __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dlog10));
421         }
422         __ addptr(rsp, 2 * wordSize);
423         break;
424     case Interpreter::java_lang_math_pow:
425       __ fld_d(Address(rsp, 3*wordSize)); // second argument
426       __ subptr(rsp, 4 * wordSize);
427       __ fstp_d(Address(rsp, 0));
428       __ fstp_d(Address(rsp, 2 * wordSize));
429       if (StubRoutines::dpow() != NULL) {
430         __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dpow())));
431       } else {
432         __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dpow));
433       }
434       __ addptr(rsp, 4 * wordSize);
435       break;
436     case Interpreter::java_lang_math_exp:
437       __ subptr(rsp, 2*wordSize);
438       __ fstp_d(Address(rsp, 0));
439       if (StubRoutines::dexp() != NULL) {
440         __ call(RuntimeAddress(CAST_FROM_FN_PTR(address, StubRoutines::dexp())));
441       } else {
442         __ call_VM_leaf0(CAST_FROM_FN_PTR(address, SharedRuntime::dexp));
443       }
444       __ addptr(rsp, 2*wordSize);
445     break;
446     default                              :
447         ShouldNotReachHere();
448   }
449 
450   // return double result in xmm0 for interpreter and compilers.
451   if (UseSSE >= 2) {
452     __ subptr(rsp, 2*wordSize);
453     __ fstp_d(Address(rsp, 0));
454     __ movdbl(xmm0, Address(rsp, 0));
455     __ addptr(rsp, 2*wordSize);
456   }
457 
458   // done, result in FPU ST(0) or XMM0
459   __ pop(rdi);                               // get return address
460   __ mov(rsp, rsi);                          // set sp to sender sp
461   __ jmp(rdi);
462 
463   return entry_point;
464 }
465