Mercurial > hg > truffle
comparison src/cpu/x86/vm/interpreterRT_x86_64.cpp @ 0:a61af66fc99e jdk7-b24
Initial load
author | duke |
---|---|
date | Sat, 01 Dec 2007 00:00:00 +0000 |
parents | |
children | dc7f315e41f7 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:a61af66fc99e |
---|---|
1 /* | |
2 * Copyright 2003-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
20 * CA 95054 USA or visit www.sun.com if you need additional information or | |
21 * have any questions. | |
22 * | |
23 */ | |
24 | |
25 #include "incls/_precompiled.incl" | |
26 #include "incls/_interpreterRT_x86_64.cpp.incl" | |
27 | |
28 #define __ _masm-> | |
29 | |
30 // Implementation of SignatureHandlerGenerator | |
31 | |
32 Register InterpreterRuntime::SignatureHandlerGenerator::from() { return r14; } | |
33 Register InterpreterRuntime::SignatureHandlerGenerator::to() { return rsp; } | |
34 Register InterpreterRuntime::SignatureHandlerGenerator::temp() { return rscratch1; } | |
35 | |
36 void InterpreterRuntime::SignatureHandlerGenerator::pass_int() { | |
37 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); | |
38 | |
39 #ifdef _WIN64 | |
40 switch (_num_args) { | |
41 case 0: | |
42 __ movl(c_rarg1, src); | |
43 _num_args++; | |
44 break; | |
45 case 1: | |
46 __ movl(c_rarg2, src); | |
47 _num_args++; | |
48 break; | |
49 case 2: | |
50 __ movl(c_rarg3, src); | |
51 _num_args++; | |
52 break; | |
53 default: | |
54 __ movl(rax, src); | |
55 __ movl(Address(to(), _stack_offset), rax); | |
56 _stack_offset += wordSize; | |
57 break; | |
58 } | |
59 #else | |
60 switch (_num_int_args) { | |
61 case 0: | |
62 __ movl(c_rarg1, src); | |
63 _num_int_args++; | |
64 break; | |
65 case 1: | |
66 __ movl(c_rarg2, src); | |
67 _num_int_args++; | |
68 break; | |
69 case 2: | |
70 __ movl(c_rarg3, src); | |
71 _num_int_args++; | |
72 break; | |
73 case 3: | |
74 __ movl(c_rarg4, src); | |
75 _num_int_args++; | |
76 break; | |
77 case 4: | |
78 __ movl(c_rarg5, src); | |
79 _num_int_args++; | |
80 break; | |
81 default: | |
82 __ movl(rax, src); | |
83 __ movl(Address(to(), _stack_offset), rax); | |
84 _stack_offset += wordSize; | |
85 break; | |
86 } | |
87 #endif | |
88 } | |
89 | |
90 void InterpreterRuntime::SignatureHandlerGenerator::pass_long() { | |
91 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); | |
92 | |
93 #ifdef _WIN64 | |
94 switch (_num_args) { | |
95 case 0: | |
96 __ movq(c_rarg1, src); | |
97 _num_args++; | |
98 break; | |
99 case 1: | |
100 __ movq(c_rarg2, src); | |
101 _num_args++; | |
102 break; | |
103 case 2: | |
104 __ movq(c_rarg3, src); | |
105 _num_args++; | |
106 break; | |
107 case 3: | |
108 default: | |
109 __ movq(rax, src); | |
110 __ movq(Address(to(), _stack_offset), rax); | |
111 _stack_offset += wordSize; | |
112 break; | |
113 } | |
114 #else | |
115 switch (_num_int_args) { | |
116 case 0: | |
117 __ movq(c_rarg1, src); | |
118 _num_int_args++; | |
119 break; | |
120 case 1: | |
121 __ movq(c_rarg2, src); | |
122 _num_int_args++; | |
123 break; | |
124 case 2: | |
125 __ movq(c_rarg3, src); | |
126 _num_int_args++; | |
127 break; | |
128 case 3: | |
129 __ movq(c_rarg4, src); | |
130 _num_int_args++; | |
131 break; | |
132 case 4: | |
133 __ movq(c_rarg5, src); | |
134 _num_int_args++; | |
135 break; | |
136 default: | |
137 __ movq(rax, src); | |
138 __ movq(Address(to(), _stack_offset), rax); | |
139 _stack_offset += wordSize; | |
140 break; | |
141 } | |
142 #endif | |
143 } | |
144 | |
145 void InterpreterRuntime::SignatureHandlerGenerator::pass_float() { | |
146 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); | |
147 | |
148 #ifdef _WIN64 | |
149 if (_num_args < Argument::n_float_register_parameters_c-1) { | |
150 __ movflt(as_XMMRegister(++_num_args), src); | |
151 } else { | |
152 __ movl(rax, src); | |
153 __ movl(Address(to(), _stack_offset), rax); | |
154 _stack_offset += wordSize; | |
155 } | |
156 #else | |
157 if (_num_fp_args < Argument::n_float_register_parameters_c) { | |
158 __ movflt(as_XMMRegister(_num_fp_args++), src); | |
159 } else { | |
160 __ movl(rax, src); | |
161 __ movl(Address(to(), _stack_offset), rax); | |
162 _stack_offset += wordSize; | |
163 } | |
164 #endif | |
165 } | |
166 | |
167 void InterpreterRuntime::SignatureHandlerGenerator::pass_double() { | |
168 const Address src(from(), Interpreter::local_offset_in_bytes(offset() + 1)); | |
169 | |
170 #ifdef _WIN64 | |
171 if (_num_args < Argument::n_float_register_parameters_c-1) { | |
172 __ movdbl(as_XMMRegister(++_num_args), src); | |
173 } else { | |
174 __ movq(rax, src); | |
175 __ movq(Address(to(), _stack_offset), rax); | |
176 _stack_offset += wordSize; | |
177 } | |
178 #else | |
179 if (_num_fp_args < Argument::n_float_register_parameters_c) { | |
180 __ movdbl(as_XMMRegister(_num_fp_args++), src); | |
181 } else { | |
182 __ movq(rax, src); | |
183 __ movq(Address(to(), _stack_offset), rax); | |
184 _stack_offset += wordSize; | |
185 } | |
186 #endif | |
187 } | |
188 | |
189 void InterpreterRuntime::SignatureHandlerGenerator::pass_object() { | |
190 const Address src(from(), Interpreter::local_offset_in_bytes(offset())); | |
191 | |
192 #ifdef _WIN64 | |
193 switch (_num_args) { | |
194 case 0: | |
195 assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); | |
196 __ leaq(c_rarg1, src); | |
197 _num_args++; | |
198 break; | |
199 case 1: | |
200 __ leaq(rax, src); | |
201 __ xorl(c_rarg2, c_rarg2); | |
202 __ cmpq(src, 0); | |
203 __ cmovq(Assembler::notEqual, c_rarg2, rax); | |
204 _num_args++; | |
205 break; | |
206 case 2: | |
207 __ leaq(rax, src); | |
208 __ xorl(c_rarg3, c_rarg3); | |
209 __ cmpq(src, 0); | |
210 __ cmovq(Assembler::notEqual, c_rarg3, rax); | |
211 _num_args++; | |
212 break; | |
213 default: | |
214 __ leaq(rax, src); | |
215 __ xorl(temp(), temp()); | |
216 __ cmpq(src, 0); | |
217 __ cmovq(Assembler::notEqual, temp(), rax); | |
218 __ movq(Address(to(), _stack_offset), temp()); | |
219 _stack_offset += wordSize; | |
220 break; | |
221 } | |
222 #else | |
223 switch (_num_int_args) { | |
224 case 0: | |
225 assert(offset() == 0, "argument register 1 can only be (non-null) receiver"); | |
226 __ leaq(c_rarg1, src); | |
227 _num_int_args++; | |
228 break; | |
229 case 1: | |
230 __ leaq(rax, src); | |
231 __ xorl(c_rarg2, c_rarg2); | |
232 __ cmpq(src, 0); | |
233 __ cmovq(Assembler::notEqual, c_rarg2, rax); | |
234 _num_int_args++; | |
235 break; | |
236 case 2: | |
237 __ leaq(rax, src); | |
238 __ xorl(c_rarg3, c_rarg3); | |
239 __ cmpq(src, 0); | |
240 __ cmovq(Assembler::notEqual, c_rarg3, rax); | |
241 _num_int_args++; | |
242 break; | |
243 case 3: | |
244 __ leaq(rax, src); | |
245 __ xorl(c_rarg4, c_rarg4); | |
246 __ cmpq(src, 0); | |
247 __ cmovq(Assembler::notEqual, c_rarg4, rax); | |
248 _num_int_args++; | |
249 break; | |
250 case 4: | |
251 __ leaq(rax, src); | |
252 __ xorl(c_rarg5, c_rarg5); | |
253 __ cmpq(src, 0); | |
254 __ cmovq(Assembler::notEqual, c_rarg5, rax); | |
255 _num_int_args++; | |
256 break; | |
257 default: | |
258 __ leaq(rax, src); | |
259 __ xorl(temp(), temp()); | |
260 __ cmpq(src, 0); | |
261 __ cmovq(Assembler::notEqual, temp(), rax); | |
262 __ movq(Address(to(), _stack_offset), temp()); | |
263 _stack_offset += wordSize; | |
264 break; | |
265 } | |
266 #endif | |
267 } | |
268 | |
269 void InterpreterRuntime::SignatureHandlerGenerator::generate(uint64_t fingerprint) { | |
270 // generate code to handle arguments | |
271 iterate(fingerprint); | |
272 | |
273 // return result handler | |
274 __ lea(rax, ExternalAddress(Interpreter::result_handler(method()->result_type()))); | |
275 __ ret(0); | |
276 | |
277 __ flush(); | |
278 } | |
279 | |
280 | |
281 // Implementation of SignatureHandlerLibrary | |
282 | |
283 void SignatureHandlerLibrary::pd_set_handler(address handler) {} | |
284 | |
285 | |
286 #ifdef _WIN64 | |
287 class SlowSignatureHandler | |
288 : public NativeSignatureIterator { | |
289 private: | |
290 address _from; | |
291 intptr_t* _to; | |
292 intptr_t* _reg_args; | |
293 intptr_t* _fp_identifiers; | |
294 unsigned int _num_args; | |
295 | |
296 #ifdef ASSERT | |
297 void verify_tag(frame::Tag t) { | |
298 assert(!TaggedStackInterpreter || | |
299 *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag"); | |
300 } | |
301 #endif // ASSERT | |
302 | |
303 virtual void pass_int() | |
304 { | |
305 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); | |
306 debug_only(verify_tag(frame::TagValue)); | |
307 _from -= Interpreter::stackElementSize(); | |
308 | |
309 if (_num_args < Argument::n_int_register_parameters_c-1) { | |
310 *_reg_args++ = from_obj; | |
311 _num_args++; | |
312 } else { | |
313 *_to++ = from_obj; | |
314 } | |
315 } | |
316 | |
317 virtual void pass_long() | |
318 { | |
319 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); | |
320 debug_only(verify_tag(frame::TagValue)); | |
321 _from -= 2*Interpreter::stackElementSize(); | |
322 | |
323 if (_num_args < Argument::n_int_register_parameters_c-1) { | |
324 *_reg_args++ = from_obj; | |
325 _num_args++; | |
326 } else { | |
327 *_to++ = from_obj; | |
328 } | |
329 } | |
330 | |
331 virtual void pass_object() | |
332 { | |
333 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); | |
334 debug_only(verify_tag(frame::TagReference)); | |
335 _from -= Interpreter::stackElementSize(); | |
336 if (_num_args < Argument::n_int_register_parameters_c-1) { | |
337 *_reg_args++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; | |
338 _num_args++; | |
339 } else { | |
340 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; | |
341 } | |
342 } | |
343 | |
344 virtual void pass_float() | |
345 { | |
346 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); | |
347 debug_only(verify_tag(frame::TagValue)); | |
348 _from -= Interpreter::stackElementSize(); | |
349 | |
350 if (_num_args < Argument::n_float_register_parameters_c-1) { | |
351 *_reg_args++ = from_obj; | |
352 *_fp_identifiers |= (0x01 << (_num_args*2)); // mark as float | |
353 _num_args++; | |
354 } else { | |
355 *_to++ = from_obj; | |
356 } | |
357 } | |
358 | |
359 virtual void pass_double() | |
360 { | |
361 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); | |
362 debug_only(verify_tag(frame::TagValue)); | |
363 _from -= 2*Interpreter::stackElementSize(); | |
364 | |
365 if (_num_args < Argument::n_float_register_parameters_c-1) { | |
366 *_reg_args++ = from_obj; | |
367 *_fp_identifiers |= (0x3 << (_num_args*2)); // mark as double | |
368 _num_args++; | |
369 } else { | |
370 *_to++ = from_obj; | |
371 } | |
372 } | |
373 | |
374 public: | |
375 SlowSignatureHandler(methodHandle method, address from, intptr_t* to) | |
376 : NativeSignatureIterator(method) | |
377 { | |
378 _from = from; | |
379 _to = to; | |
380 | |
381 _reg_args = to - (method->is_static() ? 4 : 5); | |
382 _fp_identifiers = to - 2; | |
383 _to = _to + 4; // Windows reserves stack space for register arguments | |
384 *(int*) _fp_identifiers = 0; | |
385 _num_args = (method->is_static() ? 1 : 0); | |
386 } | |
387 }; | |
388 #else | |
389 class SlowSignatureHandler | |
390 : public NativeSignatureIterator { | |
391 private: | |
392 address _from; | |
393 intptr_t* _to; | |
394 intptr_t* _int_args; | |
395 intptr_t* _fp_args; | |
396 intptr_t* _fp_identifiers; | |
397 unsigned int _num_int_args; | |
398 unsigned int _num_fp_args; | |
399 | |
400 #ifdef ASSERT | |
401 void verify_tag(frame::Tag t) { | |
402 assert(!TaggedStackInterpreter || | |
403 *(intptr_t*)(_from+Interpreter::local_tag_offset_in_bytes(0)) == t, "wrong tag"); | |
404 } | |
405 #endif // ASSERT | |
406 | |
407 virtual void pass_int() | |
408 { | |
409 jint from_obj = *(jint *)(_from+Interpreter::local_offset_in_bytes(0)); | |
410 debug_only(verify_tag(frame::TagValue)); | |
411 _from -= Interpreter::stackElementSize(); | |
412 | |
413 if (_num_int_args < Argument::n_int_register_parameters_c-1) { | |
414 *_int_args++ = from_obj; | |
415 _num_int_args++; | |
416 } else { | |
417 *_to++ = from_obj; | |
418 } | |
419 } | |
420 | |
421 virtual void pass_long() | |
422 { | |
423 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); | |
424 debug_only(verify_tag(frame::TagValue)); | |
425 _from -= 2*Interpreter::stackElementSize(); | |
426 | |
427 if (_num_int_args < Argument::n_int_register_parameters_c-1) { | |
428 *_int_args++ = from_obj; | |
429 _num_int_args++; | |
430 } else { | |
431 *_to++ = from_obj; | |
432 } | |
433 } | |
434 | |
435 virtual void pass_object() | |
436 { | |
437 intptr_t *from_addr = (intptr_t*)(_from + Interpreter::local_offset_in_bytes(0)); | |
438 debug_only(verify_tag(frame::TagReference)); | |
439 _from -= Interpreter::stackElementSize(); | |
440 | |
441 if (_num_int_args < Argument::n_int_register_parameters_c-1) { | |
442 *_int_args++ = (*from_addr == 0) ? NULL : (intptr_t)from_addr; | |
443 _num_int_args++; | |
444 } else { | |
445 *_to++ = (*from_addr == 0) ? NULL : (intptr_t) from_addr; | |
446 } | |
447 } | |
448 | |
449 virtual void pass_float() | |
450 { | |
451 jint from_obj = *(jint*)(_from+Interpreter::local_offset_in_bytes(0)); | |
452 debug_only(verify_tag(frame::TagValue)); | |
453 _from -= Interpreter::stackElementSize(); | |
454 | |
455 if (_num_fp_args < Argument::n_float_register_parameters_c) { | |
456 *_fp_args++ = from_obj; | |
457 _num_fp_args++; | |
458 } else { | |
459 *_to++ = from_obj; | |
460 } | |
461 } | |
462 | |
463 virtual void pass_double() | |
464 { | |
465 intptr_t from_obj = *(intptr_t*)(_from+Interpreter::local_offset_in_bytes(1)); | |
466 _from -= 2*Interpreter::stackElementSize(); | |
467 | |
468 if (_num_fp_args < Argument::n_float_register_parameters_c) { | |
469 *_fp_args++ = from_obj; | |
470 *_fp_identifiers |= (1 << _num_fp_args); // mark as double | |
471 _num_fp_args++; | |
472 } else { | |
473 *_to++ = from_obj; | |
474 } | |
475 } | |
476 | |
477 public: | |
478 SlowSignatureHandler(methodHandle method, address from, intptr_t* to) | |
479 : NativeSignatureIterator(method) | |
480 { | |
481 _from = from; | |
482 _to = to; | |
483 | |
484 _int_args = to - (method->is_static() ? 14 : 15); | |
485 _fp_args = to - 9; | |
486 _fp_identifiers = to - 10; | |
487 *(int*) _fp_identifiers = 0; | |
488 _num_int_args = (method->is_static() ? 1 : 0); | |
489 _num_fp_args = 0; | |
490 } | |
491 }; | |
492 #endif | |
493 | |
494 | |
495 IRT_ENTRY(address, | |
496 InterpreterRuntime::slow_signature_handler(JavaThread* thread, | |
497 methodOopDesc* method, | |
498 intptr_t* from, | |
499 intptr_t* to)) | |
500 methodHandle m(thread, (methodOop)method); | |
501 assert(m->is_native(), "sanity check"); | |
502 | |
503 // handle arguments | |
504 SlowSignatureHandler(m, (address)from, to + 1).iterate(UCONST64(-1)); | |
505 | |
506 // return result handler | |
507 return Interpreter::result_handler(m->result_type()); | |
508 IRT_END |