templateInterpreterGenerator_x86_64.cpp revision 9934:fd5d53ecf040
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
36address 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
115address 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 */
182address 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 */
234address 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*/
295address 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
345address 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}
422