a63518d0d119fbd9d896079f02915e4083c4d9ba
[cacao.git] / src / vm / jit / x86_64 / asmpart.S
1 /* src/vm/jit/x86_64/asmpart.S - Java-C interface functions for x86_64
2
3    Copyright (C) 1996-2005 R. Grafl, A. Krall, C. Kruegel, C. Oates,
4    R. Obermaisser, M. Platter, M. Probst, S. Ring, E. Steiner,
5    C. Thalinger, D. Thuernbeck, P. Tomsich, C. Ullrich, J. Wenninger,
6    Institut f. Computersprachen - TU Wien
7
8    This file is part of CACAO.
9
10    This program is free software; you can redistribute it and/or
11    modify it under the terms of the GNU General Public License as
12    published by the Free Software Foundation; either version 2, or (at
13    your option) any later version.
14
15    This program is distributed in the hope that it will be useful, but
16    WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18    General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
23    02111-1307, USA.
24
25    Contact: cacao@complang.tuwien.ac.at
26
27    Authors: Andreas Krall
28             Reinhard Grafl
29             Christian Thalinger
30
31    $Id: asmpart.S 2360 2005-04-24 13:07:57Z jowenn $
32
33 */
34
35
36 #include "config.h"
37 #include "vm/jit/x86_64/arch.h"
38 #include "vm/jit/x86_64/offsets.h"
39 #include "vm/jit/x86_64/asmoffsets.h"
40
41
42 /* define it like the risc way */
43
44 #define v0       %rax
45 #define v0l      %eax
46
47 #define a0       %rdi
48 #define a1       %rsi
49 #define a2       %rdx
50 #define a3       %rcx
51 #define a4       %r8
52 #define a5       %r9
53
54 #define fa0      %xmm0
55 #define fa1      %xmm1
56 #define fa2      %xmm2
57 #define fa3      %xmm3
58 #define fa4      %xmm4
59 #define fa5      %xmm5
60 #define fa6      %xmm6
61 #define fa7      %xmm7
62
63 #define itmp1    %rax
64 #define itmp2    %r10
65 #define itmp3    %r11
66
67 #define itmp1l   %eax
68 #define itmp2l   %r10d
69 #define itmp3l   %r11d
70
71 #define itmp1b   %al
72 #define itmp2b   %r10b
73 #define itmp3b   %r11b
74
75 #define xptr     itmp1
76 #define xpc      itmp2
77
78
79 /* save and restore macros ****************************************************/
80
81 #define SAVE_ARGUMENT_REGISTERS \
82         mov     a0,0*8(%rsp)            ; \
83         mov     a1,1*8(%rsp)            ; \
84         mov     a2,2*8(%rsp)            ; \
85         mov     a3,3*8(%rsp)            ; \
86         mov     a4,4*8(%rsp)            ; \
87         mov     a5,5*8(%rsp)            ; \
88         movq    fa0,6*8(%rsp)           ; \
89         movq    fa1,7*8(%rsp)           ; \
90         movq    fa2,8*8(%rsp)           ; \
91         movq    fa3,9*8(%rsp)           ; \
92         movq    fa4,10*8(%rsp)          ; \
93         movq    fa5,11*8(%rsp)          ; \
94         movq    fa6,12*8(%rsp)          ; \
95         movq    fa7,13*8(%rsp)          ;
96
97
98 #define RESTORE_ARGUMENT_REGISTERS \
99         mov     0*8(%rsp),a0            ; \
100         mov     1*8(%rsp),a1            ; \
101         mov     2*8(%rsp),a2            ; \
102         mov     3*8(%rsp),a3            ; \
103         mov     4*8(%rsp),a4            ; \
104         mov     5*8(%rsp),a5            ; \
105         movq    6*8(%rsp),fa0           ; \
106         movq    7*8(%rsp),fa1           ; \
107         movq    8*8(%rsp),fa2           ; \
108         movq    9*8(%rsp),fa3           ; \
109         movq    10*8(%rsp),fa4          ; \
110         movq    11*8(%rsp),fa5          ; \
111         movq    12*8(%rsp),fa6          ; \
112         movq    13*8(%rsp),fa7          ; 
113
114
115 #define SAVE_TEMPORARY_REGISTERS \
116         mov     %rbx,14*8(%rsp)
117
118
119 #define RESTORE_TEMPORARY_REGISTERS \
120         mov     14*8(%rsp),%rbx
121
122
123         .text
124
125
126 /********************* exported functions and variables ***********************/
127
128         .globl asm_calljavafunction
129         .globl asm_calljavafunction_int
130
131         .globl asm_calljavafunction2
132         .globl asm_calljavafunction2int
133         .globl asm_calljavafunction2long
134         .globl asm_calljavafunction2float
135         .globl asm_calljavafunction2double
136
137         .globl asm_call_jit_compiler
138         .globl asm_handle_exception
139         .globl asm_handle_nat_exception
140
141         .globl asm_wrapper_patcher
142         .globl asm_wrapper_patcher_builtin_new
143
144         .globl asm_wrapper_patcher_builtin_newarray
145         .globl asm_wrapper_patcher_builtin_multianewarray
146         .globl asm_wrapper_patcher_builtin_checkarraycast
147         .globl asm_wrapper_patcher_builtin_arrayinstanceof
148
149         .globl asm_builtin_checkarraycast
150         .globl asm_builtin_aastore
151
152 #if defined(USE_THREADS)
153         .globl asm_builtin_monitorenter
154         .globl asm_builtin_monitorexit
155 #endif
156
157         .globl asm_builtin_f2i
158         .globl asm_builtin_f2l
159         .globl asm_builtin_d2i
160         .globl asm_builtin_d2l
161
162         .globl asm_perform_threadswitch
163         .globl asm_initialize_thread_stack
164         .globl asm_switchstackandcall
165         .globl asm_criticalsections
166         .globl asm_getclassvalues_atomic
167
168         .globl asm_prepare_native_stackinfo
169         .globl asm_remove_native_stackinfo
170         .globl asm_throw_and_handle_exception
171         .globl asm_throw_and_handle_hardware_arithmetic_exception               
172
173 /********************* function asm_calljavafunction ***************************
174 *                                                                              *
175 *   This function calls a Java-method (which possibly needs compilation)       *
176 *   with up to 4 address parameters.                                           *
177 *                                                                              *
178 *   This functions calls the JIT-compiler which eventually translates the      *
179 *   method into machine code.                                                  *
180 *                                                                              *
181 *   C-prototype:                                                               *
182 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
183 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
184 *                                                                              *
185 *******************************************************************************/
186
187 call_name:
188         .align  8
189
190         .quad   0                         /* catch type all                       */
191         .quad   calljava_xhandler         /* handler pc                           */
192         .quad   calljava_xhandler         /* end pc                               */
193         .quad   asm_calljavafunction      /* start pc                             */
194         .long   1                         /* extable size                         */
195         .long   0
196         .quad   0                         /* line number table start              */
197         .quad   0                         /* line number table size               */
198         .long   0
199         .long   0                         /* fltsave                              */
200         .long   0                         /* intsave                              */
201         .long   0                         /* isleaf                               */
202         .long   0                         /* IsSync                               */
203         .long   8                         /* frame size                           */
204         .quad   0                         /* method pointer (pointer to name)     */
205
206 asm_calljavafunction:
207 asm_calljavafunction_int:
208         sub     $(3*8),%rsp               /* keep stack 16-byte aligned           */
209         mov     %rbp,0*8(%rsp)
210         mov     %rbx,1*8(%rsp)            /* %rbx is not a callee saved in cacao  */
211         mov     %rdi,%rax                 /* move function pointer to %rax        */
212                                                                           /* compilerstub uses this               */
213
214         mov     %rsi,%rdi                 /* pass remaining parameters            */
215         mov     %rdx,%rsi
216         mov     %rcx,%rdx
217         mov     %r8,%rcx
218         
219         lea     asm_call_jit_compiler,%r11
220         call    *%r11                     /* call JIT compiler                    */
221
222         mov     0*8(%rsp),%rbp
223         mov             1*8(%rsp),%rbx
224         add     $(3*8),%rsp               /* free stack space                     */
225         ret
226
227 calljava_xhandler:
228         mov     %rax,%rdi                 /* pass exception pointer               */
229         call    builtin_throw_exception
230         mov     0*8(%rsp),%rbp
231         mov             1*8(%rsp),%rbx
232         add     $(3*8),%rsp
233         xor     %rax,%rax                 /* return NULL                          */
234         ret
235
236
237 /********************* function asm_calljavafunction ***************************
238 *                                                                              *
239 *   This function calls a Java-method (which possibly needs compilation)       *
240 *   with up to 4 address parameters.                                           *
241 *                                                                              *
242 *   This functions calls the JIT-compiler which eventually translates the      *
243 *   method into machine code.                                                  *
244 *                                                                              *
245 *   C-prototype:                                                               *
246 *    javaobject_header *asm_calljavamethod (methodinfo *m,                     *
247 *         void *arg1, void *arg2, void *arg3, void *arg4);                     *
248 *                                                                              *
249 *******************************************************************************/
250
251 call_name2:
252         .align  8
253
254         .quad   0                         /* catch type all                       */
255         .quad   calljava_xhandler2        /* handler pc                           */
256         .quad   calljava_xhandler2        /* end pc                               */
257         .quad   asm_calljavafunction2     /* start pc                             */
258         .long   1                         /* extable size                         */
259         .quad   0                         /* line number table  start             */
260         .quad   0                         /* line number table  size              */
261         .long   0                         /* fltsave                              */
262         .long   0                         /* intsave                              */
263         .long   0                         /* isleaf                               */
264         .long   0                         /* IsSync                               */
265         .long   24                        /* frame size                           */
266         .quad   0                         /* method pointer (pointer to name)     */
267
268 asm_calljavafunction2:
269 asm_calljavafunction2int:
270 asm_calljavafunction2long:
271 asm_calljavafunction2float:
272 asm_calljavafunction2double:
273         sub     $(7*8),%rsp               /* keep stack 16-byte aligned           */
274         mov     %rbx,0*8(%rsp)            /* %rbx is not a callee saved in cacao  */
275         mov     %rbp,1*8(%rsp)
276         mov     %r12,2*8(%rsp)
277         mov     %r13,3*8(%rsp)
278         mov     %r14,4*8(%rsp)
279         mov     %r15,5*8(%rsp)
280
281         mov     %rdi,%rax                 /* move method pointer for compiler     */
282         xor     %rbp,%rbp                 /* set argument stack frame to zero     */
283
284         test    %rsi,%rsi                 /* maybe we have no args...             */
285         jle     L_copy_done
286
287         mov     %rsi,itmp3                /* arg count                            */
288         mov     %rcx,itmp2                /* pointer to arg block                 */
289
290         mov     itmp2,%r14                /* save argument block pointer          */
291         mov     itmp3,%r15                /* save argument count                  */
292
293         sub     $sizejniblock,itmp2       /* initialize pointer (smaller code)    */
294         add     $1,itmp3                  /* initialize argument count            */
295         xor     %r12,%r12                 /* initialize integer argument counter  */
296         xor     %r13,%r13                 /* initialize float argument counter    */
297
298 L_register_copy:
299         add     $sizejniblock,itmp2       /* goto next argument block             */
300         dec     itmp3                     /* argument count - 1                   */
301         jz      L_register_copy_done
302         andb    $0x02,offjniitemtype(itmp2) /* is this a float/double type?       */
303         jnz     L_register_handle_float   /* yes, handle it                       */
304
305         cmp     $INT_ARG_CNT,%r12         /* are we out of integer argument       */
306         je      L_register_copy           /* register? yes, next loop             */
307
308         lea     jumptable_integer,%rbp
309         mov     0(%rbp,%r12,8),%rbx
310         inc     %r12                      /* integer argument counter + 1         */
311         jmp     *%rbx
312
313 L_register_handle_float:
314         cmp     $FLT_ARG_CNT,%r13         /* are we out of float argument         */
315         je      L_register_copy           /* register? yes, next loop             */
316
317         lea     jumptable_float,%rbp
318         mov     0(%rbp,%r13,8),%rbx
319         inc     %r13                      /* float argument counter + 1           */
320         jmp     *%rbx
321         
322 L_register_copy_done:
323         mov     %r15,%rbp                 /* calculate remaining arguments        */
324         sub     %r12,%rbp                 /* - integer arguments in registers     */
325         sub     %r13,%rbp                 /* - float arguments in registers       */
326         jle     L_copy_done               /* are all assigned to registers?       */
327
328         shl     $3,%rbp                   /* calculate stack size                 */
329         sub     %rbp,%rsp                 /* stack frame for arguments            */
330         mov     %rsp,%rbx                 /* use %rbx as temp sp                  */
331
332         sub     $sizejniblock,%r14        /* initialize pointer (smaller code)    */
333         add     $1,%r15                   /* initialize argument count            */
334                 
335 L_stack_copy_loop:
336         add     $sizejniblock,%r14        /* goto next argument block             */
337         dec     %r15                      /* are there any arguments left?        */
338         jz      L_copy_done               /* no test needed after dec             */
339
340         andb    $0x02,offjniitemtype(%r14) /* is this a float/double type?        */
341         jnz     L_stack_handle_float
342         dec     %r12                      /* arguments assigned to registers      */
343         jge     L_stack_copy_loop
344         jmp     L_stack_copy
345
346 L_stack_handle_float:
347         dec     %r13                      /* arguments assigned to registers      */
348         jge     L_stack_copy_loop
349
350 L_stack_copy:
351     mov     offjniitem(%r14),itmp3    /* copy s8 argument onto stack          */
352     mov     itmp3,0(%rbx)
353     add     $8,%rbx                   /* increase sp to next argument         */
354         jmp     L_stack_copy_loop
355
356 L_copy_done:
357         lea     asm_call_jit_compiler,%r11/* %rax still contains method pointer   */
358         call    *%r11                     /* call JIT compiler                    */
359
360         add     %rbp,%rsp                 /* remove argument stack frame if any   */
361
362         mov     5*8(%rsp),%r15            /* restore callee saved registers       */
363         mov     4*8(%rsp),%r14
364         mov     3*8(%rsp),%r13
365         mov     2*8(%rsp),%r12
366         mov     1*8(%rsp),%rbp
367         mov     0*8(%rsp),%rbx
368         add     $(7*8),%rsp               /* free stack space                     */
369         ret
370                 
371 calljava_xhandler2:
372         mov     %rax,%rdi                 /* pass exception pointer               */
373         call    builtin_throw_exception
374
375         mov     5*8(%rsp),%r15            /* restore callee saved registers       */
376         mov     4*8(%rsp),%r14
377         mov     3*8(%rsp),%r13
378         mov     2*8(%rsp),%r12
379         mov     1*8(%rsp),%rbp
380         mov     0*8(%rsp),%rbx
381         add     $(7*8),%rsp               /* free stack space                     */
382         xor     %rax,%rax                 /* return NULL                          */
383         ret
384
385
386 jumptable_integer:
387         .quad   handle_a0
388         .quad   handle_a1
389         .quad   handle_a2
390         .quad   handle_a3
391         .quad   handle_a4
392         .quad   handle_a5
393
394 handle_a0:
395         mov     offjniitem(itmp2),a0
396         jmp     L_register_copy
397 handle_a1:
398         mov     offjniitem(itmp2),a1
399         jmp     L_register_copy
400 handle_a2:
401         mov     offjniitem(itmp2),a2
402         jmp     L_register_copy
403 handle_a3:
404         mov     offjniitem(itmp2),a3
405         jmp     L_register_copy
406 handle_a4:
407         mov     offjniitem(itmp2),a4
408         jmp     L_register_copy
409 handle_a5:
410         mov     offjniitem(itmp2),a5
411         jmp     L_register_copy
412
413
414 jumptable_float:
415         .quad   handle_fa0
416         .quad   handle_fa1
417         .quad   handle_fa2
418         .quad   handle_fa3
419         .quad   handle_fa4
420         .quad   handle_fa5
421         .quad   handle_fa6
422         .quad   handle_fa7
423
424 handle_fa0:
425         movq    offjniitem(itmp2),fa0
426         jmp     L_register_copy
427 handle_fa1:
428         movq    offjniitem(itmp2),fa1
429         jmp     L_register_copy
430 handle_fa2:
431         movq    offjniitem(itmp2),fa2
432         jmp     L_register_copy
433 handle_fa3:
434         movq    offjniitem(itmp2),fa3
435         jmp     L_register_copy
436 handle_fa4:
437         movq    offjniitem(itmp2),fa4
438         jmp     L_register_copy
439 handle_fa5:
440         movq    offjniitem(itmp2),fa5
441         jmp     L_register_copy
442 handle_fa6:
443         movq    offjniitem(itmp2),fa6
444         jmp     L_register_copy
445 handle_fa7:
446         movq    offjniitem(itmp2),fa7
447         jmp     L_register_copy
448
449
450 /****************** function asm_call_jit_compiler *****************************
451 *                                                                              *
452 *   invokes the compiler for untranslated JavaVM methods.                      *
453 *                                                                              *
454 *   Register R0 contains a pointer to the method info structure (prepared      *
455 *   by createcompilerstub). Using the return address in R26 and the            *
456 *   offset in the LDA instruction or using the value in methodptr R28 the      *
457 *   patching address for storing the method address can be computed:           *
458 *                                                                              *
459 *   method address was either loaded using                                     *
460 *                                                                              *
461 *   i386_mov_imm_reg(a, REG_ITMP2)                ; invokestatic/special       *
462 *   i386_call_reg(REG_ITMP2)                                                   *
463 *                                                                              *
464 *   or                                                                         *
465 *                                                                              *
466 *   i386_mov_membase_reg(REG_SP, 0, REG_ITMP2)    ; invokevirtual/interface    *
467 *   i386_mov_membase_reg(REG_ITMP2, OFFSET(, vftbl), REG_ITMP3)                *
468 *   i386_mov_membase_reg(REG_ITMP3, OFFSET(vftbl, table[0]) + \                *
469 *       sizeof(methodptr) * m->vftblindex, REG_ITMP1)                          *
470 *   i386_call_reg(REG_ITMP1)                                                   *
471 *                                                                              *
472 *   in the static case the method pointer can be computed using the            *
473 *   return address and the lda function following the jmp instruction          *
474 *                                                                              *
475 *******************************************************************************/
476
477 asm_call_jit_compiler:
478         sub     $8,%rsp                 /* keep stack 16-byte aligned             */
479
480         mov     %rbx,(%rsp)             /* save register                          */
481         
482         mov     8(%rsp),%r11    /* get return address                         */
483         mov     -1(%r11),%bl    /* get function code                          */
484         cmp     $0xd2,%bl               /* called with `call *REG_ITMP2' (%r10)?      */
485         jne     L_not_static_special
486
487         sub     $11,%r11        /* calculate address of immediate             */
488         jmp             L_call_jit_compile
489                 
490 L_not_static_special:
491                 cmp     $0xd0,%bl               /* called with `call *REG_ITMP1' (%rax)       */
492                 jne     L_not_virtual_interface
493                 
494                 sub     $7,%r11         /* calculate address of offset                */
495                 mov     (%r11),%r11d    /* get offset (32-bit)                        */
496                 add     %r10,%r11       /* add base address to get method address     */
497                 jmp     L_call_jit_compile
498
499 L_not_virtual_interface:        /* a call from asm_calljavamethod             */
500                 xor     %r11,%r11
501                 
502 L_call_jit_compile:
503         mov     (%rsp),%rbx     /* restore register                           */
504         
505         sub     $(24*8),%rsp    /* 8 + 6*8 + 8*8 + 8*8                        */
506         
507                 mov     %r11,0*8(%rsp)  /* save address for method pointer            */
508
509         mov     a0,1*8(%rsp)    /* save arguments                             */
510         mov     a1,2*8(%rsp)
511         mov     a2,3*8(%rsp)
512         mov     a3,4*8(%rsp)
513         mov     a4,5*8(%rsp)
514         mov     a5,6*8(%rsp)
515
516         movq    fa0,7*8(%rsp)
517         movq    fa1,8*8(%rsp)
518         movq    fa2,9*8(%rsp)
519         movq    fa3,10*8(%rsp)
520         movq    fa4,11*8(%rsp)
521         movq    fa5,12*8(%rsp)
522         movq    fa6,13*8(%rsp)
523         movq    fa7,14*8(%rsp)
524
525         movq    %xmm8,15*8(%rsp)/* we use them as callee saved registers      */
526         movq    %xmm9,16*8(%rsp)
527         movq    %xmm10,17*8(%rsp)
528         movq    %xmm11,18*8(%rsp)
529         movq    %xmm12,19*8(%rsp)
530         movq    %xmm13,20*8(%rsp)
531         movq    %xmm14,21*8(%rsp)
532         movq    %xmm15,22*8(%rsp)
533
534         mov     %rax,%rdi       /* pass method pointer                        */
535                 call    jit_compile
536
537         mov     0*8(%rsp),%r11
538         
539         mov     1*8(%rsp),a0
540         mov     2*8(%rsp),a1
541         mov     3*8(%rsp),a2
542         mov     4*8(%rsp),a3
543         mov     5*8(%rsp),a4
544         mov     6*8(%rsp),a5
545
546         movq    7*8(%rsp),fa0
547         movq    8*8(%rsp),fa1
548         movq    9*8(%rsp),fa2
549         movq    10*8(%rsp),fa3
550         movq    11*8(%rsp),fa4
551         movq    12*8(%rsp),fa5
552         movq    13*8(%rsp),fa6
553         movq    14*8(%rsp),fa7
554
555         movq    15*8(%rsp),%xmm8
556         movq    16*8(%rsp),%xmm9
557         movq    17*8(%rsp),%xmm10
558         movq    18*8(%rsp),%xmm11
559         movq    19*8(%rsp),%xmm12
560         movq    20*8(%rsp),%xmm13
561         movq    21*8(%rsp),%xmm14
562         movq    22*8(%rsp),%xmm15
563
564         add     $(24*8),%rsp
565         add     $8,%rsp                 /* keep stack 16-byte aligned             */
566
567         test    %rax,%rax               /* check for exception                    */
568         je      L_asm_call_jit_compiler_exception
569
570         test    %r11,%r11               /* is address == 0 (asm_calljavamethod)   */
571         je      L_call_method
572
573         mov     %rax,(%r11)             /* and now save the new pointer           */
574
575 L_call_method:
576         jmp     *%rax                   /* ...and now call the new method         */
577
578 L_asm_call_jit_compiler_exception:
579 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
580         call    builtin_asm_get_exceptionptrptr
581         mov     %rax,itmp2
582 #else
583         lea     _exceptionptr,itmp2
584 #endif
585         mov     (itmp2),xptr                /* get the exception pointer          */
586         movl    $0,(itmp2)                  /* clear the exception pointer        */
587
588         pop     xpc                         /* delete return address              */
589         sub     $5,xpc                      /* faulting address is ra - 5         */
590
591         jmp     asm_handle_exception
592
593
594 /********************* function asm_handle_exception ***************************
595 *                                                                              *
596 *   This function handles an exception. It does not use the usual calling      *
597 *   conventions. The exception pointer is passed in REG_ITMP1 and the          *
598 *   pc from the exception raising position is passed in REG_ITMP2. It searches *
599 *   the local exception table for a handler. If no one is found, it unwinds    *
600 *   stacks and continues searching the callers.                                *
601 *                                                                              *
602 *   void asm_handle_exception (exceptionptr, exceptionpc);                     *
603 *                                                                              *
604 *******************************************************************************/
605
606 asm_handle_nat_exception:
607         add     $8,%rsp                     /* clear return address of native stub*/
608                 
609 asm_handle_exception:
610         sub     $(4*8),%rsp
611         mov     xptr,0*8(%rsp)              /* save exception pointer             */
612         mov     xpc,1*8(%rsp)               /* save exception pc                  */
613         
614         mov     xpc,%rdi                    /* exception pc                       */
615         call    codegen_findmethod
616         mov     %rax,itmp3
617         mov     %rax,2*8(%rsp)              /* save data segment pointer          */
618         
619         mov     0*8(%rsp),%rax              /* restore exception pointer          */
620         mov     1*8(%rsp),%r10              /* restore exception pc               */
621         
622 ex_stack_loop:
623         mov     %rax,%rdi                   /* exception pointer                  */
624         mov     MethodPointer(itmp3),%rsi   /* method pointer                     */
625         mov     xpc,%rdx                    /* exception pc                       */
626         mov     $0,%rcx
627         mov     $1,%r8                      /* set noindent flag                  */
628         call    builtin_trace_exception
629
630         mov     2*8(%rsp),itmp3             /* %r11 = data segment pointer        */
631         mov     ExTableSize(itmp3),%rcx     /* %rcx = exception table size        */
632         test    %rcx,%rcx                                       /* if empty table skip                */
633         je      empty_table
634
635         lea     ExTableStart(itmp3),%rdi    /* %rdi = start of exception table    */
636         mov     0*8(%rsp),xptr              /* get xptr                           */
637                 
638 ex_table_loop:
639         mov     1*8(%rsp),xpc               /* get xpc                            */
640                 
641         mov     ExStartPC(%rdi),%rdx        /* %rdx = exception start pc          */
642         cmp     xpc,%rdx                    /* %rdx = (startpc <= xpc)            */
643         jg      ex_table_cont               /* if (false) continue                */
644         mov     ExEndPC(%rdi),%rdx          /* %rdx = exception end pc            */
645         cmp     %rdx,xpc                    /* %rdx = (xpc < endpc)               */
646         jge     ex_table_cont               /* if (false) continue                */
647         mov     ExCatchType(%rdi),%rdx      /* %rdx = exception catch type        */
648         test    %rdx,%rdx                   /* NULL catches everything            */
649         je      ex_handle_it
650
651         cmpl    $0,offclassloaded(%rdx)     /* check if class is loaded           */
652         jne     L_class_loaded
653
654         sub     $(4*8),%rsp
655         mov     %rax,0*8(%rsp)
656         mov     %rcx,1*8(%rsp)
657         mov     %rdx,2*8(%rsp)
658         mov     %rdi,3*8(%rsp)
659
660         mov     %rdx,%rdi
661         call    load_class_bootstrap
662
663         mov     0*8(%rsp),%rax
664         mov     1*8(%rsp),%rcx
665         mov     2*8(%rsp),%rdx
666         mov     3*8(%rsp),%rdi
667         add     $(4*8),%rsp
668
669 L_class_loaded:
670         cmpl    $0,offclasslinked(%rdx)     /* check if class is linked           */
671         jne     L_class_linked
672
673         sub     $(4*8),%rsp
674         mov     %rax,0*8(%rsp)
675         mov     %rcx,1*8(%rsp)
676         mov     %rdx,2*8(%rsp)
677         mov     %rdi,3*8(%rsp)
678
679         mov     %rdx,%rdi
680         call    link_class
681
682         mov     0*8(%rsp),%rax
683         mov     1*8(%rsp),%rcx
684         mov     2*8(%rsp),%rdx
685         mov     3*8(%rsp),%rdi
686         add     $(4*8),%rsp
687
688 L_class_linked:
689 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
690         push    %rdx
691
692 _crit_restart1:
693         mov     0(%rsp),%rdx
694 #endif
695
696 _crit_begin1:
697         mov     offobjvftbl(%rax),%rsi      /* %rsi = vftblptr(xptr)              */
698         mov     offclassvftbl(%rdx),%rdx    /* %rdx = vftblptr(catchtype) class (not obj) */
699         mov     offbaseval(%rsi),%esi       /* %esi = baseval(xptr)               */
700         mov     offbaseval(%rdx),%r10d      /* %r10d = baseval(catchtype)         */
701         mov     offdiffval(%rdx),%edx       /* %edx = diffval(catchtype)          */
702 _crit_end1:
703         sub     %r10d,%esi                  /* %esi = baseval(xptr) - baseval(catchtype) */
704
705 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
706         add     $8,%rsp
707 #endif
708
709         cmp     %edx,%esi                   /* xptr is instanceof catchtype       */
710         ja      ex_table_cont
711                 
712 ex_handle_it:
713                 mov     ExHandlerPC(%rdi),xpc       /* xpc = exception handler pc     */
714
715         mov     0*8(%rsp),%rax              /* restore exception pointer      */
716         add     $(4*8),%rsp                 /* free stack frame               */
717
718         jmp             *xpc                        /* jump to the handler            */
719
720 ex_table_cont:
721         lea             ExEntrySize(%rdi),%rdi      /* next exception table entry     */
722         dec     %rcx                        /* decrement entry counter        */
723         test    %rcx,%rcx                   /* if (t0 > 0) next entry         */
724         jg              ex_table_loop
725                 
726 empty_table:
727         mov     0*8(%rsp),%rax              /* restore exception pointer      */
728         mov     1*8(%rsp),%r10              /* restore exception pc           */
729         mov     2*8(%rsp),%r11                          /* restore data segment pointer   */
730         add     $(4*8),%rsp
731         
732                 mov     %rax,%rcx                                       /* save exception pointer         */
733                                 
734 ex_already_cleared:             
735                 movl    IsSync(%r11),%eax                       /* %rax = SyncOffset              */
736                 test    %rax,%rax                                       /* if zero no monitorexit         */
737                 je              no_monitor_exit
738
739 #if defined(USE_THREADS)                
740                 add     %rsp,%rax
741                 mov     -8(%rax),%rdi
742
743         sub     $(4*8),%rsp
744         mov     %rcx,0*8(%rsp)
745         mov     %r10,1*8(%rsp)
746         mov     %r11,2*8(%rsp)
747         
748                 call    builtin_monitorexit
749
750         mov     0*8(%rsp),%rcx
751         mov     1*8(%rsp),%r10
752         mov     2*8(%rsp),%r11
753         add     $(4*8),%rsp
754 #endif
755
756 no_monitor_exit:
757                 mov             FrameSize(%r11),%eax        /* %eax = frame size              */
758                 add             %rax,%rsp                   /* unwind stack                   */
759                 mov             %rsp,%rax                   /* %rax = pointer to save area    */
760
761                 mov             IntSave(%r11),%edx          /* %edx = saved int register count*/
762         test    %edx,%edx
763         je              noint
764         
765                 cmp     $1,%edx
766                 je              int1
767                 cmp             $2,%edx
768                 je              int2
769                 cmp             $3,%edx
770                 je              int3
771                 cmp             $4,%edx
772                 je              int4
773                 cmp             $5,%edx
774                 je              int5
775         
776         mov     -48(%rax),%rbx
777 int5:   
778         mov     -40(%rax),%rbp
779 int4:   
780         mov     -32(%rax),%r12
781 int3:   
782         mov     -24(%rax),%r13
783 int2:   
784                 mov     -16(%rax),%r14
785 int1:   
786                 mov     -8(%rax),%r15
787
788                 shl             $3,%edx                     /* multiply by 8 bytes            */
789                 sub     %rdx,%rax
790                 
791 noint:
792                 mov     FltSave(%r11),%edx          /* %edx = saved flt register count*/
793                 test    %edx,%edx
794                 je      noflt
795
796         cmpl    $1,%edx
797         je      flt1
798         cmpl    $2,%edx
799         je      flt2
800         cmpl    $3,%edx
801         je      flt3
802         cmpl    $4,%edx
803         je      flt4
804         cmpl    $5,%edx
805         je      flt5
806         cmpl    $6,%edx
807         je      flt7
808         cmpl    $7,%edx
809         je      flt7
810
811         movq    -64(%rax),%xmm8
812 flt7:   
813         movq    -56(%rax),%xmm9
814 flt6:   
815         movq    -48(%rax),%xmm10
816 flt5:   
817         movq    -40(%rax),%xmm11
818 flt4:   
819         movq    -32(%rax),%xmm12
820 flt3:   
821         movq    -24(%rax),%xmm13
822 flt2:   
823         movq    -16(%rax),%xmm14
824 flt1:   
825         movq    -8(%rax),%xmm15
826                 
827 noflt:                                  
828                 pop     %r10                                            /* the new xpc is return address  */
829                 sub     $3,%r10                     /* subtract 3 bytes for call      */
830
831         sub     $(2*8),%rsp
832         mov     %rcx,0*8(%rsp)
833         mov     %r10,1*8(%rsp)
834
835         mov     %r10,%rdi
836         call    codegen_findmethod          /* get the new data segment ptr   */
837         mov     %rax,%r11
838         
839         mov     0*8(%rsp),%rcx
840         mov     1*8(%rsp),%r10
841         add     $(2*8),%rsp
842
843         mov     %rcx,%rax                                       /* restore saved exception pointer*/
844
845         sub     $(4*8),%rsp
846                                         
847         mov     %rax,0*8(%rsp)              /* save exception pointer         */
848         mov     %r10,1*8(%rsp)              /* save exception pc              */
849                 mov     %r11,2*8(%rsp)                          /* save data segment pointer      */
850                 
851                 jmp             ex_stack_loop
852
853
854 /* asm_wrapper_patcher *********************************************************
855
856    XXX
857
858    Stack layout:
859      24   return address
860      16   machine code (which is patched back later)
861       8   unresolved class/method/field reference
862       0   pointer to patcher function
863
864 *******************************************************************************/
865
866 asm_wrapper_patcher:
867         sub     $(18*8),%rsp                /* stack frame (16-byte aligned)      */
868
869         SAVE_ARGUMENT_REGISTERS
870         SAVE_TEMPORARY_REGISTERS
871
872         mov     itmp1,15*8(%rsp)            /* save itmp1 and itmp2               */
873         mov     itmp2,16*8(%rsp)            /* can be used by some instructions   */
874
875         mov     %rsp,a0                     /* pass stack pointer                 */
876         add     $(19*8),a0                  /* skip patcher function pointer      */
877         mov     18*8(%rsp),itmp3            /* get function pointer               */
878         call    *itmp3                      /* call the patcher function          */
879         mov     v0,itmp3                    /* save return value                  */
880
881         RESTORE_ARGUMENT_REGISTERS
882         RESTORE_TEMPORARY_REGISTERS
883
884         mov     15*8(%rsp),itmp1            /* restore itmp1 and itmp2            */
885         mov     16*8(%rsp),itmp2            /* can be used by some instructions   */
886
887         add     $((3+18)*8),%rsp            /* remove stack frame, keep ra        */
888
889         test    itmp3,itmp3                 /* exception thrown?                  */
890         jz      L_asm_wrapper_patcher_exception
891         ret                                 /* call new patched code              */
892
893 L_asm_wrapper_patcher_exception:
894         /*stack bottom is xpc and it is directly below the last java stackframe*/
895         push $0
896         push $0
897         push $0 /*padding*/
898         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
899
900 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
901         call    builtin_asm_get_exceptionptrptr
902         mov     v0,itmp2
903 #else
904         lea     _exceptionptr,itmp2
905 #endif
906         mov     (itmp2),a0                /* get the exception pointer          */
907         movl    $0,(itmp2)                  /* clear exception pointer */
908         call    helper_fillin_stacktrace
909
910         mov     v0,xptr
911
912         call    asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
913
914         pop     xpc
915         pop     xpc                         /* get and remove return address      */
916         jmp     asm_handle_exception
917
918
919 /* asm_wrapper_patcher_builtin_new *********************************************
920
921    XXX
922
923    Arguments:
924      a0   contains the class reference
925
926 *******************************************************************************/
927
928 asm_wrapper_patcher_builtin_new:
929         sub     $(1*8),%rsp                 /* stack frame (16-byte aligned)      */
930         mov     %rsp,a1                     /* pass stack pointer                 */
931         add     $(1*8),a1
932         call    patcher_builtin_new         /* call the helper function           */
933         add     $(1*8),%rsp                 /* remove stack frame                 */
934         test    v0,v0                       /* exception thrown?                  */
935         jz      L_asm_wrapper_patcher_exception
936         ret                                 /* call new patched code              */
937
938
939 /* asm_wrapper_patcher_builtin_* ***********************************************
940
941    XXX
942
943    Arguments:
944      a1   contains the class reference
945
946 *******************************************************************************/
947
948 asm_wrapper_patcher_builtin_newarray:
949         lea     patcher_builtin_newarray,itmp1
950         jmp     L_asm_wrapper_patcher_builtin_main
951
952 asm_wrapper_patcher_builtin_multianewarray:
953         lea     patcher_builtin_multianewarray,itmp1
954         jmp     L_asm_wrapper_patcher_builtin_main
955
956 asm_wrapper_patcher_builtin_checkarraycast:
957         lea     patcher_builtin_checkarraycast,itmp1
958         jmp     L_asm_wrapper_patcher_builtin_main
959
960 asm_wrapper_patcher_builtin_arrayinstanceof:
961         lea     patcher_builtin_arrayinstanceof,itmp1
962
963 L_asm_wrapper_patcher_builtin_main:
964         sub     $(1*8),%rsp                 /* stack frame (16-byte aligned)      */
965         mov     a0,0*8(%rsp)                /* save argument                      */
966         mov     %rsp,a0                     /* pass stack pointer                 */
967         add     $(1*8),a0
968         call    *itmp1                      /* call the patcher function          */
969         mov     0*8(%rsp),a0                /* restore argument                   */
970         add     $(1*8),%rsp                 /* remove stack frame                 */
971         test    v0,v0                       /* exception thrown?                  */
972         jz      L_asm_wrapper_patcher_exception
973         ret                                 /* call new patched code              */
974
975
976
977
978 /********************* function asm_builtin_monitorenter ***********************
979 *                                                                              *
980 *   Does null check and calls monitorenter or throws an exception              *
981 *                                                                              *
982 *******************************************************************************/
983
984 #if defined(USE_THREADS)
985 asm_builtin_monitorenter:
986         test    %rdi,%rdi
987         je      nb_monitorenter             /* if (null) throw exception          */
988         jmp     builtin_monitorenter        /* else call builtin_monitorenter     */
989
990 nb_monitorenter:
991         /*call    new_nullpointerexception*/
992         pop     xpc                        /* delete return address              */
993         sub     $3,xpc                     /* faulting address is ra - 3         */
994         mov     string_java_lang_NullPointerException,xptr
995         jmp     asm_throw_and_handle_exception
996 #endif
997                 
998
999 /********************* function asm_builtin_monitorexit ************************
1000 *                                                                              *
1001 *   Does null check and calls monitorexit or throws an exception               *
1002 *                                                                              *
1003 *******************************************************************************/
1004
1005 #if defined(USE_THREADS)
1006 asm_builtin_monitorexit:
1007         test    %rdi,%rdi
1008         je      nb_monitorexit              /* if (null) throw exception          */
1009         jmp     builtin_monitorexit         /* else call builtin_monitorenter     */
1010
1011 nb_monitorexit:
1012         /*call    new_nullpointerexception*/
1013         pop     xpc                        /* delete return address              */
1014         sub     $3,xpc                     /* faulting address is ra - 3         */
1015         mov     string_java_lang_NullPointerException,xptr
1016         jmp     asm_throw_and_handle_exception
1017 #endif
1018
1019
1020 /********************* function asm_builtin_x2x ********************************
1021 *                                                                              *
1022 *   Wrapper functions for float to int corner cases                            *
1023 *                                                                              *
1024 *******************************************************************************/
1025
1026 asm_builtin_f2i:
1027         sub     $(14*8),%rsp
1028         
1029         SAVE_ARGUMENT_REGISTERS
1030         
1031         movq    %xmm8,%xmm0
1032         call    builtin_f2i
1033         
1034         RESTORE_ARGUMENT_REGISTERS
1035         
1036         add     $(14*8),%rsp
1037         ret
1038
1039
1040 asm_builtin_f2l:
1041         sub     $(14*8),%rsp
1042         
1043         SAVE_ARGUMENT_REGISTERS
1044         
1045         movq    %xmm8,%xmm0
1046         call    builtin_f2l
1047         
1048         RESTORE_ARGUMENT_REGISTERS
1049         
1050         add     $(14*8),%rsp
1051         ret
1052
1053
1054 asm_builtin_d2i:
1055         sub     $(14*8),%rsp
1056         
1057         SAVE_ARGUMENT_REGISTERS
1058         
1059         movq    %xmm8,%xmm0
1060         call    builtin_d2i
1061         
1062         RESTORE_ARGUMENT_REGISTERS
1063         
1064         add     $(14*8),%rsp
1065         ret
1066
1067
1068 asm_builtin_d2l:
1069         sub     $(14*8),%rsp
1070         
1071         SAVE_ARGUMENT_REGISTERS
1072         
1073         movq    %xmm8,%xmm0
1074         call    builtin_d2l
1075         
1076         RESTORE_ARGUMENT_REGISTERS
1077         
1078         add     $(14*8),%rsp
1079         ret
1080
1081
1082 /* asm_builtin_checkarraycast **************************************************
1083
1084    Does the cast check and eventually throws an exception.
1085
1086 *******************************************************************************/
1087
1088 asm_builtin_checkarraycast:
1089         sub     $24,%rsp                    /* keep stack 16-byte aligned         */
1090         mov     %rdi,(%rsp)                 /* save object pointer                */
1091         call    builtin_checkarraycast      /* builtin_checkarraycast             */
1092         test    %rax,%rax                   /* if (false) throw exception         */
1093         je      nb_carray_throw
1094         mov     (%rsp),%rax                 /* return object pointer              */
1095         add     $24,%rsp                    /* free stack space                   */
1096         ret
1097
1098 nb_carray_throw:
1099         /*call    new_classcastexception*/
1100         add     $24,%rsp
1101         pop     xpc                        /* delete return address              */
1102         sub     $3,xpc                     /* faulting address is ra - 3         */
1103         mov     string_java_lang_ClassCastException,xptr
1104         jmp     asm_throw_and_handle_exception
1105
1106                 
1107 /* asm_builtin_aastore *********************************************************
1108
1109    Checks if the object can be stored in the given array and stores the
1110    address if it's possible. This function can also throw some exceptions.
1111
1112 *******************************************************************************/
1113
1114 asm_builtin_aastore:
1115         sub     $(3*8),%rsp             /* allocate stack space                   */
1116         test    %rdi,%rdi               /* if null pointer throw exception        */
1117         je      nb_aastore_null
1118
1119         movl    offarraysize(%rdi),%eax /* load size                              */
1120         cmpl    %eax,%esi               /* do bound check                         */
1121         jae     nb_aastore_bound        /* if out of bounds throw exception       */
1122
1123         shl     $3,%rsi                 /* index * 8                              */
1124         mov     %rdi,%r10
1125         add     %rsi,%r10               /* add index * 8 to arrayref              */
1126
1127         mov     %r10,(%rsp)             /* save store position                    */
1128         mov     %rdx,8(%rsp)            /* save object                            */
1129
1130         mov     %rdx,%rsi               /* object is second argument              */
1131         call    builtin_canstore        /* builtin_canstore(arrayref,object)      */
1132         test    %rax,%rax               /* if (false) throw exception             */
1133         je      nb_aastore_throw
1134
1135         mov     (%rsp),%r10             /* restore store position                 */
1136         mov     8(%rsp),%rdx            /* restore object                         */
1137         mov     %rdx,offobjarrdata(%r10)/* store objectptr in array               */
1138         add     $(3*8),%rsp             /* free stack space                       */
1139         ret
1140
1141 nb_aastore_null:
1142         add     $24,%rsp
1143         pop     xpc                    /* delete return address from stack       */
1144         sub     $3,xpc                 /* faulting address is return adress - 3  */
1145         mov     string_java_lang_NullPointerException,xptr
1146         jmp    asm_throw_and_handle_exception
1147
1148 nb_aastore_bound:
1149         add     $24,%rsp
1150         push    $0 /*directly below return address*/
1151         push    $0 /*internal*/
1152         push    $0 /*padding*/
1153         mov     %rsi,itmp1
1154         
1155         call    asm_prepare_native_stackinfo
1156
1157         mov     itmp1,%rdi               /* move index into a0                     */
1158         call    new_arrayindexoutofboundsexception
1159
1160         call    asm_remove_native_stackinfo
1161
1162         pop     xpc                    /* just remove one quadword                  */
1163         pop     xpc                    /* delete return address                  */
1164         sub     $3,xpc                 /* faulting address is return adress - 3  */
1165         jmp     asm_handle_exception
1166                 
1167 nb_aastore_throw:
1168         /*call    new_arraystoreexception*/
1169         add     $24,%rsp
1170         pop     xpc                    /* delete return address                  */
1171         sub     $3,xpc                 /* faulting address is return adress - 3  */
1172         mov     string_java_lang_ArrayStoreException,xptr
1173         jmp     asm_throw_and_handle_exception
1174
1175                 
1176 /******************* function asm_initialize_thread_stack **********************
1177 *                                                                              *
1178 * initialized a thread stack                                                   *
1179 * (to)->restorePoint = asm_initialize_thread_stack((u1*)(func), (to)->stackEnd)*
1180 *                                                                              *
1181 *******************************************************************************/
1182
1183 asm_initialize_thread_stack:
1184         sub     $(7*8),%rsi
1185
1186         xor     %r10,%r10
1187         mov     %r10,0*8(%rsi)
1188         mov     %r10,1*8(%rsi)
1189         mov     %r10,2*8(%rsi)
1190         mov     %r10,3*8(%rsi)
1191         mov     %r10,4*8(%rsi)
1192         mov     %r10,5*8(%rsi)
1193
1194         mov     %rdi,6*8(%rsi)          /* save (u1*) (func)                  */
1195         mov     %rsi,%rax               /* return restorepoint in %rax        */
1196         ret
1197
1198
1199 /******************* function asm_perform_threadswitch *************************
1200 *                                                                              *
1201 *   void asm_perform_threadswitch (u1 **from, u1 **to, u1 **stackTop);         *
1202 *                                                                              *
1203 *   performs a threadswitch                                                    *
1204 *                                                                              *
1205 *******************************************************************************/
1206
1207 asm_perform_threadswitch:
1208         sub     $(7*8),%rsp             /* allocate stack frame               */
1209
1210         mov     %rbx,0*8(%rsp)
1211         mov     %rbp,1*8(%rsp)
1212         mov     %r12,2*8(%rsp)
1213         mov     %r13,3*8(%rsp)
1214         mov     %r14,4*8(%rsp)
1215         mov     %r15,5*8(%rsp)
1216
1217         mov     7*8(%rsp),%rax                  /* save current return address        */
1218         mov     %rax,6*8(%rsp)
1219
1220         mov     %rsp,(%rdi)                     /* first argument **from              */
1221         mov     %rsp,(%rdx)                     /* third argument **stackTop          */
1222
1223         mov     (%rsi),%rsp                     /* load new stack pointer             */
1224
1225         mov     0*8(%rsp),%rbx
1226         mov     1*8(%rsp),%rbp
1227         mov     2*8(%rsp),%r12
1228         mov     3*8(%rsp),%r13
1229         mov     4*8(%rsp),%r14
1230         mov     5*8(%rsp),%r15
1231
1232         mov     6*8(%rsp),%rax          /* restore return address             */
1233         add     $(7*8),%rsp             /* free stack frame                   */
1234         mov     %rax,(%rsp)
1235         ret
1236                 
1237
1238 /********************* function asm_switchstackandcall *************************
1239 *                                                                              *
1240 *  int asm_switchstackandcall (void *stack, void *func, void **stacktopsave,   *
1241 *                                      void *p);                                       *
1242 *                                                                              *
1243 *   Switches to a new stack, calls a function and switches back.               *
1244 *       a0 (%rdi)     new stack pointer                                        *
1245 *       a1 (%rsi)     function pointer                                         *
1246 *               a2 (%rdx)     pointer to variable where stack top should be stored     *
1247 *       a3 (%rcx)     pointer to user data, is passed to the function          *
1248 *                                                                              *
1249 *******************************************************************************/
1250
1251 asm_switchstackandcall:
1252         sub     $(1*8),%rsp             /* keep stack 16-byte aligned         */
1253         sub     $16,%rdi                                /* allocate new stack                 */
1254
1255         mov     8(%rsp),%rax                    /* save return address on new stack   */
1256         mov     %rax,(%rdi)
1257         mov     %rsp,8(%rdi)                    /* save old stack pointer on new stack*/
1258         mov     %rsp,(%rdx)                             /* save old stack pointer to variable */
1259
1260         mov     %rdi,%rsp                               /* switch to new stack                */
1261
1262         mov     %rcx,%rdi                       /* pass pointer                       */
1263         call    *%rsi                                   /* and call function                  */
1264
1265         mov     (%rsp),%r10                             /* load return address                */
1266         mov     8(%rsp),%rsp                    /* switch to old stack                */
1267         add     $(1*8),%rsp             /* free stack space                   */
1268         mov     %r10,(%rsp)             /* write return adress                */
1269         ret
1270
1271
1272
1273
1274 /************************ function asm_prepare_native_stackinfo ****************************
1275 *                                                                                          *
1276 *    creates a stackfame for the begin of a native function (either builtin or not )       *
1277 *    expected stack at begin of function                                                   *
1278 *                                        ....                                              *
1279 *                   address of the jit call which invokes the native                       *
1280 *                   begin address of stack frame of the java method                        *
1281 *                   method pointer or 0 (for built ins)                                    *
1282 *                   padding for stackframesize 16*n+8                                      *
1283 *                   return address                                                         *
1284 *                                                                                          *
1285 *    at end of function:                                                                   *
1286 *                                          ...                                             *
1287 *                   address of the jit call which invokes the native                       *
1288 *                   begin address of stack frame of the java method                        *
1289 *                   method pointer or 0 (for built ins)                                    *
1290 *                   address of thread specific top of native list                          *
1291 *                   old value of thread specific head                                      *
1292 *                   padding for stackframesize 16*n+8)                                     *
1293 *                   return address                                                         *
1294 *                                                                                          *
1295 *                                        ....                                              *
1296 * This thing is less efficient than the original #define (callerside)                      *
1297 * destroyes REG_ITMP2, keeps REG_ITMP1                                                     *
1298 ********************************************************************************************/
1299
1300
1301 asm_prepare_native_stackinfo:
1302         sub $16,%rsp  /*space for the 2 new pointers*/
1303         mov 16(%rsp),itmp2
1304         mov itmp2,(%rsp)
1305         push itmp1
1306         call builtin_asm_get_stackframeinfo
1307
1308         mov itmp1, 32(%rsp)
1309         mov (itmp1),itmp2
1310         mov itmp2,24(%rsp)
1311         mov %rsp,itmp2
1312         add $24,itmp2
1313         mov itmp2,(itmp1)
1314         pop itmp1
1315         ret
1316
1317                 
1318
1319 /************************ function asm_remove _native_stackinfo *******************************************
1320 *                                                                                                         *
1321 *    removes a stackfame for the begin of a native function (either builtin or not)                       *
1322 *    expected stack at begin of function                                                                  *
1323 *                   address of the jit call which invokes the native                                      *
1324 *                   begin address of stack frame of the java method                                       *
1325 *                   method pointer or 0 (for built ins)                                                   *
1326 *                   address thread specific top of native list                                            *
1327 *                   old value of thread specific head                                                     *
1328 *                   padding                                                                               *
1329 *                   return address                                                                        *
1330 *                                                                                                         *
1331 *    at end of function:                                                                                  *
1332 *                             ....                                                                        *
1333 *                   return adresss of the jit call which invokes the native                               *
1334 *                   padding                                                                               *
1335 *                   return address                                                                        *
1336 *                                                                                                         *
1337 *                                                                                                         *
1338 *                                                                                                         *
1339 * This thing is less efficient than the original #define (callerside), uses ITMP2,uses ITMP3,keeps ITMP1  *
1340 ***********************************************************************************************************/
1341
1342 asm_remove_native_stackinfo:
1343         mov 16(%rsp),itmp2
1344         mov 24(%rsp),itmp3
1345         mov itmp2,(itmp3)
1346         pop itmp3
1347         add $32,%rsp
1348         push itmp3
1349         ret
1350
1351
1352
1353 asm_throw_and_handle_exception:
1354         push xpc /* the pushed XPC is directly below the java frame*/
1355         push $0 
1356         push $0
1357         push $0 /*padding*/
1358         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1359         mov itmp1,%rdi
1360
1361         call new_exception
1362
1363         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1364
1365         pop xpc
1366         pop xpc
1367
1368         jmp asm_handle_exception
1369         ret /*should never be reached */
1370
1371
1372 asm_throw_and_handle_hardware_arithmetic_exception:
1373
1374         push xpc
1375         push $0 /* the pushed XPC is directly below the java frame*/
1376         push $0
1377         push $0 /*padding*/
1378         call asm_prepare_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1379
1380         mov string_java_lang_ArithmeticException_message,%rsi
1381         mov string_java_lang_ArithmeticException,%rdi
1382
1383         call new_exception_message
1384
1385         call asm_remove_native_stackinfo /* be aware of the stack effect and calling convention explained above*/
1386         pop xpc
1387         pop xpc
1388
1389         jmp asm_handle_exception
1390         ret /*should never be reached */
1391
1392
1393 asm_getclassvalues_atomic:
1394 _crit_restart2:
1395 _crit_begin2:
1396         movl    offbaseval(a0),itmp1l
1397         movl    offdiffval(a0),itmp2l
1398         movl    offbaseval(a1),itmp3l
1399 _crit_end2:
1400         movl    itmp1l,offcast_super_baseval(a2)
1401         movl    itmp2l,offcast_super_diffval(a2)
1402         movl    itmp3l,offcast_sub_baseval(a2)
1403         ret
1404
1405         .data
1406                 
1407 asm_criticalsections:
1408 #if defined(USE_THREADS) && defined(NATIVE_THREADS)
1409         .quad   _crit_begin1
1410         .quad   _crit_end1
1411         .quad   _crit_restart1
1412         .quad   _crit_begin2
1413         .quad   _crit_end2
1414         .quad   _crit_restart2
1415 #endif
1416         .quad 0
1417
1418                 
1419 /*
1420  * These are local overrides for various environment variables in Emacs.
1421  * Please do not remove this and leave it at the end of the file, where
1422  * Emacs will automagically detect them.
1423  * ---------------------------------------------------------------------
1424  * Local variables:
1425  * mode: asm
1426  * indent-tabs-mode: t
1427  * c-basic-offset: 4
1428  * tab-width: 4
1429  * End:
1430  */