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