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