- added gnu header
[cacao.git] / src / vm / jit / x86_64 / asmpart.S
1 /* jit/x86_64/asmpart.S - Java-C interface functions for x86_64
2
3    Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
4    Institut f. Computersprachen, TU Wien
5    R. Grafl, A. Krall, C. Kruegel, C. Oates, R. Obermaisser, M. Probst,
6    S. Ring, E. Steiner, C. Thalinger, D. Thuernbeck, P. Tomsich,
7    J. Wenninger
8
9    This file is part of CACAO.
10
11    This program is free software; you can redistribute it and/or
12    modify it under the terms of the GNU General Public License as
13    published by the Free Software Foundation; either version 2, or (at
14    your option) any later version.
15
16    This program is distributed in the hope that it will be useful, but
17    WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    General Public License for more details.
20
21    You should have received a copy of the GNU General Public License
22    along with this program; if not, write to the Free Software
23    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
24    02111-1307, USA.
25
26    Contact: cacao@complang.tuwien.ac.at
27
28    Authors: Andreas Krall
29             Reinhard Grafl
30             Christian Thalinger
31
32    $Id: asmpart.S 713 2003-12-07 20:40:43Z twisti $
33
34 */
35
36
37 #include "offsets.h"
38
39         .text
40
41
42 /********************* exported functions and variables ***********************/
43
44         .globl asm_calljavamethod
45         .globl asm_calljavafunction
46         .globl asm_calljavafunction2
47         .globl asm_calljavafunction2long
48         .globl asm_calljavafunction2double
49         .globl asm_call_jit_compiler
50         .globl asm_dumpregistersandcall
51         .globl asm_handle_exception
52         .globl asm_handle_nat_exception
53         .globl asm_builtin_checkcast    
54         .globl asm_builtin_checkarraycast
55         .globl asm_builtin_anewarray
56         .globl asm_builtin_newarray_array
57         .globl asm_builtin_aastore
58         .globl asm_builtin_monitorenter
59         .globl asm_builtin_monitorexit
60     .globl asm_builtin_f2i
61     .globl asm_builtin_f2l
62     .globl asm_builtin_d2i
63     .globl asm_builtin_d2l
64         .globl asm_builtin_arrayinstanceof
65         .globl asm_perform_threadswitch
66         .globl asm_initialize_thread_stack
67         .globl asm_switchstackandcall
68         .globl asm_getcallingmethod
69     .globl asm_builtin_trace
70     .globl asm_builtin_exittrace
71     
72 /*************************** imported functions *******************************/
73
74         .globl jit_compile
75         .globl builtin_monitorexit
76         .globl builtin_throw_exception
77         .globl builtin_trace_exception
78         .globl findmethod
79
80         
81 /********************* function asm_calljavamethod *****************************
82 *                                                                              *
83 *   This function calls a Java-method (which possibly needs compilation)       *
84 *   with up to 4 parameters.                                                   *
85 *                                                                              *
86 *   This functions calls the JIT-compiler which eventually translates the      *
87 *   method into machine code.                                                  *
88 *                                                                              *
89 *   An possibly throwed exception will be returned to the caller as function   *
90 *   return value, so the java method cannot return a fucntion value (this      *
91 *   function usually calls 'main' and '<clinit>' which do not return a         *
92 *   function value).                                                           *
93 *                                                                              *
94 *   C-prototype:                                                               *
95 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
96 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
97 *                                                                              *
98 *******************************************************************************/
99
100 #define         MethodPointer   -8
101 #define         FrameSize       -12
102 #define     IsSync          -16
103 #define     IsLeaf          -20
104 #define     IntSave         -24
105 #define     FltSave         -28
106 #define     ExTableSize     -32
107 #define     ExTableStart    -32
108
109 #define     ExEntrySize     -32
110 #define     ExStartPC       -8
111 #define     ExEndPC         -16
112 #define     ExHandlerPC     -24
113 #define     ExCatchType     -32
114
115 call_name:
116         .ascii  "calljavamethod\0\0"
117
118         .align  8
119         .quad   0                         /* catch type all                       */
120         .quad   calljava_xhandler         /* handler pc                           */
121         .quad   calljava_xhandler         /* end pc                               */
122         .quad   asm_calljavamethod        /* start pc                             */
123         .long   1                         /* extable size                         */
124         .long   0                         /* fltsave                              */
125         .long   0                         /* intsave                              */
126         .long   0                         /* isleaf                               */
127         .long   0                         /* IsSync                               */
128         .long   8                         /* frame size                           */
129         .quad   0                         /* method pointer (pointer to name)     */
130
131 asm_calljavamethod:
132         sub     $8,%rsp               /* keep %rsp 16-byte aligned            */
133         mov     %rbp,(%rsp)
134         
135         mov     %rdi,%rax             /* move function pointer to %rax        */
136                                       /* compilerstub uses this               */
137         
138         mov     %rsi,%rdi             /* pass remaining parameters            */
139         mov     %rdx,%rsi
140         mov     %rcx,%rdx
141         mov     %r8,%rcx
142         
143         lea             asm_call_jit_compiler,%r11
144         call    *%r11                 /* call JIT compiler                    */
145                 
146 calljava_jit:
147 calljava_return:
148 calljava_ret:
149         xor     %rax,%rax
150         mov     (%rsp),%rbp
151         add     $8,%rsp               /* keep %rsp 16-byte aligned            */
152         ret
153
154 calljava_xhandler:
155         mov     %rax,%rdi                         /* pass exception pointer               */
156         call    builtin_throw_exception
157         mov     (%rsp),%rbp
158         add     $8,%rsp
159         ret
160
161
162 /********************* function asm_calljavafunction ***************************
163 *                                                                              *
164 *   This function calls a Java-method (which possibly needs compilation)       *
165 *   with up to 4 address parameters.                                           *
166 *                                                                              *
167 *   This functions calls the JIT-compiler which eventually translates the      *
168 *   method into machine code.                                                  *
169 *                                                                              *
170 *   C-prototype:                                                               *
171 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
172 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
173 *                                                                              *
174 *******************************************************************************/
175
176 call_name2:
177         .ascii  "calljavafunction\0\0"
178
179         .align  8
180         .quad   0                         /* catch type all                       */
181         .quad   calljava_xhandler2        /* handler pc                           */
182         .quad   calljava_xhandler2        /* end pc                               */
183         .quad   asm_calljavafunction      /* start pc                             */
184         .long   1                         /* extable size                         */
185         .long   0                         /* fltsave                              */
186         .long   0                         /* intsave                              */
187         .long   0                         /* isleaf                               */
188         .long   0                         /* IsSync                               */
189         .long   8                         /* frame size                           */
190         .quad   0                         /* method pointer (pointer to name)     */
191
192 asm_calljavafunction:
193         sub     $8,%rsp               /* keep stack 16-byte aligned           */
194         mov     %rbp,(%rsp)
195         mov     %rdi,%rax             /* move function pointer to %rax        */
196                                       /* compilerstub uses this               */
197
198         mov     %rsi,%rdi             /* pass remaining parameters            */
199         mov     %rdx,%rsi
200         mov     %rcx,%rdx
201         mov     %r8,%rcx
202         
203         lea     asm_call_jit_compiler,%r11
204         call    *%r11                 /* call JIT compiler                    */
205         
206 calljava_jit2:
207 calljava_return2:
208 calljava_ret2:
209         mov     (%rsp),%rbp
210         add     $8,%rsp               /* free stack space                     */
211         ret
212
213 calljava_xhandler2:
214         mov     %rax,%rdi                 /* pass exception pointer               */
215         call    builtin_throw_exception
216         mov     (%rsp),%rbp
217         add     $8,%rsp
218         ret
219                                                 
220
221 /********************* function asm_calljavafunction ***************************
222 *                                                                              *
223 *   This function calls a Java-method (which possibly needs compilation)       *
224 *   with up to 4 address parameters.                                           *
225 *                                                                              *
226 *   This functions calls the JIT-compiler which eventually translates the      *
227 *   method into machine code.                                                  *
228 *                                                                              *
229 *   C-prototype:                                                               *
230 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
231 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
232 *                                                                              *
233 *******************************************************************************/
234
235 call_name3:
236         .ascii  "calljavafunction2\0\0"
237
238         .align  8
239         .quad   0                         /* catch type all                       */
240         .quad   calljava_xhandler3        /* handler pc                           */
241         .quad   calljava_xhandler3        /* end pc                               */
242         .quad   asm_calljavafunction2     /* start pc                             */
243         .long   1                         /* extable size                         */
244         .long   0                         /* fltsave                              */
245         .long   0                         /* intsave                              */
246         .long   0                         /* isleaf                               */
247         .long   0                         /* IsSync                               */
248         .long   8                         /* frame size                           */
249         .quad   0                         /* method pointer (pointer to name)     */
250
251 asm_calljavafunction2:
252 asm_calljavafunction2double:
253 asm_calljavafunction2long:
254         sub     $8,%rsp               /* keep stack 16-byte aligned           */
255
256         mov     %rdi,%rax             /* save method pointer for compiler     */
257         mov     %rcx,%r10             /* pointer to arg block                 */
258         
259         mov     offjniitem(%r10),%rdi /* move args into registers             */
260         mov     offjniitem + sizejniblock * 1(%r10),%rsi
261         mov     offjniitem + sizejniblock * 2(%r10),%rdx
262         mov     offjniitem + sizejniblock * 3(%r10),%rcx
263         
264         lea     asm_call_jit_compiler,%r11
265         call    *%r11                 /* call JIT compiler                    */
266         
267 calljava_jit3:
268 calljava_return3:
269 calljava_ret3:
270         add     $8,%rsp               /* free stack space                     */
271         ret
272
273 calljava_xhandler3:
274         mov     %rax,%rdi                 /* pass exception pointer               */
275         call    builtin_throw_exception
276         add     $8,%rsp
277         ret
278                                                 
279
280 /****************** function asm_call_jit_compiler *****************************
281 *                                                                              *
282 *   invokes the compiler for untranslated JavaVM methods.                      *
283 *                                                                              *
284 *   Register R0 contains a pointer to the method info structure (prepared      *
285 *   by createcompilerstub). Using the return address in R26 and the            *
286 *   offset in the LDA instruction or using the value in methodptr R28 the      *
287 *   patching address for storing the method address can be computed:           *
288 *                                                                              *
289 *   method address was either loaded using                                     *
290 *                                                                              *
291 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
292 *   i386_call_reg(REG_ITMP2)                                                   *
293 *                                                                              *
294 *   or                                                                         *
295 *                                                                              *
296 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP2)    ; invokevirtual/interface    *
297 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3)                *
298 *   i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \                *
299 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
300 *   i386_call_reg(REG_ITMP1)                                                   *
301 *                                                                              *
302 *   in the static case the method pointer can be computed using the            *
303 *   return address and the lda function following the jmp instruction          *
304 *                                                                              *
305 *******************************************************************************/
306
307
308 asm_call_jit_compiler:
309         sub     $8,%rsp         /* keep stack 16-byte aligned                 */
310
311         mov     %rbx,(%rsp)     /* save register                              */
312         
313         mov     8(%rsp),%r11    /* get return address                         */
314         mov     -1(%r11),%bl    /* get function code                          */
315         cmp     $0xd2,%bl               /* called with `call *REG_ITMP2' (%r10)?      */
316         jne     L_not_static_special
317
318         sub     $11,%r11        /* calculate address of immediate             */
319         jmp             L_call_jit_compile
320                 
321 L_not_static_special:
322                 cmp     $0xd0,%bl               /* called with `call *REG_ITMP1' (%rax)       */
323                 jne     L_not_virtual_interface
324                 
325                 sub     $7,%r11         /* calculate address of offset                */
326                 mov     (%r11),%r11d    /* get offset (32-bit)                        */
327                 add     %r10,%r11       /* add base address to get method address     */
328                 jmp     L_call_jit_compile
329
330 L_not_virtual_interface:        /* a call from asm_calljavamethod             */
331                 xor     %r11,%r11
332                 
333 L_call_jit_compile:
334         mov     (%rsp),%rbx     /* restore register                           */
335         
336         sub     $(24*8),%rsp    /* 8 + 48 + 64 + 64                           */
337         
338                 mov     %r11,0*8(%rsp)  /* save address for method pointer            */
339
340         mov     %rdi,1*8(%rsp)  /* save arguments                             */
341         mov     %rsi,2*8(%rsp)
342         mov     %rdx,3*8(%rsp)
343         mov     %rcx,4*8(%rsp)
344         mov     %r8,5*8(%rsp)
345         mov     %r9,6*8(%rsp)
346
347         movq    %xmm0,7*8(%rsp)
348         movq    %xmm1,8*8(%rsp)
349         movq    %xmm2,9*8(%rsp)
350         movq    %xmm3,10*8(%rsp)
351         movq    %xmm4,11*8(%rsp)
352         movq    %xmm5,12*8(%rsp)
353         movq    %xmm6,13*8(%rsp)
354         movq    %xmm7,14*8(%rsp)
355
356         movq    %xmm8,15*8(%rsp) /* we use them as callee saved registers      */
357         movq    %xmm9,16*8(%rsp)
358         movq    %xmm10,17*8(%rsp)
359         movq    %xmm11,18*8(%rsp)
360         movq    %xmm12,19*8(%rsp)
361         movq    %xmm13,20*8(%rsp)
362         movq    %xmm14,21*8(%rsp)
363         movq    %xmm15,22*8(%rsp)
364
365         mov     %rax,%rdi       /* pass method pointer                        */
366                 call    jit_compile
367
368         mov     0*8(%rsp),%r11
369         
370         mov     1*8(%rsp),%rdi
371         mov     2*8(%rsp),%rsi
372         mov     3*8(%rsp),%rdx
373         mov     4*8(%rsp),%rcx
374         mov     5*8(%rsp),%r8
375         mov     6*8(%rsp),%r9
376
377         movq    7*8(%rsp),%xmm0
378         movq    8*8(%rsp),%xmm1
379         movq    9*8(%rsp),%xmm2
380         movq    10*8(%rsp),%xmm3
381         movq    11*8(%rsp),%xmm4
382         movq    12*8(%rsp),%xmm5
383         movq    13*8(%rsp),%xmm6
384         movq    14*8(%rsp),%xmm7
385
386         movq    15*8(%rsp),%xmm8
387         movq    16*8(%rsp),%xmm9
388         movq    17*8(%rsp),%xmm10
389         movq    18*8(%rsp),%xmm11
390         movq    19*8(%rsp),%xmm12
391         movq    20*8(%rsp),%xmm13
392         movq    21*8(%rsp),%xmm14
393         movq    22*8(%rsp),%xmm15
394
395         add     $(24*8),%rsp
396
397                 test    %r11,%r11               /* is address == 0 (asm_calljavamethod)       */
398                 je              L_call_method
399                 
400                 mov     %rax,(%r11)             /* and now save the new pointer               */
401
402 L_call_method:
403         add     $8,%rsp         /* keep stack 16-byte aligned                 */
404                 jmp             *%rax                   /* ...and now call the new method             */
405
406
407
408 /****************** function asm_dumpregistersandcall **************************
409 *                                                                              *
410 *   This funtion saves all callee saved registers and calls the function       *
411 *   which is passed as parameter.                                              *
412 *                                                                              *
413 *   This function is needed by the garbage collector, which needs to access    *
414 *   all registers which are stored on the stack. Unused registers are          *
415 *   cleared to avoid interferances with the GC.                                *
416 *                                                                              *
417 *   void asm_dumpregistersandcall (functionptr f);                             *
418 *                                                                              *
419 *******************************************************************************/
420
421 asm_dumpregistersandcall:
422         sub     $(7*8),%rsp             /* allocate stack space               */
423
424         mov     %rbx,0*8(%rsp)          /* save all callee saved registers    */
425         mov     %rsp,1*8(%rsp)
426         mov     %rbp,2*8(%rsp)
427         mov     %r12,3*8(%rsp)
428         mov     %r13,4*8(%rsp)
429         mov     %r14,5*8(%rsp)
430         mov     %r15,6*8(%rsp)
431
432         xor     %rax,%rax               /* intialize the remaining registers  */
433         xor     %rcx,%rcx
434         xor     %rdx,%rdx
435         xor     %rsi,%rsi
436         xor     %r8,%r8
437         xor     %r9,%r9
438         xor     %r10,%r10
439         xor     %r11,%r11
440         
441         call    *%rdi                   /* call function                      */
442
443         mov     0*8(%rsp),%rbx
444         mov     1*8(%rsp),%rsp
445         mov     2*8(%rsp),%rbp
446         mov     3*8(%rsp),%r12
447         mov     4*8(%rsp),%r13
448         mov     5*8(%rsp),%r14
449         mov     6*8(%rsp),%r15
450
451         add     $(7*8),%rsp        
452         ret
453
454
455 /********************* function asm_handle_exception ***************************
456 *                                                                              *
457 *   This function handles an exception. It does not use the usual calling      *
458 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
459 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
460 *   the local exception table for a handler. If no one is found, it unwinds    *
461 *   stacks and continues searching the callers.                                *
462 *                                                                              *
463 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
464 *                                                                              *
465 *******************************************************************************/
466
467 asm_handle_nat_exception:
468         add     $8,%rsp                                         /* clear return address of native stub */
469                 
470 asm_handle_exception:
471         sub     $(4*8),%rsp
472         mov     %rax,0*8(%rsp)              /* save exception pointer         */
473         mov     %r10,1*8(%rsp)              /* save exception pc              */
474         
475         mov     %r10,%rdi                   /* exception pc                   */
476         call    findmethod
477         mov     %rax,%r11
478         mov     %rax,2*8(%rsp)                          /* save data segment pointer      */
479         
480         mov     0*8(%rsp),%rax              /* restore exception pointer      */
481         mov     1*8(%rsp),%r10              /* restore exception pc           */
482         
483 ex_stack_loop:
484         mov     %rax,%rdi                                       /* exception pointer              */
485         mov     MethodPointer(%r11),%rsi        /* method pointer                 */
486         mov     %r10,%rdx                   /* exception pc                   */
487         mov     $1,%rcx                                         /* set no unwind flag             */
488         call    builtin_trace_exception
489
490                 mov     2*8(%rsp),%r11                          /* %r11 = data segment pointer    */
491                 mov     ExTableSize(%r11),%rcx          /* %rcx = exception table size    */
492                 test    %rcx,%rcx                                       /* if empty table skip            */
493                 je              empty_table
494
495                 lea             ExTableStart(%r11),%rdi         /* %rdi = start of exception table */
496                 mov     0*8(%rsp),%rax                          /* get xptr                       */
497                 
498 ex_table_loop:
499                 mov     1*8(%rsp),%r10              /* get xpc                        */
500                 
501                 mov     ExStartPC(%rdi),%rdx        /* %rdx = exception start pc      */
502                 cmp     %r10,%rdx                   /* %rdx = (startpc <= xpc)        */
503                 jg              ex_table_cont               /* if (false) continue            */
504                 mov     ExEndPC(%rdi),%rdx          /* %rdx = exception end pc        */
505                 cmp     %rdx,%r10                   /* %rdx = (xpc < endpc)           */
506                 jge             ex_table_cont               /* if (false) continue            */
507                 mov     ExCatchType(%rdi),%rdx      /* %rdx = exception catch type    */
508                 test    %rdx,%rdx                   /* NULL catches everything        */
509                 je              ex_handle_it
510
511                 mov     offobjvftbl(%rax),%rsi      /* %rsi = vftblptr(xptr)          */
512                 mov     offclassvftbl(%rdx),%rdx    /* %rdx = vftblptr(catchtype) class (not obj) */
513                 mov     offbaseval(%rsi),%esi       /* %esi = baseval(xptr)           */
514                 mov     offbaseval(%rdx),%r10d      /* %r10d = baseval(catchtype)     */
515                 mov     offdiffval(%rdx),%edx       /* %edx = diffval(catchtype)      */
516                 sub     %r10d,%esi                  /* %esi = baseval(xptr) - baseval(catchtype) */
517                 cmp     %edx,%esi                   /* xptr is instanceof catchtype   */
518                 ja              ex_table_cont
519                 
520 ex_handle_it:
521                 mov     ExHandlerPC(%rdi),%r10      /* xpc = exception handler pc     */
522
523         mov     0*8(%rsp),%rax              /* restore exception pointer      */
524         add     $(4*8),%rsp                 /* free stack frame               */
525
526         jmp             *%r10                       /* jump to the handler            */
527
528 ex_table_cont:
529         lea             ExEntrySize(%rdi),%rdi      /* next exception table entry     */
530         dec     %rcx                        /* decrement entry counter        */
531         test    %rcx,%rcx                   /* if (t0 > 0) next entry         */
532         jg              ex_table_loop
533                 
534 empty_table:
535         mov     0*8(%rsp),%rax              /* restore exception pointer      */
536         mov     1*8(%rsp),%r10              /* restore exception pc           */
537         mov     2*8(%rsp),%r11                          /* restore data segment pointer   */
538         add     $(4*8),%rsp
539         
540                 mov     %rax,%rcx                                       /* save exception pointer         */
541                                 
542 ex_already_cleared:             
543                 movl    IsSync(%r11),%eax                       /* %rax = SyncOffset              */
544                 test    %rax,%rax                                       /* if zero no monitorexit         */
545                 je              no_monitor_exit
546                 
547                 add     %rsp,%rax
548                 mov     -8(%rax),%rdi
549
550         sub     $(4*8),%rsp
551         mov     %rcx,0*8(%rsp)
552         mov     %r10,1*8(%rsp)
553         mov     %r11,2*8(%rsp)
554         
555                 call    builtin_monitorexit
556
557         mov     0*8(%rsp),%rcx
558         mov     1*8(%rsp),%r10
559         mov     2*8(%rsp),%r11
560         add     $(4*8),%rsp
561                 
562 no_monitor_exit:
563                 mov             FrameSize(%r11),%eax        /* %eax = frame size              */
564                 add             %rax,%rsp                   /* unwind stack                   */
565                 mov             %rsp,%rax                   /* %rax = pointer to save area    */
566
567                 mov             IntSave(%r11),%edx          /* %edx = saved int register count */
568         test    %edx,%edx
569         je              noint
570         
571                 cmp     $1,%edx
572                 je              int1
573                 cmp             $2,%edx
574                 je              int2
575                 cmp             $3,%edx
576                 je              int3
577                 cmp             $4,%edx
578                 je              int4
579                 cmp             $5,%edx
580                 je              int5
581         
582         mov     -48(%rax),%rbx
583 int5:   
584         mov     -40(%rax),%rbp
585 int4:   
586         mov     -32(%rax),%r12
587 int3:   
588         mov     -24(%rax),%r13
589 int2:   
590                 mov     -16(%rax),%r14
591 int1:   
592                 mov     -8(%rax),%r15
593
594                 shl             $3,%edx                     /* multiply by 8 bytes             */
595                 sub     %rdx,%rax
596                 
597 noint:
598                 mov     FltSave(%r11),%edx          /* %edx = saved flt register count */
599                 test    %edx,%edx
600                 je      noflt
601
602         cmpl    $1,%edx
603         je      flt1
604         cmpl    $2,%edx
605         je      flt2
606         cmpl    $3,%edx
607         je      flt3
608         cmpl    $4,%edx
609         je      flt4
610         cmpl    $5,%edx
611         je      flt5
612         cmpl    $6,%edx
613         je      flt7
614         cmpl    $7,%edx
615         je      flt7
616
617         movq    -64(%rax),%xmm8
618 flt7:   
619         movq    -56(%rax),%xmm9
620 flt6:   
621         movq    -48(%rax),%xmm10
622 flt5:   
623         movq    -40(%rax),%xmm11
624 flt4:   
625         movq    -32(%rax),%xmm12
626 flt3:   
627         movq    -24(%rax),%xmm13
628 flt2:   
629         movq    -16(%rax),%xmm14
630 flt1:   
631         movq    -8(%rax),%xmm15
632                 
633 noflt:                                  
634                 pop     %r10                                            /* the new xpc is return address  */
635                 sub     $3,%r10                     /* subtract 3 bytes for call      */
636
637         sub     $(2*8),%rsp
638         mov     %rcx,0*8(%rsp)
639         mov     %r10,1*8(%rsp)
640
641         mov     %r10,%rdi
642         call    findmethod                              /* get the new data segment ptr   */
643         mov     %rax,%r11
644         
645         mov     0*8(%rsp),%rcx
646         mov     1*8(%rsp),%r10
647         add     $(2*8),%rsp
648
649         mov     %rcx,%rax                                       /* restore saved exception pointer */
650
651         sub     $(4*8),%rsp
652                                         
653         mov     %rax,0*8(%rsp)              /* save exception pointer         */
654         mov     %r10,1*8(%rsp)              /* save exception pc              */
655                 mov     %r11,2*8(%rsp)                          /* save data segment pointer      */
656                 
657                 jmp             ex_stack_loop
658
659
660 /********************* function asm_builtin_monitorenter ***********************
661 *                                                                              *
662 *   Does null check and calls monitorenter or throws an exception              *
663 *                                                                              *
664 *******************************************************************************/
665
666 asm_builtin_monitorenter:
667         test    %rdi,%rdi
668         je      nb_monitorenter                 /* if (null) throw exception          */
669         jmp     builtin_monitorenter    /* else call builtin_monitorenter     */
670
671 nb_monitorenter:
672         pop     %r10                                    /* delete return address */
673         sub     $3,%r10                                 /* faulting address is return adress - 3 */
674         mov     proto_java_lang_NullPointerException,%rax
675         jmp     asm_handle_exception
676                 
677
678 /********************* function asm_builtin_monitorexit ************************
679 *                                                                              *
680 *   Does null check and calls monitorexit or throws an exception               *
681 *                                                                              *
682 *******************************************************************************/
683
684 asm_builtin_monitorexit:
685         test    %rdi,%rdi
686         je      nb_monitorexit                  /* if (null) throw exception          */
687         jmp     builtin_monitorexit             /* else call builtin_monitorenter     */
688
689 nb_monitorexit:
690         pop     %r10                                    /* delete return address */
691         sub     $3,%r10                                 /* faulting address is return adress - 3 */
692         mov     proto_java_lang_NullPointerException,%rax
693         jmp     asm_handle_exception
694
695
696 /********************* function asm_builtin_x2x ********************************
697 *                                                                              *
698 *   Wrapper functions for float to int corner cases                            *
699 *                                                                              *
700 *******************************************************************************/
701
702 asm_builtin_f2i:
703         sub     $(14*8),%rsp
704
705         mov     %rdi,0*8(%rsp)
706         mov     %rsi,1*8(%rsp)
707         mov     %rdx,2*8(%rsp)
708         mov     %rcx,3*8(%rsp)
709         mov     %r8,4*8(%rsp)
710         mov     %r9,5*8(%rsp)
711         
712         movq    %xmm0,6*8(%rsp)
713         movq    %xmm1,7*8(%rsp)
714         movq    %xmm2,8*8(%rsp)
715         movq    %xmm3,9*8(%rsp)
716         movq    %xmm4,10*8(%rsp)
717         movq    %xmm5,11*8(%rsp)
718         movq    %xmm6,12*8(%rsp)
719         movq    %xmm7,13*8(%rsp)
720
721         movq    %xmm8,%xmm0
722         call    builtin_f2i
723         
724         mov     0*8(%rsp),%rdi
725         mov     1*8(%rsp),%rsi
726         mov     2*8(%rsp),%rdx
727         mov     3*8(%rsp),%rcx
728         mov     4*8(%rsp),%r8
729         mov     5*8(%rsp),%r9
730
731         movq    6*8(%rsp),%xmm0
732         movq    7*8(%rsp),%xmm1
733         movq    8*8(%rsp),%xmm2
734         movq    9*8(%rsp),%xmm3
735         movq    10*8(%rsp),%xmm4
736         movq    11*8(%rsp),%xmm5
737         movq    12*8(%rsp),%xmm6
738         movq    13*8(%rsp),%xmm7
739         
740         add     $(14*8),%rsp
741         ret
742
743 asm_builtin_f2l:
744         sub     $(14*8),%rsp
745
746         mov     %rdi,0*8(%rsp)
747         mov     %rsi,1*8(%rsp)
748         mov     %rdx,2*8(%rsp)
749         mov     %rcx,3*8(%rsp)
750         mov     %r8,4*8(%rsp)
751         mov     %r9,5*8(%rsp)
752         
753         movq    %xmm0,6*8(%rsp)
754         movq    %xmm1,7*8(%rsp)
755         movq    %xmm2,8*8(%rsp)
756         movq    %xmm3,9*8(%rsp)
757         movq    %xmm4,10*8(%rsp)
758         movq    %xmm5,11*8(%rsp)
759         movq    %xmm6,12*8(%rsp)
760         movq    %xmm7,13*8(%rsp)
761
762         movq    %xmm8,%xmm0
763         call    builtin_f2l
764         
765         mov     0*8(%rsp),%rdi
766         mov     1*8(%rsp),%rsi
767         mov     2*8(%rsp),%rdx
768         mov     3*8(%rsp),%rcx
769         mov     4*8(%rsp),%r8
770         mov     5*8(%rsp),%r9
771
772         movq    6*8(%rsp),%xmm0
773         movq    7*8(%rsp),%xmm1
774         movq    8*8(%rsp),%xmm2
775         movq    9*8(%rsp),%xmm3
776         movq    10*8(%rsp),%xmm4
777         movq    11*8(%rsp),%xmm5
778         movq    12*8(%rsp),%xmm6
779         movq    13*8(%rsp),%xmm7
780         
781         add     $(14*8),%rsp
782         ret
783
784                 
785 asm_builtin_d2i:
786         sub     $(14*8),%rsp
787
788         mov     %rdi,0*8(%rsp)
789         mov     %rsi,1*8(%rsp)
790         mov     %rdx,2*8(%rsp)
791         mov     %rcx,3*8(%rsp)
792         mov     %r8,4*8(%rsp)
793         mov     %r9,5*8(%rsp)
794         
795         movq    %xmm0,6*8(%rsp)
796         movq    %xmm1,7*8(%rsp)
797         movq    %xmm2,8*8(%rsp)
798         movq    %xmm3,9*8(%rsp)
799         movq    %xmm4,10*8(%rsp)
800         movq    %xmm5,11*8(%rsp)
801         movq    %xmm6,12*8(%rsp)
802         movq    %xmm7,13*8(%rsp)
803
804         movq    %xmm8,%xmm0
805         call    builtin_d2i
806         
807         mov     0*8(%rsp),%rdi
808         mov     1*8(%rsp),%rsi
809         mov     2*8(%rsp),%rdx
810         mov     3*8(%rsp),%rcx
811         mov     4*8(%rsp),%r8
812         mov     5*8(%rsp),%r9
813
814         movq    6*8(%rsp),%xmm0
815         movq    7*8(%rsp),%xmm1
816         movq    8*8(%rsp),%xmm2
817         movq    9*8(%rsp),%xmm3
818         movq    10*8(%rsp),%xmm4
819         movq    11*8(%rsp),%xmm5
820         movq    12*8(%rsp),%xmm6
821         movq    13*8(%rsp),%xmm7
822         
823         add     $(14*8),%rsp
824         ret
825
826
827 asm_builtin_d2l:
828         sub     $(14*8),%rsp
829
830         mov     %rdi,0*8(%rsp)
831         mov     %rsi,1*8(%rsp)
832         mov     %rdx,2*8(%rsp)
833         mov     %rcx,3*8(%rsp)
834         mov     %r8,4*8(%rsp)
835         mov     %r9,5*8(%rsp)
836         
837         movq    %xmm0,6*8(%rsp)
838         movq    %xmm1,7*8(%rsp)
839         movq    %xmm2,8*8(%rsp)
840         movq    %xmm3,9*8(%rsp)
841         movq    %xmm4,10*8(%rsp)
842         movq    %xmm5,11*8(%rsp)
843         movq    %xmm6,12*8(%rsp)
844         movq    %xmm7,13*8(%rsp)
845
846         movq    %xmm8,%xmm0
847         call    builtin_d2l
848         
849         mov     0*8(%rsp),%rdi
850         mov     1*8(%rsp),%rsi
851         mov     2*8(%rsp),%rdx
852         mov     3*8(%rsp),%rcx
853         mov     4*8(%rsp),%r8
854         mov     5*8(%rsp),%r9
855
856         movq    6*8(%rsp),%xmm0
857         movq    7*8(%rsp),%xmm1
858         movq    8*8(%rsp),%xmm2
859         movq    9*8(%rsp),%xmm3
860         movq    10*8(%rsp),%xmm4
861         movq    11*8(%rsp),%xmm5
862         movq    12*8(%rsp),%xmm6
863         movq    13*8(%rsp),%xmm7
864         
865         add     $(14*8),%rsp
866         ret
867
868         
869 /*********************** function new_builtin_checkcast ************************
870 *                                                                              *
871 *   Does the cast check and eventually throws an exception                     *
872 *                                                                              *
873 *******************************************************************************/
874
875 asm_builtin_checkcast:
876         xor     %rax,%rax
877         mov     %rax,(%rax)
878         ret
879
880                 
881 /******************* function asm_builtin_checkarraycast ***********************
882 *                                                                              *
883 *   Does the cast check and eventually throws an exception                     *
884 *                                                                              *
885 *******************************************************************************/
886
887 asm_builtin_checkarraycast:
888         sub     $24,%rsp                                /* keep stack 16-byte aligned         */
889         mov     %rdi,(%rsp)                             /* save object pointer                */
890         call    builtin_checkarraycast  /* builtin_checkarraycast             */
891         test    %rax,%rax               /* if (false) throw exception         */
892         je      nb_carray_throw
893         mov     (%rsp),%rax             /* return object pointer              */
894         add     $24,%rsp                /* free stack space                   */
895         ret
896
897 nb_carray_throw:
898         add     $24,%rsp
899         pop     %r10                                    /* delete return address              */
900         sub     $3,%r10                                 /* faulting address is return adress - 3 */
901         mov     proto_java_lang_ClassCastException,%rax
902         jmp     asm_handle_exception
903
904                 
905 /******************* function asm_builtin_aastore ******************************
906 *                                                                              *
907 *   Does the cast check and eventually throws an exception                     *
908 *                                                                              *
909 *******************************************************************************/
910
911 asm_builtin_aastore:
912         sub     $24,%rsp                        /* allocate stack space               */
913         test    %rdi,%rdi                               /* if null pointer throw exception    */
914         je      nb_aastore_null
915
916         movl    offarraysize(%rdi),%eax /* load size                          */
917         cmpl    %eax,%esi                               /* do bound check                     */
918         ja      nb_aastore_bound                /* if out of bounds throw exception   */
919
920         shl     $3,%rsi                                 /* index * 8                          */
921         mov     %rdi,%r10
922         add     %rsi,%r10                               /* add index * 8 to arrayref          */
923                 
924         mov     %r10,(%rsp)                     /* save store position                */
925         mov     %rdx,8(%rsp)            /* save object                        */
926         
927         mov     %rdx,%rsi               /* object is second argument          */
928         call    builtin_canstore                /* builtin_canstore(arrayref,object)  */
929         test    %rax,%rax                               /* if (false) throw exception         */
930         je      nb_aastore_throw
931
932         mov     (%rsp),%r10             /* restore store position             */
933         mov     8(%rsp),%rdx            /* restore object                     */
934         mov     %rdx,offobjarrdata(%r10)/* store objectptr in array           */
935         add     $24,%rsp                /* free stack space                   */
936         ret
937
938 nb_aastore_null:
939         add     $24,%rsp
940         pop     %r10                                    /* delete return address */
941         sub     $3,%r10                                 /* faulting address is return adress - 3 */
942                 
943         mov     proto_java_lang_NullPointerException,%rax
944         jmp     asm_handle_exception
945
946 nb_aastore_bound:
947         add     $24,%rsp
948         pop     %r10                                    /* delete return address */
949         sub     $3,%r10                                 /* faulting address is return adress - 3 */
950                 
951         mov     proto_java_lang_ArrayIndexOutOfBoundsException,%rax
952         jmp     asm_handle_exception
953                 
954 nb_aastore_throw:
955         add     $24,%rsp
956         pop     %r10                                    /* delete return address */
957         sub     $3,%r10                                 /* faulting address is return adress - 3 */
958                 
959         mov     proto_java_lang_ArrayStoreException,%rax
960         jmp             asm_handle_exception
961
962                 
963 /******************* function asm_initialize_thread_stack **********************
964 *                                                                              *
965 * initialized a thread stack                                                   *
966 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
967 *                                                                              *
968 *******************************************************************************/
969
970 asm_initialize_thread_stack:
971         sub     $(7*8),%rsi
972
973         xor     %r10,%r10
974         mov     %r10,0*8(%rsi)
975         mov     %r10,1*8(%rsi)
976         mov     %r10,2*8(%rsi)
977         mov     %r10,3*8(%rsi)
978         mov     %r10,4*8(%rsi)
979         mov     %r10,5*8(%rsi)
980
981         mov     %rdi,6*8(%rsi)          /* save (u1*) (func)                  */
982         mov     %rsi,%rax               /* return restorepoint in %rax        */
983         ret
984
985
986 /******************* function asm_perform_threadswitch *************************
987 *                                                                              *
988 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
989 *                                                                              *
990 *   performs a threadswitch                                                    *
991 *                                                                              *
992 *******************************************************************************/
993
994 asm_perform_threadswitch:
995         sub     $(7*8),%rsp             /* allocate stack frame               */
996
997         mov     %rbx,0*8(%rsp)
998         mov     %rbp,1*8(%rsp)
999         mov     %r12,2*8(%rsp)
1000         mov     %r13,3*8(%rsp)
1001         mov     %r14,4*8(%rsp)
1002         mov     %r15,5*8(%rsp)
1003
1004         mov     7*8(%rsp),%rax                  /* save current return address        */
1005         mov     %rax,6*8(%rsp)
1006
1007         mov     %rsp,(%rdi)                     /* first argument **from              */
1008         mov     %rsp,(%rdx)                     /* third argument **stackTop          */
1009
1010         mov     (%rsi),%rsp                     /* load new stack pointer             */
1011
1012         mov     0*8(%rsp),%rbx
1013         mov     1*8(%rsp),%rbp
1014         mov     2*8(%rsp),%r12
1015         mov     3*8(%rsp),%r13
1016         mov     4*8(%rsp),%r14
1017         mov     5*8(%rsp),%r15
1018
1019         mov     6*8(%rsp),%rax          /* restore return address             */
1020         add     $(7*8),%rsp             /* free stack frame                   */
1021         mov     %rax,(%rsp)
1022         ret
1023                 
1024
1025 /********************* function asm_switchstackandcall *************************
1026 *                                                                              *
1027 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
1028 *                                      void *p);                                       *
1029 *                                                                              *
1030 *   Switches to a new stack, calls a function and switches back.               *
1031 *       a0 (%rdi)     new stack pointer                                        *
1032 *       a1 (%rsi)     function pointer                                         *
1033 *               a2 (%rdx)     pointer to variable where stack top should be stored     *
1034 *       a3 (%rcx)     pointer to user data, is passed to the function          *
1035 *                                                                              *
1036 *******************************************************************************/
1037
1038 asm_switchstackandcall:
1039         sub     $8,%rsp                 /* keep stack 16-byte aligned         */
1040         sub     $16,%rdi                                /* allocate new stack                 */
1041
1042         mov     8(%rsp),%rax                    /* save return address on new stack   */
1043         mov     %rax,(%rdi)
1044         mov     %rsp,8(%rdi)                    /* save old stack pointer on new stack */
1045         mov     %rsp,(%rdx)                             /* save old stack pointer to variable */
1046
1047         mov     %rdi,%rsp                               /* switch to new stack                */
1048
1049         mov     %rcx,%rdi                       /* pass pointer                       */
1050         call    *%rsi                                   /* and call function                  */
1051
1052         mov     (%rsp),%r10                             /* load return address                */
1053         mov     8(%rsp),%rsp                    /* switch to old stack                */
1054         add     $8,%rsp                 /* free stack space                   */
1055         mov     %r10,(%rsp)             /* write return adress                */
1056         ret
1057
1058                 
1059 /********************* function asm_getcallingmethod ***************************
1060 *                                                                              *
1061 *   classinfo *asm_getcallingmethod ();                                                                    *
1062 *                                                                                                                                                          *    
1063 *   goes back stack frames to get the calling method                                               *
1064 *                                                                                                                                                          *
1065 *                               t2 .. sp                                                                                                       *
1066 *                               t3 .. ra                                                                                                       *
1067 *                               t4 .. pv                                                                                                       *
1068 *                                                                              *
1069 *   Stack:                                                                     *
1070 *       java function                                                          *
1071 *       native stub                                                            *
1072 *       Java_java_lang_System_getCallerClass                                   *
1073 *                                                                              *
1074 *******************************************************************************/
1075
1076 asm_getcallingmethod:
1077         mov     %rbp,%rax               /* return address of native function  */
1078         add     $(2*8),%rax             /* %rsp, return address               */
1079         add     $(7*8),%rax             /* native stub stackframe             */
1080         mov     (%rax),%rdi             /* return address to java function    */
1081         call    findmethod
1082         mov     MethodPointer(%rax),%rax
1083         ret
1084
1085
1086 /*********************** function asm_builtin_trace ****************************
1087 *                                                                              *
1088 *   Intended to be called from the native stub. Saves all argument registers   *
1089 *   and calls builtin_trace_args.                                              *
1090 *                                                                              *
1091 *******************************************************************************/
1092
1093 asm_builtin_trace:
1094         sub     $(15*8),%rsp       /* 14 + 1 */
1095         
1096         mov     %rdi,0*8(%rsp)  /* save arguments                             */
1097         mov     %rsi,1*8(%rsp)
1098         mov     %rdx,2*8(%rsp)
1099         mov     %rcx,3*8(%rsp)
1100         mov     %r8,4*8(%rsp)
1101         mov     %r9,5*8(%rsp)
1102
1103         movq    %xmm0,6*8(%rsp)
1104         movq    %xmm1,7*8(%rsp)
1105         movq    %xmm2,8*8(%rsp)
1106         movq    %xmm3,9*8(%rsp)
1107         movq    %xmm4,10*8(%rsp)
1108         movq    %xmm5,11*8(%rsp)
1109         movq    %xmm6,12*8(%rsp)
1110         movq    %xmm7,13*8(%rsp)
1111
1112         call    builtin_trace_args
1113
1114         mov     0*8(%rsp),%rdi
1115         mov     1*8(%rsp),%rsi
1116         mov     2*8(%rsp),%rdx
1117         mov     3*8(%rsp),%rcx
1118         mov     4*8(%rsp),%r8
1119         mov     5*8(%rsp),%r9
1120
1121         movq    6*8(%rsp),%xmm0
1122         movq    7*8(%rsp),%xmm1
1123         movq    8*8(%rsp),%xmm2
1124         movq    9*8(%rsp),%xmm3
1125         movq    10*8(%rsp),%xmm4
1126         movq    11*8(%rsp),%xmm5
1127         movq    12*8(%rsp),%xmm6
1128         movq    13*8(%rsp),%xmm7
1129
1130         add     $(15*8),%rsp
1131         ret
1132
1133
1134 /********************* function asm_builtin_exittrace **************************
1135 *                                                                              *
1136 *   Intended to be called from the native stub. Saves return value and calls   *
1137 *   builtin_displaymethodstop.                                                 *
1138 *                                                                              *
1139 *******************************************************************************/
1140
1141 asm_builtin_exittrace:
1142         sub     $(3*8),%rsp
1143         mov     %rax,0*8(%rsp)
1144         movq    %xmm0,1*8(%rsp)
1145         movq    %xmm0,%xmm1
1146         call    builtin_displaymethodstop
1147         mov     0*8(%rsp),%rax
1148         movq    1*8(%rsp),%xmm0
1149         add     $(3*8),%rsp
1150         ret
1151
1152
1153 asm_printf:
1154         push    %rbp
1155         mov     %rsp,%rbp
1156         
1157         push    %rax
1158         push    %rcx
1159         push    %rdx
1160         push    %rbx
1161         push    %rsi
1162         push    %rdi
1163         push    %r8
1164         push    %r9
1165         push    %r10
1166         push    %r11
1167         push    %r12
1168         push    %r13
1169         push    %r14
1170         push    %r15
1171
1172         mov     16(%rbp),%rdi
1173         call    asmprintf
1174
1175         pop     %r15
1176         pop     %r14
1177         pop     %r13
1178         pop     %r12
1179         pop     %r11
1180         pop     %r10
1181         pop     %r9
1182         pop     %r8
1183         pop     %rdi
1184         pop     %rsi
1185         pop     %rbx
1186         pop     %rdx
1187         pop     %rcx
1188         pop     %rax
1189         
1190         leave
1191         ret
1192         
1193 /*
1194  * These are local overrides for various environment variables in Emacs.
1195  * Please do not remove this and leave it at the end of the file, where
1196  * Emacs will automagically detect them.
1197  * ---------------------------------------------------------------------
1198  * Local variables:
1199  * mode: asm
1200  * indent-tabs-mode: t
1201  * c-basic-offset: 4
1202  * tab-width: 4
1203  * End:
1204  */